diff --git a/configure.ac b/configure.ac index 1be4dbbdf..4e0b050f0 100644 --- a/configure.ac +++ b/configure.ac @@ -3290,8 +3290,8 @@ AC_ARG_WITH([cavium-v], [ --with-cavium-v=PATH PATH to Cavium V/software dir ], [ AC_MSG_CHECKING([for cavium]) - CPPFLAGS="$CPPFLAGS -DHAVE_CAVIUM -DHAVE_CAVIUM_V" - LIB_ADD="-lrt $LIB_ADD" + AM_CFLAGS="$AM_CFLAGS -DHAVE_CAVIUM -DHAVE_CAVIUM_V" + LIB_ADD="-lrt -lcrypto $LIB_ADD" if test "x$withval" == "xyes" ; then AC_MSG_ERROR([need a PATH for --with-cavium]) @@ -3300,21 +3300,17 @@ AC_ARG_WITH([cavium-v], trycaviumdir=$withval fi - LDFLAGS="$AM_LDFLAGS $trycaviumdir/api/obj/cavium_common.o $trycaviumdir/api/obj/cavium_sym_crypto.o $trycaviumdir/api/obj/cavium_asym_crypto.o" - CPPFLAGS="$CPPFLAGS -I$trycaviumdir/include" + AC_CHECK_FILES([$trycaviumdir/lib/libnitrox.a], [AM_CPPFLAGS="-I$trycaviumdir/include $AM_CPPFLAGS"], [ENABLED_CAVIUM_V=no]) + LIB_STATIC_ADD="$trycaviumdir/lib/libnitrox.a $LIB_STATIC_ADD" - #AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "cavium_common.h"]], [[ CspShutdown(0); ]])],[ cavium_linked=yes ],[ cavium_linked=no ]) - - if test "x$cavium_linked" == "xno" ; then - AC_MSG_ERROR([cavium isn't found. - If it's already installed, specify its path using --with-cavium-v=/dir/]) - else - AM_CFLAGS="$AM_CFLAGS -DHAVE_CAVIUM -DHAVE_CAVIUM_V" + if test "$ENABLED_CAVIUM_V" = "no"; then + AC_MSG_ERROR([Could not find Nitrox library]) fi - AC_MSG_RESULT([yes]) enable_shared=no enable_static=yes + enable_opensslextra=yes + ENABLED_CAVIUM=yes ENABLED_CAVIUM_V=yes ], @@ -3325,6 +3321,7 @@ AC_ARG_WITH([cavium-v], ) AM_CONDITIONAL([BUILD_CAVIUM], [test "x$ENABLED_CAVIUM" = "xyes"]) +AM_CONDITIONAL([BUILD_CAVIUM_V], [test "x$ENABLED_CAVIUM_V" = "xyes"]) # Intel Quick Assist diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index beb5d53bd..0d6f80614 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -7544,10 +7544,17 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) /* if async and byte count above threshold */ + /* only 12-byte IV is supported in HW */ if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES && - sz >= WC_ASYNC_THRESH_AES_GCM) { + sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == NONCE_SZ) { #if defined(HAVE_CAVIUM) - /* Not yet supported, contact wolfSSL if interested in using */ + #ifdef HAVE_CAVIUM_V + if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */ + return NitroxAesGcmEncrypt(aes, out, in, sz, + (const byte*)aes->asyncKey, aes->keylen, iv, ivSz, + authTag, authTagSz, authIn, authInSz); + } + #endif #elif defined(HAVE_INTEL_QA) return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz, (const byte*)aes->asyncKey, aes->keylen, iv, ivSz, @@ -7887,10 +7894,17 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) /* if async and byte count above threshold */ + /* only 12-byte IV is supported in HW */ if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES && - sz >= WC_ASYNC_THRESH_AES_GCM) { + sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == NONCE_SZ) { #if defined(HAVE_CAVIUM) - /* Not yet supported, contact wolfSSL if interested in using */ + #ifdef HAVE_CAVIUM_V + if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */ + return NitroxAesGcmDecrypt(aes, out, in, sz, + (const byte*)aes->asyncKey, aes->keylen, iv, ivSz, + authTag, authTagSz, authIn, authInSz); + } + #endif #elif defined(HAVE_INTEL_QA) return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz, (const byte*)aes->asyncKey, aes->keylen, iv, ivSz, diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e7b647bec..b39ae1c93 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5534,7 +5534,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, /* make sure we're right justified */ encodedSigSz = wc_EncodeSignature(encodedSig, sigCtx->digest, sigCtx->digestSz, sigCtx->typeH); - if (encodedSigSz == verifySz && + if (encodedSigSz == verifySz && sigCtx->out != NULL && XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) { ret = 0; } diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 4abf9c0c9..2f78d29a2 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2728,6 +2728,49 @@ int wc_ecc_get_curve_id_from_params(int fieldSize, } +#ifdef WOLFSSL_ASYNC_CRYPT +static INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp) +{ + if (key == NULL || mp == NULL) + return BAD_FUNC_ARG; + if (*mp == NULL) { + *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT); + if (*mp == NULL) { + return MEMORY_E; + } + XMEMSET(*mp, 0, sizeof(mp_int)); + } + return 0; +} +static INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp) +{ + if (key && mp && *mp) { + mp_clear(*mp); + XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT); + *mp = NULL; + } +} + +static int wc_ecc_alloc_async(ecc_key* key) +{ + int err = wc_ecc_alloc_mpint(key, &key->r); + if (err == 0) + err = wc_ecc_alloc_mpint(key, &key->s); + return err; +} + +static void wc_ecc_free_async(ecc_key* key) +{ + wc_ecc_free_mpint(key, &key->r); + wc_ecc_free_mpint(key, &key->s); +#ifdef HAVE_CAVIUM_V + wc_ecc_free_mpint(key, &key->e); + wc_ecc_free_mpint(key, &key->signK); +#endif /* HAVE_CAVIUM_V */ +} +#endif /* WOLFSSL_ASYNC_CRYPT */ + + #ifdef HAVE_ECC_DHE /** Create an ECC shared secret between two keys @@ -2872,26 +2915,45 @@ static int wc_ecc_shared_secret_gen_async(ecc_key* private_key, { int err; -#ifdef HAVE_CAVIUM - /* TODO: Not implemented - use software for now */ - err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve); +#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) +#ifdef HAVE_CAVIUM_V + /* verify the curve is supported by hardware */ + if (NitroxEccIsCurveSupported(private_key)) +#endif + { + word32 keySz = private_key->dp->size; -#elif defined(HAVE_INTEL_QA) - /* sync public key x/y */ - err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF); - if (err == MP_OKAY) - err = wc_mp_to_bigint(&private_key->k, &private_key->k.raw); - if (err == MP_OKAY) - err = wc_mp_to_bigint(point->x, &point->x->raw); - if (err == MP_OKAY) - err = wc_mp_to_bigint(point->y, &point->y->raw); - if (err == MP_OKAY) - err = IntelQaEcdh(&private_key->asyncDev, - &private_key->k.raw, &point->x->raw, &point->y->raw, - out, outlen, - &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw, - private_key->dp->cofactor); -#else /* WOLFSSL_ASYNC_CRYPT_TEST */ + /* sync public key x/y */ + err = wc_mp_to_bigint_sz(&private_key->k, &private_key->k.raw, keySz); + if (err == MP_OKAY) + err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz); + if (err == MP_OKAY) + err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz); + #ifdef HAVE_CAVIUM_V + /* allocate buffer for output */ + if (err == MP_OKAY) + err = wc_ecc_alloc_mpint(private_key, &private_key->e); + if (err == MP_OKAY) + err = wc_bigint_alloc(&private_key->e->raw, + NitroxEccGetSize(private_key)*2); + if (err == MP_OKAY) + err = NitroxEcdh(private_key, + &private_key->k.raw, &point->x->raw, &point->y->raw, + private_key->e->raw.buf, &private_key->e->raw.len, + &curve->prime->raw); + #else + if (err == MP_OKAY) + err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF); + if (err == MP_OKAY) + err = IntelQaEcdh(&private_key->asyncDev, + &private_key->k.raw, &point->x->raw, &point->y->raw, + out, outlen, + &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw, + private_key->dp->cofactor); + #endif + return err; + } +#elif defined(WOLFSSL_ASYNC_CRYPT_TEST) if (wc_AsyncTestInit(&private_key->asyncDev, ASYNC_TEST_ECC_SHARED_SEC)) { WC_ASYNC_TEST* testDev = &private_key->asyncDev.test; testDev->eccSharedSec.private_key = private_key; @@ -2900,9 +2962,11 @@ static int wc_ecc_shared_secret_gen_async(ecc_key* private_key, testDev->eccSharedSec.outLen = outlen; return WC_PENDING_E; } - err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve); #endif + /* use sync in other cases */ + err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve); + return err; } #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -2983,6 +3047,18 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, case ECC_STATE_SHARED_SEC_RES: private_key->state = ECC_STATE_SHARED_SEC_RES; + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) + if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { + #ifdef HAVE_CAVIUM_V + /* verify the curve is supported by hardware */ + if (NitroxEccIsCurveSupported(private_key)) { + /* copy output */ + *outlen = private_key->dp->size; + XMEMCPY(out, private_key->e->raw.buf, *outlen); + } + #endif /* HAVE_CAVIUM_V */ + } + #endif /* WOLFSSL_ASYNC_CRYPT */ err = 0; break; @@ -2996,6 +3072,10 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, return err; } + /* cleanup */ +#ifdef WOLFSSL_ASYNC_CRYPT + wc_ecc_free_async(private_key); +#endif private_key->state = ECC_STATE_NONE; return err; @@ -3397,66 +3477,6 @@ int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key) return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF); } -static INLINE int wc_ecc_alloc_rs(ecc_key* key, mp_int** r, mp_int** s) -{ - int err = 0; - -#ifndef WOLFSSL_ASYNC_CRYPT - (void)key; -#endif - - if (*r == NULL) { - #ifdef WOLFSSL_ASYNC_CRYPT - *r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT); - if (*r == NULL) { - return MEMORY_E; - } - key->r = *r; - #endif - } - if (*s == NULL) { - #ifdef WOLFSSL_ASYNC_CRYPT - *s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT); - if (*s == NULL) { - XFREE(*r, key->heap, DYNAMIC_TYPE_BIGINT); - return MEMORY_E; - } - key->s = *s; - #endif - } - - /* initialize mp_int */ - if (*r) - XMEMSET(*r, 0, sizeof(mp_int)); - if (*s) - XMEMSET(*s, 0, sizeof(mp_int)); - - return err; -} - -static INLINE void wc_ecc_free_rs(ecc_key* key, mp_int** r, mp_int** s) -{ - if (*r) { - mp_clear(*r); - - #ifdef WOLFSSL_ASYNC_CRYPT - XFREE(*r, key->heap, DYNAMIC_TYPE_BIGINT); - key->r = NULL; - #endif - *r = NULL; - } - if (*s) { - mp_clear(*s); - - #ifdef WOLFSSL_ASYNC_CRYPT - XFREE(*s, key->heap, DYNAMIC_TYPE_BIGINT); - key->s = NULL; - #endif - *s = NULL; - } - (void)key; -} - /* Setup dynamic pointers if using normal math for proper freeing */ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) { @@ -3612,8 +3632,6 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, mp_int *r = NULL, *s = NULL; #ifndef WOLFSSL_ASYNC_CRYPT mp_int r_lcl, s_lcl; - r = &r_lcl; - s = &s_lcl; #endif if (in == NULL || out == NULL || outlen == NULL || key == NULL || @@ -3621,15 +3639,22 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, return ECC_BAD_ARG_E; } +#ifdef WOLFSSL_ASYNC_CRYPT + err = wc_ecc_alloc_async(key); + if (err != 0) + return err; + r = key->r; + s = key->s; +#else + r = &r_lcl; + s = &s_lcl; +#endif + switch(key->state) { case ECC_STATE_NONE: case ECC_STATE_SIGN_DO: key->state = ECC_STATE_SIGN_DO; - err = wc_ecc_alloc_rs(key, &r, &s); - if (err != 0) - break; - if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){ break; } @@ -3650,13 +3675,13 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, key->state = ECC_STATE_SIGN_ENCODE; #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) - /* restore r/s */ - r = key->r; - s = key->s; - if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { - /* only do this if not simulator, since it overwrites result */ + #ifdef HAVE_CAVIUM_V + /* Nitrox requires r and s in sep buffer, so split it */ + NitroxEccRsSplit(key, &r->raw, &s->raw); + #endif #ifndef WOLFSSL_ASYNC_CRYPT_TEST + /* only do this if not simulator, since it overwrites result */ wc_bigint_to_mp(&r->raw, r); wc_bigint_to_mp(&s->raw, s); #endif @@ -3666,7 +3691,7 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, /* encoded with DSA header */ err = StoreECC_DSA_Sig(out, outlen, r, s); - /* always free r/s */ + /* done with R/S */ mp_clear(r); mp_clear(s); break; @@ -3683,7 +3708,9 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, } /* cleanup */ - wc_ecc_free_rs(key, &r, &s); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_ecc_free_async(key); +#endif key->state = ECC_STATE_NONE; return err; @@ -3705,8 +3732,12 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, { int err; #ifndef WOLFSSL_SP_MATH - mp_int e; + mp_int* e; +#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V) + mp_int e_lcl; #endif +#endif /* !WOLFSSL_SP_MATH */ + DECLARE_CURVE_SPECS(1) if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) @@ -3739,7 +3770,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap); #endif } -#endif +#endif /* WOLFSSL_HAVE_SP_ECC */ + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ defined(WOLFSSL_ASYNC_CRYPT_TEST) @@ -3757,9 +3789,18 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } #endif +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V) + err = wc_ecc_alloc_mpint(key, &key->e); + if (err != 0) + return err; + e = key->e; +#else + e = &e_lcl; +#endif + /* get the hash and load it as a bignum into 'e' */ /* init the bignums */ - if ((err = mp_init(&e)) != MP_OKAY) { + if ((err = mp_init(e)) != MP_OKAY) { return err; } @@ -3774,11 +3815,11 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, /* truncate down to byte size, may be all that's needed */ if ((WOLFSSL_BIT_SIZE * inlen) > orderBits) inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; - err = mp_read_unsigned_bin(&e, (byte*)in, inlen); + err = mp_read_unsigned_bin(e, (byte*)in, inlen); /* may still need bit truncation too */ if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits) - mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); + mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); } /* make up a key and export the public copy */ @@ -3788,40 +3829,74 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { - #ifdef HAVE_CAVIUM - /* TODO: Not implemented */ - #elif defined(HAVE_INTEL_QA) - mp_int k; + #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) + #ifdef HAVE_CAVIUM_V + if (NitroxEccIsCurveSupported(key)) + #endif + { + word32 keySz = key->dp->size; + mp_int* k; + #ifdef HAVE_CAVIUM_V + err = wc_ecc_alloc_mpint(key, &key->signK); + if (err != 0) + return err; + k = key->signK; + #else + mp_int k_lcl; + k = &k_lcl; + #endif - err = mp_init(&k); - /* make sure r and s are allocated */ - if (err == MP_OKAY) - err = wc_bigint_alloc(&key->r->raw, key->dp->size); - if (err == MP_OKAY) - err = wc_bigint_alloc(&key->s->raw, key->dp->size); - /* load e and k */ - if (err == MP_OKAY) - err = wc_mp_to_bigint(&e, &e.raw); - if (err == MP_OKAY) - err = wc_mp_to_bigint(&key->k, &key->k.raw); - if (err == MP_OKAY) - err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); - if (err == MP_OKAY) - err = wc_ecc_gen_k(rng, key->dp->size, &k, curve->order); - if (err == MP_OKAY) - err = wc_mp_to_bigint(&k, &k.raw); - if (err == MP_OKAY) - err = IntelQaEcdsaSign(&key->asyncDev, &e.raw, &key->k.raw, - &k.raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw, - &curve->prime->raw, &curve->order->raw, &curve->Gx->raw, - &curve->Gy->raw); + err = mp_init(k); - mp_clear(&e); - mp_clear(&k); - wc_ecc_curve_free(curve); + /* make sure r and s are allocated */ + #ifdef HAVE_CAVIUM_V + /* Nitrox V needs single buffer for R and S */ + if (err == MP_OKAY) + err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2); + /* Nitrox V only needs Prime and Order */ + if (err == MP_OKAY) + err = wc_ecc_curve_load(key->dp, &curve, + (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER)); + #else + if (err == MP_OKAY) + err = wc_bigint_alloc(&key->r->raw, key->dp->size); + if (err == MP_OKAY) + err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); + #endif + if (err == MP_OKAY) + err = wc_bigint_alloc(&key->s->raw, key->dp->size); - return err; - #endif + /* load e and k */ + if (err == MP_OKAY) + err = wc_mp_to_bigint_sz(e, &e->raw, keySz); + if (err == MP_OKAY) + err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz); + if (err == MP_OKAY) + err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order); + if (err == MP_OKAY) + err = wc_mp_to_bigint_sz(k, &k->raw, keySz); + + #ifdef HAVE_CAVIUM_V + if (err == MP_OKAY) + err = NitroxEcdsaSign(key, &e->raw, &key->k.raw, &k->raw, + &r->raw, &s->raw, &curve->prime->raw, &curve->order->raw); + #else + if (err == MP_OKAY) + err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k.raw, + &k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw, + &curve->prime->raw, &curve->order->raw, &curve->Gx->raw, + &curve->Gy->raw); + #endif + + #ifndef HAVE_CAVIUM_V + mp_clear(e); + mp_clear(k); + #endif + wc_ecc_curve_free(curve); + + return err; + } + #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */ } #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -3865,7 +3940,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, if (err != MP_OKAY) break; /* s = e + xr */ - err = mp_add(&e, s, s); + err = mp_add(e, s, s); if (err != MP_OKAY) break; /* s = e + xr */ @@ -3883,9 +3958,9 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } } - mp_clear(&e); + mp_clear(e); wc_ecc_curve_free(curve); -#endif +#endif /* WOLFSSL_SP_MATH */ return err; } @@ -3924,9 +3999,11 @@ int wc_ecc_free(ecc_key* key) return 0; } -#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) +#ifdef WOLFSSL_ASYNC_CRYPT + #ifdef WC_ASYNC_ENABLE_ECC wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC); - wc_ecc_free_rs(key, &key->r, &key->s); + #endif + wc_ecc_free_async(key); #endif #ifdef WOLFSSL_ATECC508A @@ -4206,14 +4283,23 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, mp_int *r = NULL, *s = NULL; #ifndef WOLFSSL_ASYNC_CRYPT mp_int r_lcl, s_lcl; - r = &r_lcl; - s = &s_lcl; #endif if (sig == NULL || hash == NULL || res == NULL || key == NULL) { return ECC_BAD_ARG_E; } +#ifdef WOLFSSL_ASYNC_CRYPT + err = wc_ecc_alloc_async(key); + if (err != 0) + return err; + r = key->r; + s = key->s; +#else + r = &r_lcl; + s = &s_lcl; +#endif + switch(key->state) { case ECC_STATE_NONE: case ECC_STATE_VERIFY_DECODE: @@ -4226,10 +4312,6 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, * If either of those don't allocate correctly, none of * the rest of this function will execute, and everything * gets cleaned up at the end. */ - err = wc_ecc_alloc_rs(key, &r, &s); - if (err != 0) - break; - /* decode DSA header */ err = DecodeECC_DSA_Sig(sig, siglen, r, s); if (err < 0) { @@ -4250,12 +4332,6 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, key->state = ECC_STATE_VERIFY_RES; err = 0; - #ifdef WOLFSSL_ASYNC_CRYPT - /* restore r/s */ - r = key->r; - s = key->s; - #endif - /* done with R/S */ mp_clear(r); mp_clear(s); @@ -4272,7 +4348,9 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, } /* cleanup */ - wc_ecc_free_rs(key, &r, &s); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_ecc_free_async(key); +#endif key->state = ECC_STATE_NONE; return err; @@ -4294,19 +4372,20 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, word32 hashlen, int* res, ecc_key* key) { int err; -#ifndef WOLFSSL_ATECC508A -#ifndef WOLFSSL_SP_MATH +#ifdef WOLFSSL_ATECC508A + byte sigRS[ATECC_KEY_SIZE*2]; +#elif !defined(WOLFSSL_SP_MATH) int did_init = 0; ecc_point *mG = NULL, *mQ = NULL; mp_int v; mp_int w; mp_int u1; mp_int u2; - mp_int e; - DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT) + mp_int* e; +#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V) + mp_int e_lcl; #endif -#else - byte sigRS[ATECC_KEY_SIZE*2]; + DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT) #endif if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) @@ -4386,7 +4465,16 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #endif #endif - err = mp_init(&e); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V) + err = wc_ecc_alloc_mpint(key, &key->e); + if (err != 0) + return err; + e = key->e; +#else + e = &e_lcl; +#endif + + err = mp_init(e); if (err != MP_OKAY) return MEMORY_E; @@ -4410,36 +4498,48 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, /* truncate down to byte size, may be all that's needed */ if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits) hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; - err = mp_read_unsigned_bin(&e, hash, hashlen); + err = mp_read_unsigned_bin(e, hash, hashlen); /* may still need bit truncation too */ if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits) - mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); + mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); } /* check for async hardware acceleration */ #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { - #ifdef HAVE_CAVIUM - /* TODO: Not implemented */ - #elif defined(HAVE_INTEL_QA) - err = wc_mp_to_bigint(&e, &e.raw); - if (err == MP_OKAY) - err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw); - if (err == MP_OKAY) - err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw); - if (err == MP_OKAY) - err = IntelQaEcdsaVerify(&key->asyncDev, &e.raw, &key->pubkey.x->raw, - &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw, - &curve->Bf->raw, &curve->prime->raw, &curve->order->raw, - &curve->Gx->raw, &curve->Gy->raw, res); - - mp_clear(&e); - - wc_ecc_curve_free(curve); - - return err; + #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) + #ifdef HAVE_CAVIUM_V + if (NitroxEccIsCurveSupported(key)) #endif + { + word32 keySz = key->dp->size; + + err = wc_mp_to_bigint_sz(e, &e->raw, keySz); + if (err == MP_OKAY) + err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz); + if (err == MP_OKAY) + err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz); + if (err == MP_OKAY) + #ifdef HAVE_CAVIUM_V + err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw, + &key->pubkey.y->raw, &r->raw, &s->raw, + &curve->prime->raw, &curve->order->raw, res); + #else + err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw, + &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw, + &curve->Bf->raw, &curve->prime->raw, &curve->order->raw, + &curve->Gx->raw, &curve->Gy->raw, res); + #endif + + #ifndef HAVE_CAVIUM_V + mp_clear(e); + #endif + wc_ecc_curve_free(curve); + + return err; + } + #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */ } #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -4465,7 +4565,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, /* u1 = ew */ if (err == MP_OKAY) - err = mp_mulmod(&e, &w, curve->order, &u1); + err = mp_mulmod(e, &w, curve->order, &u1); /* u2 = rw */ if (err == MP_OKAY) @@ -4494,7 +4594,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, err = wc_ecc_mulmod_ex(&u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap); if (err == MP_OKAY) err = wc_ecc_point_add(mG, mQ, mG, curve->prime); -#else /* FREESCALE_LTC_ECC */ +#else #ifndef ECC_SHAMIR { mp_digit mp = 0; @@ -4544,7 +4644,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, wc_ecc_del_point_h(mG, key->heap); wc_ecc_del_point_h(mQ, key->heap); - mp_clear(&e); + mp_clear(e); if (did_init) { mp_clear(&v); mp_clear(&w); @@ -4554,7 +4654,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, wc_ecc_curve_free(curve); -#endif +#endif /* WOLFSSL_SP_MATH */ #endif /* WOLFSSL_ATECC508A */ return err; diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 68a29430c..59dbb410c 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -287,23 +287,6 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) hmac->innerHashKeyed = 0; hmac->macType = (byte)type; -#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) - if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { - #if defined(HAVE_CAVIUM) - if (length > WC_HMAC_BLOCK_SIZE) { - return WC_KEY_SIZE_E; - } - - if (key != NULL) { - XMEMCPY(hmac->ipad, key, length); - } - hmac->keyLen = (word16)length; - - return 0; /* nothing to do here */ - #endif /* HAVE_CAVIUM */ - } -#endif /* WOLFSSL_ASYNC_CRYPT */ - ret = _InitHmac(hmac, type, heap); if (ret != 0) return ret; @@ -545,13 +528,18 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { - #if defined(HAVE_INTEL_QA) - if (length > hmac_block_size) - length = hmac_block_size; - /* update key length */ - hmac->keyLen = (word16)length; + #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM) + #ifdef HAVE_INTEL_QA + if (IntelQaHmacGetType(hmac->macType, NULL) == 0) + #endif + { + if (length > hmac_block_size) + length = hmac_block_size; + /* update key length */ + hmac->keyLen = (word16)length; - return ret; + return ret; + } /* no need to pad below */ #endif } @@ -667,8 +655,10 @@ int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) #if defined(HAVE_CAVIUM) return NitroxHmacUpdate(hmac, msg, length); #elif defined(HAVE_INTEL_QA) - return IntelQaHmac(&hmac->asyncDev, hmac->macType, - (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length); + if (IntelQaHmacGetType(hmac->macType, NULL) == 0) { + return IntelQaHmac(&hmac->asyncDev, hmac->macType, + (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length); + } #endif } #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -759,10 +749,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) return hashLen; #if defined(HAVE_CAVIUM) - return NitroxHmacFinal(hmac, hmac->macType, hash, hashLen); + return NitroxHmacFinal(hmac, hash, hashLen); #elif defined(HAVE_INTEL_QA) - return IntelQaHmac(&hmac->asyncDev, hmac->macType, - (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen); + if (IntelQaHmacGetType(hmac->macType, NULL) == 0) { + return IntelQaHmac(&hmac->asyncDev, hmac->macType, + (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen); + } #endif } #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -982,10 +974,6 @@ int wc_HmacInit(Hmac* hmac, void* heap, int devId) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) hmac->keyLen = 0; - #ifdef HAVE_CAVIUM - hmac->dataLen = 0; - hmac->data = NULL; /* buffered input data */ - #endif /* HAVE_CAVIUM */ ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC, hmac->heap, devId); @@ -1004,11 +992,6 @@ void wc_HmacFree(Hmac* hmac) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC); - -#ifdef HAVE_CAVIUM - XFREE(hmac->data, hmac->heap, DYNAMIC_TYPE_HMAC); - hmac->data = NULL; -#endif /* HAVE_CAVIUM */ #endif /* WOLFSSL_ASYNC_CRYPT */ } diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 24275c566..fd1c7e1d2 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -1465,6 +1465,7 @@ static int wc_RsaFunctionAsync(const byte* in, word32 inLen, byte* out, case RSA_PRIVATE_DECRYPT: case RSA_PRIVATE_ENCRYPT: #ifdef HAVE_CAVIUM + key->dataLen = key->n.raw.len; ret = NitroxRsaExptMod(in, inLen, key->d.raw.buf, key->d.raw.len, key->n.raw.buf, key->n.raw.len, @@ -1489,6 +1490,7 @@ static int wc_RsaFunctionAsync(const byte* in, word32 inLen, byte* out, case RSA_PUBLIC_ENCRYPT: case RSA_PUBLIC_DECRYPT: #ifdef HAVE_CAVIUM + key->dataLen = key->n.raw.len; ret = NitroxRsaExptMod(in, inLen, key->e.raw.buf, key->e.raw.len, key->n.raw.buf, key->n.raw.len, @@ -1731,7 +1733,8 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \ defined(HAVE_CAVIUM) - if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && key->n.raw.buf) { + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && + pad_type != WC_RSA_PSS_PAD && key->n.raw.buf) { /* Async operations that include padding */ if (rsa_type == RSA_PUBLIC_ENCRYPT && pad_value == RSA_BLOCK_TYPE_2) { @@ -1833,14 +1836,14 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \ defined(HAVE_CAVIUM) /* Async operations that include padding */ - if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && + pad_type != WC_RSA_PSS_PAD) { if (rsa_type == RSA_PRIVATE_DECRYPT && pad_value == RSA_BLOCK_TYPE_2) { key->state = RSA_STATE_DECRYPT_RES; key->data = NULL; - if (outPtr) - *outPtr = in; - return NitroxRsaPrivateDecrypt(in, inLen, out, &key->dataLen, key); + return NitroxRsaPrivateDecrypt(in, inLen, out, &key->dataLen, + key); } else if (rsa_type == RSA_PUBLIC_DECRYPT && pad_value == RSA_BLOCK_TYPE_1) { @@ -1911,14 +1914,14 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, case RSA_STATE_DECRYPT_RES: #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \ defined(HAVE_CAVIUM) - if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { - /* return event ret */ - ret = key->asyncDev.event.ret; - if (ret == 0) { - /* convert result */ - byte* dataLen = (byte*)&key->dataLen; - ret = (dataLen[0] << 8) | (dataLen[1]); - } + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && + pad_type != WC_RSA_PSS_PAD) { + /* convert result */ + byte* dataLen = (byte*)&key->dataLen; + ret = (dataLen[0] << 8) | (dataLen[1]); + + if (outPtr) + *outPtr = in; } #endif break; diff --git a/wolfcrypt/src/wolfmath.c b/wolfcrypt/src/wolfmath.c index 8e6a0b4d1..ececf0133 100644 --- a/wolfcrypt/src/wolfmath.c +++ b/wolfcrypt/src/wolfmath.c @@ -235,22 +235,46 @@ void wc_bigint_free(WC_BIGINT* a) } } -int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst) +/* sz: make sure the buffer is at least that size and zero padded. + * A `sz == 0` will use the size of `src`. + * The calulcates sz is stored into dst->len in `wc_bigint_alloc`. + */ +int wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz) { int err; - word32 sz; + word32 x, y; if (src == NULL || dst == NULL) return BAD_FUNC_ARG; - sz = mp_unsigned_bin_size(src); + /* get size of source */ + x = mp_unsigned_bin_size(src); + if (sz < x) + sz = x; + + /* make sure destination is allocated and large enough */ err = wc_bigint_alloc(dst, sz); - if (err == MP_OKAY) - err = mp_to_unsigned_bin(src, dst->buf); + if (err == MP_OKAY) { + + /* leading zero pad */ + y = sz - x; + XMEMSET(dst->buf, 0, y); + + /* export src as unsigned bin to destination buf */ + err = mp_to_unsigned_bin(src, dst->buf + y); + } return err; } +int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst) +{ + if (src == NULL || dst == NULL) + return BAD_FUNC_ARG; + + return wc_mp_to_bigint_sz(src, dst, 0); +} + int wc_bigint_to_mp(WC_BIGINT* src, mp_int* dst) { int err; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 93624af74..7785e325d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6128,7 +6128,7 @@ int aesgcm_test(void) }; /* FIPS, QAT and STM32F2/4 HW Crypto only support 12-byte IV */ -#if !defined(HAVE_FIPS) && !defined(HAVE_INTEL_QA) && \ +#if !defined(HAVE_FIPS) && \ !defined(STM32_CRYPTO) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ !defined(WOLFSSL_XILINX_CRYPT) @@ -13987,6 +13987,13 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if (ret != 0) goto done; + /* only perform the below tests if the key size matches */ + if (dp == NULL && keySize > 0 && wc_ecc_size(&userA) != keySize) { + ret = ECC_CURVE_OID_E; + goto done; + } + + #ifdef HAVE_ECC_DHE x = ECC_SHARED_SIZE; do { @@ -14965,11 +14972,16 @@ static int ecc_test_custom_curves(WC_RNG* rng) } #endif + ret = wc_ecc_init_ex(&key, HEAP_HINT, devId); + if (ret != 0) { + return -6715; + } + inOutIdx = 0; ret = wc_EccPublicKeyDecode(eccKeyExplicitCurve, &inOutIdx, &key, sizeof(eccKeyExplicitCurve)); if (ret != 0) - return -6715; + return -6716; wc_ecc_free(&key); diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index f0a7c31ee..8c0eb28d1 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -326,6 +326,10 @@ struct ecc_key { mp_int* r; /* sign/verify temps */ mp_int* s; WC_ASYNC_DEV asyncDev; + #ifdef HAVE_CAVIUM_V + mp_int* e; /* Sign, Verify and Shared Secret */ + mp_int* signK; + #endif #ifdef WOLFSSL_CERT_GEN CertSignCtx certSignCtx; /* context info for cert sign (MakeSignature) */ #endif diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index 8ae8d70d6..c3556b332 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -157,10 +157,6 @@ typedef struct Hmac { #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; word16 keyLen; /* hmac key length (key in ipad) */ - #ifdef HAVE_CAVIUM - byte* data; /* buffered input data for one call */ - word16 dataLen; - #endif /* HAVE_CAVIUM */ #endif /* WOLFSSL_ASYNC_CRYPT */ } Hmac; diff --git a/wolfssl/wolfcrypt/wolfevent.h b/wolfssl/wolfcrypt/wolfevent.h index ed83a1b01..f4b0b979f 100644 --- a/wolfssl/wolfcrypt/wolfevent.h +++ b/wolfssl/wolfcrypt/wolfevent.h @@ -29,9 +29,6 @@ #ifndef SINGLE_THREADED #include #endif -#ifdef HAVE_CAVIUM - #include -#endif #ifndef WOLFSSL_WOLFSSL_TYPE_DEFINED #define WOLFSSL_WOLFSSL_TYPE_DEFINED @@ -74,7 +71,10 @@ struct WOLF_EVENT { #endif } dev; #ifdef HAVE_CAVIUM - CavReqId reqId; + word64 reqId; + #ifdef WOLFSSL_NITROX_DEBUG + word32 pendCount; + #endif #endif #ifndef WC_NO_ASYNC_THREADING pthread_t threadId; diff --git a/wolfssl/wolfcrypt/wolfmath.h b/wolfssl/wolfcrypt/wolfmath.h index d7c9cc786..8d0ab6d81 100644 --- a/wolfssl/wolfcrypt/wolfmath.h +++ b/wolfssl/wolfcrypt/wolfmath.h @@ -61,6 +61,7 @@ void wc_bigint_free(WC_BIGINT* a); int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst); + int wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz); int wc_bigint_to_mp(WC_BIGINT* src, mp_int* dst); #endif /* HAVE_WOLF_BIGINT */