diff --git a/src/internal.c b/src/internal.c index 7cce86cf6..aef649c80 100644 --- a/src/internal.c +++ b/src/internal.c @@ -32701,7 +32701,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, byte b; byte bogusID = 0; /* flag for a bogus session id */ ProtocolVersion pv; - Suites clSuites; +#ifdef WOLFSSL_SMALL_STACK + Suites* clSuites = NULL; +#else + Suites clSuites[1]; +#endif word32 i = *inOutIdx; word32 begin = i; int ret = 0; @@ -33019,31 +33023,40 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto out; } - ato16(&input[i], &clSuites.suiteSz); +#ifdef WOLFSSL_SMALL_STACK + clSuites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, + DYNAMIC_TYPE_SUITES); + if (clSuites == NULL) { + ret = MEMORY_E; + goto out; + } +#endif + XMEMSET(clSuites, 0, sizeof(Suites)); + ato16(&input[i], &clSuites->suiteSz); i += OPAQUE16_LEN; /* Cipher suite lists are always multiples of two in length. */ - if (clSuites.suiteSz % 2 != 0) { + if (clSuites->suiteSz % 2 != 0) { ret = BUFFER_ERROR; goto out; } /* suites and compression length check */ - if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz) { + if ((i - begin) + clSuites->suiteSz + OPAQUE8_LEN > helloSz) { ret = BUFFER_ERROR; goto out; } - if (clSuites.suiteSz > WOLFSSL_MAX_SUITE_SZ) { + if (clSuites->suiteSz > WOLFSSL_MAX_SUITE_SZ) { ret = BUFFER_ERROR; goto out; } - XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz); + XMEMCPY(clSuites->suites, input + i, clSuites->suiteSz); #ifdef HAVE_SERVER_RENEGOTIATION_INFO /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */ - if (FindSuite(&clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= 0) { + if (FindSuite(clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= 0) { TLSX* extension; /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */ @@ -33061,7 +33074,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif /* HAVE_SERVER_RENEGOTIATION_INFO */ #if defined(HAVE_FALLBACK_SCSV) || defined(OPENSSL_ALL) /* check for TLS_FALLBACK_SCSV suite */ - if (FindSuite(&clSuites, TLS_FALLBACK_SCSV, 0) >= 0) { + if (FindSuite(clSuites, TLS_FALLBACK_SCSV, 0) >= 0) { WOLFSSL_MSG("Found Fallback SCSV"); if (ssl->ctx->method->version.minor > pv.minor) { WOLFSSL_MSG("Client trying to connect with lesser version"); @@ -33076,12 +33089,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (IsDtlsNotSctpMode(ssl) && IsDtlsNotSrtpMode(ssl) && !IsSCR(ssl)) { ret = wc_HmacUpdate(&cookieHmac, input + i - OPAQUE16_LEN, - clSuites.suiteSz + OPAQUE16_LEN); + clSuites->suiteSz + OPAQUE16_LEN); if (ret != 0) goto out; } #endif /* WOLFSSL_DTLS */ - i += clSuites.suiteSz; - clSuites.hashSigAlgoSz = 0; + i += clSuites->suiteSz; + clSuites->hashSigAlgoSz = 0; /* compression length */ b = input[i++]; @@ -33200,7 +33213,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_TLS_EXTENSIONS /* tls extensions */ if ((ret = TLSX_Parse(ssl, input + i, totalExtSz, client_hello, - &clSuites))) + clSuites))) goto out; #ifdef WOLFSSL_TLS13 if (TLSX_Find(ssl->extensions, @@ -33252,15 +33265,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto out; } - clSuites.hashSigAlgoSz = hashSigAlgoSz; - if (clSuites.hashSigAlgoSz > WOLFSSL_MAX_SIGALGO) { + clSuites->hashSigAlgoSz = hashSigAlgoSz; + if (clSuites->hashSigAlgoSz > WOLFSSL_MAX_SIGALGO) { WOLFSSL_MSG("ClientHello SigAlgo list exceeds max, " "truncating"); - clSuites.hashSigAlgoSz = WOLFSSL_MAX_SIGALGO; + clSuites->hashSigAlgoSz = WOLFSSL_MAX_SIGALGO; } - XMEMCPY(clSuites.hashSigAlgo, &input[i], - clSuites.hashSigAlgoSz); + XMEMCPY(clSuites->hashSigAlgo, &input[i], + clSuites->hashSigAlgoSz); i += hashSigAlgoSz; } @@ -33290,7 +33303,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* ProcessOld uses same resume code */ if (ssl->options.resuming) { - ret = HandleTlsResumption(ssl, bogusID, &clSuites); + ret = HandleTlsResumption(ssl, bogusID, clSuites); if (ret != 0) goto out; @@ -33345,7 +33358,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ret = CertSetupCbWrapper(ssl); #endif if (ret == 0) - ret = MatchSuite(ssl, &clSuites); + ret = MatchSuite(ssl, clSuites); #ifdef WOLFSSL_EXTRA_ALERTS if (ret == BUFFER_ERROR) @@ -33373,7 +33386,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS wc_HmacFree(&cookieHmac); #endif - +#ifdef WOLFSSL_SMALL_STACK + if (clSuites != NULL) + XFREE(clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); +#endif WOLFSSL_LEAVE("DoClientHello", ret); WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO); diff --git a/tests/api.c b/tests/api.c index 7e13a379f..07f6d0ef4 100644 --- a/tests/api.c +++ b/tests/api.c @@ -50514,7 +50514,7 @@ static int test_tls13_apis(void) #ifndef NO_WOLFSSL_SERVER WOLFSSL_CTX* serverCtx; WOLFSSL* serverSsl; -#ifndef NO_CERTS +#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM) const char* ourCert = svrCertFile; const char* ourKey = svrKeyFile; #endif @@ -50575,7 +50575,7 @@ static int test_tls13_apis(void) #endif #ifndef NO_WOLFSSL_SERVER serverTls12Ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()); -#ifndef NO_CERTS +#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM) wolfSSL_CTX_use_certificate_chain_file(serverTls12Ctx, ourCert); wolfSSL_CTX_use_PrivateKey_file(serverTls12Ctx, ourKey, WOLFSSL_FILETYPE_PEM); #endif @@ -50589,7 +50589,7 @@ static int test_tls13_apis(void) #endif #ifndef NO_WOLFSSL_SERVER serverCtx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()); -#ifndef NO_CERTS +#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM) wolfSSL_CTX_use_certificate_chain_file(serverCtx, ourCert); wolfSSL_CTX_use_PrivateKey_file(serverCtx, ourKey, WOLFSSL_FILETYPE_PEM); #endif diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index ed91473f0..1ff29d5ea 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -52,60 +52,13 @@ /* Macro to disable benchmark */ #ifndef NO_CRYPT_BENCHMARK -/* only for stack size check */ -#ifdef HAVE_STACK_SIZE - #include - #include +#include -#elif defined(WOLFSSL_ASYNC_CRYPT) +/* only for stack size check */ +#if defined(WOLFSSL_ASYNC_CRYPT) #ifndef WC_NO_ASYNC_THREADING #define WC_ENABLE_BENCH_THREADING #endif - -/* benchmark multi-threading - disable for FIPS self test */ -#elif !defined(SINGLE_THREADED) && !defined(WC_NO_BENCH_THREADING) && \ - defined(HAVE_PTHREAD) && !defined(HAVE_RENESAS_SYNC) - - #define WC_ENABLE_BENCH_THREADING - #if defined(_POSIX_THREADS) - typedef void* THREAD_RETURN; - typedef pthread_t THREAD_TYPE; - #define WOLFSSL_THREAD - #if !defined(__MINGW32__) - #define INFINITE (-1) - #define WAIT_OBJECT_0 0L - #endif - #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET) || defined(FREESCALE_MQX) - typedef unsigned int THREAD_RETURN; - typedef int THREAD_TYPE; - #define WOLFSSL_THREAD - #elif defined(WOLFSSL_TIRTOS) - typedef void THREAD_RETURN; - typedef Task_Handle THREAD_TYPE; - #ifdef HAVE_STACK_SIZE - #undef EXIT_TEST - #define EXIT_TEST(ret) - #endif - #define WOLFSSL_THREAD - #elif defined(WOLFSSL_ZEPHYR) - typedef void THREAD_RETURN; - typedef struct k_thread THREAD_TYPE; - #ifdef HAVE_STACK_SIZE - #undef EXIT_TEST - #define EXIT_TEST(ret) - #endif - #define WOLFSSL_THREAD - #elif defined(NETOS) - typedef UINT THREAD_RETURN; - typedef TX_THREAD THREAD_TYPE; - #define WOLFSSL_THREAD - #define INFINITE TX_WAIT_FOREVER - #define WAIT_OBJECT_0 TX_NO_WAIT - #else - typedef unsigned int THREAD_RETURN; - typedef intptr_t THREAD_TYPE; - #define WOLFSSL_THREAD __stdcall - #endif #endif #ifdef USE_FLAT_BENCHMARK_H @@ -1079,10 +1032,9 @@ static const char* bench_desc_words[][15] = { #pragma warning(disable: 4996) #endif - #ifdef WOLFSSL_CURRTIME_REMAP #define current_time WOLFSSL_CURRTIME_REMAP -#elif !defined(HAVE_STACK_SIZE) +#else double current_time(int reset); #endif @@ -8100,7 +8052,6 @@ void bench_sphincsKeySign(byte level, byte optim) #endif /* HAVE_SPHINCS */ #endif /* HAVE_PQC */ -#ifndef HAVE_STACK_SIZE #if defined(_WIN32) && !defined(INTIME_RTOS) #define WIN32_LEAN_AND_MEAN @@ -8315,7 +8266,6 @@ void bench_sphincsKeySign(byte level, byte optim) } #endif /* _WIN32 */ -#endif /* !HAVE_STACK_SIZE */ #if defined(HAVE_GET_CYCLES) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index d16da0882..53c540e49 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -13587,7 +13587,7 @@ int GetName(DecodedCert* cert, int nameType, int maxIdx) word32 localIdx; byte tag; - WOLFSSL_MSG("Getting Cert Name"); + WOLFSSL_MSG("Getting Name"); if (nameType == ISSUER) { full = cert->issuer; @@ -13634,7 +13634,7 @@ int GetName(DecodedCert* cert, int nameType, int maxIdx) char* full; byte* hash; - WOLFSSL_MSG("Getting Cert Name"); + WOLFSSL_MSG("Getting Name"); XMEMSET(dataASN, 0, sizeof(dataASN)); /* Initialize for data and don't check optional prefix OID. */ @@ -14008,9 +14008,9 @@ int wc_ValidateDate(const byte* date, byte format, int dateType) struct tm* localTime; struct tm* tmpTime; int i = 0; - int timeDiff = 0 ; - int diffHH = 0 ; int diffMM = 0 ; - int diffSign = 0 ; + int timeDiff = 0; + int diffHH = 0, diffMM = 0; + int diffSign = 0; #if defined(NEED_TMP_TIME) struct tm tmpTimeStorage; @@ -15345,6 +15345,9 @@ static int ConfirmSignature(SignatureCtx* sigCtx, byte* rsaKeyIdx) { int ret = 0; +#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT) + CertAttribute* certatt = NULL; +#endif if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL || keySz == 0 || sig == NULL || sigSz == 0) { @@ -15363,12 +15366,10 @@ static int ConfirmSignature(SignatureCtx* sigCtx, #if !defined(WOLFSSL_RENESAS_TSIP_TLS) && !defined(WOLFSSL_RENESAS_SCEPROTECT) (void)rsaKeyIdx; #else - CertAttribute* certatt = NULL; - #if !defined(NO_RSA) || defined(HAVE_ECC) certatt = (CertAttribute*)&sigCtx->CertAtt; #endif - if(certatt) { + if (certatt) { certatt->keyIndex = rsaKeyIdx; certatt->cert = buf; certatt->certSz = bufSz; diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index f54d16da1..cb05fa4bf 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -4667,7 +4667,7 @@ int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) #endif /* WOLFSSL_KEY_GEN || HAVE_COMP_KEY || HAVE_ECC || DEBUG_WOLFSSL */ -#if defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) +#if (defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)) || !defined(NO_DH) || !defined(NO_DSA) const FLASH_QUALIFIER mp_digit ltm_prime_tab[PRIME_SIZE] = { 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, @@ -5018,7 +5018,7 @@ LBL_B:mp_clear (&b); return err; } -#endif /* WOLFSSL_KEY_GEN NO_DH NO_DSA NO_RSA */ +#endif /* (WOLFSSL_KEY_GEN && !NO_RSA) || !NO_DH || !NO_DSA */ #ifdef WOLFSSL_KEY_GEN diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index b002323c2..e5247b8f1 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -318,6 +318,10 @@ void WOLFSSL_TIME(int count) int dc_log_printf(char*, ...); #endif +#ifdef HAVE_STACK_SIZE_VERBOSE +#include +#endif + static void wolfssl_log(const int logLevel, const char *const logMessage) { if (log_function) @@ -359,6 +363,9 @@ static void wolfssl_log(const int logLevel, const char *const logMessage) printk("%s\n", logMessage); #elif defined(WOLFSSL_RENESAS_RA6M4) myprintf("%s\n", logMessage); +#elif defined(STACK_SIZE_CHECKPOINT_MSG) && \ + defined(HAVE_STACK_SIZE_VERBOSE) && defined(HAVE_STACK_SIZE_VERBOSE_LOG) + STACK_SIZE_CHECKPOINT_MSG(logMessage); #else fprintf(stderr, "%s\n", logMessage); #endif diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 26e830c52..fdb6de0f4 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -363,16 +363,19 @@ static int Hash_df(DRBG_internal* drbg, byte* out, word32 outSz, byte type, #else wc_Sha256 sha[1]; #endif -#ifdef WC_ASYNC_ENABLE_SHA256 - WC_DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap); - if (digest == NULL) - return MEMORY_E; +#ifdef WOLFSSL_SMALL_STACK + byte* digest; #else byte digest[WC_SHA256_DIGEST_SIZE]; #endif - (void)drbg; -#ifdef WC_ASYNC_ENABLE_SHA256 + if (drbg == NULL) { + return DRBG_FAILURE; + } + +#ifdef WOLFSSL_SMALL_STACK + digest = (byte*)XMALLOC(WC_SHA256_DIGEST_SIZE, drbg->heap, + DYNAMIC_TYPE_DIGEST); if (digest == NULL) return DRBG_FAILURE; #endif @@ -431,8 +434,8 @@ static int Hash_df(DRBG_internal* drbg, byte* out, word32 outSz, byte type, ForceZero(digest, WC_SHA256_DIGEST_SIZE); -#ifdef WC_ASYNC_ENABLE_SHA256 - WC_FREE_VAR(digest, drbg->heap); +#ifdef WOLFSSL_SMALL_STACK + XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST); #endif return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE; @@ -441,31 +444,44 @@ static int Hash_df(DRBG_internal* drbg, byte* out, word32 outSz, byte type, /* Returns: DRBG_SUCCESS or DRBG_FAILURE */ static int Hash_DRBG_Reseed(DRBG_internal* drbg, const byte* seed, word32 seedSz) { + int ret; +#ifdef WOLFSSL_SMALL_STACK + byte* newV; +#else byte newV[DRBG_SEED_LEN]; +#endif if (drbg == NULL) { return DRBG_FAILURE; } +#ifdef WOLFSSL_SMALL_STACK + newV = (byte*)XMALLOC(DRBG_SEED_LEN, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (newV == NULL) { + return MEMORY_E; + } +#endif XMEMSET(newV, 0, DRBG_SEED_LEN); - if (Hash_df(drbg, newV, sizeof(newV), drbgReseed, - drbg->V, sizeof(drbg->V), seed, seedSz) != DRBG_SUCCESS) { - return DRBG_FAILURE; + ret = Hash_df(drbg, newV, DRBG_SEED_LEN, drbgReseed, + drbg->V, sizeof(drbg->V), seed, seedSz); + if (ret == DRBG_SUCCESS) { + XMEMCPY(drbg->V, newV, sizeof(drbg->V)); + ForceZero(newV, DRBG_SEED_LEN); + + ret = Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V, + sizeof(drbg->V), NULL, 0); + } + if (ret == DRBG_SUCCESS) { + drbg->reseedCtr = 1; + drbg->lastBlock = 0; + drbg->matchCount = 0; } - XMEMCPY(drbg->V, newV, sizeof(drbg->V)); - ForceZero(newV, sizeof(newV)); - - if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V, - sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) { - return DRBG_FAILURE; - } - - drbg->reseedCtr = 1; - drbg->lastBlock = 0; - drbg->matchCount = 0; - return DRBG_SUCCESS; +#ifdef WOLFSSL_SMALL_STACK + XFREE(newV, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; } /* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */ @@ -491,9 +507,7 @@ int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz) static WC_INLINE void array_add_one(byte* data, word32 dataSz) { int i; - - for (i = dataSz - 1; i >= 0; i--) - { + for (i = dataSz - 1; i >= 0; i--) { data[i]++; if (data[i] != 0) break; } @@ -503,7 +517,13 @@ static WC_INLINE void array_add_one(byte* data, word32 dataSz) static int Hash_gen(DRBG_internal* drbg, byte* out, word32 outSz, const byte* V) { int ret = DRBG_FAILURE; +#ifdef WOLFSSL_SMALL_STACK + byte* data; + byte* digest; +#else byte data[DRBG_SEED_LEN]; + byte digest[WC_SHA256_DIGEST_SIZE]; +#endif int i; int len; word32 checkBlock; @@ -512,22 +532,32 @@ static int Hash_gen(DRBG_internal* drbg, byte* out, word32 outSz, const byte* V) #else wc_Sha256 sha[1]; #endif -#ifdef WC_ASYNC_ENABLE_SHA256 - WC_DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap); - if (digest == NULL) - return MEMORY_E; -#else - byte digest[WC_SHA256_DIGEST_SIZE]; + + if (drbg == NULL) { + return DRBG_FAILURE; + } + +#ifdef WOLFSSL_SMALL_STACK + data = (byte*)XMALLOC(DRBG_SEED_LEN, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER); + digest = (byte*)XMALLOC(WC_SHA256_DIGEST_SIZE, drbg->heap, + DYNAMIC_TYPE_DIGEST); + if (data == NULL || digest == NULL) { + XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST); + XFREE(data, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER); + return DRBG_FAILURE; + } #endif /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for * the continuous test. */ - if (outSz == 0) outSz = 1; + if (outSz == 0) { + outSz = 1; + } len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); - XMEMCPY(data, V, sizeof(data)); + XMEMCPY(data, V, DRBG_SEED_LEN); for (i = 0; i < len; i++) { #ifndef WOLFSSL_SMALL_STACK_CACHE #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) @@ -537,7 +567,7 @@ static int Hash_gen(DRBG_internal* drbg, byte* out, word32 outSz, const byte* V) #endif if (ret == 0) #endif - ret = wc_Sha256Update(sha, data, sizeof(data)); + ret = wc_Sha256Update(sha, data, DRBG_SEED_LEN); if (ret == 0) ret = wc_Sha256Final(sha, digest); #ifndef WOLFSSL_SMALL_STACK_CACHE @@ -580,10 +610,11 @@ static int Hash_gen(DRBG_internal* drbg, byte* out, word32 outSz, const byte* V) break; } } - ForceZero(data, sizeof(data)); + ForceZero(data, DRBG_SEED_LEN); -#ifdef WC_ASYNC_ENABLE_SHA256 - WC_FREE_VAR(digest, drbg->heap); +#ifdef WOLFSSL_SMALL_STACK + XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST); + XFREE(data, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE; @@ -630,14 +661,17 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz) if (drbg->reseedCtr == RESEED_INTERVAL) { return DRBG_NEED_RESEED; - } else { - #ifdef WC_ASYNC_ENABLE_SHA256 - WC_DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap); - if (digest == NULL) - return MEMORY_E; - #else + } + else { + #ifndef WOLFSSL_SMALL_STACK byte digest[WC_SHA256_DIGEST_SIZE]; + #else + byte* digest = (byte*)XMALLOC(WC_SHA256_DIGEST_SIZE, drbg->heap, + DYNAMIC_TYPE_DIGEST); + if (digest == NULL) + return DRBG_FAILURE; #endif + type = drbgGenerateH; reseedCtr = drbg->reseedCtr; @@ -674,8 +708,8 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz) drbg->reseedCtr++; } ForceZero(digest, WC_SHA256_DIGEST_SIZE); - #ifdef WC_ASYNC_ENABLE_SHA256 - WC_FREE_VAR(digest, drbg->heap); + #ifdef WOLFSSL_SMALL_STACK + XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST); #endif } @@ -690,11 +724,10 @@ static int Hash_DRBG_Instantiate(DRBG_internal* drbg, const byte* seed, word32 s int ret = DRBG_FAILURE; XMEMSET(drbg, 0, sizeof(DRBG_internal)); -#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) drbg->heap = heap; +#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) drbg->devId = devId; #else - (void)heap; (void)devId; #endif @@ -735,8 +768,9 @@ static int Hash_DRBG_Uninstantiate(DRBG_internal* drbg) ForceZero(drbg, sizeof(DRBG_internal)); - for (i = 0; i < sizeof(DRBG_internal); i++) + for (i = 0; i < sizeof(DRBG_internal); i++) { compareSum |= compareDrbg[i] ^ 0; + } return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE; } @@ -838,12 +872,13 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, seedSz = MAX_SEED_SZ; if (wc_RNG_HealthTestLocal(0) == 0) { - #ifdef WC_ASYNC_ENABLE_SHA256 - WC_DECLARE_VAR(seed, byte, MAX_SEED_SZ, rng->heap); + #ifndef WOLFSSL_SMALL_STACK + byte seed[MAX_SEED_SZ]; + #else + byte* seed = (byte*)XMALLOC(MAX_SEED_SZ, rng->heap, + DYNAMIC_TYPE_SEED); if (seed == NULL) return MEMORY_E; - #else - byte seed[MAX_SEED_SZ]; #endif #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY) @@ -892,12 +927,13 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, } ForceZero(seed, seedSz); - #ifdef WC_ASYNC_ENABLE_SHA256 - WC_FREE_VAR(seed, rng->heap); + #ifdef WOLFSSL_SMALL_STACK + XFREE(seed, rng->heap, DYNAMIC_TYPE_SEED); #endif } - else + else { ret = DRBG_CONT_FAILURE; + } if (ret == DRBG_SUCCESS) { #ifdef WOLFSSL_CHECK_MEM_ZERO @@ -1044,13 +1080,21 @@ int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz); if (ret == DRBG_NEED_RESEED) { if (wc_RNG_HealthTestLocal(1) == 0) { + #ifndef WOLFSSL_SMALL_STACK byte newSeed[SEED_SZ + SEED_BLOCK_SZ]; - - ret = wc_GenerateSeed(&rng->seed, newSeed, + ret = DRBG_SUCCESS; + #else + byte* newSeed = (byte*)XMALLOC(SEED_SZ + SEED_BLOCK_SZ, rng->heap, + DYNAMIC_TYPE_SEED); + ret = (newSeed == NULL) ? MEMORY_E : DRBG_SUCCESS; + #endif + if (ret == DRBG_SUCCESS) { + ret = wc_GenerateSeed(&rng->seed, newSeed, SEED_SZ + SEED_BLOCK_SZ); - if (ret != 0) - ret = DRBG_FAILURE; - else + if (ret != 0) + ret = DRBG_FAILURE; + } + if (ret == DRBG_SUCCESS) ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ); if (ret == DRBG_SUCCESS) @@ -1060,9 +1104,13 @@ int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz); ForceZero(newSeed, sizeof(newSeed)); + #ifdef WOLFSSL_SMALL_STACK + XFREE(newSeed, rng->heap, DYNAMIC_TYPE_SEED); + #endif } - else + else { ret = DRBG_CONT_FAILURE; + } } if (ret == DRBG_SUCCESS) { @@ -1167,7 +1215,8 @@ int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz, } #ifdef WOLFSSL_SMALL_STACK - drbg = (DRBG_internal*)XMALLOC(sizeof(DRBG_internal), NULL, DYNAMIC_TYPE_RNG); + drbg = (DRBG_internal*)XMALLOC(sizeof(DRBG_internal), heap, + DYNAMIC_TYPE_RNG); if (drbg == NULL) { return MEMORY_E; } @@ -1210,7 +1259,7 @@ exit_rng_ht: } #ifdef WOLFSSL_SMALL_STACK - XFREE(drbg, NULL, DYNAMIC_TYPE_RNG); + XFREE(drbg, heap, DYNAMIC_TYPE_RNG); #endif return ret; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 12642bc65..92accfff9 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -27,14 +27,13 @@ #include #endif #include -#include -#include #ifndef NO_CRYPT_TEST -#if defined(HAVE_STACK_SIZE) && !defined(HAVE_WOLFCRYPT_TEST_OPTIONS) - #define HAVE_WOLFCRYPT_TEST_OPTIONS -#endif +#include +#include +#include +#include #if defined(HAVE_WOLFCRYPT_TEST_OPTIONS) #include @@ -48,15 +47,12 @@ #include #endif -#if defined(HAVE_STACK_SIZE_VERBOSE) +#ifdef HAVE_STACK_SIZE_VERBOSE #ifdef WOLFSSL_TEST_MAX_RELATIVE_STACK_BYTES static ssize_t max_relative_stack = WOLFSSL_TEST_MAX_RELATIVE_STACK_BYTES; #else static ssize_t max_relative_stack = -1; #endif -#else - #define STACK_SIZE_CHECKPOINT_WITH_MAX_CHECK(max, ...) (__VA_ARGS__, 0) - #define STACK_SIZE_INIT() #endif #ifdef WOLFSSL_TRACK_MEMORY_VERBOSE diff --git a/wolfssl/test.h b/wolfssl/test.h index f282cb38a..a6647cfbf 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1,4 +1,29 @@ -/* test.h */ +/* test.h + * + * Copyright (C) 2006-2022 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +/*! + \file ../wolfssl/test.h + \brief Header file containing test inline functions +*/ + +/* Testing functions */ #ifndef wolfSSL_TEST_H #define wolfSSL_TEST_H @@ -252,57 +277,6 @@ #endif #endif - - -#ifdef SINGLE_THREADED - #if defined(WC_32BIT_CPU) - typedef void* THREAD_RETURN; - #else - typedef unsigned int THREAD_RETURN; - #endif - typedef void* THREAD_TYPE; - #define WOLFSSL_THREAD -#else - #if defined(_POSIX_THREADS) && !defined(__MINGW32__) - typedef void* THREAD_RETURN; - typedef pthread_t THREAD_TYPE; - #define WOLFSSL_THREAD - #define INFINITE (-1) - #define WAIT_OBJECT_0 0L - #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET) || defined(FREESCALE_MQX) - typedef unsigned int THREAD_RETURN; - typedef int THREAD_TYPE; - #define WOLFSSL_THREAD - #elif defined(WOLFSSL_TIRTOS) - typedef void THREAD_RETURN; - typedef Task_Handle THREAD_TYPE; - #ifdef HAVE_STACK_SIZE - #undef EXIT_TEST - #define EXIT_TEST(ret) - #endif - #define WOLFSSL_THREAD - #elif defined(WOLFSSL_ZEPHYR) - typedef void THREAD_RETURN; - typedef struct k_thread THREAD_TYPE; - #ifdef HAVE_STACK_SIZE - #undef EXIT_TEST - #define EXIT_TEST(ret) - #endif - #define WOLFSSL_THREAD - #elif defined(NETOS) - typedef UINT THREAD_RETURN; - typedef TX_THREAD THREAD_TYPE; - #define WOLFSSL_THREAD - #define INFINITE TX_WAIT_FOREVER - #define WAIT_OBJECT_0 TX_NO_WAIT - #else - typedef unsigned int THREAD_RETURN; - typedef intptr_t THREAD_TYPE; - #define WOLFSSL_THREAD __stdcall - #endif -#endif - - #ifndef MY_EX_USAGE #define MY_EX_USAGE 2 #endif @@ -3004,335 +2978,6 @@ static WC_INLINE void CaCb(unsigned char* der, int sz, int type) } #endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) */ -#ifdef HAVE_STACK_SIZE - -typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args); -#define STACK_CHECK_VAL 0x01 - -struct stack_size_debug_context { - unsigned char *myStack; - size_t stackSize; -#ifdef HAVE_STACK_SIZE_VERBOSE - size_t *stackSizeHWM_ptr; - thread_func fn; - void *args; -#endif -}; - -#ifdef HAVE_STACK_SIZE_VERBOSE - -/* per-subtest stack high water mark tracking. - * - * enable with - * - * ./configure --enable-stacksize=verbose [...] - */ - -static THREAD_RETURN debug_stack_size_verbose_shim(struct stack_size_debug_context *shim_args) { - StackSizeCheck_myStack = shim_args->myStack; - StackSizeCheck_stackSize = shim_args->stackSize; - StackSizeCheck_stackSizeHWM_ptr = shim_args->stackSizeHWM_ptr; - return shim_args->fn(shim_args->args); -} - -static WC_INLINE int StackSizeSetOffset(const char *funcname, void *p) -{ - if (StackSizeCheck_myStack == NULL) - return -BAD_FUNC_ARG; - - StackSizeCheck_stackOffsetPointer = p; - - printf("setting stack relative offset reference mark in %s to +%lu\n", - funcname, (unsigned long)((char*)(StackSizeCheck_myStack + - StackSizeCheck_stackSize) - (char *)p)); - - return 0; -} - -static WC_INLINE ssize_t StackSizeHWM(void) -{ - size_t i; - ssize_t used; - - if (StackSizeCheck_myStack == NULL) - return -BAD_FUNC_ARG; - - for (i = 0; i < StackSizeCheck_stackSize; i++) { - if (StackSizeCheck_myStack[i] != STACK_CHECK_VAL) { - break; - } - } - - used = StackSizeCheck_stackSize - i; - if ((ssize_t)*StackSizeCheck_stackSizeHWM_ptr < used) - *StackSizeCheck_stackSizeHWM_ptr = used; - - return used; -} - -static WC_INLINE ssize_t StackSizeHWM_OffsetCorrected(void) -{ - ssize_t used = StackSizeHWM(); - if (used < 0) - return used; - if (StackSizeCheck_stackOffsetPointer) - used -= (ssize_t)(((char *)StackSizeCheck_myStack + StackSizeCheck_stackSize) - (char *)StackSizeCheck_stackOffsetPointer); - return used; -} - -static -#ifdef __GNUC__ -__attribute__((unused)) __attribute__((noinline)) -#endif -int StackSizeHWMReset(void) -{ - volatile ssize_t i; - - if (StackSizeCheck_myStack == NULL) - return -BAD_FUNC_ARG; - - for (i = (ssize_t)((char *)&i - (char *)StackSizeCheck_myStack) - (ssize_t)sizeof i - 1; i >= 0; --i) - { - StackSizeCheck_myStack[i] = STACK_CHECK_VAL; - } - - return 0; -} - -#define STACK_SIZE_CHECKPOINT(...) ({ \ - ssize_t HWM = StackSizeHWM_OffsetCorrected(); \ - __VA_ARGS__; \ - printf(" relative stack peak usage = %ld bytes\n", (long int)HWM); \ - StackSizeHWMReset(); \ - }) - -#define STACK_SIZE_CHECKPOINT_WITH_MAX_CHECK(max, ...) ({ \ - ssize_t HWM = StackSizeHWM_OffsetCorrected(); \ - int _ret; \ - __VA_ARGS__; \ - printf(" relative stack peak usage = %ld bytes\n", (long int)HWM); \ - _ret = StackSizeHWMReset(); \ - if ((max >= 0) && (HWM > (ssize_t)(max))) { \ - fprintf(stderr, \ - " relative stack usage at %s L%d exceeds designated max %ld bytes.\n", \ - __FILE__, __LINE__, (long int)(max)); \ - _ret = -1; \ - } \ - _ret; \ - }) - - -#ifdef __GNUC__ -#define STACK_SIZE_INIT() (void)StackSizeSetOffset(__FUNCTION__, __builtin_frame_address(0)) -#endif - -#endif /* HAVE_STACK_SIZE_VERBOSE */ - -static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf) -{ - size_t i; - int ret; - void* status; - unsigned char* myStack = NULL; - size_t stackSize = 1024*1024*2; - pthread_attr_t myAttr; - pthread_t threadId; -#ifdef HAVE_STACK_SIZE_VERBOSE - struct stack_size_debug_context shim_args; -#endif - -#ifdef PTHREAD_STACK_MIN - if (stackSize < PTHREAD_STACK_MIN) - stackSize = PTHREAD_STACK_MIN; -#endif - - ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize); - if (ret != 0 || myStack == NULL) { - err_sys_with_errno("posix_memalign failed\n"); - return -1; - } - - XMEMSET(myStack, STACK_CHECK_VAL, stackSize); - - ret = pthread_attr_init(&myAttr); - if (ret != 0) - err_sys("attr_init failed"); - - ret = pthread_attr_setstack(&myAttr, myStack, stackSize); - if (ret != 0) - err_sys("attr_setstackaddr failed"); - -#ifdef HAVE_STACK_SIZE_VERBOSE - StackSizeCheck_stackSizeHWM = 0; - shim_args.myStack = myStack; - shim_args.stackSize = stackSize; - shim_args.stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM; - shim_args.fn = tf; - shim_args.args = args; - ret = pthread_create(&threadId, &myAttr, (thread_func)debug_stack_size_verbose_shim, (void *)&shim_args); -#else - ret = pthread_create(&threadId, &myAttr, tf, args); -#endif - if (ret != 0) { - printf("ret = %d\n", ret); - perror("pthread_create failed"); - exit(EXIT_FAILURE); - } - - ret = pthread_join(threadId, &status); - if (ret != 0) - err_sys("pthread_join failed"); - - for (i = 0; i < stackSize; i++) { - if (myStack[i] != STACK_CHECK_VAL) { - break; - } - } - - free(myStack); -#ifdef HAVE_STACK_SIZE_VERBOSE - printf("stack used = %lu\n", StackSizeCheck_stackSizeHWM > (stackSize - i) - ? (unsigned long)StackSizeCheck_stackSizeHWM - : (unsigned long)(stackSize - i)); -#else - { - size_t used = stackSize - i; - printf("stack used = %lu\n", (unsigned long)used); - } -#endif - - return (int)((size_t)status); -} - -static WC_INLINE int StackSizeCheck_launch(func_args* args, thread_func tf, pthread_t *threadId, void **stack_context) -{ - int ret; - unsigned char* myStack = NULL; - size_t stackSize = 1024*1024*2; - pthread_attr_t myAttr; - -#ifdef PTHREAD_STACK_MIN - if (stackSize < PTHREAD_STACK_MIN) - stackSize = PTHREAD_STACK_MIN; -#endif - - struct stack_size_debug_context *shim_args = (struct stack_size_debug_context *)malloc(sizeof *shim_args); - if (! shim_args) { - perror("malloc"); - exit(EXIT_FAILURE); - } - - ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize); - if (ret != 0 || myStack == NULL) { - err_sys_with_errno("posix_memalign failed\n"); - free(shim_args); - return -1; - } - - XMEMSET(myStack, STACK_CHECK_VAL, stackSize); - - ret = pthread_attr_init(&myAttr); - if (ret != 0) - err_sys("attr_init failed"); - - ret = pthread_attr_setstack(&myAttr, myStack, stackSize); - if (ret != 0) - err_sys("attr_setstackaddr failed"); - - shim_args->myStack = myStack; - shim_args->stackSize = stackSize; -#ifdef HAVE_STACK_SIZE_VERBOSE - shim_args->stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM; - shim_args->fn = tf; - shim_args->args = args; - ret = pthread_create(threadId, &myAttr, (thread_func)debug_stack_size_verbose_shim, (void *)shim_args); -#else - ret = pthread_create(threadId, &myAttr, tf, args); -#endif - if (ret != 0) { - fprintf(stderr,"pthread_create failed: %s",strerror(ret)); - exit(EXIT_FAILURE); - } - - *stack_context = (void *)shim_args; - - return 0; -} - -static WC_INLINE int StackSizeCheck_reap(pthread_t threadId, void *stack_context) -{ - struct stack_size_debug_context *shim_args = (struct stack_size_debug_context *)stack_context; - size_t i; - void *status; - int ret = pthread_join(threadId, &status); - if (ret != 0) - err_sys("pthread_join failed"); - - for (i = 0; i < shim_args->stackSize; i++) { - if (shim_args->myStack[i] != STACK_CHECK_VAL) { - break; - } - } - - free(shim_args->myStack); -#ifdef HAVE_STACK_SIZE_VERBOSE - printf("stack used = %lu\n", - *shim_args->stackSizeHWM_ptr > (shim_args->stackSize - i) - ? (unsigned long)*shim_args->stackSizeHWM_ptr - : (unsigned long)(shim_args->stackSize - i)); -#else - { - size_t used = shim_args->stackSize - i; - printf("stack used = %lu\n", (unsigned long)used); - } -#endif - free(shim_args); - - return (int)((size_t)status); -} - - -#endif /* HAVE_STACK_SIZE */ - -#ifndef STACK_SIZE_CHECKPOINT -#define STACK_SIZE_CHECKPOINT(...) (__VA_ARGS__) -#endif -#ifndef STACK_SIZE_INIT -#define STACK_SIZE_INIT() -#endif - -#ifdef STACK_TRAP - -/* good settings - --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP" - -*/ - -#ifdef HAVE_STACK_SIZE - /* client only for now, setrlimit will fail if pthread_create() called */ - /* STACK_SIZE does pthread_create() on client */ - #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail" -#endif /* HAVE_STACK_SIZE */ - -static WC_INLINE void StackTrap(void) -{ - struct rlimit rl; - if (getrlimit(RLIMIT_STACK, &rl) != 0) - err_sys_with_errno("getrlimit failed"); - printf("rlim_cur = %llu\n", rl.rlim_cur); - rl.rlim_cur = 1024*21; /* adjust trap size here */ - if (setrlimit(RLIMIT_STACK, &rl) != 0) - err_sys_with_errno("setrlimit failed"); -} - -#else /* STACK_TRAP */ - -static WC_INLINE void StackTrap(void) -{ -} - -#endif /* STACK_TRAP */ - #if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY) diff --git a/wolfssl/wolfcrypt/mem_track.h b/wolfssl/wolfcrypt/mem_track.h index cba10ffc4..ceea2416d 100644 --- a/wolfssl/wolfcrypt/mem_track.h +++ b/wolfssl/wolfcrypt/mem_track.h @@ -19,6 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +/* Memory and stack use tracking */ + +#ifndef WOLFSSL_MEM_TRACK_H +#define WOLFSSL_MEM_TRACK_H + +#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY) /* The memory tracker overrides the wolfSSL memory callback system and uses a * static to track the total, peak and currently allocated bytes. @@ -55,377 +61,757 @@ */ -#ifndef WOLFSSL_MEM_TRACK_H -#define WOLFSSL_MEM_TRACK_H +#include +#include "wolfssl/wolfcrypt/logging.h" -#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY) - - #include "wolfssl/wolfcrypt/logging.h" - - #if defined(WOLFSSL_TRACK_MEMORY) - #define DO_MEM_STATS - #if defined(__linux__) || defined(__MACH__) - #define DO_MEM_LIST - #endif +#if defined(WOLFSSL_TRACK_MEMORY) + #define DO_MEM_STATS + #if defined(__linux__) || defined(__MACH__) + #define DO_MEM_LIST #endif - - - typedef struct memoryStats { - long totalAllocs; /* number of allocations */ - long totalDeallocs; /* number of deallocations */ - long totalBytes; /* total number of bytes allocated */ - long peakBytes; /* concurrent max bytes */ - long currentBytes; /* total current bytes in use */ -#ifdef WOLFSSL_TRACK_MEMORY_VERBOSE - long peakAllocsTripOdometer; /* peak number of concurrent allocations, - * subject to reset by - * wolfCrypt_heap_peak_checkpoint() - */ - long peakBytesTripOdometer; /* peak concurrent bytes, subject to reset - * by wolfCrypt_heap_peak_checkpoint() - */ #endif - } memoryStats; - typedef struct memHint { - size_t thisSize; /* size of this memory */ - #ifdef DO_MEM_LIST - struct memHint* next; - struct memHint* prev; - #ifdef WOLFSSL_DEBUG_MEMORY - const char* func; - unsigned int line; - #endif - #endif - void* thisMemory; /* actual memory for user */ - } memHint; +typedef struct memoryStats { + long totalAllocs; /* number of allocations */ + long totalDeallocs; /* number of deallocations */ + long totalBytes; /* total number of bytes allocated */ + long peakBytes; /* concurrent max bytes */ + long currentBytes; /* total current bytes in use */ +#ifdef WOLFSSL_TRACK_MEMORY_VERBOSE + long peakAllocsTripOdometer; /* peak number of concurrent allocations, + * subject to reset by + * wolfCrypt_heap_peak_checkpoint() + */ + long peakBytesTripOdometer; /* peak concurrent bytes, subject to reset + * by wolfCrypt_heap_peak_checkpoint() + */ +#endif +} memoryStats; - typedef struct memoryTrack { - union { - memHint hint; - byte alignit[sizeof(memHint) + ((16-1) & ~(16-1))]; /* make sure we have strong alignment */ - } u; - } memoryTrack; +typedef struct memHint { + size_t thisSize; /* size of this memory */ #ifdef DO_MEM_LIST - /* track allocations and report at end */ - typedef struct memoryList { - memHint* head; - memHint* tail; - word32 count; - } memoryList; + struct memHint* next; + struct memHint* prev; + #ifdef WOLFSSL_DEBUG_MEMORY + const char* func; + unsigned int line; + #endif +#endif + void* thisMemory; /* actual memory for user */ +} memHint; + +typedef struct memoryTrack { + union { + memHint hint; + byte alignit[sizeof(memHint) + ((16-1) & ~(16-1))]; /* make sure we have strong alignment */ + } u; +} memoryTrack; + +#ifdef DO_MEM_LIST +/* track allocations and report at end */ +typedef struct memoryList { + memHint* head; + memHint* tail; + word32 count; +} memoryList; #endif #if defined(WOLFSSL_TRACK_MEMORY) - static memoryStats ourMemStats; +static memoryStats ourMemStats; - #ifdef DO_MEM_LIST - #include - static memoryList ourMemList; - static pthread_mutex_t memLock = PTHREAD_MUTEX_INITIALIZER; - #endif +#ifdef DO_MEM_LIST + #include + static memoryList ourMemList; + static pthread_mutex_t memLock = PTHREAD_MUTEX_INITIALIZER; +#endif #endif - /* if defined to not using inline then declare function prototypes */ - #ifdef NO_INLINE - #define WC_STATIC - #ifdef WOLFSSL_DEBUG_MEMORY - WOLFSSL_LOCAL void* TrackMalloc(size_t sz, const char* func, unsigned int line); - WOLFSSL_LOCAL void TrackFree(void* ptr, const char* func, unsigned int line); - WOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line); - #else - WOLFSSL_LOCAL void* TrackMalloc(size_t sz); - WOLFSSL_LOCAL void TrackFree(void* ptr); - WOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz); - #endif - WOLFSSL_LOCAL int InitMemoryTracker(void); - WOLFSSL_LOCAL void ShowMemoryTracker(void); - #else - #define WC_STATIC static - #endif - -#ifdef WOLFSSL_DEBUG_MEMORY - WC_STATIC WC_INLINE void* TrackMalloc(size_t sz, const char* func, unsigned int line) -#else - WC_STATIC WC_INLINE void* TrackMalloc(size_t sz) -#endif - { - memoryTrack* mt; - memHint* header; - - if (sz == 0) - return NULL; - - #ifdef FREERTOS - mt = (memoryTrack*)pvPortMalloc(sizeof(memoryTrack) + sz); - #else - mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz); - #endif - if (mt == NULL) - return NULL; - - header = &mt->u.hint; - header->thisSize = sz; - header->thisMemory = (byte*)mt + sizeof(memoryTrack); - +/* if defined to not using inline then declare function prototypes */ +#ifdef NO_INLINE + #define WC_STATIC #ifdef WOLFSSL_DEBUG_MEMORY - #ifdef WOLFSSL_DEBUG_MEMORY_PRINT - fprintf(stderr, "Alloc: %p -> %u at %s:%d\n", header->thisMemory, (word32)sz, func, line); + WOLFSSL_LOCAL void* TrackMalloc(size_t sz, const char* func, unsigned int line); + WOLFSSL_LOCAL void TrackFree(void* ptr, const char* func, unsigned int line); + WOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line); #else - (void)func; - (void)line; + WOLFSSL_LOCAL void* TrackMalloc(size_t sz); + WOLFSSL_LOCAL void TrackFree(void* ptr); + WOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz); #endif - #endif - - #ifdef DO_MEM_STATS - ourMemStats.totalAllocs++; - ourMemStats.totalBytes += sz; - ourMemStats.currentBytes += sz; - #ifdef WOLFSSL_TRACK_MEMORY_VERBOSE - if (ourMemStats.peakAllocsTripOdometer < ourMemStats.totalAllocs - ourMemStats.totalDeallocs) - ourMemStats.peakAllocsTripOdometer = ourMemStats.totalAllocs - ourMemStats.totalDeallocs; - if (ourMemStats.peakBytesTripOdometer < ourMemStats.currentBytes) { - ourMemStats.peakBytesTripOdometer = ourMemStats.currentBytes; - #endif - if (ourMemStats.currentBytes > ourMemStats.peakBytes) - ourMemStats.peakBytes = ourMemStats.currentBytes; - #ifdef WOLFSSL_TRACK_MEMORY_VERBOSE - } - #endif - #endif - #ifdef DO_MEM_LIST - if (pthread_mutex_lock(&memLock) == 0) { - #ifdef WOLFSSL_DEBUG_MEMORY - header->func = func; - header->line = line; - #endif - - /* Setup event */ - header->next = NULL; - if (ourMemList.tail == NULL) { - ourMemList.head = header; - header->prev = NULL; - } - else { - ourMemList.tail->next = header; - header->prev = ourMemList.tail; - } - ourMemList.tail = header; /* add to the end either way */ - ourMemList.count++; - - pthread_mutex_unlock(&memLock); - } - #endif - - return header->thisMemory; - } - + WOLFSSL_LOCAL int InitMemoryTracker(void); + WOLFSSL_LOCAL void ShowMemoryTracker(void); +#else + #define WC_STATIC static +#endif #ifdef WOLFSSL_DEBUG_MEMORY - WC_STATIC WC_INLINE void TrackFree(void* ptr, const char* func, unsigned int line) +WC_STATIC WC_INLINE void* TrackMalloc(size_t sz, const char* func, unsigned int line) #else - WC_STATIC WC_INLINE void TrackFree(void* ptr) +WC_STATIC WC_INLINE void* TrackMalloc(size_t sz) #endif - { - memoryTrack* mt; - memHint* header; - size_t sz; +{ + memoryTrack* mt; + memHint* header; - if (ptr == NULL) { - return; - } + if (sz == 0) + return NULL; - mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack)); - header = &mt->u.hint; - sz = header->thisSize; +#ifdef FREERTOS + mt = (memoryTrack*)pvPortMalloc(sizeof(memoryTrack) + sz); +#else + mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz); +#endif + if (mt == NULL) + return NULL; - #ifdef DO_MEM_LIST - if (pthread_mutex_lock(&memLock) == 0) - { - #endif - - #ifdef DO_MEM_STATS - ourMemStats.currentBytes -= header->thisSize; - ourMemStats.totalDeallocs++; - #endif - - #ifdef DO_MEM_LIST - if (header == ourMemList.head && header == ourMemList.tail) { - ourMemList.head = NULL; - ourMemList.tail = NULL; - } - else if (header == ourMemList.head) { - ourMemList.head = header->next; - ourMemList.head->prev = NULL; - } - else if (header == ourMemList.tail) { - ourMemList.tail = header->prev; - ourMemList.tail->next = NULL; - } - else { - memHint* next = header->next; - memHint* prev = header->prev; - if (next) - next->prev = prev; - if (prev) - prev->next = next; - } - ourMemList.count--; - - pthread_mutex_unlock(&memLock); - } - #endif + header = &mt->u.hint; + header->thisSize = sz; + header->thisMemory = (byte*)mt + sizeof(memoryTrack); #ifdef WOLFSSL_DEBUG_MEMORY #ifdef WOLFSSL_DEBUG_MEMORY_PRINT - fprintf(stderr, "Free: %p -> %u at %s:%d\n", ptr, (word32)sz, func, line); + fprintf(stderr, "Alloc: %p -> %u at %s:%d\n", header->thisMemory, (word32)sz, func, line); #else - (void)func; - (void)line; + (void)func; + (void)line; #endif #endif - (void)sz; - #ifdef FREERTOS - vPortFree(mt); - #else - free(mt); +#ifdef DO_MEM_STATS + ourMemStats.totalAllocs++; + ourMemStats.totalBytes += sz; + ourMemStats.currentBytes += sz; + #ifdef WOLFSSL_TRACK_MEMORY_VERBOSE + if (ourMemStats.peakAllocsTripOdometer < ourMemStats.totalAllocs - ourMemStats.totalDeallocs) + ourMemStats.peakAllocsTripOdometer = ourMemStats.totalAllocs - ourMemStats.totalDeallocs; + if (ourMemStats.peakBytesTripOdometer < ourMemStats.currentBytes) { + ourMemStats.peakBytesTripOdometer = ourMemStats.currentBytes; #endif + if (ourMemStats.currentBytes > ourMemStats.peakBytes) + ourMemStats.peakBytes = ourMemStats.currentBytes; + #ifdef WOLFSSL_TRACK_MEMORY_VERBOSE } + #endif +#endif +#ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) { + #ifdef WOLFSSL_DEBUG_MEMORY + header->func = func; + header->line = line; + #endif + + /* Setup event */ + header->next = NULL; + if (ourMemList.tail == NULL) { + ourMemList.head = header; + header->prev = NULL; + } + else { + ourMemList.tail->next = header; + header->prev = ourMemList.tail; + } + ourMemList.tail = header; /* add to the end either way */ + ourMemList.count++; + + pthread_mutex_unlock(&memLock); + } +#endif + + return header->thisMemory; +} #ifdef WOLFSSL_DEBUG_MEMORY - WC_STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line) +WC_STATIC WC_INLINE void TrackFree(void* ptr, const char* func, unsigned int line) #else - WC_STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz) +WC_STATIC WC_INLINE void TrackFree(void* ptr) #endif - { - #ifdef WOLFSSL_DEBUG_MEMORY - void* ret = TrackMalloc(sz, func, line); - #else - void* ret = TrackMalloc(sz); - #endif +{ + memoryTrack* mt; + memHint* header; + size_t sz; - if (ptr) { - /* if realloc is bigger, don't overread old ptr */ - memoryTrack* mt; - memHint* header; - - mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack)); - header = &mt->u.hint; - - if (header->thisSize < sz) - sz = header->thisSize; - } - - if (ret && ptr) - XMEMCPY(ret, ptr, sz); - - if (ret) { - #ifdef WOLFSSL_DEBUG_MEMORY - TrackFree(ptr, func, line); - #else - TrackFree(ptr); - #endif - } - - return ret; + if (ptr == NULL) { + return; } + mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack)); + header = &mt->u.hint; + sz = header->thisSize; + +#ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) + { +#endif + +#ifdef DO_MEM_STATS + ourMemStats.currentBytes -= header->thisSize; + ourMemStats.totalDeallocs++; +#endif + +#ifdef DO_MEM_LIST + if (header == ourMemList.head && header == ourMemList.tail) { + ourMemList.head = NULL; + ourMemList.tail = NULL; + } + else if (header == ourMemList.head) { + ourMemList.head = header->next; + ourMemList.head->prev = NULL; + } + else if (header == ourMemList.tail) { + ourMemList.tail = header->prev; + ourMemList.tail->next = NULL; + } + else { + memHint* next = header->next; + memHint* prev = header->prev; + if (next) + next->prev = prev; + if (prev) + prev->next = next; + } + ourMemList.count--; + + pthread_mutex_unlock(&memLock); + } +#endif + +#ifdef WOLFSSL_DEBUG_MEMORY +#ifdef WOLFSSL_DEBUG_MEMORY_PRINT + fprintf(stderr, "Free: %p -> %u at %s:%d\n", ptr, (word32)sz, func, line); +#else + (void)func; + (void)line; +#endif +#endif + (void)sz; + +#ifdef FREERTOS + vPortFree(mt); +#else + free(mt); +#endif +} + + +#ifdef WOLFSSL_DEBUG_MEMORY +WC_STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line) +#else +WC_STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz) +#endif +{ +#ifdef WOLFSSL_DEBUG_MEMORY + void* ret = TrackMalloc(sz, func, line); +#else + void* ret = TrackMalloc(sz); +#endif + + if (ptr) { + /* if realloc is bigger, don't overread old ptr */ + memoryTrack* mt; + memHint* header; + + mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack)); + header = &mt->u.hint; + + if (header->thisSize < sz) + sz = header->thisSize; + } + + if (ret && ptr) + XMEMCPY(ret, ptr, sz); + + if (ret) { + #ifdef WOLFSSL_DEBUG_MEMORY + TrackFree(ptr, func, line); + #else + TrackFree(ptr); + #endif + } + + return ret; +} + #ifdef WOLFSSL_TRACK_MEMORY - static wolfSSL_Malloc_cb mfDefault = NULL; - static wolfSSL_Free_cb ffDefault = NULL; - static wolfSSL_Realloc_cb rfDefault = NULL; +static wolfSSL_Malloc_cb mfDefault = NULL; +static wolfSSL_Free_cb ffDefault = NULL; +static wolfSSL_Realloc_cb rfDefault = NULL; - WC_STATIC WC_INLINE int InitMemoryTracker(void) - { - int ret; - - ret = wolfSSL_GetAllocators(&mfDefault, &ffDefault, &rfDefault); - if (ret < 0) { - fprintf(stderr, "wolfSSL GetAllocators failed to get the defaults\n"); - } - ret = wolfSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc); - if (ret < 0) { - fprintf(stderr, "wolfSSL SetAllocators failed for track memory\n"); - return ret; - } - - #ifdef DO_MEM_LIST - if (pthread_mutex_lock(&memLock) == 0) - { - #endif - - #ifdef DO_MEM_STATS - ourMemStats.totalAllocs = 0; - ourMemStats.totalDeallocs = 0; - ourMemStats.totalBytes = 0; - ourMemStats.peakBytes = 0; - ourMemStats.currentBytes = 0; -#ifdef WOLFSSL_TRACK_MEMORY_VERBOSE - ourMemStats.peakAllocsTripOdometer = 0; - ourMemStats.peakBytesTripOdometer = 0; -#endif - #endif - - #ifdef DO_MEM_LIST - XMEMSET(&ourMemList, 0, sizeof(ourMemList)); - - pthread_mutex_unlock(&memLock); - } - #endif +WC_STATIC WC_INLINE int InitMemoryTracker(void) +{ + int ret; + ret = wolfSSL_GetAllocators(&mfDefault, &ffDefault, &rfDefault); + if (ret < 0) { + fprintf(stderr, "wolfSSL GetAllocators failed to get the defaults\n"); + } + ret = wolfSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc); + if (ret < 0) { + fprintf(stderr, "wolfSSL SetAllocators failed for track memory\n"); return ret; } - WC_STATIC WC_INLINE void ShowMemoryTracker(void) +#ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) { - #ifdef DO_MEM_LIST - if (pthread_mutex_lock(&memLock) == 0) - { - #endif +#endif - #ifdef DO_MEM_STATS - fprintf(stderr, "total Allocs = %9ld\n", ourMemStats.totalAllocs); - fprintf(stderr, "total Deallocs = %9ld\n", ourMemStats.totalDeallocs); - fprintf(stderr, "total Bytes = %9ld\n", ourMemStats.totalBytes); - fprintf(stderr, "peak Bytes = %9ld\n", ourMemStats.peakBytes); - fprintf(stderr, "current Bytes = %9ld\n", ourMemStats.currentBytes); - #endif +#ifdef DO_MEM_STATS + ourMemStats.totalAllocs = 0; + ourMemStats.totalDeallocs = 0; + ourMemStats.totalBytes = 0; + ourMemStats.peakBytes = 0; + ourMemStats.currentBytes = 0; +#ifdef WOLFSSL_TRACK_MEMORY_VERBOSE + ourMemStats.peakAllocsTripOdometer = 0; + ourMemStats.peakBytesTripOdometer = 0; +#endif +#endif - #ifdef DO_MEM_LIST - if (ourMemList.count > 0) { - /* print list of allocations */ - memHint* header; - for (header = ourMemList.head; header != NULL; header = header->next) { - fprintf(stderr, "Leak: Ptr %p, Size %u" - #ifdef WOLFSSL_DEBUG_MEMORY - ", Func %s, Line %d" - #endif - "\n", - (byte*)header + sizeof(memHint), (unsigned int)header->thisSize - #ifdef WOLFSSL_DEBUG_MEMORY - , header->func, header->line - #endif - ); - } - } +#ifdef DO_MEM_LIST + XMEMSET(&ourMemList, 0, sizeof(ourMemList)); - pthread_mutex_unlock(&memLock); - } - #endif - } - - WC_STATIC WC_INLINE int CleanupMemoryTracker(void) - { - /* restore default allocators */ - return wolfSSL_SetAllocators(mfDefault, ffDefault, rfDefault); + pthread_mutex_unlock(&memLock); } #endif -#endif /* USE_WOLFSSL_MEMORY */ + return ret; +} + +WC_STATIC WC_INLINE void ShowMemoryTracker(void) +{ +#ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) + { +#endif + +#ifdef DO_MEM_STATS + fprintf(stderr, "total Allocs = %9ld\n", ourMemStats.totalAllocs); + fprintf(stderr, "total Deallocs = %9ld\n", ourMemStats.totalDeallocs); + fprintf(stderr, "total Bytes = %9ld\n", ourMemStats.totalBytes); + fprintf(stderr, "peak Bytes = %9ld\n", ourMemStats.peakBytes); + fprintf(stderr, "current Bytes = %9ld\n", ourMemStats.currentBytes); +#endif + +#ifdef DO_MEM_LIST + if (ourMemList.count > 0) { + /* print list of allocations */ + memHint* header; + for (header = ourMemList.head; header != NULL; header = header->next) { + fprintf(stderr, "Leak: Ptr %p, Size %u" + #ifdef WOLFSSL_DEBUG_MEMORY + ", Func %s, Line %d" + #endif + "\n", + (byte*)header + sizeof(memHint), (unsigned int)header->thisSize + #ifdef WOLFSSL_DEBUG_MEMORY + , header->func, header->line + #endif + ); + } + } + + pthread_mutex_unlock(&memLock); + } +#endif +} + +WC_STATIC WC_INLINE int CleanupMemoryTracker(void) +{ + /* restore default allocators */ + return wolfSSL_SetAllocators(mfDefault, ffDefault, rfDefault); +} +#endif /* WOLFSSL_TRACK_MEMORY */ + +#endif /* USE_WOLFSSL_MEMORY && !WOLFSSL_STATIC_MEMORY */ + + +#ifdef HAVE_STACK_SIZE + +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef void* (*thread_func)(void* args); +#define STACK_CHECK_VAL 0x01 + +struct stack_size_debug_context { + unsigned char *myStack; + size_t stackSize; +#ifdef HAVE_STACK_SIZE_VERBOSE + size_t *stackSizeHWM_ptr; + thread_func fn; + void *args; +#endif +}; + +struct func_args; /* forward declaration */ + +#ifdef HAVE_STACK_SIZE_VERBOSE + +/* per-subtest stack high water mark tracking. + * + * enable with + * + * ./configure --enable-stacksize=verbose [...] + */ + +static void* debug_stack_size_verbose_shim( + struct stack_size_debug_context *shim_args) +{ + StackSizeCheck_myStack = shim_args->myStack; + StackSizeCheck_stackSize = shim_args->stackSize; + StackSizeCheck_stackSizeHWM_ptr = shim_args->stackSizeHWM_ptr; + return shim_args->fn(shim_args->args); +} + +static WC_INLINE int StackSizeSetOffset(const char *funcname, void *p) +{ + if (StackSizeCheck_myStack == NULL) + return -BAD_FUNC_ARG; + + StackSizeCheck_stackOffsetPointer = p; + + printf("setting stack relative offset reference mark in %s to +%lu\n", + funcname, (unsigned long)((char*)(StackSizeCheck_myStack + + StackSizeCheck_stackSize) - (char *)p)); + + return 0; +} + +static WC_INLINE ssize_t StackSizeHWM(void) +{ + size_t i; + ssize_t used; + + if (StackSizeCheck_myStack == NULL) + return -BAD_FUNC_ARG; + + for (i = 0; i < StackSizeCheck_stackSize; i++) { + if (StackSizeCheck_myStack[i] != STACK_CHECK_VAL) { + break; + } + } + + used = StackSizeCheck_stackSize - i; + if ((ssize_t)*StackSizeCheck_stackSizeHWM_ptr < used) + *StackSizeCheck_stackSizeHWM_ptr = used; + + return used; +} + +static WC_INLINE ssize_t StackSizeHWM_OffsetCorrected(void) +{ + ssize_t used = StackSizeHWM(); + if (used < 0) + return used; + if (StackSizeCheck_stackOffsetPointer) { + used -= (ssize_t)(((char *)StackSizeCheck_myStack + + StackSizeCheck_stackSize) - + (char *)StackSizeCheck_stackOffsetPointer); + } + return used; +} + +static +#ifdef __GNUC__ +__attribute__((unused)) __attribute__((noinline)) +#endif +int StackSizeHWMReset(void) +{ + volatile ssize_t i; + + if (StackSizeCheck_myStack == NULL) + return -BAD_FUNC_ARG; + + for (i = (ssize_t)((char *)&i - (char *)StackSizeCheck_myStack) - + (ssize_t)sizeof(i) - 1; i >= 0; --i) { + StackSizeCheck_myStack[i] = STACK_CHECK_VAL; + } + + return 0; +} + +#define STACK_SIZE_CHECKPOINT(...) ({ \ + ssize_t HWM = StackSizeHWM_OffsetCorrected(); \ + __VA_ARGS__; \ + printf(" relative stack peak usage = %ld bytes\n", (long int)HWM); \ + StackSizeHWMReset(); \ + }) + +#define STACK_SIZE_CHECKPOINT_MSG(msg) ({ \ + ssize_t HWM = StackSizeHWM_OffsetCorrected(); \ + fprintf(stderr, "%ld\t%s\n", (long int)HWM, msg); \ + StackSizeHWMReset(); \ + }) + \ + + +#define STACK_SIZE_CHECKPOINT_WITH_MAX_CHECK(max, ...) ({ \ + ssize_t HWM = StackSizeHWM_OffsetCorrected(); \ + int _ret; \ + __VA_ARGS__; \ + printf(" relative stack peak usage = %ld bytes\n", (long int)HWM); \ + _ret = StackSizeHWMReset(); \ + if ((max >= 0) && (HWM > (ssize_t)(max))) { \ + fprintf(stderr, \ + " relative stack usage at %s L%d exceeds designated max %ld bytes.\n", \ + __FILE__, __LINE__, (long int)(max)); \ + _ret = -1; \ + } \ + _ret; \ + }) + + +#if defined(__GNUC__) || defined(__clang__) +#define STACK_SIZE_INIT() \ + (void)StackSizeSetOffset(__FUNCTION__, __builtin_frame_address(0)) +#endif + +#endif /* HAVE_STACK_SIZE_VERBOSE */ + +static WC_INLINE int StackSizeCheck(struct func_args* args, thread_func tf) +{ + size_t i; + int ret; + void* status; + unsigned char* myStack = NULL; + size_t stackSize = 1024*1024*2; + pthread_attr_t myAttr; + pthread_t threadId; +#ifdef HAVE_STACK_SIZE_VERBOSE + struct stack_size_debug_context shim_args; +#endif + +#ifdef PTHREAD_STACK_MIN + if (stackSize < PTHREAD_STACK_MIN) + stackSize = PTHREAD_STACK_MIN; +#endif + + ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize); + if (ret != 0 || myStack == NULL) { + fprintf(stderr, "posix_memalign failed\n"); + return -1; + } + + XMEMSET(myStack, STACK_CHECK_VAL, stackSize); + + ret = pthread_attr_init(&myAttr); + if (ret != 0) { + fprintf(stderr, "attr_init failed\n"); + return ret; + } + + ret = pthread_attr_setstack(&myAttr, myStack, stackSize); + if (ret != 0) { + fprintf(stderr, "attr_setstackaddr failed\n"); + return ret; + } + +#ifdef HAVE_STACK_SIZE_VERBOSE + StackSizeCheck_stackSizeHWM = 0; + shim_args.myStack = myStack; + shim_args.stackSize = stackSize; + shim_args.stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM; + shim_args.fn = tf; + shim_args.args = args; + ret = pthread_create(&threadId, &myAttr, + (thread_func)debug_stack_size_verbose_shim, (void *)&shim_args); +#else + ret = pthread_create(&threadId, &myAttr, tf, args); +#endif + if (ret != 0) { + printf("ret = %d\n", ret); + perror("pthread_create failed"); + exit(EXIT_FAILURE); + } + + ret = pthread_join(threadId, &status); + if (ret != 0) { + fprintf(stderr, "pthread_join failed\n"); + return ret; + } + + for (i = 0; i < stackSize; i++) { + if (myStack[i] != STACK_CHECK_VAL) { + break; + } + } + + free(myStack); +#ifdef HAVE_STACK_SIZE_VERBOSE + printf("stack used = %lu\n", StackSizeCheck_stackSizeHWM > (stackSize - i) + ? (unsigned long)StackSizeCheck_stackSizeHWM + : (unsigned long)(stackSize - i)); + StackSizeCheck_myStack = NULL; + StackSizeCheck_stackOffsetPointer = NULL; +#else + { + size_t used = stackSize - i; + printf("stack used = %lu\n", (unsigned long)used); + } +#endif + + return (int)((size_t)status); +} + +static WC_INLINE int StackSizeCheck_launch(struct func_args* args, + thread_func tf, pthread_t *threadId, void **stack_context) +{ + int ret; + unsigned char* myStack = NULL; + size_t stackSize = 1024*1024*2; + pthread_attr_t myAttr; + +#ifdef PTHREAD_STACK_MIN + if (stackSize < PTHREAD_STACK_MIN) + stackSize = PTHREAD_STACK_MIN; +#endif + + struct stack_size_debug_context *shim_args = + (struct stack_size_debug_context *)malloc(sizeof *shim_args); + if (! shim_args) { + perror("malloc"); + exit(EXIT_FAILURE); + } + + ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize); + if (ret != 0 || myStack == NULL) { + fprintf(stderr, "posix_memalign failed\n"); + free(shim_args); + return -1; + } + + XMEMSET(myStack, STACK_CHECK_VAL, stackSize); + + ret = pthread_attr_init(&myAttr); + if (ret != 0) { + fprintf(stderr, "attr_init failed\n"); + return ret; + } + + ret = pthread_attr_setstack(&myAttr, myStack, stackSize); + if (ret != 0) { + fprintf(stderr, "attr_setstackaddr failed\n"); + } + + shim_args->myStack = myStack; + shim_args->stackSize = stackSize; +#ifdef HAVE_STACK_SIZE_VERBOSE + shim_args->stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM; + shim_args->fn = tf; + shim_args->args = args; + ret = pthread_create(threadId, &myAttr, + (thread_func)debug_stack_size_verbose_shim, (void *)shim_args); +#else + ret = pthread_create(threadId, &myAttr, tf, args); +#endif + if (ret != 0) { + fprintf(stderr,"pthread_create failed: %s",strerror(ret)); + exit(EXIT_FAILURE); + } + + *stack_context = (void *)shim_args; + + return 0; +} + +static WC_INLINE int StackSizeCheck_reap(pthread_t threadId, void *stack_context) +{ + struct stack_size_debug_context *shim_args = + (struct stack_size_debug_context *)stack_context; + size_t i; + void *status; + int ret = pthread_join(threadId, &status); + if (ret != 0) { + fprintf(stderr, "pthread_join failed\n"); + return ret; + } + + for (i = 0; i < shim_args->stackSize; i++) { + if (shim_args->myStack[i] != STACK_CHECK_VAL) { + break; + } + } + + free(shim_args->myStack); +#ifdef HAVE_STACK_SIZE_VERBOSE + printf("stack used = %lu\n", + *shim_args->stackSizeHWM_ptr > (shim_args->stackSize - i) + ? (unsigned long)*shim_args->stackSizeHWM_ptr + : (unsigned long)(shim_args->stackSize - i)); +#else + { + size_t used = shim_args->stackSize - i; + printf("stack used = %lu\n", (unsigned long)used); + } +#endif + free(shim_args); + + return (int)((size_t)status); +} + + +#endif /* HAVE_STACK_SIZE */ + + +#ifdef STACK_TRAP + +/* good settings + ./configure --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME \ + -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP" + +*/ + +#ifdef HAVE_STACK_SIZE + /* client only for now, setrlimit will fail if pthread_create() called */ + /* STACK_SIZE does pthread_create() on client */ + #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail" +#endif /* HAVE_STACK_SIZE */ + +static WC_INLINE void StackTrap(void) +{ + struct rlimit rl; + if (getrlimit(RLIMIT_STACK, &rl) != 0) { + fprintf(stderr, "getrlimit failed\n"); + } + printf("rlim_cur = %llu\n", rl.rlim_cur); + rl.rlim_cur = 1024*21; /* adjust trap size here */ + if (setrlimit(RLIMIT_STACK, &rl) != 0) { + fprintf(stderr, "setrlimit failed\n"); + } +} + +#else /* STACK_TRAP */ + +static WC_INLINE void StackTrap(void) +{ +} + +#endif /* STACK_TRAP */ + +/* Stubs when not used */ +#ifndef STACK_SIZE_CHECKPOINT +#define STACK_SIZE_CHECKPOINT(...) (__VA_ARGS__) +#endif +#ifndef STACK_SIZE_CHECKPOINT_MSG +#define STACK_SIZE_CHECKPOINT_MSG(msg) +#endif +#ifndef STACK_SIZE_CHECKPOINT_WITH_MAX_CHECK +#define STACK_SIZE_CHECKPOINT_WITH_MAX_CHECK(max, ...) (0) +#endif +#ifndef STACK_SIZE_INIT +#define STACK_SIZE_INIT() +#endif #endif /* WOLFSSL_MEM_TRACK_H */ - diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index 28ac8f640..5deea40a0 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -162,8 +162,8 @@ struct DRBG_internal { word32 lastBlock; byte V[DRBG_SEED_LEN]; byte C[DRBG_SEED_LEN]; -#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) void* heap; +#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) int devId; #endif byte matchCount; diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 026e8487e..6822f6b34 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1234,6 +1234,57 @@ typedef struct w64wrapper { #define FALSE 0 #endif + #ifdef SINGLE_THREADED + #if defined(WC_32BIT_CPU) + typedef void* THREAD_RETURN; + #else + typedef unsigned int THREAD_RETURN; + #endif + typedef void* THREAD_TYPE; + #define WOLFSSL_THREAD + #elif (defined(_POSIX_THREADS) || defined(HAVE_PTHREAD)) && \ + !defined(__MINGW32__) + typedef void* THREAD_RETURN; + typedef pthread_t THREAD_TYPE; + #define WOLFSSL_THREAD + #define INFINITE (-1) + #define WAIT_OBJECT_0 0L + #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) || \ + defined(FREESCALE_MQX) + typedef unsigned int THREAD_RETURN; + typedef int THREAD_TYPE; + #define WOLFSSL_THREAD + #elif defined(WOLFSSL_TIRTOS) + typedef void THREAD_RETURN; + typedef Task_Handle THREAD_TYPE; + #ifdef HAVE_STACK_SIZE + #undef EXIT_TEST + #define EXIT_TEST(ret) + #endif + #define WOLFSSL_THREAD + #elif defined(WOLFSSL_ZEPHYR) + typedef void THREAD_RETURN; + typedef struct k_thread THREAD_TYPE; + #ifdef HAVE_STACK_SIZE + #undef EXIT_TEST + #define EXIT_TEST(ret) + #endif + #define WOLFSSL_THREAD + #elif defined(NETOS) + typedef UINT THREAD_RETURN; + typedef TX_THREAD THREAD_TYPE; + #define WOLFSSL_THREAD + #define INFINITE TX_WAIT_FOREVER + #define WAIT_OBJECT_0 TX_NO_WAIT + #elif defined(WOLFSSL_LINUXKM) + typedef unsigned int THREAD_RETURN; + typedef size_t THREAD_TYPE; + #define WOLFSSL_THREAD + #else + typedef unsigned int THREAD_RETURN; + typedef size_t THREAD_TYPE; + #define WOLFSSL_THREAD __stdcall + #endif #if defined(HAVE_STACK_SIZE) #define EXIT_TEST(ret) return (THREAD_RETURN)((size_t)(ret))