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.
This commit is contained in:
Tobias Frauenschläger
2026-04-29 09:19:58 +02:00
parent d7a34d4e39
commit 0dd6aa3704
+3 -3
View File
@@ -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 @@ exit:
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 */