From aa1a405dd170daf0c806882e8eb84e3f488aa7e8 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 21 Jun 2016 14:06:02 -0700 Subject: [PATCH 1/6] Fixes for compressed keys. Fix to fast math "mp_cnt_lsb" to return proper value, which fixes "mp_jacobi", which fixes "mp_sqrtmod_prime", which fixes compressed keys for 224-bit key. Removed workarounds for compressed keys. Added new configure option "--enable-compkey". Fixed issue with normal math and custom curves where "t2" could be free'd and used. Fixed issue with mp_dump in integer.c, with not allocating correctly sized buffer for toradix. --- configure.ac | 13 +++++++++++++ wolfcrypt/src/ecc.c | 32 ++++++++++++++++++++++++-------- wolfcrypt/src/integer.c | 2 +- wolfcrypt/src/tfm.c | 7 ++----- wolfcrypt/test/test.c | 19 +++++-------------- wolfssl/wolfcrypt/tfm.h | 4 +--- 6 files changed, 46 insertions(+), 31 deletions(-) diff --git a/configure.ac b/configure.ac index 5ced203d5..753457d48 100644 --- a/configure.ac +++ b/configure.ac @@ -781,6 +781,19 @@ then fi +# Compressed Key +AC_ARG_ENABLE([compkey], + [AS_HELP_STRING([--enable-compkey],[Enable compressed keys support (default: disabled)])], + [ ENABLED_COMPKEY=$enableval ], + [ ENABLED_COMPKEY=no ] + ) + +if test "$ENABLED_COMPKEY" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DHAVE_COMP_KEY" +fi + + # for using memory optimization setting on both curve25519 and ed25519 ENABLED_CURVED25519_SMALL=no diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 5d99a3446..78abd861d 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2746,7 +2746,7 @@ static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime) /* Determine if curve "a" should be used in calc */ #ifdef WOLFSSL_CUSTOM_CURVES /* compute y^2 - x^3 + a*x */ - mp_clear(&t2); + mp_set(&t2, 0); if (err == MP_OKAY) err = mp_submod(prime, &a, prime, &t2); if (err == MP_OKAY) @@ -2894,7 +2894,7 @@ static int ecc_check_pubkey_order(ecc_key* key, mp_int* a, mp_int* prime, } -/* perform sanity checks on ec key validity, 0 on success */ +/* perform sanity checks on ecc key validity, 0 on success */ int wc_ecc_check_key(ecc_key* key) { mp_int prime; /* used by multiple calls so let's cache */ @@ -5462,7 +5462,7 @@ int mp_jacobi(mp_int* a, mp_int* n, int* c) res = mp_jacobi (&p1, &a1, &r); if (res == MP_OKAY) - *c = s * r; + *c = s * r; } } @@ -5474,25 +5474,39 @@ int mp_jacobi(mp_int* a, mp_int* n, int* c) } +/* Solves the modular equation x^2 = n (mod p) + * where prime number is greater than 2 (odd prime). + * The result is returned in the third argument x + * the function returns MP_OKAY on success, MP_VAL or another error on failure + */ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) { int res, legendre, done = 0; mp_int t1, C, Q, S, Z, M, T, R, two; mp_digit i; - /* first handle the simple cases */ + /* first handle the simple cases n = 0 or n = 1 */ if (mp_cmp_d(n, 0) == MP_EQ) { mp_zero(ret); return MP_OKAY; } + if (mp_cmp_d(n, 1) == MP_EQ) { + mp_set(ret, 1); + return MP_OKAY; + } /* prime must be odd */ - if (mp_cmp_d(prime, 2) == MP_EQ) + if (mp_cmp_d(prime, 2) == MP_EQ) { return MP_VAL; + } - /* TAO removed - if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; - if (legendre == -1) return MP_VAL; */ /* quadratic non-residue mod prime */ + /* is quadratic non-residue mod prime */ + if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) { + return res; + } + if (legendre == -1) { + return MP_VAL; + } if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY) return res; @@ -5587,6 +5601,8 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) while (res == MP_OKAY && done == 0) { res = mp_copy(&T, &t1); + + /* reduce to 1 and count */ i = 0; while (res == MP_OKAY) { if (mp_cmp_d(&t1, 1) == MP_EQ) diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index a74e9805c..679efafd3 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -4801,7 +4801,7 @@ void mp_dump(const char* desc, mp_int* a, byte verbose) char *buffer; int size = a->alloc; - buffer = (char*)XMALLOC(size * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buffer = (char*)XMALLOC(size * sizeof(mp_digit) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buffer == NULL) { return; } diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 31bbd7c53..0a26b8e56 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -891,7 +891,7 @@ top: int fp_invmod(fp_int *a, fp_int *b, fp_int *c) { fp_int x, y, u, v, B, D; - int neg, loop_check = 0; + int neg; /* 2. [modified] b must be odd */ if (fp_iseven (b) == FP_YES) { @@ -955,8 +955,6 @@ top: /* if not zero goto step 4 */ if (fp_iszero (&u) == FP_NO) { - if (++loop_check > 4096) /* bad input */ - return FP_VAL; goto top; } @@ -2968,8 +2966,7 @@ int mp_init_copy(fp_int * a, fp_int * b) int mp_cnt_lsb(fp_int* a) { - fp_cnt_lsb(a); - return MP_OKAY; + return fp_cnt_lsb(a); } #endif /* HAVE_COMP_KEY */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 4c2973202..bb27ab779 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6675,7 +6675,7 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) } #endif /* WOLFSSL_KEY_GEN */ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, - int testCompressedKey, const ecc_set_type* dp) + const ecc_set_type* dp) { #ifdef BENCH_EMBEDDED byte sharedA[128]; /* Needs to be at least keySize */ @@ -6735,7 +6735,6 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, #ifdef HAVE_ECC_KEY_EXPORT x = sizeof(exportBuf); - ret = wc_ecc_export_x963(&userA, exportBuf, &x); if (ret != 0) ERROR_OUT(-1006, done); @@ -6755,11 +6754,9 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, ERROR_OUT(-1009, done); #endif /* HAVE_ECC_DHE */ - if (testCompressedKey) { #ifdef HAVE_COMP_KEY /* try compressed export / import too */ x = sizeof(exportBuf); - ret = wc_ecc_export_x963_ex(&userA, exportBuf, &x, 1); if (ret != 0) ERROR_OUT(-1010, done); @@ -6780,7 +6777,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, ERROR_OUT(-1013, done); #endif /* HAVE_ECC_DHE */ #endif /* HAVE_COMP_KEY */ - } + #endif /* HAVE_ECC_KEY_IMPORT */ #endif /* HAVE_ECC_KEY_EXPORT */ @@ -6850,15 +6847,9 @@ done: #define ECC_TEST_VERIFY_COUNT 2 static int ecc_test_curve(WC_RNG* rng, int keySize) { - int ret, testCompressedKey = 1; + int ret; - /* At this time, ECC 224-bit does not work with compressed key */ - if (keySize == 28) { - testCompressedKey = 0; - } - - ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT, - testCompressedKey, NULL); + ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT, NULL); if (ret < 0) { printf("ecc_test_curve_size %d failed!: %d\n", keySize, ret); return ret; @@ -6936,7 +6927,7 @@ int ecc_test(void) "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */ }; - ret = ecc_test_curve_size(&rng, -1, ECC_TEST_VERIFY_COUNT, 0, &ecc_cust_dp); + ret = ecc_test_curve_size(&rng, -1, ECC_TEST_VERIFY_COUNT, &ecc_cust_dp); if (ret < 0) { printf("ecc_test_curve_size custom failed!: %d\n", ret); goto done; diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 42c6966b5..3d750ee24 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -347,9 +347,7 @@ typedef struct { #define TFM_SQR64 #endif -/* do we want some overflow checks - Not required if you make sure your numbers are within range (e.g. by default a modulus for fp_exptmod() can only be up to 2048 bits long) - */ +/* Optional math checks (enable WOLFSSL_DEBUG_MATH to print info) */ /* #define TFM_CHECK */ /* Is the target a P4 Prescott From dd52af0872b7e6fa8befcd3e04078f017a7ff4fe Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 21 Jun 2016 15:27:51 -0700 Subject: [PATCH 2/6] ECC cleanup / fixes. Improvements to ECC with fast math enabled to avoid mp_clear on stack variables. Refactor of ECC failure cleanup (fixes possible mem leaks with small stack enabled). Refactor of "fp_is*" response checks to use FP_YES or FP_NO. Pulled libtom enhancement/cleanup of fp_isprime. Fix for compressed keys import with custom curves (still having some issues though). --- wolfcrypt/src/ecc.c | 225 +++++++++++++++++++++------------------- wolfcrypt/src/integer.c | 2 +- wolfcrypt/src/tfm.c | 92 +++++++++------- wolfcrypt/test/test.c | 4 +- wolfssl/wolfcrypt/tfm.h | 5 +- 5 files changed, 181 insertions(+), 147 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 78abd861d..b6f7baee5 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -314,16 +314,16 @@ int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, if ( (mp_cmp(P->x, Q->x) == MP_EQ) && (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) && (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, &t1) == MP_EQ)) { - mp_clear(&t1); - mp_clear(&t2); - return ecc_projective_dbl_point(P, R, a, modulus, mp); + #ifndef USE_FAST_MATH + mp_clear(&t1); + mp_clear(&t2); + #endif + return ecc_projective_dbl_point(P, R, a, modulus, mp); } } if (err != MP_OKAY) { - mp_clear(&t1); - mp_clear(&t2); - return err; + goto done; } /* If use ALT_ECC_SIZE we need to use local stack variable since @@ -335,9 +335,7 @@ int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, z = &rz; if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { - mp_clear(&t1); - mp_clear(&t2); - return err; + goto done; } #else /* Use destination directly */ @@ -544,6 +542,7 @@ int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, err = mp_copy(z, R->z); #endif +done: #ifndef USE_FAST_MATH /* clean up */ mp_clear(&t1); @@ -606,8 +605,10 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, z = &rz; if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { + #ifndef USE_FAST_MATH mp_clear(&t1); mp_clear(&t2); + #endif return err; } #else @@ -852,9 +853,7 @@ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) z = &rz; if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { - mp_clear(&t1); - mp_clear(&t2); - return err; + goto done; } if (err == MP_OKAY) @@ -870,6 +869,10 @@ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) z = P->z; #endif + if (err != MP_OKAY) { + goto done; + } + /* first map z back to normal */ err = mp_montgomery_reduce(z, modulus, mp); @@ -907,8 +910,9 @@ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) mp_copy(z, P->z); #endif +done: + /* clean up */ #ifndef USE_FAST_MATH - /* clean up */ mp_clear(&t1); mp_clear(&t2); #endif @@ -970,7 +974,9 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, for (j = 0; j < i; j++) { wc_ecc_del_point_h(M[j], heap); } + #ifndef USE_FAST_MATH mp_clear(&mu); + #endif return MEMORY_E; } } @@ -997,8 +1003,10 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, } } +#ifndef USE_FAST_MATH /* done with mu */ mp_clear(&mu); +#endif /* calc the M tab, which holds kG for k==8..15 */ /* M[0] == 8G */ @@ -1210,8 +1218,10 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, if (err == MP_OKAY) err = mp_mulmod(G->z, &mu, modulus, tG->z); +#ifndef USE_FAST_MATH /* done with mu */ mp_clear(&mu); +#endif /* calc the M tab */ /* M[0] == G */ @@ -1534,8 +1544,10 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, *outlen = x; } +#ifndef USE_FAST_MATH mp_clear(&a); mp_clear(&prime); +#endif wc_ecc_del_point_h(result, private_key->heap); return err; @@ -1603,8 +1615,10 @@ int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point, *outlen = x; } +#ifndef USE_FAST_MATH mp_clear(&a); mp_clear(&prime); +#endif wc_ecc_del_point_h(result, private_key->heap); return err; @@ -1753,9 +1767,11 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, } wc_ecc_del_point_h(base, key->heap); +#ifndef USE_FAST_MATH mp_clear(&a); mp_clear(&prime); mp_clear(&order); +#endif ForceZero(buf, ECC_MAXSIZE); #ifdef WOLFSSL_SMALL_STACK @@ -1861,8 +1877,10 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, if (err == MP_OKAY) err = StoreECC_DSA_Sig(out, outlen, &r, &s); +#ifndef USE_FAST_MATH mp_clear(&r); mp_clear(&s); +#endif return err; } @@ -1968,8 +1986,10 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } } +#ifndef USE_FAST_MATH mp_clear(&p); mp_clear(&e); +#endif return err; } @@ -2100,8 +2120,10 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA, if (err == MP_OKAY) err = mp_mulmod(B->z, &mu, modulus, precomp[1<<2]->z); + #ifndef USE_FAST_MATH /* done with mu */ mp_clear(&mu); + #endif } } @@ -2138,13 +2160,14 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA, bitbufB = tB[0]; /* for every byte of the multiplicands */ - for (x = -1;; ) { + for (x = 0;; ) { /* grab a nibble */ if (++nibble == 4) { - ++x; if (x == (int)len) break; + if (x == (int)len) break; bitbufA = tA[x]; bitbufB = tB[x]; nibble = 0; + x++; } /* extract two bits from both, shift/update */ @@ -2264,8 +2287,10 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, if (err == MP_OKAY) err = wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, stat, key); +#ifndef USE_FAST_MATH mp_clear(&r); mp_clear(&s); +#endif return err; } @@ -2312,13 +2337,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, } if ((err = mp_init_multi(&modulus, &a, NULL, NULL, NULL, NULL)) != MP_OKAY) { - mp_clear(&v); - mp_clear(&w); - mp_clear(&u1); - mp_clear(&u2); - mp_clear(&order); - mp_clear(&e); - return MEMORY_E; + err = MEMORY_E; goto done; } /* allocate points */ @@ -2424,10 +2443,12 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, *stat = 1; } +done: /* cleanup */ wc_ecc_del_point_h(mG, key->heap); wc_ecc_del_point_h(mQ, key->heap); +#ifndef USE_FAST_MATH mp_clear(&v); mp_clear(&w); mp_clear(&u1); @@ -2436,6 +2457,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, mp_clear(&e); mp_clear(&modulus); mp_clear(&a); +#endif return err; } @@ -2535,11 +2557,13 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, } } + #ifndef USE_FAST_MATH mp_clear(&a); mp_clear(&b); mp_clear(&prime); mp_clear(&t2); mp_clear(&t1); + #endif } #endif @@ -2785,10 +2809,12 @@ static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime) } } +#ifndef USE_FAST_MATH mp_clear(&a); mp_clear(&b); mp_clear(&t1); mp_clear(&t2); +#endif return err; } @@ -2860,7 +2886,9 @@ static int ecc_check_privkey_gen_helper(ecc_key* key) if (err == MP_OKAY) err = ecc_check_privkey_gen(key, &prime); +#ifndef USE_FAST_MATH mp_clear(&prime); +#endif return err; } @@ -2931,9 +2959,11 @@ int wc_ecc_check_key(ecc_key* key) if (err == MP_OKAY && key->type == ECC_PRIVATEKEY) err = ecc_check_privkey_gen(key, &a, &prime); +#ifndef USE_FAST_MATH mp_clear(&order); mp_clear(&a); mp_clear(&prime); +#endif return err; } @@ -3062,11 +3092,13 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, mp_copy(&t2, key->pubkey.y); } + #ifndef USE_FAST_MATH mp_clear(&a); mp_clear(&b); mp_clear(&prime); mp_clear(&t2); mp_clear(&t1); + #endif } #endif /* HAVE_COMP_KEY */ @@ -3182,8 +3214,10 @@ int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen) err = MP_ZERO_E; } +#ifndef USE_FAST_MATH mp_clear(&rtmp); mp_clear(&stmp); +#endif return err; } @@ -4115,7 +4149,10 @@ static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp, /* free z */ mp_clear(fp_cache[idx].LUT[x]->z); } + +#ifndef USE_FAST_MATH mp_clear(&tmp); +#endif if (err == MP_OKAY) return MP_OKAY; @@ -4129,7 +4166,6 @@ static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp, fp_cache[idx].g = NULL; fp_cache[idx].lru_count = 0; mp_clear(&fp_cache[idx].mu); - mp_clear(&tmp); return err; } @@ -4146,20 +4182,14 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, unsigned char kb[KB_SIZE]; #endif int x; - unsigned y, z, err, bitlen, bitpos, lut_gap, first; - mp_int tk; + unsigned y, z = 0, err, bitlen, bitpos, lut_gap, first; + mp_int tk, order; - if (mp_init(&tk) != MP_OKAY) + if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY) return MP_INIT_E; /* if it's smaller than modulus we fine */ if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) { - mp_int order; - if (mp_init(&order) != MP_OKAY) { - mp_clear(&tk); - return MP_INIT_E; - } - /* find order */ y = mp_unsigned_bin_size(modulus); for (x = 0; ecc_sets[x].size; x++) { @@ -4170,22 +4200,17 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, if (y == 66) --x; if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { - mp_clear(&order); - mp_clear(&tk); - return err; + goto done; } /* k must be less than modulus */ if (mp_cmp(k, &order) != MP_LT) { if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) { - mp_clear(&tk); - mp_clear(&order); - return err; + goto done; } } else { mp_copy(k, &tk); } - mp_clear(&order); } else { mp_copy(k, &tk); } @@ -4200,29 +4225,25 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, /* get the k value */ if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) { - mp_clear(&tk); - return BUFFER_E; + err = BUFFER_E; goto done; } /* store k */ #ifdef WOLFSSL_SMALL_STACK kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (kb == NULL) - return MEMORY_E; + if (kb == NULL) { + err = MEMORY_E; goto done; + } #endif XMEMSET(kb, 0, KB_SIZE); - if ((err = mp_to_unsigned_bin(&tk, kb)) != MP_OKAY) { - mp_clear(&tk); - } - else { + if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) { /* let's reverse kb so it's little endian */ x = 0; y = mp_unsigned_bin_size(&tk); if (y > 0) { y -= 1; } - mp_clear(&tk); while ((unsigned)x < y) { z = kb[x]; kb[x] = kb[y]; kb[y] = z; @@ -4268,7 +4289,6 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, } if (err == MP_OKAY) { - z = 0; /* mp_to_unsigned_bin != MP_OKAY z will be declared/not set */ (void) z; /* Acknowledge the unused assignment */ ForceZero(kb, KB_SIZE); @@ -4280,6 +4300,13 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, } } +done: + /* cleanup */ +#ifndef USE_FAST_MATH + mp_clear(&order); + mp_clear(&tk); +#endif + #ifdef WOLFSSL_SMALL_STACK XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -4305,13 +4332,13 @@ static int accel_fp_mul2add(int idx1, int idx2, #endif int x; unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB; - mp_int tka; - mp_int tkb; - mp_int order; + mp_int tka, tkb, order; - if (mp_init_multi(&tka, &tkb, 0, 0, 0, 0) != MP_OKAY) + if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY) return MP_INIT_E; + XMEMSET(kb, 0, sizeof(kb)); + /* if it's smaller than modulus we fine */ if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { /* find order */ @@ -4323,30 +4350,18 @@ static int accel_fp_mul2add(int idx1, int idx2, /* back off if we are on the 521 bit curve */ if (y == 66) --x; - if ((err = mp_init(&order)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - return err; - } if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - mp_clear(&order); - return err; + goto done; } /* kA must be less than modulus */ if (mp_cmp(kA, &order) != MP_LT) { if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - mp_clear(&order); - return err; + goto done; } } else { mp_copy(kA, &tka); } - mp_clear(&order); } else { mp_copy(kA, &tka); } @@ -4362,30 +4377,18 @@ static int accel_fp_mul2add(int idx1, int idx2, /* back off if we are on the 521 bit curve */ if (y == 66) --x; - if ((err = mp_init(&order)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - return err; - } if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - mp_clear(&order); - return err; + goto done; } /* kB must be less than modulus */ if (mp_cmp(kB, &order) != MP_LT) { if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - mp_clear(&order); - return err; + goto done; } } else { mp_copy(kB, &tkb); } - mp_clear(&order); } else { mp_copy(kB, &tkb); } @@ -4401,26 +4404,20 @@ static int accel_fp_mul2add(int idx1, int idx2, /* get the k value */ if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) || (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) { - mp_clear(&tka); - mp_clear(&tkb); - return BUFFER_E; + err = BUFFER_E; goto done; } /* store k */ #ifdef WOLFSSL_SMALL_STACK kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (kb[0] == NULL) - return MEMORY_E; + if (kb[0] == NULL) { + err = MEMORY_E; goto done; + } #endif XMEMSET(kb[0], 0, KB_SIZE); if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) { - mp_clear(&tka); - mp_clear(&tkb); -#ifdef WOLFSSL_SMALL_STACK - XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return err; + goto done; } /* let's reverse kb so it's little endian */ @@ -4439,22 +4436,18 @@ static int accel_fp_mul2add(int idx1, int idx2, #ifdef WOLFSSL_SMALL_STACK kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (kb[1] == NULL) { - XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; + err = MEMORY_E; goto done; } #endif XMEMSET(kb[1], 0, KB_SIZE); - if ((err = mp_to_unsigned_bin(&tkb, kb[1])) != MP_OKAY) { - mp_clear(&tkb); - } - else { + if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) { x = 0; y = mp_unsigned_bin_size(&tkb); if (y > 0) { y -= 1; } - mp_clear(&tkb); + while ((unsigned)x < y) { z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z; ++x; --y; @@ -4525,6 +4518,14 @@ static int accel_fp_mul2add(int idx1, int idx2, } } +done: + /* cleanup */ +#ifndef USE_FAST_MATH + mp_clear(&tkb); + mp_clear(&tka); + mp_clear(&order); +#endif + ForceZero(kb[0], KB_SIZE); ForceZero(kb[1], KB_SIZE); @@ -4660,7 +4661,9 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, #ifndef HAVE_THREAD_LS UnLockMutex(&ecc_fp_lock); #endif /* HAVE_THREAD_LS */ +#ifndef USE_FAST_MATH mp_clear(&mu); +#endif return err; } @@ -4764,7 +4767,9 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, #ifndef HAVE_THREAD_LS UnLockMutex(&ecc_fp_lock); #endif /* HAVE_THREAD_LS */ +#ifndef USE_FAST_MATH mp_clear(&mu); +#endif return err; } @@ -5417,13 +5422,12 @@ int mp_jacobi(mp_int* a, mp_int* n, int* c) s = 0; /* step 3. write a = a1 * 2**k */ - if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { + if ((res = mp_init_multi(&a1, &p1, NULL, NULL, NULL, NULL)) != MP_OKAY) { return res; } - if ((res = mp_init (&p1)) != MP_OKAY) { - mp_clear(&a1); - return res; + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto done; } /* divide out larger power of two */ @@ -5466,9 +5470,12 @@ int mp_jacobi(mp_int* a, mp_int* n, int* c) } } - /* done */ - mp_clear (&p1); - mp_clear (&a1); +done: + /* cleanup */ +#ifndef USE_FAST_MATH + mp_clear(&p1); + mp_clear(&a1); +#endif return res; } @@ -5550,7 +5557,7 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) if (res == MP_OKAY) mp_zero(&S); - while (res == MP_OKAY && mp_iseven(&Q)) { + while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) { /* Q = Q / 2 */ res = mp_div_2(&Q, &Q); @@ -5648,6 +5655,7 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) } } +#ifndef USE_FAST_MATH /* done */ mp_clear(&t1); mp_clear(&C); @@ -5658,13 +5666,14 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) mp_clear(&T); mp_clear(&R); mp_clear(&two); +#endif return res; } /* export public ECC key in ANSI X9.63 format compressed */ -int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen) +static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen) { word32 numlen; int ret = MP_OKAY; diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 679efafd3..245340356 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -4203,7 +4203,7 @@ int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) #ifdef WOLFSSL_KEY_GEN -const mp_digit ltm_prime_tab[] = { +const mp_digit ltm_prime_tab[PRIME_SIZE] = { 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 0a26b8e56..dbd1d734b 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -521,7 +521,7 @@ int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d) int n, t, i, norm, neg; /* is divisor zero ? */ - if (fp_iszero (b) == 1) { + if (fp_iszero (b) == FP_YES) { return FP_VAL; } @@ -787,7 +787,7 @@ static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c) int res; /* b cannot be negative */ - if (b->sign == FP_NEG || fp_iszero(b) == 1) { + if (b->sign == FP_NEG || fp_iszero(b) == FP_YES) { return FP_VAL; } @@ -804,7 +804,7 @@ static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c) fp_copy(b, &y); /* 2. [modified] if x,y are both even then return an error! */ - if (fp_iseven (&x) == 1 && fp_iseven (&y) == 1) { + if (fp_iseven (&x) == FP_YES && fp_iseven (&y) == FP_YES) { return FP_VAL; } @@ -816,12 +816,12 @@ static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c) top: /* 4. while u is even do */ - while (fp_iseven (&u) == 1) { + while (fp_iseven (&u) == FP_YES) { /* 4.1 u = u/2 */ fp_div_2 (&u, &u); /* 4.2 if A or B is odd then */ - if (fp_isodd (&A) == 1 || fp_isodd (&B) == 1) { + if (fp_isodd (&A) == FP_YES || fp_isodd (&B) == FP_YES) { /* A = (A+y)/2, B = (B-x)/2 */ fp_add (&A, &y, &A); fp_sub (&B, &x, &B); @@ -832,12 +832,12 @@ top: } /* 5. while v is even do */ - while (fp_iseven (&v) == 1) { + while (fp_iseven (&v) == FP_YES) { /* 5.1 v = v/2 */ fp_div_2 (&v, &v); /* 5.2 if C or D is odd then */ - if (fp_isodd (&C) == 1 || fp_isodd (&D) == 1) { + if (fp_isodd (&C) == FP_YES || fp_isodd (&D) == FP_YES) { /* C = (C+y)/2, D = (D-x)/2 */ fp_add (&C, &y, &C); fp_sub (&D, &x, &D); @@ -861,7 +861,7 @@ top: } /* if not zero goto step 4 */ - if (fp_iszero (&u) == 0) + if (fp_iszero (&u) == FP_NO) goto top; /* now a = C, b = D, gcd == g*v */ @@ -2100,8 +2100,12 @@ void fp_sub_d(fp_int *a, fp_digit b, fp_int *c) fp_int tmp; fp_init(&tmp); fp_set(&tmp, b); +#ifdef ALT_ECC_SIZE + fp_sub(a, &tmp, &tmp); + fp_copy(&tmp, c); +#else fp_sub(a, &tmp, c); - fp_clear(&tmp); + #endif } @@ -2361,10 +2365,19 @@ int mp_set_bit(mp_int *a, mp_digit b) /* c = a * a (mod b) */ int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c) { - fp_int tmp; - fp_init(&tmp); - fp_sqr(a, &tmp); - return fp_mod(&tmp, b, c); + int err; + fp_int t; + + fp_init(&t); + fp_sqr(a, &t); +#ifdef ALT_ECC_SIZE + err = fp_mod(&t, b, &t); + fp_copy(&t, c); +#else + err = fp_mod(&t, b, c); +#endif + + return err; } /* fast math conversion */ @@ -2386,10 +2399,6 @@ int mp_montgomery_calc_normalization(mp_int *a, mp_int *b) #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ defined(WOLFSSL_DEBUG_MATH) -static const int lnz[16] = { - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - #ifdef WOLFSSL_KEY_GEN /* swap the elements of two integers, for cases where you can't simply swap the * mp_int pointers around @@ -2404,6 +2413,10 @@ static void fp_exch (fp_int * a, fp_int * b) } #endif +static const int lnz[16] = { + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + /* Counts the number of lsbs which are zero before the first zero bit */ int fp_cnt_lsb(fp_int *a) { @@ -2411,12 +2424,12 @@ int fp_cnt_lsb(fp_int *a) fp_digit q, qq; /* easy out */ - if (fp_iszero(a) == 1) { + if (fp_iszero(a) == FP_YES) { return 0; } /* scan lower digits until non-zero */ - for (x = 0; x < a->used && a->dp[x] == 0; x++); + for (x = 0; x < a->used && a->dp[x] == 0; x++) {} q = a->dp[x]; x *= DIGIT_BIT; @@ -2438,16 +2451,16 @@ static int s_is_power_of_two(fp_digit b, int *p) /* fast return if no power of two */ if ((b==0) || (b & (b-1))) { - return 0; + return FP_NO; } for (x = 0; x < DIGIT_BIT; x++) { if (b == (((fp_digit)1)< cb + d == a */ @@ -2464,7 +2477,7 @@ static int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d) } /* quick outs */ - if (b == 1 || fp_iszero(a) == 1) { + if (b == 1 || fp_iszero(a) == FP_YES) { if (d != NULL) { *d = 0; } @@ -2475,7 +2488,7 @@ static int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d) } /* power of two ? */ - if (s_is_power_of_two(b, &ix) == 1) { + if (s_is_power_of_two(b, &ix) == FP_YES) { if (d != NULL) { *d = a->dp[0] & ((((fp_digit)1)< FP_PRIME_SIZE) { + return FP_NO; + } + /* do trial division */ - for (r = 0; r < 256; r++) { + for (r = 0; r < FP_PRIME_SIZE; r++) { fp_mod_d(a, primes[r], &d); if (d == 0) { return FP_NO; } } - /* now do 8 miller rabins */ + /* now do 't' miller rabins */ fp_init(&b); - for (r = 0; r < 8; r++) { + for (r = 0; r < t; r++) { fp_set(&b, primes[r]); fp_prime_miller_rabin(a, &b, &res); if (res == FP_NO) { @@ -2715,6 +2732,11 @@ int fp_isprime(fp_int *a) return FP_YES; } +int fp_isprime(fp_int *a) +{ + return fp_isprime_ex(a, 8); +} + int fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap) { static const int USE_BBS = 1; @@ -2794,11 +2816,11 @@ void fp_gcd(fp_int *a, fp_int *b, fp_int *c) fp_int u, v, r; /* either zero than gcd is the largest */ - if (fp_iszero (a) == 1 && fp_iszero (b) == 0) { + if (fp_iszero (a) == FP_YES && fp_iszero (b) == FP_NO) { fp_abs (b, c); return; } - if (fp_iszero (a) == 0 && fp_iszero (b) == 1) { + if (fp_iszero (a) == FP_NO && fp_iszero (b) == FP_YES) { fp_abs (a, c); return; } @@ -2806,7 +2828,7 @@ void fp_gcd(fp_int *a, fp_int *b, fp_int *c) /* optimized. At this point if a == 0 then * b must equal zero too */ - if (fp_iszero (a) == 1) { + if (fp_iszero (a) == FP_YES) { fp_zero(c); return; } @@ -3044,7 +3066,7 @@ int mp_toradix (mp_int *a, char *str, int radix) } /* quick out if its zero */ - if (fp_iszero(a) == 1) { + if (fp_iszero(a) == FP_YES) { *str++ = '0'; *str = '\0'; return FP_YES; @@ -3061,7 +3083,7 @@ int mp_toradix (mp_int *a, char *str, int radix) } digs = 0; - while (fp_iszero (&t) == 0) { + while (fp_iszero (&t) == FP_NO) { if ((res = fp_div_d (&t, (fp_digit) radix, &t, &d)) != FP_OKAY) { fp_zero (&t); return res; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index bb27ab779..44c1306ff 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6763,7 +6763,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, wc_ecc_free(&pubKey); wc_ecc_init(&pubKey); - ret = wc_ecc_import_x963(exportBuf, x, &pubKey); + ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, dp); if (ret != 0) ERROR_OUT(-1011, done); @@ -6927,7 +6927,7 @@ int ecc_test(void) "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */ }; - ret = ecc_test_curve_size(&rng, -1, ECC_TEST_VERIFY_COUNT, &ecc_cust_dp); + ret = ecc_test_curve_size(&rng, 0, ECC_TEST_VERIFY_COUNT, &ecc_cust_dp); if (ret < 0) { printf("ecc_test_curve_size custom failed!: %d\n", ret); goto done; diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 3d750ee24..94efa2416 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -516,8 +516,11 @@ int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); /* perform a Miller-Rabin test of a to the base b and store result in "result" */ /*void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result);*/ +#define FP_PRIME_SIZE 256 /* 256 trial divisions + 8 Miller-Rabins, returns FP_YES if probable prime */ -/*int fp_isprime(fp_int *a);*/ +int fp_isprime(fp_int *a); +/* extended version of fp_isprime, do 't' Miller-Rabins instead of only 8 */ +int fp_isprime_ex(fp_int *a, int t); /* Primality generation flags */ /*#define TFM_PRIME_BBS 0x0001 */ /* BBS style prime */ From 1db880b6bf46c395f2e5457e5c2da76c6b831bd0 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 21 Jun 2016 15:55:17 -0700 Subject: [PATCH 3/6] Fixed issue with compressed keys and custom curves. The inLen adjustment for compressed curves was only be done for built-in curves. --- 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 b6f7baee5..b2b19aa2c 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -3014,6 +3014,9 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, } if (err == MP_OKAY) { + if (compressed) + inLen = (inLen-1)*2 + 1; /* used uncompressed len */ + /* determine the idx */ if (dp) { /* set the idx */ @@ -3022,9 +3025,6 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, key->type = ECC_PUBLICKEY; } else { - if (compressed) - inLen = (inLen-1)*2 + 1; /* used uncompressed len */ - for (x = 0; ecc_sets[x].size != 0; x++) { if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) { break; From d294dc363e2a55c4d7e0151d58491cf4fed37d31 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 21 Jun 2016 19:35:25 -0700 Subject: [PATCH 4/6] Fix scan-build warning with "redundant redeclaration of 'fp_isprime'". Changed "fp_isprime" and "fp_isprime_ex" to local static only. Also made "fp_gcd", "fp_lcm", and "fp_randprime" static functions. --- wolfcrypt/src/tfm.c | 9 +++++---- wolfssl/wolfcrypt/tfm.h | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index dbd1d734b..7fe0c43dc 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -2548,10 +2548,11 @@ int mp_mod_d(fp_int *a, fp_digit b, fp_digit *c) #ifdef WOLFSSL_KEY_GEN -void fp_gcd(fp_int *a, fp_int *b, fp_int *c); -void fp_lcm(fp_int *a, fp_int *b, fp_int *c); -int fp_isprime(fp_int *a); -int fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap); +static void fp_gcd(fp_int *a, fp_int *b, fp_int *c); +static void fp_lcm(fp_int *a, fp_int *b, fp_int *c); +static int fp_isprime_ex(fp_int *a, int t); +static int fp_isprime(fp_int *a); +static int fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap); int mp_gcd(fp_int *a, fp_int *b, fp_int *c) { diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 94efa2416..db0965d06 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -518,9 +518,9 @@ int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); #define FP_PRIME_SIZE 256 /* 256 trial divisions + 8 Miller-Rabins, returns FP_YES if probable prime */ -int fp_isprime(fp_int *a); +/*int fp_isprime(fp_int *a);*/ /* extended version of fp_isprime, do 't' Miller-Rabins instead of only 8 */ -int fp_isprime_ex(fp_int *a, int t); +/*int fp_isprime_ex(fp_int *a, int t);*/ /* Primality generation flags */ /*#define TFM_PRIME_BBS 0x0001 */ /* BBS style prime */ From 69db94d66818aafc425d5564d10df12eeb518e99 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 22 Jun 2016 07:06:07 -0700 Subject: [PATCH 5/6] Fix build error for un-initialized "kb" variable when built with fixed point cache and small stack enabled. --- wolfcrypt/src/ecc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index b2b19aa2c..da2580125 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4177,7 +4177,7 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, #define KB_SIZE 128 #ifdef WOLFSSL_SMALL_STACK - unsigned char* kb; + unsigned char* kb = NULL; #else unsigned char kb[KB_SIZE]; #endif From 47c1f4e68f7d253af123432de8d6cddb174ecbac Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 22 Jun 2016 07:22:30 -0700 Subject: [PATCH 6/6] Fix possible use of ForceZero with NULL pointer. Improve init of "kb" when small stack disabled, so memset isn't performed twice. --- wolfcrypt/src/ecc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index da2580125..d3e4f49d8 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4326,7 +4326,7 @@ static int accel_fp_mul2add(int idx1, int idx2, #define KB_SIZE 128 #ifdef WOLFSSL_SMALL_STACK - unsigned char* kb[2]; + unsigned char* kb[2] = {NULL, NULL}; #else unsigned char kb[2][KB_SIZE]; #endif @@ -4337,8 +4337,6 @@ static int accel_fp_mul2add(int idx1, int idx2, if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY) return MP_INIT_E; - XMEMSET(kb, 0, sizeof(kb)); - /* if it's smaller than modulus we fine */ if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { /* find order */ @@ -4526,8 +4524,10 @@ done: mp_clear(&order); #endif - ForceZero(kb[0], KB_SIZE); - ForceZero(kb[1], KB_SIZE); + if (kb[0]) + ForceZero(kb[0], KB_SIZE); + if (kb[1]) + ForceZero(kb[1], KB_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);