From 6da166d83be52d9bf0ded7b25661671542934c2a Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 16 Jun 2016 10:38:15 -0700 Subject: [PATCH] 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. --- wolfcrypt/src/ecc.c | 224 ++++++++++++++++++++-------------------- wolfcrypt/test/test.c | 14 +-- wolfssl/wolfcrypt/ecc.h | 3 +- 3 files changed, 117 insertions(+), 124 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 4d53bc448..4bd19bff3 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -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; - ecc_point* base = NULL; - mp_int prime; - mp_int a; - mp_int order; + int err, x; + ecc_point* base = NULL; + mp_int prime; + mp_int a; + mp_int order; #ifdef WOLFSSL_SMALL_STACK - byte* buf; + byte* buf; #else - byte buf[ECC_MAXSIZE_GEN]; + byte buf[ECC_MAXSIZE_GEN]; #endif - int keysize; - if (key == NULL || rng == NULL || dp == NULL) - return ECC_BAD_ARG_E; + if (key == NULL || rng == NULL || (keysize <= 0 && dp == NULL)) { + 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 - buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (buf == NULL) - return MEMORY_E; + buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (buf == NULL) + return MEMORY_E; #endif - key->idx = ECC_CUSTOM_IDX; - key->dp = dp; + /*generate 8 extra bytes to mitigate bias from the modulo operation below*/ + /*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*/ - /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/ - keysize = dp->size + 8; + /* make up random string */ + err = wc_RNG_GenerateBlock(rng, buf, keysize); - /* make up random string */ - err = wc_RNG_GenerateBlock(rng, buf, keysize); + /* 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 + } + } - /* 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 - } - } + if (err == MP_OKAY) { + base = wc_ecc_new_point_h(key->heap); + if (base == NULL) + err = MEMORY_E; + } - if (err == MP_OKAY) { - base = wc_ecc_new_point_h(key->heap); - if (base == NULL) - err = MEMORY_E; - } + /* read in the specs for this curve */ + if (err == MP_OKAY) + err = mp_read_radix(&prime, key->dp->prime, 16); + 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 */ - if (err == MP_OKAY) - err = mp_read_radix(&prime, key->dp->prime, 16); - 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 x/y for this key */ + if (err == MP_OKAY) + err = mp_read_radix(base->x, key->dp->Gx, 16); + if (err == MP_OKAY) + err = mp_read_radix(base->y, key->dp->Gy, 16); + if (err == MP_OKAY) + mp_set(base->z, 1); - /* read in the x/y for this key */ - if (err == MP_OKAY) - err = mp_read_radix(base->x, key->dp->Gx, 16); - 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 */ + if (err == MP_OKAY) + err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize); - /* load random buffer data into k */ - if (err == MP_OKAY) - err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize); + /* quick sanity check to make sure we're not dealing with a 0 key */ + if (err == MP_OKAY) { + 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 */ - if (err == MP_OKAY) { - if (mp_iszero(&key->k) == MP_YES) - err = MP_ZERO_E; - } + /* the key should be smaller than the order of base point */ + if (err == MP_OKAY) { + if (mp_cmp(&key->k, &order) != MP_LT) + err = mp_mod(&key->k, &order, &key->k); + } - /* the key should be smaller than the order of base point */ - if (err == MP_OKAY) { - if (mp_cmp(&key->k, &order) != MP_LT) - err = mp_mod(&key->k, &order, &key->k); - } - /* make the public key */ - if (err == MP_OKAY) - err = wc_ecc_mulmod_ex(&key->k, base, &key->pubkey, &a, &prime, 1, - 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 - /* validate the public key, order * pubkey = point at infinity */ - if (err == MP_OKAY) - err = ecc_check_pubkey_order(key, &a, &prime, &order); + /* validate the public key, order * pubkey = point at infinity */ + if (err == MP_OKAY) + err = ecc_check_pubkey_order(key, &a, &prime, &order); #endif /* WOLFSSL_VALIDATE_KEYGEN */ - if (err == MP_OKAY) - key->type = ECC_PRIVATEKEY; + if (err == MP_OKAY) + key->type = ECC_PRIVATEKEY; - 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); - } + 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); + } - wc_ecc_del_point_h(base, key->heap); - mp_clear(&a); - mp_clear(&prime); - mp_clear(&order); + wc_ecc_del_point_h(base, key->heap); + mp_clear(&a); + mp_clear(&prime); + mp_clear(&order); - ForceZero(buf, ECC_MAXSIZE); + ForceZero(buf, ECC_MAXSIZE); #ifdef WOLFSSL_SMALL_STACK - XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); #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 x, err; - - 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; + return wc_ecc_make_key_ex(rng, keysize, key, NULL); } /* 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; 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; /* find r = x1 mod n */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c22fbf714..4c2973202 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6703,12 +6703,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, wc_ecc_init(&userB); wc_ecc_init(&pubKey); - if (dp) { - ret = wc_ecc_make_key_ex(rng, &userA, dp); - } - else { - ret = wc_ecc_make_key(rng, keySize, &userA); - } + ret = wc_ecc_make_key_ex(rng, keySize, &userA, dp); if (ret != 0) ERROR_OUT(-1014, done); @@ -6716,12 +6711,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if (ret != 0) ERROR_OUT(-1023, done); - if (dp) { - ret = wc_ecc_make_key_ex(rng, &userB, dp); - } - else { - ret = wc_ecc_make_key(rng, keySize, &userB); - } + ret = wc_ecc_make_key_ex(rng, keySize, &userB, dp); if (ret != 0) ERROR_OUT(-1002, done); diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index a38fb5c2a..8daadf768 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -179,7 +179,8 @@ extern const ecc_set_type ecc_sets[]; WOLFSSL_API int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key); 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 int wc_ecc_check_key(ecc_key* key);