From 88a2531652b9a989bf482db606880cd59750d6e0 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 17 Jul 2018 09:17:39 +1000 Subject: [PATCH 1/3] Cache the data allocated in SHA-2 Transform functions SHA-2 algorithms allocate W each call to transform when using WOLFSSL_SMALL_STACK. Put a pointer into the SHA-2 object to cache W. Change code to call the SHA-2 Free functions now that they are required. Only cache when WOLFSSL_SMALL_STACK_CACHE is defined. --- wolfcrypt/src/hash.c | 95 ++++++++++++++++++++++---------------- wolfcrypt/src/hmac.c | 60 ++++++++++++++++++++++++ wolfcrypt/src/sha256.c | 47 +++++++++++++++++-- wolfcrypt/src/sha512.c | 43 ++++++++++++++++- wolfssl/wolfcrypt/sha256.h | 3 ++ wolfssl/wolfcrypt/sha512.h | 3 ++ 6 files changed, 203 insertions(+), 48 deletions(-) diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index f2db30de8..4ac728d5b 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -707,35 +707,38 @@ int wc_HashFinal(wc_HashAlg* hash, enum wc_HashType type, byte* out) #endif /* !NO_SHA */ #if defined(WOLFSSL_SHA224) -int wc_Sha224Hash(const byte* data, word32 len, byte* hash) -{ - int ret = 0; -#ifdef WOLFSSL_SMALL_STACK - wc_Sha224* sha224; -#else - wc_Sha224 sha224[1]; -#endif + int wc_Sha224Hash(const byte* data, word32 len, byte* hash) + { + int ret = 0; + #ifdef WOLFSSL_SMALL_STACK + wc_Sha224* sha224; + #else + wc_Sha224 sha224[1]; + #endif -#ifdef WOLFSSL_SMALL_STACK - sha224 = (wc_Sha224*)XMALLOC(sizeof(wc_Sha224), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (sha224 == NULL) - return MEMORY_E; -#endif + #ifdef WOLFSSL_SMALL_STACK + sha224 = (wc_Sha224*)XMALLOC(sizeof(wc_Sha224), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (sha224 == NULL) + return MEMORY_E; + #endif - if ((ret = wc_InitSha224(sha224)) != 0) { - WOLFSSL_MSG("InitSha224 failed"); - } - else if ((ret = wc_Sha224Update(sha224, data, len)) != 0) { - WOLFSSL_MSG("Sha224Update failed"); - } - else if ((ret = wc_Sha224Final(sha224, hash)) != 0) { - WOLFSSL_MSG("Sha224Final failed"); - } + if ((ret = wc_InitSha224(sha224)) != 0) { + WOLFSSL_MSG("InitSha224 failed"); + } + else { + if ((ret = wc_Sha224Update(sha224, data, len)) != 0) { + WOLFSSL_MSG("Sha224Update failed"); + } + else if ((ret = wc_Sha224Final(sha224, hash)) != 0) { + WOLFSSL_MSG("Sha224Final failed"); + } + wc_Sha224Free(sha224); + } -#ifdef WOLFSSL_SMALL_STACK - XFREE(sha224, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + #ifdef WOLFSSL_SMALL_STACK + XFREE(sha224, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; } @@ -761,13 +764,17 @@ int wc_Sha224Hash(const byte* data, word32 len, byte* hash) if ((ret = wc_InitSha256(sha256)) != 0) { WOLFSSL_MSG("InitSha256 failed"); } - else if ((ret = wc_Sha256Update(sha256, data, len)) != 0) { - WOLFSSL_MSG("Sha256Update failed"); - } - else if ((ret = wc_Sha256Final(sha256, hash)) != 0) { - WOLFSSL_MSG("Sha256Final failed"); + else { + if ((ret = wc_Sha256Update(sha256, data, len)) != 0) { + WOLFSSL_MSG("Sha256Update failed"); + } + else if ((ret = wc_Sha256Final(sha256, hash)) != 0) { + WOLFSSL_MSG("Sha256Final failed"); + } + wc_Sha256Free(sha256); } + #ifdef WOLFSSL_SMALL_STACK XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -799,11 +806,14 @@ int wc_Sha224Hash(const byte* data, word32 len, byte* hash) if ((ret = wc_InitSha512(sha512)) != 0) { WOLFSSL_MSG("InitSha512 failed"); } - else if ((ret = wc_Sha512Update(sha512, data, len)) != 0) { - WOLFSSL_MSG("Sha512Update failed"); - } - else if ((ret = wc_Sha512Final(sha512, hash)) != 0) { - WOLFSSL_MSG("Sha512Final failed"); + else { + if ((ret = wc_Sha512Update(sha512, data, len)) != 0) { + WOLFSSL_MSG("Sha512Update failed"); + } + else if ((ret = wc_Sha512Final(sha512, hash)) != 0) { + WOLFSSL_MSG("Sha512Final failed"); + } + wc_Sha512Free(sha512); } #ifdef WOLFSSL_SMALL_STACK @@ -833,11 +843,14 @@ int wc_Sha224Hash(const byte* data, word32 len, byte* hash) if ((ret = wc_InitSha384(sha384)) != 0) { WOLFSSL_MSG("InitSha384 failed"); } - else if ((ret = wc_Sha384Update(sha384, data, len)) != 0) { - WOLFSSL_MSG("Sha384Update failed"); - } - else if ((ret = wc_Sha384Final(sha384, hash)) != 0) { - WOLFSSL_MSG("Sha384Final failed"); + else { + if ((ret = wc_Sha384Update(sha384, data, len)) != 0) { + WOLFSSL_MSG("Sha384Update failed"); + } + else if ((ret = wc_Sha384Final(sha384, hash)) != 0) { + WOLFSSL_MSG("Sha384Final failed"); + } + wc_Sha384Free(sha384); } #ifdef WOLFSSL_SMALL_STACK diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 6bc5a660f..b60d92717 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1002,6 +1002,66 @@ void wc_HmacFree(Hmac* hmac) if (hmac == NULL) return; + switch (hmac->macType) { + #ifndef NO_MD5 + case WC_MD5: + wc_Md5Free(&hmac->hash.md5); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + wc_ShaFree(&hmac->hash.sha); + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + wc_Sha224Free(&hmac->hash.sha224); + break; + #endif /* WOLFSSL_SHA224 */ + + #ifndef NO_SHA256 + case WC_SHA256: + wc_Sha256Free(&hmac->hash.sha256); + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + wc_Sha384Free(&hmac->hash.sha384); + break; + #endif /* WOLFSSL_SHA384 */ + case WC_SHA512: + wc_Sha512Free(&hmac->hash.sha512); + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef HAVE_BLAKE2 + case BLAKE2B_ID: + break; + #endif /* HAVE_BLAKE2 */ + + #ifdef WOLFSSL_SHA3 + case WC_SHA3_224: + wc_Sha3_224_Free(&hmac->hash.sha3); + break; + case WC_SHA3_256: + wc_Sha3_256_Free(&hmac->hash.sha3); + break; + case WC_SHA3_384: + wc_Sha3_384_Free(&hmac->hash.sha3); + break; + case WC_SHA3_512: + wc_Sha3_512_Free(&hmac->hash.sha3); + break; + #endif /* WOLFSSL_SHA3 */ + + default: + break; + } + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC); #endif /* WOLFSSL_ASYNC_CRYPT */ diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 560126428..5a6aa9a53 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -454,6 +454,10 @@ static int InitSha256(wc_Sha256* sha256) if (ret != 0) return ret; + #ifdef WOLFSSL_SMALL_STACK_CACHE + sha256->W = NULL; + #endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256) ret = wolfAsync_DevCtxInit(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256, sha256->heap, devId); @@ -518,11 +522,19 @@ static int InitSha256(wc_Sha256* sha256) word32 S[8], t0, t1; int i; - #ifdef WOLFSSL_SMALL_STACK + #ifdef WOLFSSL_SMALL_STACK_CACHE + word32* W = sha256->W; + if (W == NULL) { + W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL, + DYNAMIC_TYPE_RNG); + if (W == NULL) + return MEMORY_E; + sha256->W = W; + } + #elif defined(WOLFSSL_SMALL_STACK) word32* W; - W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL, - DYNAMIC_TYPE_TMP_BUFFER); + DYNAMIC_TYPE_TMP_BUFFER); if (W == NULL) return MEMORY_E; #else @@ -560,10 +572,9 @@ static int InitSha256(wc_Sha256* sha256) sha256->digest[i] += S[i]; } - #ifdef WOLFSSL_SMALL_STACK + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE) XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - return 0; } #endif @@ -2611,6 +2622,10 @@ SHA256_NOINLINE static int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256, if (ret != 0) return ret; + #ifdef WOLFSSL_SMALL_STACK_CACHE + sha224->W = NULL; + #endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224) ret = wolfAsync_DevCtxInit(&sha224->asyncDev, WOLFSSL_ASYNC_MARKER_SHA224, sha224->heap, devId); @@ -2682,6 +2697,13 @@ SHA256_NOINLINE static int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256, if (sha224 == NULL) return; +#ifdef WOLFSSL_SMALL_STACK_CACHE + if (sha224->W != NULL) { + XFREE(sha224->W, NULL, DYNAMIC_TYPE_RNG); + sha224->W = NULL; + } +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224) wolfAsync_DevCtxFree(&sha224->asyncDev, WOLFSSL_ASYNC_MARKER_SHA224); #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -2699,6 +2721,13 @@ void wc_Sha256Free(wc_Sha256* sha256) if (sha256 == NULL) return; +#ifdef WOLFSSL_SMALL_STACK_CACHE + if (sha256->W != NULL) { + XFREE(sha256->W, NULL, DYNAMIC_TYPE_RNG); + sha256->W = NULL; + } +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256) wolfAsync_DevCtxFree(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256); #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -2721,6 +2750,7 @@ void wc_Sha256Free(wc_Sha256* sha256) ret = wc_Sha224Copy(sha224, &tmpSha224); if (ret == 0) { ret = wc_Sha224Final(&tmpSha224, hash); + wc_Sha224Free(&tmpSha224); } return ret; } @@ -2732,6 +2762,9 @@ void wc_Sha256Free(wc_Sha256* sha256) return BAD_FUNC_ARG; XMEMCPY(dst, src, sizeof(wc_Sha224)); + #ifdef WOLFSSL_SMALL_STACK_CACHE + dst->W = NULL; + #endif #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); @@ -2752,6 +2785,7 @@ int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash) ret = wc_Sha256Copy(sha256, &tmpSha256); if (ret == 0) { ret = wc_Sha256Final(&tmpSha256, hash); + wc_Sha256Free(&tmpSha256); } return ret; } @@ -2763,6 +2797,9 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) return BAD_FUNC_ARG; XMEMCPY(dst, src, sizeof(wc_Sha256)); +#ifdef WOLFSSL_SMALL_STACK_CACHE + dst->W = NULL; +#endif #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 09ba84cf7..fb5db0aec 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -374,6 +374,10 @@ static int InitSha512(wc_Sha512* 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); @@ -466,7 +470,16 @@ static int _Transform_Sha512(wc_Sha512* sha512) word32 j; word64 T[8]; -#ifdef WOLFSSL_SMALL_STACK +#ifdef WOLFSSL_SMALL_STACK_CACHE + word64* W = sha512->W; + if (W == NULL) { + W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (W == NULL) + return MEMORY_E; + sha512->W = W; + } +#elif defined(WOLFSSL_SMALL_STACK) word64* W; W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (W == NULL) @@ -511,7 +524,7 @@ static int _Transform_Sha512(wc_Sha512* sha512) ForceZero(W, sizeof(word64) * 16); ForceZero(T, sizeof(T)); -#ifdef WOLFSSL_SMALL_STACK +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE) XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -770,6 +783,13 @@ void wc_Sha512Free(wc_Sha512* sha512) if (sha512 == NULL) return; +#ifdef WOLFSSL_SMALL_STACK_CACHE + if (sha512->W != NULL) { + XFREE(sha512->W, NULL, DYNAMIC_TYPE_TMP_BUFFER); + sha512->W = NULL; + } +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512); #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -2701,6 +2721,10 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) if (ret != 0) return ret; +#ifdef WOLFSSL_SMALL_STACK_CACHE + sha384->W = NULL; +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384) ret = wolfAsync_DevCtxInit(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384, sha384->heap, devId); @@ -2723,6 +2747,13 @@ void wc_Sha384Free(wc_Sha384* sha384) if (sha384 == NULL) return; +#ifdef WOLFSSL_SMALL_STACK_CACHE + if (sha384->W != NULL) { + XFREE(sha384->W, NULL, DYNAMIC_TYPE_TMP_BUFFER); + sha384->W = NULL; + } +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384) wolfAsync_DevCtxFree(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384); #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -2744,6 +2775,7 @@ int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash) ret = wc_Sha512Copy(sha512, &tmpSha512); if (ret == 0) { ret = wc_Sha512Final(&tmpSha512, hash); + wc_Sha512Free(&tmpSha512); } return ret; } @@ -2756,6 +2788,9 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) return BAD_FUNC_ARG; XMEMCPY(dst, src, sizeof(wc_Sha512)); +#ifdef WOLFSSL_SMALL_STACK_CACHE + dst->W = NULL; +#endif #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); @@ -2776,6 +2811,7 @@ int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash) ret = wc_Sha384Copy(sha384, &tmpSha384); if (ret == 0) { ret = wc_Sha384Final(&tmpSha384, hash); + wc_Sha384Free(&tmpSha384); } return ret; } @@ -2787,6 +2823,9 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) return BAD_FUNC_ARG; XMEMCPY(dst, src, sizeof(wc_Sha384)); +#ifdef WOLFSSL_SMALL_STACK_CACHE + dst->W = NULL; +#endif #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index a799ab5d9..59f2d4587 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -137,6 +137,9 @@ typedef struct wc_Sha256 { #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLFSSL_SMALL_STACK_CACHE + word32* W; +#endif #endif } wc_Sha256; diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 078257b32..0cebf9da0 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -116,6 +116,9 @@ typedef struct wc_Sha512 { #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLFSSL_SMALL_STACK_CACHE + word64* W; +#endif } wc_Sha512; #endif From 6ef800e5f79f296b64635689c120c5e03092d3c4 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 17 Jul 2018 09:33:24 +1000 Subject: [PATCH 2/3] Cache Sha256 for small stack when asked in random Small stack builds see SHA-256 allocating W a lot. Cache the SHA-256 object in DRBG when WOLFSSL_SMALL_STACK_CACHE is defined. Call free function on SHA-256 object now that it is required. --- wolfcrypt/src/random.c | 87 +++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index c685bcef6..3d82637b6 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -217,6 +217,9 @@ typedef struct DRBG { int devId; #endif byte matchCount; +#ifdef WOLFSSL_SMALL_STACK_CACHE + wc_Sha256 sha256; +#endif } DRBG; @@ -233,7 +236,11 @@ static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type, int i; int len; word32 bits = (outSz * 8); /* reverse byte order */ - wc_Sha256 sha; +#ifdef WOLFSSL_SMALL_STACK_CACHE + wc_Sha256* sha = &drbg->sha256; +#else + wc_Sha256 sha[1]; +#endif DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap); (void)drbg; @@ -249,34 +256,38 @@ static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type, + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); for (i = 0, ctr = 1; i < len; i++, ctr++) { +#ifndef WOLFSSL_SMALL_STACK_CACHE #ifdef WOLFSSL_ASYNC_CRYPT - ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId); + ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId); #else - ret = wc_InitSha256(&sha); + ret = wc_InitSha256(sha); #endif if (ret != 0) break; if (ret == 0) - ret = wc_Sha256Update(&sha, &ctr, sizeof(ctr)); +#endif + ret = wc_Sha256Update(sha, &ctr, sizeof(ctr)); if (ret == 0) - ret = wc_Sha256Update(&sha, (byte*)&bits, sizeof(bits)); + ret = wc_Sha256Update(sha, (byte*)&bits, sizeof(bits)); if (ret == 0) { /* churning V is the only string that doesn't have the type added */ if (type != drbgInitV) - ret = wc_Sha256Update(&sha, &type, sizeof(type)); + ret = wc_Sha256Update(sha, &type, sizeof(type)); } if (ret == 0) - ret = wc_Sha256Update(&sha, inA, inASz); + ret = wc_Sha256Update(sha, inA, inASz); if (ret == 0) { if (inB != NULL && inBSz > 0) - ret = wc_Sha256Update(&sha, inB, inBSz); + ret = wc_Sha256Update(sha, inB, inBSz); } if (ret == 0) - ret = wc_Sha256Final(&sha, digest); + ret = wc_Sha256Final(sha, digest); - wc_Sha256Free(&sha); +#ifndef WOLFSSL_SMALL_STACK_CACHE + wc_Sha256Free(sha); +#endif if (ret == 0) { if (outSz > OUTPUT_BLOCK_LEN) { XMEMCPY(out, digest, OUTPUT_BLOCK_LEN); @@ -349,7 +360,11 @@ static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V) int i; int len; word32 checkBlock; - wc_Sha256 sha; +#ifdef WOLFSSL_SMALL_STACK_CACHE + wc_Sha256* sha = &drbg->sha256; +#else + wc_Sha256 sha[1]; +#endif DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap); /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for @@ -361,16 +376,20 @@ static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V) XMEMCPY(data, V, sizeof(data)); for (i = 0; i < len; i++) { +#ifndef WOLFSSL_SMALL_STACK_CACHE #ifdef WOLFSSL_ASYNC_CRYPT - ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId); + ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId); #else - ret = wc_InitSha256(&sha); + ret = wc_InitSha256(sha); #endif if (ret == 0) - ret = wc_Sha256Update(&sha, data, sizeof(data)); +#endif + ret = wc_Sha256Update(sha, data, sizeof(data)); if (ret == 0) - ret = wc_Sha256Final(&sha, digest); - wc_Sha256Free(&sha); + ret = wc_Sha256Final(sha, digest); +#ifndef WOLFSSL_SMALL_STACK_CACHE + wc_Sha256Free(sha); +#endif if (ret == 0) { XMEMCPY(&checkBlock, digest, sizeof(word32)); @@ -437,7 +456,11 @@ static WC_INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen static int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz) { int ret; - wc_Sha256 sha; +#ifdef WOLFSSL_SMALL_STACK_CACHE + wc_Sha256* sha = &drbg->sha256; +#else + wc_Sha256 sha[1]; +#endif byte type; word32 reseedCtr; @@ -450,19 +473,23 @@ static int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz) ret = Hash_gen(drbg, out, outSz, drbg->V); if (ret == DRBG_SUCCESS) { +#ifndef WOLFSSL_SMALL_STACK_CACHE #ifdef WOLFSSL_ASYNC_CRYPT - ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId); + ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId); #else - ret = wc_InitSha256(&sha); + ret = wc_InitSha256(sha); #endif if (ret == 0) - ret = wc_Sha256Update(&sha, &type, sizeof(type)); +#endif + ret = wc_Sha256Update(sha, &type, sizeof(type)); if (ret == 0) - ret = wc_Sha256Update(&sha, drbg->V, sizeof(drbg->V)); + ret = wc_Sha256Update(sha, drbg->V, sizeof(drbg->V)); if (ret == 0) - ret = wc_Sha256Final(&sha, digest); + ret = wc_Sha256Final(sha, digest); - wc_Sha256Free(&sha); +#ifndef WOLFSSL_SMALL_STACK_CACHE + wc_Sha256Free(sha); +#endif if (ret == 0) { array_add(drbg->V, sizeof(drbg->V), digest, WC_SHA256_DIGEST_SIZE); @@ -499,6 +526,16 @@ static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz, (void)devId; #endif +#ifdef WOLFSSL_SMALL_STACK_CACHE + #ifdef WOLFSSL_ASYNC_CRYPT + ret = wc_InitSha256_ex(&drbg->sha256, drbg->heap, drbg->devId); + #else + ret = wc_InitSha256(&drbg->sha256); + #endif + if (ret != 0) + return ret; +#endif + if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz, nonce, nonceSz) == DRBG_SUCCESS && Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V, @@ -520,6 +557,10 @@ static int Hash_DRBG_Uninstantiate(DRBG* drbg) int compareSum = 0; byte* compareDrbg = (byte*)drbg; +#ifdef WOLFSSL_SMALL_STACK_CACHE + wc_Sha256Free(&drbg->sha256); +#endif + ForceZero(drbg, sizeof(DRBG)); for (i = 0; i < sizeof(DRBG); i++) From befe15ddb962b872f9460b692bfeb504618ead94 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 17 Jul 2018 09:36:49 +1000 Subject: [PATCH 3/3] Add configure option to cache when using small stack --- configure.ac | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/configure.ac b/configure.ac index 202197048..4789fa946 100644 --- a/configure.ac +++ b/configure.ac @@ -2759,6 +2759,18 @@ fi +# Small Stack - Cache on object +AC_ARG_ENABLE([smallstackcache], + [AS_HELP_STRING([--enable-smallstackcache],[Enable Small Stack Usage Caching (default: disabled)])], + [ ENABLED_SMALL_STACK_CACHE=$enableval ], + [ ENABLED_SMALL_STACK_CACHE=no ] + ) + +if test "x$ENABLED_SMALL_STACK_CACHE" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SMALL_STACK_CACHE" +fi + # Small Stack AC_ARG_ENABLE([smallstack], [AS_HELP_STRING([--enable-smallstack],[Enable Small Stack Usage (default: disabled)])], @@ -2766,6 +2778,10 @@ AC_ARG_ENABLE([smallstack], [ ENABLED_SMALL_STACK=no ] ) +if test "x$ENABLED_SMALL_STACK_CACHE" = "xyes" +then + ENABLED_SMALL_STACK=yes +fi if test "x$ENABLED_SMALL_STACK" = "xyes" then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SMALL_STACK"