From 1aca9a607947f4b6fa4809d76a6a08a08c0b39ed Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 10 Nov 2016 11:39:29 -0800 Subject: [PATCH 1/3] Fix for "wc_ecc_make_key_ex" if call to rng fails. Issue only applies to !USE_FAST_MATH case on failure response from call to "wc_RNG_GenerateBlock". --- wolfcrypt/src/ecc.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index d2cd04a2f..49a4b73a1 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2505,23 +2505,27 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) /* make up random string */ err = wc_RNG_GenerateBlock(rng, buf, keysize); + if (err != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return err; + } /* setup the key variables */ - if (err == 0) { - err = mp_init_multi(&key->k, &prime, &order, &a, NULL, NULL); - if (err == MP_OKAY) { - #ifndef ALT_ECC_SIZE - err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, - NULL, NULL, NULL); - #else - key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; - key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; - key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; - alt_fp_init(key->pubkey.x); - alt_fp_init(key->pubkey.y); - alt_fp_init(key->pubkey.z); - #endif - } + err = mp_init_multi(&key->k, &prime, &order, &a, NULL, NULL); + if (err == MP_OKAY) { + #ifndef ALT_ECC_SIZE + err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, + NULL, NULL, NULL); + #else + key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; + key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; + key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; + alt_fp_init(key->pubkey.x); + alt_fp_init(key->pubkey.y); + alt_fp_init(key->pubkey.z); + #endif } if (err == MP_OKAY) { From 6d5485b88f19f736f6082ad78b1ba36fb5193d0e Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 11 Nov 2016 20:03:58 -0800 Subject: [PATCH 2/3] Fix to "mp_init_multi" so failure ensures a later "mp_clear" won't free on un-initialized pointer. Applies to !USE_FAST_MATH only. No measurable benchmark difference. --- wolfcrypt/src/integer.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index be7bd5fcb..030d3fa01 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -100,6 +100,13 @@ int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, { int res = MP_OKAY; + if (a) XMEMSET(a, 0, sizeof(mp_int)); + if (b) XMEMSET(b, 0, sizeof(mp_int)); + if (c) XMEMSET(c, 0, sizeof(mp_int)); + if (d) XMEMSET(d, 0, sizeof(mp_int)); + if (e) XMEMSET(e, 0, sizeof(mp_int)); + if (f) XMEMSET(f, 0, sizeof(mp_int)); + if (a && ((res = mp_init(a)) != MP_OKAY)) return res; @@ -454,7 +461,7 @@ void mp_zero (mp_int * a) { int n; mp_digit *tmp; - + if (a == NULL) return; @@ -4418,7 +4425,7 @@ int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap) XMEMSET(buf, 0, len); XFREE(buf, heap, DYNAMIC_TYPE_RSA); - + return MP_OKAY; } From cee321323ad723114404365a5531acc1b9906653 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 14 Nov 2016 12:38:01 -0800 Subject: [PATCH 3/3] Better handle "mp_init_multi" failure in "wc_ecc_make_key_ex". --- wolfcrypt/src/ecc.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 49a4b73a1..867d85e54 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2514,20 +2514,25 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) /* setup the key variables */ err = mp_init_multi(&key->k, &prime, &order, &a, NULL, NULL); - if (err == MP_OKAY) { - #ifndef ALT_ECC_SIZE - err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, - NULL, NULL, NULL); - #else - key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; - key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; - key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; - alt_fp_init(key->pubkey.x); - alt_fp_init(key->pubkey.y); - alt_fp_init(key->pubkey.z); + if (err != MP_OKAY) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif + return err; } +#ifndef ALT_ECC_SIZE + err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, + NULL, NULL, NULL); +#else + key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; + key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; + key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; + alt_fp_init(key->pubkey.x); + alt_fp_init(key->pubkey.y); + alt_fp_init(key->pubkey.z); +#endif + if (err == MP_OKAY) { base = wc_ecc_new_point_h(key->heap); if (base == NULL) @@ -2580,14 +2585,15 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) if (err == MP_OKAY) key->type = ECC_PRIVATEKEY; + /* cleanup these on failure case only */ if (err != MP_OKAY) { - /* clean up */ mp_clear(key->pubkey.x); mp_clear(key->pubkey.y); mp_clear(key->pubkey.z); mp_forcezero(&key->k); } + /* cleanup allocations */ wc_ecc_del_point_h(base, key->heap); #ifndef USE_FAST_MATH mp_clear(&a);