diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index b38b7054a..cee7fe16d 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1224,7 +1224,7 @@ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, #endif static int _ecc_validate_public_key(ecc_key* key, int partial, int priv); #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT) -static int _ecc_pairwise_consistency_test(ecc_key* key); +static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng); #endif @@ -4607,8 +4607,8 @@ int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng) } -int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, - int flags) +static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, + int curve_id, int flags) { int err; @@ -4826,12 +4826,21 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, #endif /* WOLFSSL_ATECC508A */ + return err; +} + + +int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, + int flags) +{ + int err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags); + if (err == MP_OKAY) { err = _ecc_validate_public_key(key, 0, 0); } #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT) if (err == MP_OKAY) { - err = _ecc_pairwise_consistency_test(key); + err = _ecc_pairwise_consistency_test(key, rng); } #endif @@ -5549,8 +5558,8 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng, else #endif { - err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey, - key->dp->id); + err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id, + WC_ECC_FLAG_NONE); } if (err != MP_OKAY) break; @@ -8289,11 +8298,57 @@ static int ecc_check_privkey_gen_helper(ecc_key* key) #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT) /* Performs a Pairwise Consistency Test on an ECC key pair. */ -static int _ecc_pairwise_consistency_test(ecc_key* key) +static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng) { int err = 0; + int flags = key->flags; - if (ecc_check_privkey_gen_helper(key) != 0) + if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) + flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN); + + if (flags & WC_ECC_FLAG_COFACTOR) { + err = ecc_check_privkey_gen_helper(key); + } + + if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) { + byte* sig; + byte* digest; + word32 sigLen, digestLen; + int dynRng = 0, res = 0; + + sigLen = wc_ecc_sig_size(key); + digestLen = WC_SHA256_DIGEST_SIZE; + sig = (byte*)XMALLOC(sigLen + digestLen, NULL, DYNAMIC_TYPE_ECC); + if (sig == NULL) + return MEMORY_E; + digest = sig + sigLen; + + if (rng == NULL) { + dynRng = 1; + rng = wc_rng_new(NULL, 0, NULL); + if (rng == NULL) { + XFREE(sig, NULL, DYNAMIC_TYPE_ECC); + return MEMORY_E; + } + } + + err = wc_RNG_GenerateBlock(rng, digest, digestLen); + + if (!err) + err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen, + rng, key); + if (!err) + err = wc_ecc_verify_hash(sig, sigLen, + digest, WC_SHA256_DIGEST_SIZE, &res, key); + + if (dynRng) { + wc_rng_free(rng); + } + ForceZero(sig, sigLen + digestLen); + XFREE(sig, NULL, DYNAMIC_TYPE_ECC); + } + + if (err != 0) err = ECC_PCT_E; return err; @@ -9050,7 +9105,7 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, #ifdef WOLFSSL_VALIDATE_ECC_IMPORT if ((pub != NULL) && (ret == MP_OKAY)) /* public key needed to perform key validation */ - ret = _ecc_pairwise_consistency_test(key); + ret = _ecc_validate_public_key(key, 1, 1); #endif return ret; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c537645b2..f016f9b5f 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -21200,6 +21200,7 @@ static int ecc_test_sign_vectors(WC_RNG* rng) if (ret != 0) { goto done; } + wc_ecc_set_flags(&key, WC_ECC_FLAG_DEC_SIGN); ret = wc_ecc_sign_set_k(k, sizeof(k), &key); if (ret != 0) { @@ -21566,6 +21567,7 @@ static int ecc_test_make_pub(WC_RNG* rng) /* make public key for shared secret */ wc_ecc_init_ex(pub, HEAP_HINT, devId); ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, pub); + wc_ecc_set_flags(key, WC_ECC_FLAG_COFACTOR); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &pub->asyncDev, WC_ASYNC_FLAG_NONE); #endif diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 76bbb6567..ac2c7636b 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -403,9 +403,7 @@ typedef struct { /* ECC Flags */ enum { WC_ECC_FLAG_NONE = 0x00, -#ifdef HAVE_ECC_CDH WC_ECC_FLAG_COFACTOR = 0x01, -#endif WC_ECC_FLAG_DEC_SIGN = 0x02, };