From 0dd6aa37043ba804cb2f1c852ca867239026e39d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Wed, 29 Apr 2026 09:19:58 +0200 Subject: [PATCH] Prevent ECC tmp key leak and UB in wc_ecc_mulmod_ex ecc_key_tmp_final was guarded by `if (err == MP_OKAY)`, leaking key->t1/t2 (and x/y/z under ALT_ECC_SIZE) whenever an allocation or mulmod step after ecc_key_tmp_init failed. Simply removing the guard is unsafe here: unlike wc_ecc_mulmod_ex2 (whose arg checks `return` directly), this function XMALLOC'd `key` before the arg checks and used `goto exit`, so a bad-arg call would hand uninitialized memory to ecc_key_tmp_final and XFREE garbage pointers. Defer the XMALLOC until after the arg/range checks so `key` is NULL on the early-error paths, then call ecc_key_tmp_final unconditionally to plug the leak on the late-error paths. --- wolfcrypt/src/ecc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 684a7d4c0d..34b1f7cdb1 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -3733,7 +3733,7 @@ int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, #endif int i, err; #ifdef WOLFSSL_SMALL_STACK_CACHE - ecc_key *key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC); + ecc_key *key = NULL; #endif mp_digit mp; @@ -3753,6 +3753,7 @@ int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, } #ifdef WOLFSSL_SMALL_STACK_CACHE + key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC); if (key == NULL) { err = MP_MEM; goto exit; @@ -3815,8 +3816,7 @@ int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, if (key) { if (R) R->key = NULL; - if (err == MP_OKAY) - ecc_key_tmp_final(key, heap); + ecc_key_tmp_final(key, heap); XFREE(key, heap, DYNAMIC_TYPE_ECC); } #endif /* WOLFSSL_SMALL_STACK_CACHE */