From c23489e6ed40b417dc340d4b87a83bd526d8d088 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 10 Dec 2018 16:51:54 -0800 Subject: [PATCH 1/3] Added support for QAT RSA Key Generation. --- configure.ac | 2 +- wolfcrypt/benchmark/benchmark.c | 5 +-- wolfcrypt/src/rsa.c | 62 ++++++++++++++------------------- wolfcrypt/test/test.c | 2 +- 4 files changed, 30 insertions(+), 41 deletions(-) diff --git a/configure.ac b/configure.ac index 5dc354df1..ceeaffab8 100644 --- a/configure.ac +++ b/configure.ac @@ -1681,7 +1681,7 @@ if test "$ENABLED_STACKSIZE" = "yes" then AC_CHECK_FUNC([posix_memalign], [], [AC_MSG_ERROR(stacksize needs posix_memalign)]) AC_CHECK_FUNC([pthread_attr_setstack], [], AC_CHECK_LIB([pthread],[pthread_attr_setstack])) - AM_CFLAGS="$AM_CFLAGS -DHAVE_STACK_SIZE -DWOLFSSL_LOW_MEMORY" + AM_CFLAGS="$AM_CFLAGS -DHAVE_STACK_SIZE" fi diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 06f1263f4..a2162568b 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -1452,16 +1452,13 @@ static void* benchmarks_do(void* args) bench_rsaKeyGen(0); } #endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) - /* async supported in simulator only */ - #ifdef WOLFSSL_ASYNC_CRYPT_TEST + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA_KEYGEN) if (bench_asym_algs & BENCH_RSA_SZ) { bench_rsaKeyGen_size(1, bench_size); } else { bench_rsaKeyGen(1); } - #endif #endif } #endif diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index c5c50c7e3..f297890e1 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -3057,7 +3057,7 @@ static int _CheckProbablePrime(mp_int* p, mp_int* q, mp_int* e, int nlen, if (ret != MP_EQ) goto exit; /* e divides p-1 */ /* 4.5.1,5.6.1 - Check primality of p with 8 rounds of M-R. - * mp_prime_is_prime_ex() performs test divisons against the first 256 + * mp_prime_is_prime_ex() performs test divisions against the first 256 * prime numbers. After that it performs 8 rounds of M-R using random * bases between 2 and n-2. * mp_prime_is_prime() performs the same test divisions and then does @@ -3162,12 +3162,13 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) } #endif -#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \ + defined(WC_ASYNC_ENABLE_RSA_KEYGEN) if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { #ifdef HAVE_CAVIUM /* TODO: Not implemented */ #elif defined(HAVE_INTEL_QA) - /* TODO: Not implemented */ + return IntelQaRsaKeyGen(&key->asyncDev, key, size, e, rng); #else if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_RSA_MAKE)) { WC_ASYNC_TEST* testDev = &key->asyncDev.test; @@ -3210,7 +3211,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #endif /* generate value */ err = wc_RNG_GenerateBlock(rng, buf, primeSz); - if (err == 0) { /* prime lower bound has the MSB set, set it in candidate */ buf[0] |= 0x80; @@ -3246,7 +3246,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #endif /* generate value */ err = wc_RNG_GenerateBlock(rng, buf, primeSz); - if (err == 0) { /* prime lower bound has the MSB set, set it in candidate */ buf[0] |= 0x80; @@ -3276,50 +3275,40 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) XFREE(buf, key->heap, DYNAMIC_TYPE_RSA); } + + /* Setup RsaKey buffers */ if (err == MP_OKAY) err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL); - if (err == MP_OKAY) err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL); - if (err == MP_OKAY) - err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */ - - if (err == MP_OKAY) - err = mp_sub_d(&q, 1, &tmp2); /* tmp2 = q-1 */ - - if (err == MP_OKAY) - err = mp_lcm(&tmp1, &tmp2, &tmp3); /* tmp3 = lcm(p-1, q-1),last loop */ - + /* Software Key Calculation */ + if (err == MP_OKAY) /* tmp1 = p-1 */ + err = mp_sub_d(&p, 1, &tmp1); + if (err == MP_OKAY) /* tmp2 = q-1 */ + err = mp_sub_d(&q, 1, &tmp2); + if (err == MP_OKAY) /* tmp3 = lcm(p-1, q-1), last loop */ + err = mp_lcm(&tmp1, &tmp2, &tmp3); /* make key */ - if (err == MP_OKAY) - err = mp_set_int(&key->e, (mp_digit)e); /* key->e = e */ - + if (err == MP_OKAY) /* key->e = e */ + err = mp_set_int(&key->e, (mp_digit)e); if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */ err = mp_invmod(&key->e, &tmp3, &key->d); - - if (err == MP_OKAY) - err = mp_mul(&p, &q, &key->n); /* key->n = pq */ - - if (err == MP_OKAY) - err = mp_mod(&key->d, &tmp1, &key->dP); /* key->dP = d mod(p-1) */ - - if (err == MP_OKAY) - err = mp_mod(&key->d, &tmp2, &key->dQ); /* key->dQ = d mod(q-1) */ - - if (err == MP_OKAY) - err = mp_invmod(&q, &p, &key->u); /* key->u = 1/q mod p */ - + if (err == MP_OKAY) /* key->n = pq */ + err = mp_mul(&p, &q, &key->n); + if (err == MP_OKAY) /* key->dP = d mod(p-1) */ + err = mp_mod(&key->d, &tmp1, &key->dP); + if (err == MP_OKAY) /* key->dQ = d mod(q-1) */ + err = mp_mod(&key->d, &tmp2, &key->dQ); + if (err == MP_OKAY) /* key->u = 1/q mod p */ + err = mp_invmod(&q, &p, &key->u); if (err == MP_OKAY) err = mp_copy(&p, &key->p); - if (err == MP_OKAY) err = mp_copy(&q, &key->q); - if (err == MP_OKAY) - key->type = RSA_PRIVATE; - #ifdef HAVE_WOLF_BIGINT + /* make sure raw unsigned bin version is available */ if (err == MP_OKAY) err = wc_mp_to_bigint(&key->n, &key->n.raw); if (err == MP_OKAY) @@ -3338,6 +3327,9 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) err = wc_mp_to_bigint(&key->u, &key->u.raw); #endif + if (err == MP_OKAY) + key->type = RSA_PRIVATE; + mp_clear(&tmp1); mp_clear(&tmp2); mp_clear(&tmp3); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 4f3be7c45..46ec6bb9d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -10713,7 +10713,7 @@ static int rsa_keygen_test(WC_RNG* rng) keySz = 2048; #endif /* HAVE_FIPS */ - ret = wc_InitRsaKey(&genKey, HEAP_HINT); + ret = wc_InitRsaKey_ex(&genKey, HEAP_HINT, devId); if (ret != 0) { ERROR_OUT(-6962, exit_rsa); } From cbbe63ec62a34e66f54ee5a0e92c020cdd22bce9 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 12 Dec 2018 16:33:34 -0800 Subject: [PATCH 2/3] Added QAT SHA3 support. Fix for SHA512/SHA384 with QAT and Intel ASM enabled. --- wolfcrypt/src/sha3.c | 24 ++++++++---- wolfcrypt/src/sha512.c | 86 ++++++++++++++++-------------------------- 2 files changed, 50 insertions(+), 60 deletions(-) diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index 88d1c2533..d32b1ed8e 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -692,7 +692,7 @@ static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId) */ static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) { - int ret = 0; + int ret; if (sha3 == NULL || (data == NULL && len > 0)) { return BAD_FUNC_ARG; @@ -700,13 +700,18 @@ static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) { - #if defined(HAVE_INTEL_QA) - return IntelQaSymSha3(&sha3->asyncDev, NULL, data, len); + #if defined(HAVE_INTEL_QA) && defined(QAT_V2) + /* QAT only supports SHA3_256 */ + if (p == WC_SHA3_256_COUNT) { + ret = IntelQaSymSha3(&sha3->asyncDev, NULL, data, len); + if (ret != NOT_COMPILED_IN) + return ret; + } #endif } #endif /* WOLFSSL_ASYNC_CRYPT */ - Sha3Update(sha3, data, len, p); + ret = Sha3Update(sha3, data, len, p); return ret; } @@ -729,9 +734,14 @@ static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) { - #if defined(HAVE_INTEL_QA) - return IntelQaSymSha3(&sha3->asyncDev, hash, NULL, - SHA3_DIGEST_SIZE); + #if defined(HAVE_INTEL_QA) && defined(QAT_V2) + /* QAT only supports SHA3_256 */ + /* QAT SHA-3 only supported on v2 (8970 or later cards) */ + if (len == WC_SHA3_256_DIGEST_SIZE) { + ret = IntelQaSymSha3(&sha3->asyncDev, hash, NULL, len); + if (ret != NOT_COMPILED_IN) + return ret; + } #endif } #endif /* WOLFSSL_ASYNC_CRYPT */ diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index c975654fb..6bd4f7719 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -352,56 +352,48 @@ static int InitSha512(wc_Sha512* sha512) transform_check = 1; } - - int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) - { - int ret = InitSha512(sha512); - - (void)heap; - (void)devId; - - Sha512_SetTransform(); - - return ret; - } - #endif /* WOLFSSL_SHA512 */ #else #define Transform_Sha512(sha512) _Transform_Sha512(sha512) - #ifdef WOLFSSL_SHA512 +#endif - int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) - { - int ret = 0; +#ifdef WOLFSSL_SHA512 - if (sha512 == NULL) - return BAD_FUNC_ARG; +int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) +{ + int ret = 0; - sha512->heap = heap; + if (sha512 == NULL) + return BAD_FUNC_ARG; - ret = InitSha512(sha512); - if (ret != 0) - return ret; - - #ifdef WOLFSSL_SMALL_STACK_CACHE - sha512->W = NULL; - #endif - - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) - ret = wolfAsync_DevCtxInit(&sha512->asyncDev, - WOLFSSL_ASYNC_MARKER_SHA512, sha512->heap, devId); - #else - (void)devId; - #endif /* WOLFSSL_ASYNC_CRYPT */ + sha512->heap = heap; + ret = InitSha512(sha512); + if (ret != 0) return ret; - } - #endif /* WOLFSSL_SHA512 */ +#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + Sha512_SetTransform(); +#endif + +#ifdef WOLFSSL_SMALL_STACK_CACHE + sha512->W = NULL; +#endif + +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) + ret = wolfAsync_DevCtxInit(&sha512->asyncDev, + WOLFSSL_ASYNC_MARKER_SHA512, sha512->heap, devId); +#else + (void)devId; +#endif /* WOLFSSL_ASYNC_CRYPT */ + + return ret; +} + +#endif /* WOLFSSL_SHA512 */ -#endif /* Hardware Acceleration */ static const word64 K512[80] = { W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), @@ -2713,21 +2705,6 @@ int wc_Sha384Final(wc_Sha384* sha384, byte* hash) return InitSha384(sha384); /* reset state */ } - -/* Hardware Acceleration */ -#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) - int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) - { - int ret = InitSha384(sha384); - - (void)heap; - (void)devId; - - Sha512_SetTransform(); - - return ret; - } -#else int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) { int ret; @@ -2741,6 +2718,9 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) if (ret != 0) return ret; +#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + Sha512_SetTransform(); +#endif #ifdef WOLFSSL_SMALL_STACK_CACHE sha384->W = NULL; #endif @@ -2754,7 +2734,7 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) return ret; } -#endif + #endif /* WOLFSSL_IMX6_CAAM */ int wc_InitSha384(wc_Sha384* sha384) From c478a2791a1afc699292d2008f450f79bb5dfeb2 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 14 Dec 2018 15:13:17 -0800 Subject: [PATCH 3/3] Fix to disable the raw `Hmac_UpdateFinal_CT` HMAC calculation for async crypt. Resolves issue using `-v 2 -l ECDHE-RSA-AES128-SHA` with QAT. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ceeaffab8..5779471e5 100644 --- a/configure.ac +++ b/configure.ac @@ -4175,7 +4175,7 @@ AC_ARG_ENABLE([asynccrypt], if test "$ENABLED_ASYNCCRYPT" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ASYNC_CRYPT -DHAVE_WOLF_EVENT -DHAVE_WOLF_BIGINT" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ASYNC_CRYPT -DHAVE_WOLF_EVENT -DHAVE_WOLF_BIGINT -DWOLFSSL_NO_HASH_RAW" # if no async hardware then use simulator for testing if test "x$ENABLED_CAVIUM" = "xno" && test "x$ENABLED_INTEL_QA" = "xno"