Merge pull request #4966 from dgarske/kcapi

Fixes for KCAPI AES GCM and ECC
This commit is contained in:
Sean Parkinson
2022-03-25 10:18:16 +10:00
committed by GitHub
15 changed files with 375 additions and 200 deletions

View File

@ -2075,19 +2075,21 @@ then
AS_IF([test "$enable_kcapi_hash" != "no"], [ENABLED_KCAPI_HASH=yes])
AS_IF([test "$enable_kcapi_hmac" != "no"], [ENABLED_KCAPI_HMAC=yes])
AS_IF([test "$enable_kcapi_aes" != "no"], [ENABLED_KCAPI_AES=yes])
# currently the PK alg KCAPI options run into build failures, so disabling here for now.
# AS_IF([test "$enable_kcapi_rsa" != "no"], [ENABLED_KCAPI_RSA=yes])
# AS_IF([test "$enable_kcapi_dh" != "no"], [ENABLED_KCAPI_DH=yes])
# AS_IF([test "$enable_kcapi_ecc" != "no"], [ENABLED_KCAPI_ECC=yes])
AS_IF([test "$enable_kcapi_rsa" != "no"], [ENABLED_KCAPI_RSA=yes])
AS_IF([test "$enable_kcapi_dh" != "no"], [ENABLED_KCAPI_DH=yes])
AS_IF([test "$enable_kcapi_ecc" != "no"], [ENABLED_KCAPI_ECC=yes])
fi
AS_IF([test "$ENABLED_KCAPI_HASH" != "no" ||
if test "$ENABLED_KCAPI_HASH" != "no" ||
test "$ENABLED_KCAPI_HMAC" != "no" ||
test "$ENABLED_KCAPI_AES" != "no" ||
test "$ENABLED_KCAPI_RSA" != "no" ||
test "$ENABLED_KCAPI_DH" != "no" ||
test "$ENABLED_KCAPI_ECC" != "no"],
[LIBS="$LIBS -lkcapi"])
test "$ENABLED_KCAPI_ECC" != "no"
then
LIBS="$LIBS -lkcapi"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_KCAPI"
fi
if test "$ENABLED_KCAPI_HASH" = "yes"
then
@ -3594,16 +3596,10 @@ AS_CASE([$FIPS_VERSION],
-DHAVE_FIPS_VERSION_MINOR=$HAVE_FIPS_VERSION_MINOR \
-DHAVE_ECC_CDH \
-DWC_RSA_NO_PADDING \
-DWOLFSSL_ECDSA_SET_K \
-DWOLFSSL_VALIDATE_ECC_IMPORT \
-DECC_USER_CURVES \
-DHAVE_ECC192 \
-DHAVE_ECC224 \
-DHAVE_ECC256 \
-DHAVE_ECC384 \
-DHAVE_ECC521 \
-DWOLFSSL_ECDSA_SET_K \
-DWC_RNG_SEED_CB \
-DWOLFSSL_VALIDATE_FFC_IMPORT \
-DHAVE_FFDHE_Q \
-DHAVE_FFDHE_3072 \
@ -3611,6 +3607,15 @@ AS_CASE([$FIPS_VERSION],
-DHAVE_FFDHE_6144 \
-DHAVE_FFDHE_8192"
# KCAPI API does not support custom k for sign, don't force enable ECC key sizes and do not use seed callback
AS_IF([test "x$ENABLED_KCAPI_ECC" = "xno"],
[AM_CFLAGS="$AM_CFLAGS \
-DWC_RNG_SEED_CB \
-DWOLFSSL_ECDSA_SET_K \
-DHAVE_ECC192 \
-DHAVE_ECC224 \
-DHAVE_ECC256"])
DEFAULT_MAX_CLASSIC_ASYM_KEY_BITS=8192
# force various features to FIPS 140-3 defaults, unless overridden with v5-dev:
@ -3883,8 +3888,8 @@ if test "x$ENABLED_HASHDRBG" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_HASHDRBG"
else
# turn on Hash DRBG if FIPS is on
if test "x$ENABLED_FIPS" = "xyes"
# turn on Hash DRBG if FIPS is on (don't force on for KCAPI)
if test "x$ENABLED_FIPS" = "xyes" && test "x$ENABLED_KCAPI" = "xno"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_HASHDRBG"
ENABLED_HASHDRBG=yes

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);
}
@ -5572,7 +5575,7 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
return err;
}
#elif defined(WOLFSSL_KCAPI_ECC)
err = KcapiEcc_Sign(key, in, inlen, out, outlen);
err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
if (err != MP_OKAY) {
return err;
}
@ -8604,10 +8607,6 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
int err;
ecc_point* base = NULL;
ecc_point* res = NULL;
#ifdef WOLFSSL_KCAPI_ECC
ecc_key pubKey;
word32 len;
#endif
#ifdef WOLFSSL_NO_MALLOC
ecc_point lcl_base;
ecc_point lcl_res;
@ -8672,7 +8671,29 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
if (err == MP_OKAY)
err = mp_set(base->z, 1);
#ifndef WOLFSSL_KCAPI_ECC
#ifdef WOLFSSL_KCAPI_ECC
if (err == MP_OKAY) {
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);
}
if (err == MP_OKAY) {
err = mp_read_unsigned_bin(res->y,
key->pubkey_raw + pubkey_sz/2,
pubkey_sz/2);
}
if (err == MP_OKAY) {
err = mp_set(res->z, 1);
}
}
(void)a;
(void)prime;
#else
#ifdef ECC_TIMING_RESISTANT
if (err == MP_OKAY)
err = wc_ecc_mulmod_ex2(&key->k, base, res, a, prime, curve->order,
@ -8682,29 +8703,10 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
err = wc_ecc_mulmod_ex2(&key->k, base, res, a, prime, curve->order,
NULL, 1, key->heap);
#endif
#else
/* Using Shared Secret to perform scalar multiplication
* Calculates the x ordinidate only.
*/
if (err == MP_OKAY) {
err = wc_ecc_init(&pubKey);
if (err == MP_OKAY) {
wc_ecc_copy_point(base, &pubKey.pubkey);
}
if (err == MP_OKAY) {
err = KcapiEcc_SetPubKey(&pubKey);
}
if (err == MP_OKAY) {
len = key->dp->size;
err = KcapiEcc_SharedSecret(key, &pubKey, pubKey.pubkey_raw,
&len);
}
}
#endif /* !WOLFSSL_KCAPI_ECC */
#endif /* WOLFSSL_KCAPI_ECC */
}
if (err == MP_OKAY) {
#ifndef WOLFSSL_KCAPI_ECC
/* compare result to public key */
if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
@ -8712,17 +8714,6 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
/* didn't match */
err = ECC_PRIV_KEY_E;
}
#else
err = mp_read_unsigned_bin(pubKey.pubkey.x, pubKey.pubkey_raw, len);
/* compare result to public key - y can be negative! */
if (err == MP_OKAY && ((!mp_isone(res->z)) ||
mp_cmp(pubKey.pubkey.x, key->pubkey.x) != MP_EQ)) {
/* didn't match */
err = ECC_PRIV_KEY_E;
}
(void)a;
(void)prime;
#endif
}
wc_ecc_curve_free(curve);
@ -8735,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)
@ -8754,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);
@ -8836,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 */
@ -9096,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;
}
@ -9118,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 */
@ -9204,14 +9203,14 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
/* For SECP256R1 only save raw public key for hardware */
if (curve_id == ECC_SECP256R1 && inLen <= sizeof(key->pubkey_raw)) {
if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
#ifdef HAVE_COMP_KEY
if (!compressed)
#endif
XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
}
#elif defined(WOLFSSL_KCAPI_ECC)
XMEMCPY(key->pubkey_raw + KCAPI_PARAM_SZ, (byte*)in, inLen);
XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
#endif
if (err == MP_OKAY) {
@ -9884,11 +9883,11 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
#elif defined(WOLFSSL_KCAPI_ECC)
if (err == MP_OKAY) {
word32 keySz = key->dp->size;
err = wc_export_int(key->pubkey.x, key->pubkey_raw + KCAPI_PARAM_SZ,
err = wc_export_int(key->pubkey.x, key->pubkey_raw,
&keySz, keySz, WC_TYPE_UNSIGNED_BIN);
if (err == MP_OKAY) {
err = wc_export_int(key->pubkey.y,
&key->pubkey_raw[KCAPI_PARAM_SZ + keySz], &keySz, keySz,
&key->pubkey_raw[keySz], &keySz, keySz,
WC_TYPE_UNSIGNED_BIN);
}
}

View File

@ -234,8 +234,8 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
{
int ret = 0;
byte* data = NULL;
word32 dataSz = authInSz + sz + authTagSz;
ssize_t rc;
word32 dataSz;
int inbuflen = 0, outbuflen = 0;
size_t pageSz = (size_t)sysconf(_SC_PAGESIZE);
/* argument checks */
@ -255,16 +255,22 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
}
if (ret == 0) {
ret = posix_memalign((void*)&data, pageSz, dataSz);
if (ret < 0) {
ret = MEMORY_E;
ret = kcapi_aead_init(&aes->handle, WC_NAME_AESGCM, 0);
if (ret != 0) {
WOLFSSL_MSG("Error with first time setup of kcapi");
}
}
if (ret == 0) {
ret = kcapi_aead_init(&aes->handle, WC_NAME_AESGCM, 0);
if (ret != 0) {
WOLFSSL_MSG("Error with first time setup of kcapi");
inbuflen = (int)kcapi_aead_inbuflen_enc( aes->handle, sz, authInSz,
authTagSz);
outbuflen = (int)kcapi_aead_outbuflen_enc(aes->handle, sz, authInSz,
authTagSz);
dataSz = (inbuflen > outbuflen) ? inbuflen : outbuflen;
ret = posix_memalign((void*)&data, pageSz, dataSz);
if (ret < 0) {
ret = MEMORY_E;
}
}
@ -287,16 +293,18 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
XMEMCPY(data, authIn, authInSz);
XMEMCPY(data + authInSz, in, sz);
rc = kcapi_aead_encrypt(aes->handle, data, dataSz, iv, data, dataSz,
KCAPI_ACCESS_HEURISTIC);
if (rc < 0) {
ret = (int)kcapi_aead_encrypt(aes->handle, data, inbuflen, iv, data,
outbuflen, KCAPI_ACCESS_HEURISTIC);
if (ret < 0) {
WOLFSSL_MSG("GcmEncrypt failed");
ret = (int)rc;
}
else if ((word32)rc != dataSz) {
else if (ret != outbuflen) {
WOLFSSL_MSG("GcmEncrypt produced wrong output length");
ret = BAD_FUNC_ARG;
}
else {
ret = 0; /* success */
}
}
if (ret == 0) {
@ -327,9 +335,8 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
{
int ret = 0;
byte* data = NULL;
word32 dataSz = authInSz + sz + authTagSz;
word32 outSz = authInSz + sz;
ssize_t rc;
word32 dataSz;
int inbuflen = 0, outbuflen = 0;
size_t pageSz = (size_t)sysconf(_SC_PAGESIZE);
/* argument checks */
@ -350,16 +357,22 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
}
if (ret == 0) {
ret = posix_memalign((void*)&data, pageSz, dataSz);
if (ret < 0) {
ret = MEMORY_E;
ret = kcapi_aead_init(&aes->handle, WC_NAME_AESGCM, 0);
if (ret != 0) {
WOLFSSL_MSG("Error with first time setup of kcapi");
}
}
if (ret == 0) {
ret = kcapi_aead_init(&aes->handle, WC_NAME_AESGCM, 0);
if (ret != 0) {
WOLFSSL_MSG("Error with first time setup of kcapi");
inbuflen = (int)kcapi_aead_inbuflen_dec( aes->handle, sz, authInSz,
authTagSz);
outbuflen = (int)kcapi_aead_outbuflen_dec(aes->handle, sz, authInSz,
authTagSz);
dataSz = (inbuflen > outbuflen) ? inbuflen : outbuflen;
ret = posix_memalign((void*)&data, pageSz, dataSz);
if (ret < 0) {
ret = MEMORY_E;
}
}
@ -380,19 +393,20 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
XMEMCPY(data + authInSz, in, sz);
XMEMCPY(data + authInSz + sz, authTag, authTagSz);
rc = kcapi_aead_decrypt(aes->handle, data, dataSz, iv, data, outSz,
KCAPI_ACCESS_HEURISTIC);
if (rc < 0) {
ret = (int)kcapi_aead_decrypt(aes->handle, data, inbuflen, iv, data,
outbuflen, KCAPI_ACCESS_HEURISTIC);
if (ret < 0) {
WOLFSSL_MSG("GcmDecrypt failed");
if (rc == -EBADMSG)
if (ret == -EBADMSG)
ret = AES_GCM_AUTH_E;
else
ret = (int)rc;
}
else if ((word32)rc != outSz) {
else if (ret != outbuflen) {
WOLFSSL_MSG("GcmDecrypt produced wrong output length");
ret = BAD_FUNC_ARG;
}
else {
ret = 0; /* success */
}
}
if (ret == 0) {

View File

@ -26,7 +26,7 @@
#include <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_KCAPI_DH)
#if defined(WOLFSSL_KCAPI_DH) && !defined(NO_DH)
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
@ -232,4 +232,4 @@ int KcapiDh_SharedSecret(DhKey* private_key, const byte* pub, word32 pubSz,
return ret;
}
#endif /* WOLFSSL_KCAPI_DH */
#endif /* WOLFSSL_KCAPI_DH && !NO_DH */

View File

@ -26,7 +26,7 @@
#include <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_KCAPI_ECC)
#if defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC)
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
@ -34,6 +34,9 @@
#include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
#include <wolfssl/wolfcrypt/ecc.h>
#ifndef ECC_CURVE_NIST_P256
#define ECC_CURVE_NIST_P256 2
#endif
#ifndef ECC_CURVE_NIST_P384
#define ECC_CURVE_NIST_P384 3
#endif
@ -79,70 +82,119 @@ static int KcapiEcc_CurveId(int curve_id, word32* kcapiCurveId)
return ret;
}
int KcapiEcc_MakeKey(ecc_key* key, int keysize, int curve_id)
int KcapiEcc_LoadKey(ecc_key* key, byte* pubkey_raw, word32* pubkey_sz,
int release_handle)
{
int ret = 0;
int sz = 0;
word32 kcapiCurveId;
word32 kcapiCurveId = 0;
word32 keySz;
int handleInit = 0;
if (curve_id == ECC_CURVE_DEF) {
switch (keysize) {
case 32:
curve_id = ECC_SECP256R1;
break;
case 48:
curve_id = ECC_SECP384R1;
break;
case 66:
curve_id = ECC_SECP521R1;
break;
default:
if (key == NULL || key->dp == NULL) {
ret = BAD_FUNC_ARG;
break;
}
}
if (ret == 0) {
ret = KcapiEcc_CurveId(curve_id, &kcapiCurveId);
}
if (key->handle != NULL) {
kcapi_kpp_destroy(key->handle);
key->handle = NULL;
}
if (ret == 0) {
keySz = key->dp->size;
ret = KcapiEcc_CurveId(key->dp->id, &kcapiCurveId);
}
/* if handle doesn't exist create one */
if (ret == 0 && key->handle == NULL) {
ret = kcapi_kpp_init(&key->handle, WC_NAME_ECDH, 0);
if (ret != 0) {
WOLFSSL_MSG("KcapiEcc_MakeKey: Failed to initialize");
}
}
if (ret == 0) {
handleInit = 1;
ret = kcapi_kpp_ecdh_setcurve(key->handle, kcapiCurveId);
}
if (ret == 0) {
ret = kcapi_kpp_setkey(key->handle, NULL, 0);
if (ret >= 0) {
ret = 0;
}
}
}
/* set the key */
if (ret == 0) {
sz = ret = (int)kcapi_kpp_keygen(key->handle, key->pubkey_raw,
sizeof(key->pubkey_raw), KCAPI_ACCESS_HEURISTIC);
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 = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw, sz / 2);
ret = 0;
}
}
/* optionally export public key */
if (ret == 0 && pubkey_raw != NULL && pubkey_sz != NULL) {
if (*pubkey_sz < keySz*2) {
ret = BUFFER_E;
}
if (ret == 0) {
ret = mp_read_unsigned_bin(key->pubkey.y, key->pubkey_raw + sz / 2,
sz / 2);
ret = (int)kcapi_kpp_keygen(key->handle, pubkey_raw, keySz*2,
KCAPI_ACCESS_HEURISTIC);
if (ret >= 0) {
*pubkey_sz = ret;
ret = 0;
}
}
}
if (handleInit && release_handle && key != NULL && key->handle != NULL) {
kcapi_kpp_destroy(key->handle);
key->handle = NULL;
}
return ret;
}
int KcapiEcc_MakeKey(ecc_key* key, int keysize, int curve_id)
{
int ret = 0;
word32 pubkey_sz = (word32)sizeof(key->pubkey_raw);
/* free existing handle */
if (key != NULL && key->handle != NULL) {
kcapi_kpp_destroy(key->handle);
key->handle = NULL;
}
/* check arguments */
if (key == NULL || key->dp == NULL) {
ret = BAD_FUNC_ARG;
}
ret = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 0);
if (ret == 0) {
ret = mp_read_unsigned_bin(key->pubkey.x,
key->pubkey_raw, pubkey_sz / 2);
}
if (ret == 0) {
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;
}
if ((ret != 0) && (key->handle != NULL)) {
/* if error release handle now */
if (ret != 0 && key->handle != NULL) {
kcapi_kpp_destroy(key->handle);
key->handle = NULL;
}
/* These are not used. The key->dp is set */
(void)keysize;
(void)curve_id;
return ret;
}
@ -150,26 +202,37 @@ int KcapiEcc_MakeKey(ecc_key* key, int keysize, int curve_id)
int KcapiEcc_SharedSecret(ecc_key* private_key, ecc_key* public_key, byte* out,
word32* outlen)
{
int ret;
int ret = 0;
word32 kcapiCurveId = 0;
byte* buf_aligned = NULL;
byte* pub_aligned = NULL;
byte* out_aligned = NULL;
size_t pageSz = (size_t)sysconf(_SC_PAGESIZE);
byte* pub = public_key->pubkey_raw;
byte* pub;
word32 keySz;
if (private_key == NULL || private_key->dp == NULL || public_key == NULL) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
pub = public_key->pubkey_raw;
keySz = private_key->dp->size;
ret = KcapiEcc_CurveId(private_key->dp->id, &kcapiCurveId);
}
if (ret == 0 && private_key->handle == NULL) {
ret = kcapi_kpp_init(&private_key->handle, WC_NAME_ECDH, 0);
if (ret == 0) {
ret = kcapi_kpp_ecdh_setcurve(private_key->handle, kcapiCurveId);
if (ret >= 0) {
ret = 0;
}
}
}
/* if a private key value is set, load and use it */
if (mp_iszero(&private_key->k) != MP_YES) {
if (ret == 0 && mp_iszero(&private_key->k) != MP_YES) {
byte priv[MAX_ECC_BYTES];
word32 keySz = private_key->dp->size;
ret = wc_export_int(&private_key->k, priv, &keySz, keySz,
WC_TYPE_UNSIGNED_BIN);
if (ret == 0) {
@ -196,18 +259,20 @@ int KcapiEcc_SharedSecret(ecc_key* private_key, ecc_key* public_key, byte* out,
}
else {
pub_aligned = buf_aligned + pageSz;
XMEMCPY(pub_aligned, pub, public_key->dp->size * 2);
XMEMCPY(pub_aligned, pub, keySz * 2);
}
ret = (int)kcapi_kpp_ssgen(private_key->handle, pub_aligned,
public_key->dp->size * 2, out_aligned,
*outlen, KCAPI_ACCESS_HEURISTIC);
keySz * 2, out_aligned, keySz * 2, KCAPI_ACCESS_HEURISTIC);
if (ret >= 0) {
*outlen = ret/2;
*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 */
}
}
@ -233,34 +298,45 @@ static int KcapiEcc_SetPrivKey(ecc_key* key)
if (ret == 0) {
priv[0] = ECDSA_KEY_VERSION;
priv[1] = kcapiCurveId;
ret = wc_export_int(&key->k, priv + 2, &keySz, keySz,
ret = wc_export_int(&key->k, priv + KCAPI_PARAM_SZ, &keySz, keySz,
WC_TYPE_UNSIGNED_BIN);
}
if (ret == 0) {
/* call with NULL to so KCAPI treats incoming data as hash */
ret = kcapi_akcipher_setkey(key->handle, NULL, 0);
if (ret >= 0) {
ret = kcapi_akcipher_setkey(key->handle, priv, KCAPI_PARAM_SZ + keySz);
if (ret >= 0) {
ret = 0;
}
}
}
return ret;
}
int KcapiEcc_Sign(ecc_key* key, const byte* hash, word32 hashLen, byte* sig,
word32* sigLen)
word32 sigLen)
{
int ret = 0;
byte* buf_aligned = NULL;
byte* hash_aligned = NULL;
byte* sig_aligned = NULL;
size_t pageSz = (size_t)sysconf(_SC_PAGESIZE);
int handleInit = 0;
word32 keySz;
if (key->handle == NULL) {
if (key == NULL || key->dp == NULL) {
ret = BAD_FUNC_ARG;
}
if (ret == 0 && key->handle == NULL) {
ret = kcapi_akcipher_init(&key->handle, WC_NAME_ECDSA, 0);
if (ret != 0) {
WOLFSSL_MSG("KcapiEcc_Sign: Failed to initialize");
}
if (ret == 0) {
handleInit = 1;
ret = KcapiEcc_SetPrivKey(key);
}
}
@ -272,6 +348,13 @@ int KcapiEcc_Sign(ecc_key* key, const byte* hash, word32 hashLen, byte* sig,
}
}
}
if (ret == 0) {
/* make sure signature output is large enough */
keySz = key->dp->size;
if (sigLen < keySz*2) {
ret = BUFFER_E;
}
}
if (ret == 0) {
sig_aligned = ((size_t)sig % pageSz == 0) ? sig : buf_aligned;
if ((size_t)hash % pageSz == 0) {
@ -282,44 +365,56 @@ int KcapiEcc_Sign(ecc_key* key, const byte* hash, word32 hashLen, byte* sig,
XMEMCPY(hash_aligned, hash, hashLen);
}
ret = (int)kcapi_akcipher_sign(key->handle, hash_aligned, hashLen,
sig_aligned, *sigLen,
KCAPI_ACCESS_HEURISTIC);
sig_aligned, keySz*2, KCAPI_ACCESS_HEURISTIC);
if (ret >= 0) {
*sigLen = ret;
ret = 0;
if (sig_aligned != sig) {
XMEMCPY(sig, sig_aligned, ret);
}
ret = 0; /* mark success */
}
}
/* Using free as this is in an environment that will have it
* available along with posix_memalign. */
if (buf_aligned != NULL) {
free(buf_aligned);
}
if (handleInit) {
kcapi_kpp_destroy(key->handle);
key->handle = NULL;
}
return ret;
}
#endif
#ifdef HAVE_ECC_VERIFY
int KcapiEcc_SetPubKey(ecc_key* key)
static int KcapiEcc_SetPubKey(ecc_key* key)
{
int ret;
int len = KCAPI_PARAM_SZ + key->dp->size * 2;
word32 kcapiCurveId;
word32 keySz = key->dp->size;
byte pub[KCAPI_PARAM_SZ + (MAX_ECC_BYTES * 2)];
int pubLen;
ret = KcapiEcc_CurveId(key->dp->id, &kcapiCurveId);
if (ret == 0) {
key->pubkey_raw[0] = ECDSA_KEY_VERSION;
key->pubkey_raw[1] = kcapiCurveId;
pub[0] = ECDSA_KEY_VERSION;
pub[1] = kcapiCurveId;
XMEMCPY(&pub[KCAPI_PARAM_SZ], key->pubkey_raw, keySz * 2);
pubLen = KCAPI_PARAM_SZ + (keySz * 2);
ret = kcapi_akcipher_setpubkey(key->handle, key->pubkey_raw, len);
/* call with NULL to so KCAPI treats incoming data as hash */
ret = kcapi_akcipher_setpubkey(key->handle, NULL, 0);
if (ret >= 0) {
ret = kcapi_akcipher_setpubkey(key->handle, pub, pubLen);
if (ret >= 0) {
ret = 0;
}
}
}
return ret;
}
@ -330,32 +425,48 @@ int KcapiEcc_Verify(ecc_key* key, const byte* hash, word32 hashLen, byte* sig,
int ret = 0;
byte* sigHash_aligned = NULL;
size_t pageSz = (size_t)sysconf(_SC_PAGESIZE);
int handleInit = 0;
word32 keySz = 0;
byte* outbuf = NULL;
if (key->handle == NULL) {
if (key == NULL || key->dp == NULL) {
ret = BAD_FUNC_ARG;
}
if (ret == 0 && key->handle == NULL) {
ret = kcapi_akcipher_init(&key->handle, WC_NAME_ECDSA, 0);
if (ret != 0) {
WOLFSSL_MSG("KcapiEcc_Verify: Failed to initialize");
}
}
if (ret == 0) {
handleInit = 1;
ret = KcapiEcc_SetPubKey(key);
}
}
if (ret == 0) {
ret = posix_memalign((void*)&sigHash_aligned, pageSz, sigLen + hashLen);
if (ret < 0) {
ret = MEMORY_E;
}
}
if (ret == 0) {
keySz = key->dp->size;
ret = posix_memalign((void*)&outbuf, pageSz, keySz * 2);
if (ret < 0) {
ret = MEMORY_E;
}
}
if (ret == 0) {
XMEMCPY(sigHash_aligned, sig, sigLen);
XMEMCPY(sigHash_aligned + sigLen, hash, hashLen);
ret = (int)kcapi_akcipher_verify(key->handle, sigHash_aligned,
sigLen + hashLen, NULL, hashLen, KCAPI_ACCESS_HEURISTIC);
sigLen + hashLen, outbuf, keySz * 2,
KCAPI_ACCESS_HEURISTIC);
if (ret >= 0) {
ret = 0;
}
(void)outbuf; /* not used */
}
/* Using free as this is in an environment that will have it
@ -363,8 +474,16 @@ int KcapiEcc_Verify(ecc_key* key, const byte* hash, word32 hashLen, byte* sig,
if (sigHash_aligned != NULL) {
free(sigHash_aligned);
}
if (outbuf != NULL) {
free(outbuf);
}
if (handleInit) {
kcapi_kpp_destroy(key->handle);
key->handle = NULL;
}
return ret;
}
#endif
#endif /* WOLFSSL_KCAPI_ECC */
#endif /* WOLFSSL_KCAPI_ECC && HAVE_ECC */

View File

@ -642,4 +642,3 @@ int wc_Sha512_256Copy(wc_Sha512* src, wc_Sha512* dst)
#endif /* WOLFSSL_SHA512 */
#endif /* WOLFSSL_KCAPI_HASH */

View File

@ -26,7 +26,7 @@
#include <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_KCAPI_HMAC)
#if defined(WOLFSSL_KCAPI_HMAC) && !defined(NO_HMAC)
#define FIPS_NO_WRAPPERS
@ -334,5 +334,4 @@ int wc_HmacFinal(Hmac* hmac, byte* hash)
return ret;
}
#endif /* WOLFSSL_KCAPI_HMAC */
#endif /* WOLFSSL_KCAPI_HMAC && !NO_HMAC */

View File

@ -26,7 +26,7 @@
#include <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_KCAPI_RSA)
#if defined(WOLFSSL_KCAPI_RSA) && !defined(NO_RSA)
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
@ -356,5 +356,4 @@ int KcapiRsa_Encrypt(RsaKey* key, const byte* in, word32 inLen, byte* out,
return ret;
}
#endif /* WOLFSSL_KCAPI_RSA */
#endif /* WOLFSSL_KCAPI_RSA && !NO_RSA */

View File

@ -2786,8 +2786,33 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
return 0;
}
#endif
/* End wc_GenerateSeed */
#if defined(CUSTOM_RAND_GENERATE_BLOCK) && defined(WOLFSSL_KCAPI)
#include <fcntl.h>
int wc_hwrng_generate_block(byte *output, word32 sz)
{
int fd;
int len;
int ret = 0;
fd = open("/dev/hwrng", O_RDONLY);
if (fd == -1)
return OPEN_RAN_E;
while(sz)
{
len = (int)read(fd, output, sz);
if (len == -1)
{
ret = READ_RAN_E;
break;
}
sz -= len;
output += len;
}
close(fd);
return ret;
}
#endif
#endif /* WC_NO_RNG */
#endif /* HAVE_FIPS */

View File

@ -1120,13 +1120,15 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
return err_sys("AES-GCM test failed!\n", ret);
#endif
#if !defined(WOLFSSL_AFALG_XILINX_AES) && !defined(WOLFSSL_XILINX_CRYPT) && \
!(defined(WOLF_CRYPTO_CB) && \
!defined(WOLFSSL_KCAPI_AES) && !(defined(WOLF_CRYPTO_CB) && \
(defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC)))
if ((ret = aesgcm_default_test()) != 0) {
return err_sys("AES-GCM test failed!\n", ret);
}
#endif
if (ret == 0) {
TEST_PASS("AES-GCM test passed!\n");
}
#endif
#if defined(HAVE_AESCCM) && defined(WOLFSSL_AES_128)
@ -21039,7 +21041,8 @@ done:
#endif
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K)
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K) && \
!defined(WOLFSSL_KCAPI_ECC)
static int ecc_test_sign_vectors(WC_RNG* rng)
{
int ret;
@ -21714,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;
@ -21748,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
@ -21994,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 */
@ -22076,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)
@ -24118,7 +24125,8 @@ WOLFSSL_TEST_SUBROUTINE int ecc_test(void)
#endif
#endif
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K)
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K) && \
!defined(WOLFSSL_KCAPI_ECC)
ret = ecc_test_sign_vectors(&rng);
if (ret != 0) {
printf("ecc_test_sign_vectors failed! %d\n", ret);

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);

View File

@ -466,7 +466,7 @@ struct ecc_key {
#endif
#ifdef WOLFSSL_KCAPI_ECC
struct kcapi_handle* handle;
byte pubkey_raw[KCAPI_PARAM_SZ + MAX_ECC_BYTES * 2];
byte pubkey_raw[MAX_ECC_BYTES * 2];
#endif
#ifdef WOLFSSL_ASYNC_CRYPT

View File

@ -36,16 +36,16 @@
#define WC_ECCKEY_TYPE_DEFINED
#endif
int KcapiEcc_SetPubKey(ecc_key* key);
void KcapiEcc_Free(ecc_key* key);
int KcapiEcc_MakeKey(ecc_key* key, int keysize, int curve_id);
int KcapiEcc_SharedSecret(ecc_key* private_key, ecc_key* public_key, byte* out,
word32* outlen);
int KcapiEcc_Sign(ecc_key* key, const byte* hash, word32 hashLen, byte* sig,
word32* sigLen);
int KcapiEcc_Verify(ecc_key* key, const byte* hash, word32 hashLen, byte* sig,
word32 sigLen);
WOLFSSL_LOCAL void KcapiEcc_Free(ecc_key* key);
WOLFSSL_LOCAL int KcapiEcc_MakeKey(ecc_key* key, int keysize, int curve_id);
WOLFSSL_LOCAL int KcapiEcc_LoadKey(ecc_key* key, byte* pubkey_raw,
word32* pubkey_sz, int release_handle);
WOLFSSL_LOCAL int KcapiEcc_SharedSecret(ecc_key* private_key,
ecc_key* public_key, byte* out, word32* outlen);
WOLFSSL_LOCAL int KcapiEcc_Sign(ecc_key* key, const byte* hash, word32 hashLen,
byte* sig, word32 sigLen);
WOLFSSL_LOCAL int KcapiEcc_Verify(ecc_key* key, const byte* hash, word32 hashLen,
byte* sig, word32 sigLen);
#endif /* WOLF_CRYPT_KCAPI_ECC_H */

View File

@ -99,6 +99,11 @@
* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc
* extern int myRngFunc(byte* output, word32 sz);
*/
#if defined(CUSTOM_RAND_GENERATE_BLOCK) && defined(WOLFSSL_KCAPI)
#undef CUSTOM_RAND_GENERATE_BLOCK
#define CUSTOM_RAND_GENERATE_BLOCK wc_hwrng_generate_block
WOLFSSL_LOCAL int wc_hwrng_generate_block(byte *output, word32 sz);
#endif
#elif defined(HAVE_HASHDRBG)
#ifdef NO_SHA256
#error "Hash DRBG requires SHA-256."

View File

@ -1627,9 +1627,12 @@ extern void uITRON4_free(void *p) ;
#define WOLFSSL_AES_GCM_FIXED_IV_AAD
#endif
#ifdef WOLFSSL_KCAPI_ECC
#undef ECC_USER_CURVES
#define ECC_USER_CURVES
#undef NO_ECC256
#undef HAVE_ECC384
#define HAVE_ECC384
#undef HAVE_ECC521
#define HAVE_ECC521
#endif