Add sign/verify PCT to ECC.

This commit is contained in:
John Safranek
2021-04-14 10:53:02 -07:00
committed by Daniel Pouzzner
parent 9bf36f329a
commit 3eaeaf3a57
3 changed files with 66 additions and 11 deletions

View File

@ -1224,7 +1224,7 @@ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
#endif #endif
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv); static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT) #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 #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, static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
int flags) int curve_id, int flags)
{ {
int err; 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 */ #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) { if (err == MP_OKAY) {
err = _ecc_validate_public_key(key, 0, 0); err = _ecc_validate_public_key(key, 0, 0);
} }
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT) #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT)
if (err == MP_OKAY) { if (err == MP_OKAY) {
err = _ecc_pairwise_consistency_test(key); err = _ecc_pairwise_consistency_test(key, rng);
} }
#endif #endif
@ -5549,8 +5558,8 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
else else
#endif #endif
{ {
err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey, err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
key->dp->id); WC_ECC_FLAG_NONE);
} }
if (err != MP_OKAY) break; 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) #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT)
/* Performs a Pairwise Consistency Test on an ECC key pair. */ /* 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 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; err = ECC_PCT_E;
return err; return err;
@ -9050,7 +9105,7 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
if ((pub != NULL) && (ret == MP_OKAY)) if ((pub != NULL) && (ret == MP_OKAY))
/* public key needed to perform key validation */ /* public key needed to perform key validation */
ret = _ecc_pairwise_consistency_test(key); ret = _ecc_validate_public_key(key, 1, 1);
#endif #endif
return ret; return ret;

View File

@ -21200,6 +21200,7 @@ static int ecc_test_sign_vectors(WC_RNG* rng)
if (ret != 0) { if (ret != 0) {
goto done; goto done;
} }
wc_ecc_set_flags(&key, WC_ECC_FLAG_DEC_SIGN);
ret = wc_ecc_sign_set_k(k, sizeof(k), &key); ret = wc_ecc_sign_set_k(k, sizeof(k), &key);
if (ret != 0) { if (ret != 0) {
@ -21566,6 +21567,7 @@ static int ecc_test_make_pub(WC_RNG* rng)
/* make public key for shared secret */ /* make public key for shared secret */
wc_ecc_init_ex(pub, HEAP_HINT, devId); wc_ecc_init_ex(pub, HEAP_HINT, devId);
ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, pub); ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, pub);
wc_ecc_set_flags(key, WC_ECC_FLAG_COFACTOR);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &pub->asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &pub->asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif

View File

@ -403,9 +403,7 @@ typedef struct {
/* ECC Flags */ /* ECC Flags */
enum { enum {
WC_ECC_FLAG_NONE = 0x00, WC_ECC_FLAG_NONE = 0x00,
#ifdef HAVE_ECC_CDH
WC_ECC_FLAG_COFACTOR = 0x01, WC_ECC_FLAG_COFACTOR = 0x01,
#endif
WC_ECC_FLAG_DEC_SIGN = 0x02, WC_ECC_FLAG_DEC_SIGN = 0x02,
}; };