Merge pull request #456 from dgarske/FixEccCompKey

Fixes for ECC compressed keys
This commit is contained in:
toddouska
2016-06-22 14:47:42 -07:00
committed by GitHub
6 changed files with 237 additions and 187 deletions

View File

@ -781,6 +781,19 @@ then
fi 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 # for using memory optimization setting on both curve25519 and ed25519
ENABLED_CURVED25519_SMALL=no ENABLED_CURVED25519_SMALL=no

View File

@ -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) && if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
(get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == 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_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, &t1) == MP_EQ)) {
mp_clear(&t1); #ifndef USE_FAST_MATH
mp_clear(&t2); mp_clear(&t1);
return ecc_projective_dbl_point(P, R, a, modulus, mp); mp_clear(&t2);
#endif
return ecc_projective_dbl_point(P, R, a, modulus, mp);
} }
} }
if (err != MP_OKAY) { if (err != MP_OKAY) {
mp_clear(&t1); goto done;
mp_clear(&t2);
return err;
} }
/* If use ALT_ECC_SIZE we need to use local stack variable since /* 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; z = &rz;
if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
mp_clear(&t1); goto done;
mp_clear(&t2);
return err;
} }
#else #else
/* Use destination directly */ /* 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); err = mp_copy(z, R->z);
#endif #endif
done:
#ifndef USE_FAST_MATH #ifndef USE_FAST_MATH
/* clean up */ /* clean up */
mp_clear(&t1); mp_clear(&t1);
@ -606,8 +605,10 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
z = &rz; z = &rz;
if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
#ifndef USE_FAST_MATH
mp_clear(&t1); mp_clear(&t1);
mp_clear(&t2); mp_clear(&t2);
#endif
return err; return err;
} }
#else #else
@ -852,9 +853,7 @@ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
z = &rz; z = &rz;
if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
mp_clear(&t1); goto done;
mp_clear(&t2);
return err;
} }
if (err == MP_OKAY) if (err == MP_OKAY)
@ -870,6 +869,10 @@ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
z = P->z; z = P->z;
#endif #endif
if (err != MP_OKAY) {
goto done;
}
/* first map z back to normal */ /* first map z back to normal */
err = mp_montgomery_reduce(z, modulus, mp); 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); mp_copy(z, P->z);
#endif #endif
done:
/* clean up */
#ifndef USE_FAST_MATH #ifndef USE_FAST_MATH
/* clean up */
mp_clear(&t1); mp_clear(&t1);
mp_clear(&t2); mp_clear(&t2);
#endif #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++) { for (j = 0; j < i; j++) {
wc_ecc_del_point_h(M[j], heap); wc_ecc_del_point_h(M[j], heap);
} }
#ifndef USE_FAST_MATH
mp_clear(&mu); mp_clear(&mu);
#endif
return MEMORY_E; 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 */ /* done with mu */
mp_clear(&mu); mp_clear(&mu);
#endif
/* calc the M tab, which holds kG for k==8..15 */ /* calc the M tab, which holds kG for k==8..15 */
/* M[0] == 8G */ /* 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) if (err == MP_OKAY)
err = mp_mulmod(G->z, &mu, modulus, tG->z); err = mp_mulmod(G->z, &mu, modulus, tG->z);
#ifndef USE_FAST_MATH
/* done with mu */ /* done with mu */
mp_clear(&mu); mp_clear(&mu);
#endif
/* calc the M tab */ /* calc the M tab */
/* M[0] == G */ /* M[0] == G */
@ -1534,8 +1544,10 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
*outlen = x; *outlen = x;
} }
#ifndef USE_FAST_MATH
mp_clear(&a); mp_clear(&a);
mp_clear(&prime); mp_clear(&prime);
#endif
wc_ecc_del_point_h(result, private_key->heap); wc_ecc_del_point_h(result, private_key->heap);
return err; return err;
@ -1603,8 +1615,10 @@ int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point,
*outlen = x; *outlen = x;
} }
#ifndef USE_FAST_MATH
mp_clear(&a); mp_clear(&a);
mp_clear(&prime); mp_clear(&prime);
#endif
wc_ecc_del_point_h(result, private_key->heap); wc_ecc_del_point_h(result, private_key->heap);
return err; 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); wc_ecc_del_point_h(base, key->heap);
#ifndef USE_FAST_MATH
mp_clear(&a); mp_clear(&a);
mp_clear(&prime); mp_clear(&prime);
mp_clear(&order); mp_clear(&order);
#endif
ForceZero(buf, ECC_MAXSIZE); ForceZero(buf, ECC_MAXSIZE);
#ifdef WOLFSSL_SMALL_STACK #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) if (err == MP_OKAY)
err = StoreECC_DSA_Sig(out, outlen, &r, &s); err = StoreECC_DSA_Sig(out, outlen, &r, &s);
#ifndef USE_FAST_MATH
mp_clear(&r); mp_clear(&r);
mp_clear(&s); mp_clear(&s);
#endif
return err; 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(&p);
mp_clear(&e); mp_clear(&e);
#endif
return err; return err;
} }
@ -2100,8 +2120,10 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA,
if (err == MP_OKAY) if (err == MP_OKAY)
err = mp_mulmod(B->z, &mu, modulus, precomp[1<<2]->z); err = mp_mulmod(B->z, &mu, modulus, precomp[1<<2]->z);
#ifndef USE_FAST_MATH
/* done with mu */ /* done with mu */
mp_clear(&mu); mp_clear(&mu);
#endif
} }
} }
@ -2138,13 +2160,14 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA,
bitbufB = tB[0]; bitbufB = tB[0];
/* for every byte of the multiplicands */ /* for every byte of the multiplicands */
for (x = -1;; ) { for (x = 0;; ) {
/* grab a nibble */ /* grab a nibble */
if (++nibble == 4) { if (++nibble == 4) {
++x; if (x == (int)len) break; if (x == (int)len) break;
bitbufA = tA[x]; bitbufA = tA[x];
bitbufB = tB[x]; bitbufB = tB[x];
nibble = 0; nibble = 0;
x++;
} }
/* extract two bits from both, shift/update */ /* 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) if (err == MP_OKAY)
err = wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, stat, key); err = wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, stat, key);
#ifndef USE_FAST_MATH
mp_clear(&r); mp_clear(&r);
mp_clear(&s); mp_clear(&s);
#endif
return err; 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) { if ((err = mp_init_multi(&modulus, &a, NULL, NULL, NULL, NULL)) != MP_OKAY) {
mp_clear(&v); err = MEMORY_E; goto done;
mp_clear(&w);
mp_clear(&u1);
mp_clear(&u2);
mp_clear(&order);
mp_clear(&e);
return MEMORY_E;
} }
/* allocate points */ /* allocate points */
@ -2424,10 +2443,12 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
*stat = 1; *stat = 1;
} }
done:
/* cleanup */ /* cleanup */
wc_ecc_del_point_h(mG, key->heap); wc_ecc_del_point_h(mG, key->heap);
wc_ecc_del_point_h(mQ, key->heap); wc_ecc_del_point_h(mQ, key->heap);
#ifndef USE_FAST_MATH
mp_clear(&v); mp_clear(&v);
mp_clear(&w); mp_clear(&w);
mp_clear(&u1); 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(&e);
mp_clear(&modulus); mp_clear(&modulus);
mp_clear(&a); mp_clear(&a);
#endif
return err; 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(&a);
mp_clear(&b); mp_clear(&b);
mp_clear(&prime); mp_clear(&prime);
mp_clear(&t2); mp_clear(&t2);
mp_clear(&t1); mp_clear(&t1);
#endif
} }
#endif #endif
@ -2746,7 +2770,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 */ /* Determine if curve "a" should be used in calc */
#ifdef WOLFSSL_CUSTOM_CURVES #ifdef WOLFSSL_CUSTOM_CURVES
/* compute y^2 - x^3 + a*x */ /* compute y^2 - x^3 + a*x */
mp_clear(&t2); mp_set(&t2, 0);
if (err == MP_OKAY) if (err == MP_OKAY)
err = mp_submod(prime, &a, prime, &t2); err = mp_submod(prime, &a, prime, &t2);
if (err == MP_OKAY) if (err == MP_OKAY)
@ -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(&a);
mp_clear(&b); mp_clear(&b);
mp_clear(&t1); mp_clear(&t1);
mp_clear(&t2); mp_clear(&t2);
#endif
return err; return err;
} }
@ -2860,7 +2886,9 @@ static int ecc_check_privkey_gen_helper(ecc_key* key)
if (err == MP_OKAY) if (err == MP_OKAY)
err = ecc_check_privkey_gen(key, &prime); err = ecc_check_privkey_gen(key, &prime);
#ifndef USE_FAST_MATH
mp_clear(&prime); mp_clear(&prime);
#endif
return err; return err;
} }
@ -2894,7 +2922,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) int wc_ecc_check_key(ecc_key* key)
{ {
mp_int prime; /* used by multiple calls so let's cache */ mp_int prime; /* used by multiple calls so let's cache */
@ -2931,9 +2959,11 @@ int wc_ecc_check_key(ecc_key* key)
if (err == MP_OKAY && key->type == ECC_PRIVATEKEY) if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
err = ecc_check_privkey_gen(key, &a, &prime); err = ecc_check_privkey_gen(key, &a, &prime);
#ifndef USE_FAST_MATH
mp_clear(&order); mp_clear(&order);
mp_clear(&a); mp_clear(&a);
mp_clear(&prime); mp_clear(&prime);
#endif
return err; return err;
} }
@ -2984,6 +3014,9 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
} }
if (err == MP_OKAY) { if (err == MP_OKAY) {
if (compressed)
inLen = (inLen-1)*2 + 1; /* used uncompressed len */
/* determine the idx */ /* determine the idx */
if (dp) { if (dp) {
/* set the idx */ /* set the idx */
@ -2992,9 +3025,6 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
key->type = ECC_PUBLICKEY; key->type = ECC_PUBLICKEY;
} }
else { else {
if (compressed)
inLen = (inLen-1)*2 + 1; /* used uncompressed len */
for (x = 0; ecc_sets[x].size != 0; x++) { for (x = 0; ecc_sets[x].size != 0; x++) {
if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) { if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) {
break; break;
@ -3062,11 +3092,13 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
mp_copy(&t2, key->pubkey.y); mp_copy(&t2, key->pubkey.y);
} }
#ifndef USE_FAST_MATH
mp_clear(&a); mp_clear(&a);
mp_clear(&b); mp_clear(&b);
mp_clear(&prime); mp_clear(&prime);
mp_clear(&t2); mp_clear(&t2);
mp_clear(&t1); mp_clear(&t1);
#endif
} }
#endif /* HAVE_COMP_KEY */ #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; err = MP_ZERO_E;
} }
#ifndef USE_FAST_MATH
mp_clear(&rtmp); mp_clear(&rtmp);
mp_clear(&stmp); mp_clear(&stmp);
#endif
return err; return err;
} }
@ -4115,7 +4149,10 @@ static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
/* free z */ /* free z */
mp_clear(fp_cache[idx].LUT[x]->z); mp_clear(fp_cache[idx].LUT[x]->z);
} }
#ifndef USE_FAST_MATH
mp_clear(&tmp); mp_clear(&tmp);
#endif
if (err == MP_OKAY) if (err == MP_OKAY)
return 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].g = NULL;
fp_cache[idx].lru_count = 0; fp_cache[idx].lru_count = 0;
mp_clear(&fp_cache[idx].mu); mp_clear(&fp_cache[idx].mu);
mp_clear(&tmp);
return err; return err;
} }
@ -4141,25 +4177,19 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a,
#define KB_SIZE 128 #define KB_SIZE 128
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
unsigned char* kb; unsigned char* kb = NULL;
#else #else
unsigned char kb[KB_SIZE]; unsigned char kb[KB_SIZE];
#endif #endif
int x; int x;
unsigned y, z, err, bitlen, bitpos, lut_gap, first; unsigned y, z = 0, err, bitlen, bitpos, lut_gap, first;
mp_int tk; 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; return MP_INIT_E;
/* if it's smaller than modulus we fine */ /* if it's smaller than modulus we fine */
if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) { 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 */ /* find order */
y = mp_unsigned_bin_size(modulus); y = mp_unsigned_bin_size(modulus);
for (x = 0; ecc_sets[x].size; x++) { 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 (y == 66) --x;
if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
mp_clear(&order); goto done;
mp_clear(&tk);
return err;
} }
/* k must be less than modulus */ /* k must be less than modulus */
if (mp_cmp(k, &order) != MP_LT) { if (mp_cmp(k, &order) != MP_LT) {
if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) { if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) {
mp_clear(&tk); goto done;
mp_clear(&order);
return err;
} }
} else { } else {
mp_copy(k, &tk); mp_copy(k, &tk);
} }
mp_clear(&order);
} else { } else {
mp_copy(k, &tk); 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 */ /* get the k value */
if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) { if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) {
mp_clear(&tk); err = BUFFER_E; goto done;
return BUFFER_E;
} }
/* store k */ /* store k */
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (kb == NULL) if (kb == NULL) {
return MEMORY_E; err = MEMORY_E; goto done;
}
#endif #endif
XMEMSET(kb, 0, KB_SIZE); XMEMSET(kb, 0, KB_SIZE);
if ((err = mp_to_unsigned_bin(&tk, kb)) != MP_OKAY) { if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) {
mp_clear(&tk);
}
else {
/* let's reverse kb so it's little endian */ /* let's reverse kb so it's little endian */
x = 0; x = 0;
y = mp_unsigned_bin_size(&tk); y = mp_unsigned_bin_size(&tk);
if (y > 0) { if (y > 0) {
y -= 1; y -= 1;
} }
mp_clear(&tk);
while ((unsigned)x < y) { while ((unsigned)x < y) {
z = kb[x]; kb[x] = kb[y]; kb[y] = z; 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) { if (err == MP_OKAY) {
z = 0; /* mp_to_unsigned_bin != MP_OKAY z will be declared/not set */
(void) z; /* Acknowledge the unused assignment */ (void) z; /* Acknowledge the unused assignment */
ForceZero(kb, KB_SIZE); 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 #ifdef WOLFSSL_SMALL_STACK
XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif #endif
@ -4299,17 +4326,15 @@ static int accel_fp_mul2add(int idx1, int idx2,
#define KB_SIZE 128 #define KB_SIZE 128
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
unsigned char* kb[2]; unsigned char* kb[2] = {NULL, NULL};
#else #else
unsigned char kb[2][KB_SIZE]; unsigned char kb[2][KB_SIZE];
#endif #endif
int x; int x;
unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB; unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB;
mp_int tka; mp_int tka, tkb, order;
mp_int tkb;
mp_int 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; return MP_INIT_E;
/* if it's smaller than modulus we fine */ /* if it's smaller than modulus we fine */
@ -4323,30 +4348,18 @@ static int accel_fp_mul2add(int idx1, int idx2,
/* back off if we are on the 521 bit curve */ /* back off if we are on the 521 bit curve */
if (y == 66) --x; 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) { if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
mp_clear(&tkb); goto done;
mp_clear(&tka);
mp_clear(&order);
return err;
} }
/* kA must be less than modulus */ /* kA must be less than modulus */
if (mp_cmp(kA, &order) != MP_LT) { if (mp_cmp(kA, &order) != MP_LT) {
if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) { if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) {
mp_clear(&tkb); goto done;
mp_clear(&tka);
mp_clear(&order);
return err;
} }
} else { } else {
mp_copy(kA, &tka); mp_copy(kA, &tka);
} }
mp_clear(&order);
} else { } else {
mp_copy(kA, &tka); mp_copy(kA, &tka);
} }
@ -4362,30 +4375,18 @@ static int accel_fp_mul2add(int idx1, int idx2,
/* back off if we are on the 521 bit curve */ /* back off if we are on the 521 bit curve */
if (y == 66) --x; 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) { if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
mp_clear(&tkb); goto done;
mp_clear(&tka);
mp_clear(&order);
return err;
} }
/* kB must be less than modulus */ /* kB must be less than modulus */
if (mp_cmp(kB, &order) != MP_LT) { if (mp_cmp(kB, &order) != MP_LT) {
if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) { if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) {
mp_clear(&tkb); goto done;
mp_clear(&tka);
mp_clear(&order);
return err;
} }
} else { } else {
mp_copy(kB, &tkb); mp_copy(kB, &tkb);
} }
mp_clear(&order);
} else { } else {
mp_copy(kB, &tkb); mp_copy(kB, &tkb);
} }
@ -4401,26 +4402,20 @@ static int accel_fp_mul2add(int idx1, int idx2,
/* get the k value */ /* get the k value */
if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) || if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) ||
(mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) { (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) {
mp_clear(&tka); err = BUFFER_E; goto done;
mp_clear(&tkb);
return BUFFER_E;
} }
/* store k */ /* store k */
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (kb[0] == NULL) if (kb[0] == NULL) {
return MEMORY_E; err = MEMORY_E; goto done;
}
#endif #endif
XMEMSET(kb[0], 0, KB_SIZE); XMEMSET(kb[0], 0, KB_SIZE);
if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) { if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) {
mp_clear(&tka); goto done;
mp_clear(&tkb);
#ifdef WOLFSSL_SMALL_STACK
XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return err;
} }
/* let's reverse kb so it's little endian */ /* let's reverse kb so it's little endian */
@ -4439,22 +4434,18 @@ static int accel_fp_mul2add(int idx1, int idx2,
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (kb[1] == NULL) { if (kb[1] == NULL) {
XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); err = MEMORY_E; goto done;
return MEMORY_E;
} }
#endif #endif
XMEMSET(kb[1], 0, KB_SIZE); XMEMSET(kb[1], 0, KB_SIZE);
if ((err = mp_to_unsigned_bin(&tkb, kb[1])) != MP_OKAY) { if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) {
mp_clear(&tkb);
}
else {
x = 0; x = 0;
y = mp_unsigned_bin_size(&tkb); y = mp_unsigned_bin_size(&tkb);
if (y > 0) { if (y > 0) {
y -= 1; y -= 1;
} }
mp_clear(&tkb);
while ((unsigned)x < y) { while ((unsigned)x < y) {
z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z; z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z;
++x; --y; ++x; --y;
@ -4525,8 +4516,18 @@ static int accel_fp_mul2add(int idx1, int idx2,
} }
} }
ForceZero(kb[0], KB_SIZE); done:
ForceZero(kb[1], KB_SIZE); /* cleanup */
#ifndef USE_FAST_MATH
mp_clear(&tkb);
mp_clear(&tka);
mp_clear(&order);
#endif
if (kb[0])
ForceZero(kb[0], KB_SIZE);
if (kb[1])
ForceZero(kb[1], KB_SIZE);
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);
@ -4660,7 +4661,9 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
#ifndef HAVE_THREAD_LS #ifndef HAVE_THREAD_LS
UnLockMutex(&ecc_fp_lock); UnLockMutex(&ecc_fp_lock);
#endif /* HAVE_THREAD_LS */ #endif /* HAVE_THREAD_LS */
#ifndef USE_FAST_MATH
mp_clear(&mu); mp_clear(&mu);
#endif
return err; 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 #ifndef HAVE_THREAD_LS
UnLockMutex(&ecc_fp_lock); UnLockMutex(&ecc_fp_lock);
#endif /* HAVE_THREAD_LS */ #endif /* HAVE_THREAD_LS */
#ifndef USE_FAST_MATH
mp_clear(&mu); mp_clear(&mu);
#endif
return err; return err;
} }
@ -5417,13 +5422,12 @@ int mp_jacobi(mp_int* a, mp_int* n, int* c)
s = 0; s = 0;
/* step 3. write a = a1 * 2**k */ /* 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; return res;
} }
if ((res = mp_init (&p1)) != MP_OKAY) { if ((res = mp_copy(a, &a1)) != MP_OKAY) {
mp_clear(&a1); goto done;
return res;
} }
/* divide out larger power of two */ /* divide out larger power of two */
@ -5462,37 +5466,54 @@ int mp_jacobi(mp_int* a, mp_int* n, int* c)
res = mp_jacobi (&p1, &a1, &r); res = mp_jacobi (&p1, &a1, &r);
if (res == MP_OKAY) if (res == MP_OKAY)
*c = s * r; *c = s * r;
} }
} }
/* done */ done:
mp_clear (&p1); /* cleanup */
mp_clear (&a1); #ifndef USE_FAST_MATH
mp_clear(&p1);
mp_clear(&a1);
#endif
return res; return res;
} }
/* 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 mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
{ {
int res, legendre, done = 0; int res, legendre, done = 0;
mp_int t1, C, Q, S, Z, M, T, R, two; mp_int t1, C, Q, S, Z, M, T, R, two;
mp_digit i; 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) { if (mp_cmp_d(n, 0) == MP_EQ) {
mp_zero(ret); mp_zero(ret);
return MP_OKAY; return MP_OKAY;
} }
if (mp_cmp_d(n, 1) == MP_EQ) {
mp_set(ret, 1);
return MP_OKAY;
}
/* prime must be odd */ /* prime must be odd */
if (mp_cmp_d(prime, 2) == MP_EQ) if (mp_cmp_d(prime, 2) == MP_EQ) {
return MP_VAL; return MP_VAL;
}
/* TAO removed /* is quadratic non-residue mod prime */
if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) {
if (legendre == -1) return MP_VAL; */ /* quadratic non-residue mod prime */ return res;
}
if (legendre == -1) {
return MP_VAL;
}
if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY) if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY)
return res; return res;
@ -5536,7 +5557,7 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
if (res == MP_OKAY) if (res == MP_OKAY)
mp_zero(&S); mp_zero(&S);
while (res == MP_OKAY && mp_iseven(&Q)) { while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) {
/* Q = Q / 2 */ /* Q = Q / 2 */
res = mp_div_2(&Q, &Q); res = mp_div_2(&Q, &Q);
@ -5587,6 +5608,8 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
while (res == MP_OKAY && done == 0) { while (res == MP_OKAY && done == 0) {
res = mp_copy(&T, &t1); res = mp_copy(&T, &t1);
/* reduce to 1 and count */
i = 0; i = 0;
while (res == MP_OKAY) { while (res == MP_OKAY) {
if (mp_cmp_d(&t1, 1) == MP_EQ) if (mp_cmp_d(&t1, 1) == MP_EQ)
@ -5632,6 +5655,7 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
} }
} }
#ifndef USE_FAST_MATH
/* done */ /* done */
mp_clear(&t1); mp_clear(&t1);
mp_clear(&C); mp_clear(&C);
@ -5642,13 +5666,14 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
mp_clear(&T); mp_clear(&T);
mp_clear(&R); mp_clear(&R);
mp_clear(&two); mp_clear(&two);
#endif
return res; return res;
} }
/* export public ECC key in ANSI X9.63 format compressed */ /* 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; word32 numlen;
int ret = MP_OKAY; int ret = MP_OKAY;

View File

@ -4203,7 +4203,7 @@ int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
#ifdef WOLFSSL_KEY_GEN #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, 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
@ -4801,7 +4801,7 @@ void mp_dump(const char* desc, mp_int* a, byte verbose)
char *buffer; char *buffer;
int size = a->alloc; 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) { if (buffer == NULL) {
return; return;
} }

View File

@ -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; int n, t, i, norm, neg;
/* is divisor zero ? */ /* is divisor zero ? */
if (fp_iszero (b) == 1) { if (fp_iszero (b) == FP_YES) {
return FP_VAL; return FP_VAL;
} }
@ -787,7 +787,7 @@ static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c)
int res; int res;
/* b cannot be negative */ /* 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; 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); fp_copy(b, &y);
/* 2. [modified] if x,y are both even then return an error! */ /* 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; return FP_VAL;
} }
@ -816,12 +816,12 @@ static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c)
top: top:
/* 4. while u is even do */ /* 4. while u is even do */
while (fp_iseven (&u) == 1) { while (fp_iseven (&u) == FP_YES) {
/* 4.1 u = u/2 */ /* 4.1 u = u/2 */
fp_div_2 (&u, &u); fp_div_2 (&u, &u);
/* 4.2 if A or B is odd then */ /* 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 */ /* A = (A+y)/2, B = (B-x)/2 */
fp_add (&A, &y, &A); fp_add (&A, &y, &A);
fp_sub (&B, &x, &B); fp_sub (&B, &x, &B);
@ -832,12 +832,12 @@ top:
} }
/* 5. while v is even do */ /* 5. while v is even do */
while (fp_iseven (&v) == 1) { while (fp_iseven (&v) == FP_YES) {
/* 5.1 v = v/2 */ /* 5.1 v = v/2 */
fp_div_2 (&v, &v); fp_div_2 (&v, &v);
/* 5.2 if C or D is odd then */ /* 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 */ /* C = (C+y)/2, D = (D-x)/2 */
fp_add (&C, &y, &C); fp_add (&C, &y, &C);
fp_sub (&D, &x, &D); fp_sub (&D, &x, &D);
@ -861,7 +861,7 @@ top:
} }
/* if not zero goto step 4 */ /* if not zero goto step 4 */
if (fp_iszero (&u) == 0) if (fp_iszero (&u) == FP_NO)
goto top; goto top;
/* now a = C, b = D, gcd == g*v */ /* now a = C, b = D, gcd == g*v */
@ -891,7 +891,7 @@ top:
int fp_invmod(fp_int *a, fp_int *b, fp_int *c) int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
{ {
fp_int x, y, u, v, B, D; fp_int x, y, u, v, B, D;
int neg, loop_check = 0; int neg;
/* 2. [modified] b must be odd */ /* 2. [modified] b must be odd */
if (fp_iseven (b) == FP_YES) { if (fp_iseven (b) == FP_YES) {
@ -955,8 +955,6 @@ top:
/* if not zero goto step 4 */ /* if not zero goto step 4 */
if (fp_iszero (&u) == FP_NO) { if (fp_iszero (&u) == FP_NO) {
if (++loop_check > 4096) /* bad input */
return FP_VAL;
goto top; goto top;
} }
@ -2102,8 +2100,12 @@ void fp_sub_d(fp_int *a, fp_digit b, fp_int *c)
fp_int tmp; fp_int tmp;
fp_init(&tmp); fp_init(&tmp);
fp_set(&tmp, b); fp_set(&tmp, b);
#ifdef ALT_ECC_SIZE
fp_sub(a, &tmp, &tmp);
fp_copy(&tmp, c);
#else
fp_sub(a, &tmp, c); fp_sub(a, &tmp, c);
fp_clear(&tmp); #endif
} }
@ -2363,10 +2365,19 @@ int mp_set_bit(mp_int *a, mp_digit b)
/* c = a * a (mod b) */ /* c = a * a (mod b) */
int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c) int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c)
{ {
fp_int tmp; int err;
fp_init(&tmp); fp_int t;
fp_sqr(a, &tmp);
return fp_mod(&tmp, b, c); 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 */ /* fast math conversion */
@ -2388,10 +2399,6 @@ int mp_montgomery_calc_normalization(mp_int *a, mp_int *b)
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
defined(WOLFSSL_DEBUG_MATH) 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 #ifdef WOLFSSL_KEY_GEN
/* swap the elements of two integers, for cases where you can't simply swap the /* swap the elements of two integers, for cases where you can't simply swap the
* mp_int pointers around * mp_int pointers around
@ -2406,6 +2413,10 @@ static void fp_exch (fp_int * a, fp_int * b)
} }
#endif #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 */ /* Counts the number of lsbs which are zero before the first zero bit */
int fp_cnt_lsb(fp_int *a) int fp_cnt_lsb(fp_int *a)
{ {
@ -2413,12 +2424,12 @@ int fp_cnt_lsb(fp_int *a)
fp_digit q, qq; fp_digit q, qq;
/* easy out */ /* easy out */
if (fp_iszero(a) == 1) { if (fp_iszero(a) == FP_YES) {
return 0; return 0;
} }
/* scan lower digits until non-zero */ /* 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]; q = a->dp[x];
x *= DIGIT_BIT; x *= DIGIT_BIT;
@ -2440,16 +2451,16 @@ static int s_is_power_of_two(fp_digit b, int *p)
/* fast return if no power of two */ /* fast return if no power of two */
if ((b==0) || (b & (b-1))) { if ((b==0) || (b & (b-1))) {
return 0; return FP_NO;
} }
for (x = 0; x < DIGIT_BIT; x++) { for (x = 0; x < DIGIT_BIT; x++) {
if (b == (((fp_digit)1)<<x)) { if (b == (((fp_digit)1)<<x)) {
*p = x; *p = x;
return 1; return FP_YES;
} }
} }
return 0; return FP_NO;
} }
/* a/b => cb + d == a */ /* a/b => cb + d == a */
@ -2466,7 +2477,7 @@ static int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d)
} }
/* quick outs */ /* quick outs */
if (b == 1 || fp_iszero(a) == 1) { if (b == 1 || fp_iszero(a) == FP_YES) {
if (d != NULL) { if (d != NULL) {
*d = 0; *d = 0;
} }
@ -2477,7 +2488,7 @@ static int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d)
} }
/* power of two ? */ /* 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) { if (d != NULL) {
*d = a->dp[0] & ((((fp_digit)1)<<ix) - 1); *d = a->dp[0] & ((((fp_digit)1)<<ix) - 1);
} }
@ -2537,10 +2548,11 @@ int mp_mod_d(fp_int *a, fp_digit b, fp_digit *c)
#ifdef WOLFSSL_KEY_GEN #ifdef WOLFSSL_KEY_GEN
void fp_gcd(fp_int *a, fp_int *b, fp_int *c); static void fp_gcd(fp_int *a, fp_int *b, fp_int *c);
void fp_lcm(fp_int *a, fp_int *b, fp_int *c); static void fp_lcm(fp_int *a, fp_int *b, fp_int *c);
int fp_isprime(fp_int *a); static int fp_isprime_ex(fp_int *a, int t);
int fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap); 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) int mp_gcd(fp_int *a, fp_int *b, fp_int *c)
{ {
@ -2653,7 +2665,7 @@ static void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result)
/* a few primes */ /* a few primes */
static const fp_digit primes[256] = { static const fp_digit primes[FP_PRIME_SIZE] = {
0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
@ -2691,23 +2703,27 @@ static const fp_digit primes[256] = {
0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
}; };
int fp_isprime(fp_int *a) int fp_isprime_ex(fp_int *a, int t)
{ {
fp_int b; fp_int b;
fp_digit d = 0; fp_digit d;
int r, res; int r, res;
if (t <= 0 || t > FP_PRIME_SIZE) {
return FP_NO;
}
/* do trial division */ /* do trial division */
for (r = 0; r < 256; r++) { for (r = 0; r < FP_PRIME_SIZE; r++) {
fp_mod_d(a, primes[r], &d); fp_mod_d(a, primes[r], &d);
if (d == 0) { if (d == 0) {
return FP_NO; return FP_NO;
} }
} }
/* now do 8 miller rabins */ /* now do 't' miller rabins */
fp_init(&b); fp_init(&b);
for (r = 0; r < 8; r++) { for (r = 0; r < t; r++) {
fp_set(&b, primes[r]); fp_set(&b, primes[r]);
fp_prime_miller_rabin(a, &b, &res); fp_prime_miller_rabin(a, &b, &res);
if (res == FP_NO) { if (res == FP_NO) {
@ -2717,6 +2733,11 @@ int fp_isprime(fp_int *a)
return FP_YES; 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) int fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap)
{ {
static const int USE_BBS = 1; static const int USE_BBS = 1;
@ -2796,11 +2817,11 @@ void fp_gcd(fp_int *a, fp_int *b, fp_int *c)
fp_int u, v, r; fp_int u, v, r;
/* either zero than gcd is the largest */ /* 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); fp_abs (b, c);
return; 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); fp_abs (a, c);
return; return;
} }
@ -2808,7 +2829,7 @@ void fp_gcd(fp_int *a, fp_int *b, fp_int *c)
/* optimized. At this point if a == 0 then /* optimized. At this point if a == 0 then
* b must equal zero too * b must equal zero too
*/ */
if (fp_iszero (a) == 1) { if (fp_iszero (a) == FP_YES) {
fp_zero(c); fp_zero(c);
return; return;
} }
@ -2968,8 +2989,7 @@ int mp_init_copy(fp_int * a, fp_int * b)
int mp_cnt_lsb(fp_int* a) int mp_cnt_lsb(fp_int* a)
{ {
fp_cnt_lsb(a); return fp_cnt_lsb(a);
return MP_OKAY;
} }
#endif /* HAVE_COMP_KEY */ #endif /* HAVE_COMP_KEY */
@ -3047,7 +3067,7 @@ int mp_toradix (mp_int *a, char *str, int radix)
} }
/* quick out if its zero */ /* quick out if its zero */
if (fp_iszero(a) == 1) { if (fp_iszero(a) == FP_YES) {
*str++ = '0'; *str++ = '0';
*str = '\0'; *str = '\0';
return FP_YES; return FP_YES;
@ -3064,7 +3084,7 @@ int mp_toradix (mp_int *a, char *str, int radix)
} }
digs = 0; 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) { if ((res = fp_div_d (&t, (fp_digit) radix, &t, &d)) != FP_OKAY) {
fp_zero (&t); fp_zero (&t);
return res; return res;

View File

@ -6675,7 +6675,7 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize)
} }
#endif /* WOLFSSL_KEY_GEN */ #endif /* WOLFSSL_KEY_GEN */
static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, 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 #ifdef BENCH_EMBEDDED
byte sharedA[128]; /* Needs to be at least keySize */ 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 #ifdef HAVE_ECC_KEY_EXPORT
x = sizeof(exportBuf); x = sizeof(exportBuf);
ret = wc_ecc_export_x963(&userA, exportBuf, &x); ret = wc_ecc_export_x963(&userA, exportBuf, &x);
if (ret != 0) if (ret != 0)
ERROR_OUT(-1006, done); ERROR_OUT(-1006, done);
@ -6755,18 +6754,16 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
ERROR_OUT(-1009, done); ERROR_OUT(-1009, done);
#endif /* HAVE_ECC_DHE */ #endif /* HAVE_ECC_DHE */
if (testCompressedKey) {
#ifdef HAVE_COMP_KEY #ifdef HAVE_COMP_KEY
/* try compressed export / import too */ /* try compressed export / import too */
x = sizeof(exportBuf); x = sizeof(exportBuf);
ret = wc_ecc_export_x963_ex(&userA, exportBuf, &x, 1); ret = wc_ecc_export_x963_ex(&userA, exportBuf, &x, 1);
if (ret != 0) if (ret != 0)
ERROR_OUT(-1010, done); ERROR_OUT(-1010, done);
wc_ecc_free(&pubKey); wc_ecc_free(&pubKey);
wc_ecc_init(&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) if (ret != 0)
ERROR_OUT(-1011, done); ERROR_OUT(-1011, done);
@ -6780,7 +6777,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
ERROR_OUT(-1013, done); ERROR_OUT(-1013, done);
#endif /* HAVE_ECC_DHE */ #endif /* HAVE_ECC_DHE */
#endif /* HAVE_COMP_KEY */ #endif /* HAVE_COMP_KEY */
}
#endif /* HAVE_ECC_KEY_IMPORT */ #endif /* HAVE_ECC_KEY_IMPORT */
#endif /* HAVE_ECC_KEY_EXPORT */ #endif /* HAVE_ECC_KEY_EXPORT */
@ -6850,15 +6847,9 @@ done:
#define ECC_TEST_VERIFY_COUNT 2 #define ECC_TEST_VERIFY_COUNT 2
static int ecc_test_curve(WC_RNG* rng, int keySize) 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 */ ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT, NULL);
if (keySize == 28) {
testCompressedKey = 0;
}
ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT,
testCompressedKey, NULL);
if (ret < 0) { if (ret < 0) {
printf("ecc_test_curve_size %d failed!: %d\n", keySize, ret); printf("ecc_test_curve_size %d failed!: %d\n", keySize, ret);
return ret; return ret;
@ -6936,7 +6927,7 @@ int ecc_test(void)
"8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */
"547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */
}; };
ret = ecc_test_curve_size(&rng, -1, ECC_TEST_VERIFY_COUNT, 0, &ecc_cust_dp); ret = ecc_test_curve_size(&rng, 0, ECC_TEST_VERIFY_COUNT, &ecc_cust_dp);
if (ret < 0) { if (ret < 0) {
printf("ecc_test_curve_size custom failed!: %d\n", ret); printf("ecc_test_curve_size custom failed!: %d\n", ret);
goto done; goto done;

View File

@ -347,9 +347,7 @@ typedef struct {
#define TFM_SQR64 #define TFM_SQR64
#endif #endif
/* do we want some overflow checks /* Optional math checks (enable WOLFSSL_DEBUG_MATH to print info) */
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)
*/
/* #define TFM_CHECK */ /* #define TFM_CHECK */
/* Is the target a P4 Prescott /* Is the target a P4 Prescott
@ -518,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" */ /* 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);*/ /*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 */ /* 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 */ /* Primality generation flags */
/*#define TFM_PRIME_BBS 0x0001 */ /* BBS style prime */ /*#define TFM_PRIME_BBS 0x0001 */ /* BBS style prime */