From a967cbcb7b42490d810faf93acb0d55f6d7708ef Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 24 Mar 2021 10:31:26 -0700 Subject: [PATCH] 56Ar3 Testing Updates 1. Add PCTs for ECC and FFC. 2. Update the public key checks for ECC and FFC. --- configure.ac | 5 +- wolfcrypt/src/dh.c | 324 ++++++++++++++++++-------------- wolfcrypt/src/ecc.c | 88 ++++++--- wolfcrypt/src/error.c | 6 + wolfcrypt/test/test.c | 2 +- wolfssl/wolfcrypt/error-crypt.h | 4 +- 6 files changed, 260 insertions(+), 169 deletions(-) diff --git a/configure.ac b/configure.ac index 0666f481a..6f8053638 100644 --- a/configure.ac +++ b/configure.ac @@ -3356,10 +3356,10 @@ AS_CASE([$FIPS_VERSION], AS_IF([test "x$ENABLED_RSAPSS" != "xyes"], [ENABLED_RSAPSS="yes"; AM_CFLAGS="$AM_CFLAGS -DWC_RSA_PSS"]) AS_IF([test "x$ENABLED_ECC" != "xyes"], - [ENABLED_ECC="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_ECC -DTFM_ECC256 -DWOLFSSL_VALIDATE_ECC_IMPORT" + [ENABLED_ECC="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_ECC -DTFM_ECC256" AS_IF([test "x$ENABLED_ECC_SHAMIR" = "xyes"], [AM_CFLAGS="$AM_CFLAGS -DECC_SHAMIR"])], - [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT"]) + [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT -DWOLFSSL_VALIDATE_ECC_KEYGEN"]) AS_IF([test "x$ENABLED_AESCTR" != "xyes"], [ENABLED_AESCTR="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_COUNTER"]) AS_IF([test "x$ENABLED_CMAC" != "xyes"], @@ -3373,6 +3373,7 @@ AS_CASE([$FIPS_VERSION], AS_IF([test "x$ENABLED_AESGCM" = "xno"], [ENABLED_AESGCM="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM"]) AS_IF([test "x$ENABLED_MD5" = "xyes"],[ENABLED_MD5="no"; ENABLED_OLD_TLS="no"; AM_CFLAGS="$AM_CFLAGS -DNO_MD5 -DNO_OLD_TLS"]) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT -DECC_USER_CURVES -DHAVE_ECC256 -DHAVE_ECC384 -DHAVE_ECC521" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ECDSA_SET_K -DWC_RNG_SEED_CB" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_FFC_IMPORT -DHAVE_FFDHE_Q" AM_CFLAGS="$AM_CFLAGS -DHAVE_FFDHE_3072 -DHAVE_FFDHE_4096 -DHAVE_FFDHE_6144 -DHAVE_FFDHE_8192 -DFP_MAX_BITS=16384" diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index d023164ad..21f5034ba 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -982,7 +982,13 @@ int wc_FreeDhKey(DhKey* key) } +static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz, + const byte* prime, word32 primeSz, int partial); +static int _ffc_pairwise_consistency_test(DhKey* key, + const byte* pub, word32 pubSz, const byte* priv, word32 privSz); + #ifndef WOLFSSL_KCAPI_DH + #ifndef WC_NO_RNG /* if defined to not use floating point values do not compile in */ #ifndef WOLFSSL_DH_CONST @@ -1337,7 +1343,16 @@ static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng, ret = GeneratePrivateDh(key, rng, priv, privSz); - return (ret != 0) ? ret : GeneratePublicDh(key, priv, *privSz, pub, pubSz); + if (ret == 0) + ret = GeneratePublicDh(key, priv, *privSz, pub, pubSz); + if (ret == 0) + ret = _ffc_validate_public_key(key, pub, *pubSz, NULL, 0, 0); + if (ret == 0) { + ret = _ffc_pairwise_consistency_test(key, pub, *pubSz, priv, *privSz); + if (ret != 0) ret = DHE_PCT_FIPS_E; + } + + return ret; } #endif /* !WOLFSSL_KCAPI_DH */ @@ -1401,20 +1416,132 @@ static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng, #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */ +/* Performs a Pairwise Consistency Test on an FFC key pair. */ +static int _ffc_pairwise_consistency_test(DhKey* key, + const byte* pub, word32 pubSz, const byte* priv, word32 privSz) +{ +#ifdef WOLFSSL_SMALL_STACK + mp_int* publicKey = NULL; + mp_int* privateKey = NULL; + mp_int* checkKey = NULL; +#else + mp_int publicKey[1]; + mp_int privateKey[1]; + mp_int checkKey[1]; +#endif + int ret = 0; + + if (key == NULL || pub == NULL || priv == NULL) + return BAD_FUNC_ARG; + +#ifdef WOLFSSL_SMALL_STACK + publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); + if (publicKey == NULL) + return MEMORY_E; + privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); + if (privateKey == NULL) { + XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); + return MEMORY_E; + } + checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); + if (checkKey == NULL) { + XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); + XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); + return MEMORY_E; + } +#endif + + if (mp_init_multi(publicKey, privateKey, checkKey, + NULL, NULL, NULL) != MP_OKAY) { + + #ifdef WOLFSSL_SMALL_STACK + XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); + XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); + XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH); + #endif + return MP_INIT_E; + } + + /* Load the private and public keys into big integers. */ + if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY || + mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) { + + ret = MP_READ_E; + } + + /* Calculate checkKey = g^privateKey mod p */ + if (ret == 0) { +#ifdef WOLFSSL_HAVE_SP_DH +#ifndef WOLFSSL_SP_NO_2048 + if (mp_count_bits(&key->p) == 2048) { + ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey); + if (ret != 0) + ret = MP_EXPTMOD_E; + } + else +#endif +#ifndef WOLFSSL_SP_NO_3072 + if (mp_count_bits(&key->p) == 3072) { + ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey); + if (ret != 0) + ret = MP_EXPTMOD_E; + } + else +#endif +#ifdef WOLFSSL_SP_4096 + if (mp_count_bits(&key->p) == 4096) { + ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey); + if (ret != 0) + ret = MP_EXPTMOD_E; + } + else +#endif +#endif + { +#if !defined(WOLFSSL_SP_MATH) + if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY) + ret = MP_EXPTMOD_E; +#else + ret = WC_KEY_SIZE_E; +#endif + } + } + + /* Compare the calculated public key to the supplied check value. */ + if (ret == 0) { + if (mp_cmp(checkKey, publicKey) != MP_EQ) + ret = MP_CMP_E; + } + + mp_forcezero(privateKey); + mp_clear(publicKey); + mp_clear(checkKey); +#ifdef WOLFSSL_SMALL_STACK + XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH); + XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); + XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); +#endif + + return ret; +} + + /* Check DH Public Key for invalid numbers, optionally allowing * the public key to be checked against the large prime (q). - * Check per process in SP 800-56Ar3, section 5.6.2.3.1. + * If q is NULL, the q value of key is used. + * Check per process in SP 800-56Ar3, section 5.6.2.3.1 or 2. * * key DH key group parameters. * pub Public Key. * pubSz Public Key size. * prime Large prime (q), optionally NULL to skip check * primeSz Size of large prime + * partial Do the partial test process. (section 5.6.2.3.2) * * returns 0 on success or error code */ -int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, - const byte* prime, word32 primeSz) +static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz, + const byte* prime, word32 primeSz, int partial) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1471,7 +1598,7 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, ret = MP_INIT_E; } - /* SP 800-56Ar3, section 5.6.2.3.1, process step 1 */ + /* SP 800-56Ar3, section 5.6.2.3.2 */ /* pub (y) should not be 0 or 1 */ if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) { ret = MP_CMP_E; @@ -1488,55 +1615,57 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, ret = MP_CMP_E; } - if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) { + if (!partial) { + if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) { - /* restore key->p into p */ - if (mp_copy(&key->p, p) != MP_OKAY) - ret = MP_INIT_E; - } + /* restore key->p into p */ + if (mp_copy(&key->p, p) != MP_OKAY) + ret = MP_INIT_E; + } - /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */ - if (ret == 0 && prime != NULL) { + /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */ + if (ret == 0 && prime != NULL) { #ifdef WOLFSSL_HAVE_SP_DH #ifndef WOLFSSL_SP_NO_2048 - if (mp_count_bits(&key->p) == 2048) { - ret = sp_ModExp_2048(y, q, p, y); - if (ret != 0) - ret = MP_EXPTMOD_E; - } - else + if (mp_count_bits(&key->p) == 2048) { + ret = sp_ModExp_2048(y, q, p, y); + if (ret != 0) + ret = MP_EXPTMOD_E; + } + else #endif #ifndef WOLFSSL_SP_NO_3072 - if (mp_count_bits(&key->p) == 3072) { - ret = sp_ModExp_3072(y, q, p, y); - if (ret != 0) - ret = MP_EXPTMOD_E; - } - else + if (mp_count_bits(&key->p) == 3072) { + ret = sp_ModExp_3072(y, q, p, y); + if (ret != 0) + ret = MP_EXPTMOD_E; + } + else #endif #ifdef WOLFSSL_SP_4096 - if (mp_count_bits(&key->p) == 4096) { - ret = sp_ModExp_4096(y, q, p, y); - if (ret != 0) - ret = MP_EXPTMOD_E; - } - else + if (mp_count_bits(&key->p) == 4096) { + ret = sp_ModExp_4096(y, q, p, y); + if (ret != 0) + ret = MP_EXPTMOD_E; + } + else #endif #endif - { + { #if !defined(WOLFSSL_SP_MATH) - /* calculate (y^q) mod(p), store back into y */ - if (mp_exptmod(y, q, p, y) != MP_OKAY) - ret = MP_EXPTMOD_E; + /* calculate (y^q) mod(p), store back into y */ + if (mp_exptmod(y, q, p, y) != MP_OKAY) + ret = MP_EXPTMOD_E; #else - ret = WC_KEY_SIZE_E; + ret = WC_KEY_SIZE_E; #endif - } + } - /* verify above == 1 */ - if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ) - ret = MP_CMP_E; + /* verify above == 1 */ + if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ) + ret = MP_CMP_E; + } } mp_clear(y); @@ -1552,7 +1681,16 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, } -/* Check DH Public Key for invalid numbers +/* Performs a full public-key validation routine. */ +int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, + const byte* prime, word32 primeSz) +{ + return _ffc_validate_public_key(key, pub, pubSz, prime, primeSz, 0); +} + + +/* Check DH Public Key for invalid numbers. Performs a partial public-key + * validation routine. * * key DH key group parameters. * pub Public Key. @@ -1562,7 +1700,7 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, */ int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz) { - return wc_DhCheckPubKey_ex(key, pub, pubSz, NULL, 0); + return _ffc_validate_public_key(key, pub, pubSz, NULL, 0, 1); } @@ -1732,109 +1870,7 @@ int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz) int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz, const byte* priv, word32 privSz) { -#ifdef WOLFSSL_SMALL_STACK - mp_int* publicKey = NULL; - mp_int* privateKey = NULL; - mp_int* checkKey = NULL; -#else - mp_int publicKey[1]; - mp_int privateKey[1]; - mp_int checkKey[1]; -#endif - int ret = 0; - - if (key == NULL || pub == NULL || priv == NULL) - return BAD_FUNC_ARG; - -#ifdef WOLFSSL_SMALL_STACK - publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); - if (publicKey == NULL) - return MEMORY_E; - privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); - if (privateKey == NULL) { - XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); - return MEMORY_E; - } - checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); - if (checkKey == NULL) { - XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); - XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); - return MEMORY_E; - } -#endif - - if (mp_init_multi(publicKey, privateKey, checkKey, - NULL, NULL, NULL) != MP_OKAY) { - - #ifdef WOLFSSL_SMALL_STACK - XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); - XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); - XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH); - #endif - return MP_INIT_E; - } - - /* Load the private and public keys into big integers. */ - if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY || - mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) { - - ret = MP_READ_E; - } - - /* Calculate checkKey = g^privateKey mod p */ - if (ret == 0) { -#ifdef WOLFSSL_HAVE_SP_DH -#ifndef WOLFSSL_SP_NO_2048 - if (mp_count_bits(&key->p) == 2048) { - ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey); - if (ret != 0) - ret = MP_EXPTMOD_E; - } - else -#endif -#ifndef WOLFSSL_SP_NO_3072 - if (mp_count_bits(&key->p) == 3072) { - ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey); - if (ret != 0) - ret = MP_EXPTMOD_E; - } - else -#endif -#ifdef WOLFSSL_SP_4096 - if (mp_count_bits(&key->p) == 4096) { - ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey); - if (ret != 0) - ret = MP_EXPTMOD_E; - } - else -#endif -#endif - { -#if !defined(WOLFSSL_SP_MATH) - if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY) - ret = MP_EXPTMOD_E; -#else - ret = WC_KEY_SIZE_E; -#endif - } - } - - /* Compare the calculated public key to the supplied check value. */ - if (ret == 0) { - if (mp_cmp(checkKey, publicKey) != MP_EQ) - ret = MP_CMP_E; - } - - mp_forcezero(privateKey); - mp_clear(publicKey); - mp_clear(checkKey); -#ifdef WOLFSSL_SMALL_STACK - XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH); - XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); - XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); -#endif - - return ret; + return _ffc_pairwise_consistency_test(key, pub, pubSz, priv, privSz); } diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index ddbfa0edf..3cb0862c0 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1224,6 +1224,11 @@ static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, mp_int* prime, mp_int* order); #endif +static int _ecc_validate_public_key(ecc_key* key, int partial, int priv); +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN +static int _ecc_pairwise_consistency_test(ecc_key* key); +#endif + int mp_jacobi(mp_int* a, mp_int* n, int* c); int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret); @@ -4829,8 +4834,16 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, #endif #endif /* WOLFSSL_ATECC508A */ - if (err == MP_OKAY) - err = wc_ecc_check_key(key); + + if (err == MP_OKAY) { + err = _ecc_validate_public_key(key, 0, 0); + } + +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = _ecc_pairwise_consistency_test(key); + } +#endif return err; } @@ -8281,6 +8294,18 @@ static int ecc_check_privkey_gen_helper(ecc_key* key) return err; } + +/* Performs a Pairwise Consistency Test on an ECC key pair. */ +static int _ecc_pairwise_consistency_test(ecc_key* key) +{ + int err = 0; + + if (ecc_check_privkey_gen_helper(key) != 0) + err = ECC_PCT_FIPS_E; + + return err; +} + #endif /* WOLFSSL_VALIDATE_ECC_IMPORT */ #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH) @@ -8367,8 +8392,14 @@ int wc_ecc_get_generator(ecc_point* ecp, int curve_idx) } #endif /* OPENSSLALL */ -/* perform sanity checks on ecc key validity, 0 on success */ -int wc_ecc_check_key(ecc_key* key) + +/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3, + * ECC Full Public Key Validation Routine. If the parameter + * partial is set, then it follows section 5.6.2.3.4, the ECC + * Partial Public Key Validation Routine. + * If the parameter priv is set, add in a few extra + * checks on the bounds of the private key. */ +static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) { int err = MP_OKAY; #ifndef WOLFSSL_SP_MATH @@ -8449,6 +8480,7 @@ int wc_ecc_check_key(ecc_key* key) #endif /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */ + /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */ /* pubkey point cannot be at infinity */ if (wc_ecc_point_is_at_infinity(&key->pubkey)) { #ifdef WOLFSSL_SMALL_STACK @@ -8479,6 +8511,7 @@ int wc_ecc_check_key(ecc_key* key) #endif /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */ + /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */ /* Qx must be in the range [0, p-1] */ if (err == MP_OKAY) { if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT) @@ -8491,29 +8524,34 @@ int wc_ecc_check_key(ecc_key* key) err = ECC_OUT_OF_RANGE_E; } - /* SP 800-56Ar3, section 5.6.2.3.3, process steps 3 */ + /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */ + /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */ /* make sure point is actually on curve */ if (err == MP_OKAY) err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime); - /* SP 800-56Ar3, section 5.6.2.3.3, process steps 4 */ - /* pubkey * order must be at infinity */ - if (err == MP_OKAY) - err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af, curve->prime, - curve->order); - - /* SP 800-56Ar3, section 5.6.2.1.2 */ - /* private keys must be in the range [1, n-1] */ - if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) && - (mp_iszero(&key->k) || mp_isneg(&key->k) || - (mp_cmp(&key->k, curve->order) != MP_LT))) { - err = ECC_PRIV_KEY_E; + if (!partial) { + /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */ + /* pubkey * order must be at infinity */ + if (err == MP_OKAY) + err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af, + curve->prime, curve->order); } - /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */ - /* private * base generator must equal pubkey */ - if (err == MP_OKAY && key->type == ECC_PRIVATEKEY) - err = ecc_check_privkey_gen(key, curve->Af, curve->prime); + if (priv) { + /* SP 800-56Ar3, section 5.6.2.1.2 */ + /* private keys must be in the range [1, n-1] */ + if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) && + (mp_iszero(&key->k) || mp_isneg(&key->k) || + (mp_cmp(&key->k, curve->order) != MP_LT))) { + err = ECC_PRIV_KEY_E; + } + + /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */ + /* private * base generator must equal pubkey */ + if (err == MP_OKAY && key->type == ECC_PRIVATEKEY) + err = ecc_check_privkey_gen(key, curve->Af, curve->prime); + } wc_ecc_curve_free(curve); @@ -8532,6 +8570,14 @@ int wc_ecc_check_key(ecc_key* key) return err; } + +/* perform sanity checks on ecc key validity, 0 on success */ +int wc_ecc_check_key(ecc_key* key) +{ + return _ecc_validate_public_key(key, 0, 1); +} + + #ifdef HAVE_ECC_KEY_IMPORT /* import public ECC key in ANSI X9.63 format */ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index 677b2b831..2e41e3dac 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -545,6 +545,12 @@ const char* wc_GetErrorString(int error) case KDF_SSH_KAT_FIPS_E: return "wolfcrypt FIPS SSH KDF Known Answer Test Failure"; + case DHE_PCT_FIPS_E: + return "wolfcrypt FIPS DHE Pairwise Consistency Test Failure"; + + case ECC_PCT_FIPS_E: + return "wolfcrypt FIPS ECDHE Pairwise Consistency Test Failure"; + default: return "unknown error number"; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 3c62374e4..40b3d5905 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -16165,7 +16165,7 @@ static int dh_generate_test(WC_RNG *rng) #else DhKey smallKey[1]; #endif - byte p[2] = { 0, 5 }; + byte p[2] = { 1, 7 }; /* 263 in decimal */ byte g[2] = { 0, 2 }; #if !defined(WOLFSSL_SP_MATH) #ifdef WOLFSSL_DH_CONST diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index 618f5e364..84b320924 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -243,8 +243,10 @@ enum { KDF_TLS12_KAT_FIPS_E = -282, /* TLS12 KDF KAT failure */ KDF_TLS13_KAT_FIPS_E = -283, /* TLS13 KDF KAT failure */ KDF_SSH_KAT_FIPS_E = -284, /* SSH KDF KAT failure */ + DHE_PCT_FIPS_E = -285, /* DHE Pairwise Consistency Test failure */ + ECC_PCT_FIPS_E = -286, /* ECDHE Pairwise Consistency Test failure */ - WC_LAST_E = -284, /* Update this to indicate last error */ + WC_LAST_E = -286, /* Update this to indicate last error */ MIN_CODE_E = -300 /* errors -101 - -299 */ /* add new companion error id strings for any new error codes