Enhancement / cleanup of the "wc_ecc_make_key_ex" API so it can be used with "keysize" or "dp" and allows compatibility with existing "wc_ecc_make_key". Note: "wc_ecc_make_key_ex" was not previously public, so changing it at this point is okay.

This commit is contained in:
David Garske
2016-06-16 10:38:15 -07:00
parent d55663eaee
commit 6da166d83b
3 changed files with 117 additions and 124 deletions

View File

@@ -1624,127 +1624,145 @@ int wc_ecc_point_is_at_infinity(ecc_point* p)
} }
int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp) int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
const ecc_set_type* dp)
{ {
int err; int err, x;
ecc_point* base = NULL; ecc_point* base = NULL;
mp_int prime; mp_int prime;
mp_int a; mp_int a;
mp_int order; mp_int order;
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
byte* buf; byte* buf;
#else #else
byte buf[ECC_MAXSIZE_GEN]; byte buf[ECC_MAXSIZE_GEN];
#endif #endif
int keysize;
if (key == NULL || rng == NULL || dp == NULL) if (key == NULL || rng == NULL || (keysize <= 0 && dp == NULL)) {
return ECC_BAD_ARG_E; return BAD_FUNC_ARG;
}
/* determine curve type/index */
if (dp == NULL) {
/* find key size */
for (x = 0; (keysize > ecc_sets[x].size) &&
(ecc_sets[x].size != 0); x++);
keysize = ecc_sets[x].size;
if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) {
return BAD_FUNC_ARG;
}
dp = &ecc_sets[x];
}
else {
x = ECC_CUSTOM_IDX;
}
key->idx = x;
key->dp = dp;
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (buf == NULL) if (buf == NULL)
return MEMORY_E; return MEMORY_E;
#endif #endif
key->idx = ECC_CUSTOM_IDX; /*generate 8 extra bytes to mitigate bias from the modulo operation below*/
key->dp = dp; /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/
keysize = dp->size + 8;
/*generate 8 extra bytes to mitigate bias from the modulo operation below*/ /* make up random string */
/*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/ err = wc_RNG_GenerateBlock(rng, buf, keysize);
keysize = dp->size + 8;
/* make up random string */ /* setup the key variables */
err = wc_RNG_GenerateBlock(rng, buf, keysize); 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
}
}
/* setup the key variables */ if (err == MP_OKAY) {
if (err == 0) { base = wc_ecc_new_point_h(key->heap);
err = mp_init_multi(&key->k, &prime, &order, &a, NULL, NULL); if (base == NULL)
if (err == MP_OKAY) { err = MEMORY_E;
#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) { /* read in the specs for this curve */
base = wc_ecc_new_point_h(key->heap); if (err == MP_OKAY)
if (base == NULL) err = mp_read_radix(&prime, key->dp->prime, 16);
err = MEMORY_E; if (err == MP_OKAY)
} err = mp_read_radix(&order, key->dp->order, 16);
if (err == MP_OKAY)
err = mp_read_radix(&a, key->dp->Af, 16);
/* read in the specs for this curve */ /* read in the x/y for this key */
if (err == MP_OKAY) if (err == MP_OKAY)
err = mp_read_radix(&prime, key->dp->prime, 16); err = mp_read_radix(base->x, key->dp->Gx, 16);
if (err == MP_OKAY) if (err == MP_OKAY)
err = mp_read_radix(&order, key->dp->order, 16); err = mp_read_radix(base->y, key->dp->Gy, 16);
if (err == MP_OKAY) if (err == MP_OKAY)
err = mp_read_radix(&a, key->dp->Af, 16); mp_set(base->z, 1);
/* read in the x/y for this key */ /* load random buffer data into k */
if (err == MP_OKAY) if (err == MP_OKAY)
err = mp_read_radix(base->x, key->dp->Gx, 16); err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize);
if (err == MP_OKAY)
err = mp_read_radix(base->y, key->dp->Gy, 16);
if (err == MP_OKAY)
mp_set(base->z, 1);
/* load random buffer data into k */ /* quick sanity check to make sure we're not dealing with a 0 key */
if (err == MP_OKAY) if (err == MP_OKAY) {
err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize); if (mp_iszero(&key->k) == MP_YES)
err = MP_ZERO_E;
}
/* quick sanity check to make sure we're not dealing with a 0 key */ /* the key should be smaller than the order of base point */
if (err == MP_OKAY) { if (err == MP_OKAY) {
if (mp_iszero(&key->k) == MP_YES) if (mp_cmp(&key->k, &order) != MP_LT)
err = MP_ZERO_E; err = mp_mod(&key->k, &order, &key->k);
} }
/* the key should be smaller than the order of base point */ /* make the public key */
if (err == MP_OKAY) { if (err == MP_OKAY)
if (mp_cmp(&key->k, &order) != MP_LT) err = wc_ecc_mulmod_ex(&key->k, base, &key->pubkey, &a, &prime, 1,
err = mp_mod(&key->k, &order, &key->k); key->heap);
}
/* make the public key */
if (err == MP_OKAY)
err = wc_ecc_mulmod_ex(&key->k, base, &key->pubkey, &a, &prime, 1,
key->heap);
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
/* validate the public key, order * pubkey = point at infinity */ /* validate the public key, order * pubkey = point at infinity */
if (err == MP_OKAY) if (err == MP_OKAY)
err = ecc_check_pubkey_order(key, &a, &prime, &order); err = ecc_check_pubkey_order(key, &a, &prime, &order);
#endif /* WOLFSSL_VALIDATE_KEYGEN */ #endif /* WOLFSSL_VALIDATE_KEYGEN */
if (err == MP_OKAY) if (err == MP_OKAY)
key->type = ECC_PRIVATEKEY; key->type = ECC_PRIVATEKEY;
if (err != MP_OKAY) { if (err != MP_OKAY) {
/* clean up */ /* clean up */
mp_clear(key->pubkey.x); mp_clear(key->pubkey.x);
mp_clear(key->pubkey.y); mp_clear(key->pubkey.y);
mp_clear(key->pubkey.z); mp_clear(key->pubkey.z);
mp_forcezero(&key->k); mp_forcezero(&key->k);
} }
wc_ecc_del_point_h(base, key->heap); wc_ecc_del_point_h(base, key->heap);
mp_clear(&a); mp_clear(&a);
mp_clear(&prime); mp_clear(&prime);
mp_clear(&order); mp_clear(&order);
ForceZero(buf, ECC_MAXSIZE); ForceZero(buf, ECC_MAXSIZE);
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif #endif
return err; return err;
} }
/** /**
@@ -1757,23 +1775,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp)
*/ */
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key) int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
{ {
int x, err; return wc_ecc_make_key_ex(rng, keysize, key, NULL);
if (key == NULL || rng == NULL)
return ECC_BAD_ARG_E;
/* find key size */
for (x = 0; (keysize > ecc_sets[x].size) && (ecc_sets[x].size != 0); x++)
;
keysize = ecc_sets[x].size;
if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) {
return BAD_FUNC_ARG;
}
err = wc_ecc_make_key_ex(rng, key, &ecc_sets[x]);
key->idx = x;
return err;
} }
/* Setup dynamic pointers is using normal math for proper freeing */ /* Setup dynamic pointers is using normal math for proper freeing */
@@ -1928,7 +1930,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
err = RNG_FAILURE_E; err = RNG_FAILURE_E;
break; break;
} }
err = wc_ecc_make_key_ex(rng, &pubkey, key->dp); err = wc_ecc_make_key_ex(rng, 0, &pubkey, key->dp);
if (err != MP_OKAY) break; if (err != MP_OKAY) break;
/* find r = x1 mod n */ /* find r = x1 mod n */

View File

@@ -6703,12 +6703,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
wc_ecc_init(&userB); wc_ecc_init(&userB);
wc_ecc_init(&pubKey); wc_ecc_init(&pubKey);
if (dp) { ret = wc_ecc_make_key_ex(rng, keySize, &userA, dp);
ret = wc_ecc_make_key_ex(rng, &userA, dp);
}
else {
ret = wc_ecc_make_key(rng, keySize, &userA);
}
if (ret != 0) if (ret != 0)
ERROR_OUT(-1014, done); ERROR_OUT(-1014, done);
@@ -6716,12 +6711,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
if (ret != 0) if (ret != 0)
ERROR_OUT(-1023, done); ERROR_OUT(-1023, done);
if (dp) { ret = wc_ecc_make_key_ex(rng, keySize, &userB, dp);
ret = wc_ecc_make_key_ex(rng, &userB, dp);
}
else {
ret = wc_ecc_make_key(rng, keySize, &userB);
}
if (ret != 0) if (ret != 0)
ERROR_OUT(-1002, done); ERROR_OUT(-1002, done);

View File

@@ -179,7 +179,8 @@ extern const ecc_set_type ecc_sets[];
WOLFSSL_API WOLFSSL_API
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key); int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key);
WOLFSSL_API WOLFSSL_API
int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp); int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
const ecc_set_type* dp);
WOLFSSL_API WOLFSSL_API
int wc_ecc_check_key(ecc_key* key); int wc_ecc_check_key(ecc_key* key);