Fix for KCAPI ECC KeyGen. Disable ECC consistency checks with KCAPI. Allow public AddSignature (used to be public). Fix KCAPI ECC SharedSecret output size.

This commit is contained in:
David Garske
2022-03-21 11:43:30 -07:00
parent 8bafa7f601
commit 6e550c8d75
4 changed files with 59 additions and 34 deletions

View File

@ -1250,12 +1250,14 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen
#if !defined(WOLFSSL_SP_MATH) && \
!defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050)
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
!defined(WOLFSSL_SE050)
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);
#if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
!defined(WOLFSSL_KCAPI_ECC)
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
#endif
@ -5198,7 +5200,8 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
#if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
!defined(WOLFSSL_KCAPI_ECC)
if (err == MP_OKAY) {
err = _ecc_validate_public_key(key, 0, 0);
}
@ -8670,9 +8673,11 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
#ifdef WOLFSSL_KCAPI_ECC
if (err == MP_OKAY) {
word32 pubkey_sz = (word32)sizeof(key->pubkey_raw);
err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
word32 pubkey_sz = (word32)key->dp->size*2;
if (key->handle == NULL) {
/* if handle loaded, then pubkey_raw already populated */
err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
}
if (err == 0) {
err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
pubkey_sz/2);
@ -8721,7 +8726,8 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
* (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
#if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
!defined(WOLFSSL_KCAPI_ECC)
/* check privkey generator helper, creates prime needed */
static int ecc_check_privkey_gen_helper(ecc_key* key)
@ -8740,6 +8746,9 @@ static int ecc_check_privkey_gen_helper(ecc_key* key)
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
/* Hardware based private key, so this operation is not supported */
err = MP_OKAY; /* just report success */
#elif defined(WOLFSSL_KCAPI_ECC)
/* Hardware based private key, so this operation is not supported */
err = MP_OKAY; /* just report success */
#else
err = MP_OKAY;
ALLOC_CURVE_SPECS(2, err);
@ -8822,7 +8831,7 @@ static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
return err;
}
#endif /* FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN */
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) &&!WOLFSSL_KCAPI_ECC */
#ifndef WOLFSSL_SP_MATH
/* validate order * pubkey = point at infinity, 0 on success */
@ -9082,7 +9091,11 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
/* 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))) {
(mp_cmp(&key->k, curve->order) != MP_LT))
#ifdef WOLFSSL_KCAPI_ECC
&& key->handle == NULL
#endif
) {
err = ECC_PRIV_KEY_E;
}
@ -9104,7 +9117,7 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
#endif
FREE_CURVE_SPECS();
#endif /* WOLFSSL_ATECC508A */
#endif /* HW Based Crypto */
#else
err = WC_KEY_SIZE_E;
#endif /* !WOLFSSL_SP_MATH */

View File

@ -88,6 +88,7 @@ int KcapiEcc_LoadKey(ecc_key* key, byte* pubkey_raw, word32* pubkey_sz,
int ret = 0;
word32 kcapiCurveId = 0;
word32 keySz;
int handleInit = 0;
if (key == NULL || key->dp == NULL) {
ret = BAD_FUNC_ARG;
@ -102,6 +103,7 @@ int KcapiEcc_LoadKey(ecc_key* key, byte* pubkey_raw, word32* pubkey_sz,
if (ret == 0 && key->handle == NULL) {
ret = kcapi_kpp_init(&key->handle, WC_NAME_ECDH, 0);
if (ret == 0) {
handleInit = 1;
ret = kcapi_kpp_ecdh_setcurve(key->handle, kcapiCurveId);
if (ret >= 0) {
ret = 0;
@ -109,20 +111,26 @@ int KcapiEcc_LoadKey(ecc_key* key, byte* pubkey_raw, word32* pubkey_sz,
}
}
/* if a private key value is set, load and use it.
* otherwise use existing key->handle */
if (ret == 0 && mp_iszero(&key->k) != MP_YES) {
byte priv[MAX_ECC_BYTES];
ret = wc_export_int(&key->k, priv, &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
if (ret == 0) {
ret = kcapi_kpp_setkey(key->handle, priv, keySz);
if (ret >= 0) {
ret = 0;
/* set the key */
if (ret == 0) {
if (mp_iszero(&key->k) != MP_YES) {
/* if a private key value is set, load and use it */
byte priv[MAX_ECC_BYTES];
ret = wc_export_int(&key->k, priv, &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
if (ret == 0) {
ret = kcapi_kpp_setkey(key->handle, priv, keySz);
}
}
else {
/* generate new ephemeral key */
ret = kcapi_kpp_setkey(key->handle, NULL, 0);
}
if (ret >= 0) {
ret = 0;
}
}
/* optionally load public key */
/* optionally export public key */
if (ret == 0 && pubkey_raw != NULL && pubkey_sz != NULL) {
if (*pubkey_sz < keySz*2) {
ret = BUFFER_E;
@ -137,7 +145,7 @@ int KcapiEcc_LoadKey(ecc_key* key, byte* pubkey_raw, word32* pubkey_sz,
}
}
if (release_handle && key != NULL && key->handle != NULL) {
if (handleInit && release_handle && key != NULL && key->handle != NULL) {
kcapi_kpp_destroy(key->handle);
key->handle = NULL;
}
@ -170,6 +178,9 @@ int KcapiEcc_MakeKey(ecc_key* key, int keysize, int curve_id)
ret = mp_read_unsigned_bin(key->pubkey.y,
key->pubkey_raw + pubkey_sz / 2, pubkey_sz / 2);
}
if (ret == 0) {
ret = mp_set(key->pubkey.z, 1);
}
if (ret == 0) {
key->type = ECC_PRIVATEKEY;
}
@ -241,12 +252,6 @@ int KcapiEcc_SharedSecret(ecc_key* private_key, ecc_key* public_key, byte* out,
}
}
}
if (ret == 0) {
/* validate the output is large enough */
if (*outlen < keySz*2) {
ret = BUFFER_E;
}
}
if (ret == 0) {
out_aligned = ((size_t)out % pageSz == 0) ? out : buf_aligned;
if ((size_t)pub % pageSz == 0) {
@ -262,9 +267,12 @@ int KcapiEcc_SharedSecret(ecc_key* private_key, ecc_key* public_key, byte* out,
if (ret >= 0) {
*outlen = ret / 2;
if (out_aligned != out) {
/* don't overflow out */
if (ret > (int)*outlen)
ret = (int)*outlen;
XMEMCPY(out, out_aligned, ret);
}
ret = 0;
ret = 0; /* success */
}
}

View File

@ -21717,7 +21717,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
!defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
word32 y;
#endif
#ifdef HAVE_ECC_SIGN
#if defined(HAVE_ECC_SIGN) && !defined(WOLFSSL_KCAPI_ECC)
WC_DECLARE_VAR(sig, byte, ECC_SIG_SIZE, HEAP_HINT);
WC_DECLARE_VAR(digest, byte, ECC_DIGEST_SIZE, HEAP_HINT);
int i;
@ -21751,7 +21751,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
ERROR_OUT(-9901, done);
#endif
#ifdef HAVE_ECC_SIGN
#if defined(HAVE_ECC_SIGN) && !defined(WOLFSSL_KCAPI_ECC)
if (sig == NULL || digest == NULL)
ERROR_OUT(-9902, done);
#endif
@ -21997,7 +21997,9 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
#endif /* HAVE_ECC_KEY_IMPORT */
#endif /* HAVE_ECC_KEY_EXPORT */
#if !defined(ECC_TIMING_RESISTANT) || (defined(ECC_TIMING_RESISTANT) && !defined(WC_NO_RNG))
/* For KCAPI cannot sign using generated ECDH key */
#if !defined(ECC_TIMING_RESISTANT) || (defined(ECC_TIMING_RESISTANT) && \
!defined(WC_NO_RNG) && !defined(WOLFSSL_KCAPI_ECC))
#ifdef HAVE_ECC_SIGN
/* ECC w/out Shamir has issue with all 0 digest */
/* WC_BIGINT doesn't have 0 len well on hardware */
@ -22079,10 +22081,12 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
}
#endif /* HAVE_ECC_VERIFY */
#endif /* HAVE_ECC_SIGN */
#endif /* !ECC_TIMING_RESISTANT || (ECC_TIMING_RESISTANT && !WC_NO_RNG) */
#endif /* !ECC_TIMING_RESISTANT || (ECC_TIMING_RESISTANT &&
* !WC_NO_RNG && !WOLFSSL_KCAPI_ECC) */
#if defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG) && \
!defined(WOLFSSL_ATECC508) && !defined(WOLFSSL_ATECC608A)
!defined(WOLFSSL_ATECC508) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_KCAPI_ECC)
x = ECC_KEY_EXPORT_BUF_SIZE;
ret = wc_ecc_export_private_only(userA, exportBuf, &x);
if (ret != 0)

View File

@ -1840,7 +1840,7 @@ WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz,
WOLFSSL_LOCAL int CheckCSRSignaturePubKey(const byte* cert, word32 certSz,
void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID);
#endif /* WOLFSSL_CERT_REQ */
WOLFSSL_LOCAL int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
WOLFSSL_ASN_API int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
int sigAlgoType);
WOLFSSL_LOCAL int ParseCertRelative(DecodedCert* cert, int type, int verify,
void* cm);