Nitrox V fixes and additions:

* Added support for ECC, AES-GCM and HMAC (SHA-224 and SHA3).
* Fixes for Nitrox V with TLS.
* ECC refactor for so key based `r` and `s` apply only when building with `WOLFSSL_ASYNC_CRYPT`.
* ECC refactor for `e` and `signK` to use key based pointer for Nitrox V.
* Improved the Nitrox V HMAC to use start, update and final API's instead of caching updates.
* Fix for Intel QuickAssist with unsupported HMAC hash algos using `IntelQaHmacGetType` (such as SHA3).
* Added new API `wc_mp_to_bigint_sz` to zero pad unsigned bin.
* Fix for AES GCM to gate HW use based on IV len in aes.c and remove the gate in test.c.
* Implemented workaround to use software for AES GCM Nitrox V hardware and 13 byte AAD length for TLS.
* New debug option `WOLFSSL_NITROX_DEBUG` to add pending count.
This commit is contained in:
David Garske
2018-04-03 09:14:20 -07:00
parent adb817e8d2
commit 0c898f513d
12 changed files with 395 additions and 261 deletions

View File

@ -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

View File

@ -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,

View File

@ -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;
}

View File

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

View File

@ -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 */
}

View File

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

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -29,9 +29,6 @@
#ifndef SINGLE_THREADED
#include <wolfssl/wolfcrypt/wc_port.h>
#endif
#ifdef HAVE_CAVIUM
#include <wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h>
#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;

View File

@ -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 */