diff --git a/src/internal.c b/src/internal.c index 98fc5cc36..afc634272 100644 --- a/src/internal.c +++ b/src/internal.c @@ -309,9 +309,11 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, */ buffSz = labelSz + (RAN_LEN * 2) + 1 + ((*secretSz) * 2) + 1; log = XMALLOC(buffSz, ssl->heap, DYNAMIC_TYPE_SECRET); - if (log == NULL) return MEMORY_E; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SessionSecret log", log, buffSz); +#endif XMEMSET(log, 0, buffSz); XMEMCPY(log, label, labelSz -1); /* put label w/o terminator */ @@ -444,6 +446,9 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, log = XMALLOC(buffSz, ssl->heap, DYNAMIC_TYPE_SECRET); if (log == NULL) return MEMORY_E; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SessionSecret log", log, buffSz); +#endif XMEMSET(log, 0, buffSz); XMEMCPY(log, label, labelSz - 1); /* put label w/o terminator */ @@ -6347,6 +6352,21 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) int ret; XMEMSET(ssl, 0, sizeof(WOLFSSL)); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SSL Keys", &ssl->keys, sizeof(ssl->keys)); +#ifdef WOLFSSL_TLS13 + wc_MemZero_Add("SSL client secret", &ssl->clientSecret, + sizeof(ssl->clientSecret)); + wc_MemZero_Add("SSL client secret", &ssl->serverSecret, + sizeof(ssl->serverSecret)); +#endif +#ifdef WOLFSSL_HAVE_TLS_UNIQUE + wc_MemZero_Add("ClientFinished hash", &ssl->clientFinished, + TLS_FINISHED_SZ_MAX); + wc_MemZero_Add("ServerFinished hash", &ssl->serverFinished, + TLS_FINISHED_SZ_MAX); +#endif +#endif #if defined(WOLFSSL_STATIC_MEMORY) if (ctx->heap != NULL) { @@ -6633,6 +6653,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) WOLFSSL_MSG("Arrays Memory error"); return MEMORY_E; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SSL Arrays", ssl->arrays, sizeof(*ssl->arrays)); +#endif XMEMSET(ssl->arrays, 0, sizeof(Arrays)); #if defined(WOLFSSL_TLS13) || defined(WOLFSSL_SNIFFER) ssl->arrays->preMasterSz = ENCRYPT_LEN; @@ -6641,6 +6664,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) if (ssl->arrays->preMasterSecret == NULL) { return MEMORY_E; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SSL Arrays", ssl->arrays->preMasterSecret, ENCRYPT_LEN); +#endif XMEMSET(ssl->arrays->preMasterSecret, 0, ENCRYPT_LEN); #endif @@ -7696,6 +7722,9 @@ void FreeSSL(WOLFSSL* ssl, void* heap) if (ctx) FreeSSL_Ctx(ctx); /* will decrement and free underlying CTX if 0 */ (void)heap; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(ssl, sizeof(*ssl)); +#endif } #if !defined(NO_OLD_TLS) || defined(WOLFSSL_DTLS) || \ @@ -8736,6 +8765,10 @@ static int EdDSA_Update(WOLFSSL* ssl, const byte* data, int sz) XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES); } if (ret == 0) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("Handshake messages", msgs, + ssl->hsHashes->length + sz); + #endif ssl->hsHashes->messages = msgs; XMEMCPY(msgs + ssl->hsHashes->length, data, sz); ssl->hsHashes->prevLen = ssl->hsHashes->length; @@ -15890,10 +15923,16 @@ int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, nonce[10] ^= add[6]; nonce[11] ^= add[7]; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("ChachaAEADEncrypt nonce", nonce, CHACHA20_NONCE_SZ); +#endif /* set the nonce for chacha and get poly1305 key */ if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0) { ForceZero(nonce, CHACHA20_NONCE_SZ); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(nonce, CHACHA20_NONCE_SZ); + #endif return ret; } @@ -15901,21 +15940,37 @@ int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, poly, poly, sizeof(poly))) != 0) { ForceZero(nonce, CHACHA20_NONCE_SZ); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(nonce, CHACHA20_NONCE_SZ); + #endif return ret; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("ChachaAEADEncrypt poly", poly, CHACHA20_256_KEY_SIZE); +#endif /* set the counter after getting poly1305 key */ if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 1)) != 0) { ForceZero(nonce, CHACHA20_NONCE_SZ); ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(nonce, CHACHA20_NONCE_SZ); + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); + #endif return ret; } ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */ +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(nonce, CHACHA20_NONCE_SZ); +#endif /* encrypt the plain text */ if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out, input, msgLen)) != 0) { ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); + #endif return ret; } @@ -15924,6 +15979,9 @@ int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, if ((ret = Poly1305TagOld(ssl, add, (const byte* )out, poly, sz, tag)) != 0) { ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); + #endif return ret; } } @@ -15931,15 +15989,24 @@ int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, sizeof(poly))) != 0) { ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); + #endif return ret; } if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add, sizeof(add), out, msgLen, tag, sizeof(tag))) != 0) { ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); + #endif return ret; } } ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */ +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); +#endif /* append tag to ciphertext */ XMEMCPY(out + msgLen, tag, sizeof(tag)); @@ -16057,10 +16124,16 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, nonce[10] ^= add[6]; nonce[11] ^= add[7]; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("ChachaAEADEncrypt nonce", nonce, CHACHA20_NONCE_SZ); +#endif /* set nonce and get poly1305 key */ if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0) { ForceZero(nonce, CHACHA20_NONCE_SZ); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(nonce, CHACHA20_NONCE_SZ); + #endif return ret; } @@ -16068,21 +16141,37 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, poly, poly, sizeof(poly))) != 0) { ForceZero(nonce, CHACHA20_NONCE_SZ); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(nonce, CHACHA20_NONCE_SZ); + #endif return ret; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("ChachaAEADEncrypt poly", poly, CHACHA20_256_KEY_SIZE); +#endif /* set counter after getting poly1305 key */ if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 1)) != 0) { ForceZero(nonce, CHACHA20_NONCE_SZ); ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(nonce, CHACHA20_NONCE_SZ); + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); + #endif return ret; } ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */ +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(nonce, CHACHA20_NONCE_SZ); +#endif /* get the tag using Poly1305 */ if (ssl->options.oldPoly != 0) { if ((ret = Poly1305TagOld(ssl, add, input, poly, sz, tag)) != 0) { ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); + #endif return ret; } } @@ -16090,15 +16179,24 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, sizeof(poly))) != 0) { ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); + #endif return ret; } if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add, sizeof(add), input, msgLen, tag, sizeof(tag))) != 0) { ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); + #endif return ret; } } ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */ +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, CHACHA20_256_KEY_SIZE); +#endif /* check tag sent along with packet */ if (ConstantCompare(input + msgLen, tag, ssl->specs.aead_mac_size) != 0) { @@ -16365,9 +16463,16 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, if (ssl->encrypt.additional == NULL) ssl->encrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); - if (ssl->encrypt.nonce == NULL) + if (ssl->encrypt.nonce == NULL) { ssl->encrypt.nonce = (byte*)XMALLOC(AESGCM_NONCE_SZ, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (ssl->encrypt.nonce != NULL) { + wc_MemZero_Add("Encrypt nonce", ssl->encrypt.nonce, + AESGCM_NONCE_SZ); + } + #endif + } if (ssl->encrypt.additional == NULL || ssl->encrypt.nonce == NULL) { return MEMORY_E; @@ -16424,6 +16529,12 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, ForceZero(ssl->encrypt.nonce, AESGCM_NONCE_SZ); } #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #ifdef WOLFSSL_CHECK_MEM_ZERO + if ((ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null) && + (out != input) && (ret == 0)) { + wc_MemZero_Add("TLS Encrypt plaintext", input, sz); + } + #endif break; } @@ -16582,6 +16693,13 @@ static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input, ret = DECRYPT_ERROR; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + if ((ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null) && + (ret == 0)) { + wc_MemZero_Add("Decrypted data", plain, sz); + } +#endif + return ret; } @@ -16625,9 +16743,16 @@ static int DecryptTls(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) if (ssl->decrypt.additional == NULL) ssl->decrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); - if (ssl->decrypt.nonce == NULL) + if (ssl->decrypt.nonce == NULL) { ssl->decrypt.nonce = (byte*)XMALLOC(AESGCM_NONCE_SZ, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (ssl->decrypt.nonce != NULL) { + wc_MemZero_Add("DecryptTls nonce", ssl->decrypt.nonce, + AESGCM_NONCE_SZ); + } + #endif + } if (ssl->decrypt.additional == NULL || ssl->decrypt.nonce == NULL) { return MEMORY_E; @@ -28914,6 +29039,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, (word32*)&ssl->buffers.serverDH_Priv.length, ssl->buffers.serverDH_Pub.buffer, (word32*)&ssl->buffers.serverDH_Pub.length); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("DH private key buffer", + ssl->buffers.serverDH_Priv.buffer, + ssl->buffers.serverDH_Priv.length); + #endif break; } else @@ -29014,6 +29144,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, (word32*)&ssl->buffers.serverDH_Priv.length, ssl->buffers.serverDH_Pub.buffer, (word32*)&ssl->buffers.serverDH_Pub.length); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("DH private key buffer", + ssl->buffers.serverDH_Priv.buffer, + ssl->buffers.serverDH_Priv.length); + #endif break; } #endif /* !NO_DH && (!NO_PSK || !NO_RSA) */ @@ -32172,6 +32307,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, sizeof(TicketNonce)); #endif } + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Ticket has sensitive data in it now. */ + wc_MemZero_Add("Create Ticket internal", &it, sizeof(InternalTicket)); + #endif #ifdef WOLFSSL_TICKET_HAVE_ID { @@ -32194,6 +32333,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ID_LEN); if (ret != 0) { ForceZero(&it, sizeof(it)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(&it, sizeof(InternalTicket)); + #endif return ret; } ssl->session->haveAltSessionID = 1; @@ -32230,6 +32372,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, et->enc_ticket, sizeof(InternalTicket), &encLen, ssl->ctx->ticketEncCtx); if (ret != WOLFSSL_TICKET_RET_OK) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Internal ticket data wasn't encrypted maybe. */ + wc_MemZero_Add("Create Ticket enc_ticket", et->enc_ticket, + sizeof(InternalTicket)); + #endif ForceZero(&it, sizeof(it)); ForceZero(et->enc_ticket, sizeof(it)); } @@ -32240,6 +32387,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ForceZero(&it, sizeof(it)); ForceZero(et->enc_ticket, sizeof(it)); WOLFSSL_MSG("Bad user ticket encrypt size"); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(&it, sizeof(InternalTicket)); + #endif return BAD_TICKET_KEY_CB_SZ; } @@ -32252,6 +32402,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ForceZero(&it, sizeof(it)); ForceZero(et->enc_ticket, sizeof(it)); WOLFSSL_MSG("User ticket encrypt didn't encrypt"); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(&it, sizeof(InternalTicket)); + #endif return BAD_TICKET_ENCRYPT; } @@ -32261,18 +32414,27 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* name */ if (XMEMCMP(et->key_name, zeros, WOLFSSL_TICKET_NAME_SZ) == 0) { WOLFSSL_MSG("User ticket encrypt didn't set name"); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(&it, sizeof(InternalTicket)); + #endif return BAD_TICKET_ENCRYPT; } /* iv */ if (XMEMCMP(et->iv, zeros, WOLFSSL_TICKET_IV_SZ) == 0) { WOLFSSL_MSG("User ticket encrypt didn't set iv"); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(&it, sizeof(InternalTicket)); + #endif return BAD_TICKET_ENCRYPT; } /* mac */ if (XMEMCMP(et->mac, zeros, WOLFSSL_TICKET_MAC_SZ) == 0) { WOLFSSL_MSG("User ticket encrypt didn't set mac"); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(&it, sizeof(InternalTicket)); + #endif return BAD_TICKET_ENCRYPT; } @@ -32285,6 +32447,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } } + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(&it, sizeof(InternalTicket)); + #endif return ret; } @@ -32343,6 +32508,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } it = (InternalTicket*)et->enc_ticket; + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Internal ticket successfully decrypted. */ + wc_MemZero_Add("Do Client Ticket internal", it, sizeof(InternalTicket)); + #endif /* get master secret */ if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE) { @@ -32550,6 +32719,15 @@ static int TicketEncCbCtx_Init(WOLFSSL_CTX* ctx, TicketEncCbCtx* keyCtx) XMEMSET(keyCtx, 0, sizeof(*keyCtx)); keyCtx->ctx = ctx; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("TicketEncCbCtx_Init keyCtx->name", keyCtx->name, + sizeof(keyCtx->name)); + wc_MemZero_Add("TicketEncCbCtx_Init keyCtx->key[0]", keyCtx->key[0], + sizeof(keyCtx->key[0])); + wc_MemZero_Add("TicketEncCbCtx_Init keyCtx->key[1]", keyCtx->key[1], + sizeof(keyCtx->key[1])); +#endif + #ifndef SINGLE_THREADED ret = wc_InitMutex(&keyCtx->mutex); #endif @@ -32612,6 +32790,12 @@ static void TicketEncCbCtx_Free(TicketEncCbCtx* keyCtx) ForceZero(keyCtx->key[0], sizeof(keyCtx->key[0])); ForceZero(keyCtx->key[1], sizeof(keyCtx->key[1])); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(keyCtx->name, sizeof(keyCtx->name)); + wc_MemZero_Check(keyCtx->key[0], sizeof(keyCtx->key[0])); + wc_MemZero_Check(keyCtx->key[1], sizeof(keyCtx->key[1])); +#endif + #ifndef SINGLE_THREADED wc_FreeMutex(&keyCtx->mutex); #endif diff --git a/src/keys.c b/src/keys.c index 672f074ed..fa76977fd 100644 --- a/src/keys.c +++ b/src/keys.c @@ -2232,11 +2232,21 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, (ChaCha*)XMALLOC(sizeof(ChaCha), heap, DYNAMIC_TYPE_CIPHER); if (enc && enc->chacha == NULL) return MEMORY_E; + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (enc) { + wc_MemZero_Add("SSL keys enc chacha", enc->chacha, sizeof(ChaCha)); + } + #endif if (dec && dec->chacha == NULL) dec->chacha = (ChaCha*)XMALLOC(sizeof(ChaCha), heap, DYNAMIC_TYPE_CIPHER); if (dec && dec->chacha == NULL) return MEMORY_E; + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (dec) { + wc_MemZero_Add("SSL keys dec chacha", dec->chacha, sizeof(ChaCha)); + } + #endif if (side == WOLFSSL_CLIENT_END) { if (enc) { chachaRet = wc_Chacha_SetKey(enc->chacha, keys->client_write_key, @@ -2822,6 +2832,10 @@ static int SetAuthKeys(OneTimeAuth* authentication, Keys* keys, (Poly1305*)XMALLOC(sizeof(Poly1305), heap, DYNAMIC_TYPE_CIPHER); if (authentication && authentication->poly1305 == NULL) return MEMORY_E; + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SSL auth keys poly1305", authentication->poly1305, + sizeof(Poly1305)); + #endif if (authentication) authentication->setup = 1; #endif diff --git a/src/ssl.c b/src/ssl.c index 40412c777..bfde806dc 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6275,6 +6275,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, FreeDer(&ssl->buffers.key); } ssl->buffers.key = der; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SSL Buffers key", der->buffer, der->length); +#endif ssl->buffers.weOwnKey = 1; } else if (ctx != NULL) { @@ -6283,6 +6286,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } FreeDer(&ctx->privateKey); ctx->privateKey = der; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("CTX private key", der->buffer, der->length); +#endif } } else { @@ -6319,6 +6325,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, info->passwd_userdata); if (ret >= 0) { passwordSz = ret; + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("ProcessBuffer password", password, passwordSz); + #endif /* PKCS8 decrypt */ ret = ToTraditionalEnc(der->buffer, der->length, @@ -6334,6 +6343,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #ifdef WOLFSSL_SMALL_STACK XFREE(password, heap, DYNAMIC_TYPE_STRING); + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(password, NAME_SZ); #endif ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx, &resetSuites, &keyFormat, heap, devId); @@ -11701,6 +11712,11 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } ssl->buffers.dtlsCookieSecret.buffer = newSecret; ssl->buffers.dtlsCookieSecret.length = secretSz; + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wolfSSL_DTLS_SetCookieSecret secret", + ssl->buffers.dtlsCookieSecret.buffer, + ssl->buffers.dtlsCookieSecret.length); + #endif } /* If the supplied secret is NULL, randomly generate a new secret. */ @@ -19469,6 +19485,10 @@ WOLFSSL_SESSION* wolfSSL_NewSession(void* heap) ret->type = WOLFSSL_SESSION_TYPE_HEAP; ret->heap = heap; ret->masterSecret = ret->_masterSecret; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SESSION master secret", ret->masterSecret, SECRET_LEN); + wc_MemZero_Add("SESSION id", ret->sessionID, ID_LEN); +#endif #ifndef NO_CLIENT_CACHE ret->serverID = ret->_serverID; #endif @@ -36754,6 +36774,10 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio, XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL); return NULL; } + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wolfSSL_d2i_PKCS8PrivateKey_bio password", password, + passwordSz); + #endif ret = ToTraditionalEnc(der, len, password, passwordSz, &algId); if (ret < 0) { @@ -36762,6 +36786,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio, } ForceZero(password, passwordSz); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(password, passwordSz); + #endif } p = der; @@ -37798,6 +37825,10 @@ int wolfSSL_RAND_write_file(const char* fname) else { XFILE f; + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wolfSSL_RAND_write_file buf", buf, bytes); + #endif + f = XFOPEN(fname, "wb"); if (f == XBADFILE) { WOLFSSL_MSG("Error opening the file"); @@ -37811,6 +37842,8 @@ int wolfSSL_RAND_write_file(const char* fname) ForceZero(buf, bytes); #ifdef WOLFSSL_SMALL_STACK XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(buf, sizeof(buf)); #endif } #endif @@ -37878,6 +37911,11 @@ int wolfSSL_RAND_egd(const char* nm) ret = WOLFSSL_FATAL_ERROR; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + if (ret == WOLFSSL_SUCCESS) { + wc_MemZero_Add("wolfSSL_RAND_egd buf", buf, 256); + } +#endif while (ret == WOLFSSL_SUCCESS && bytes < 255 && idx + 2 < 256) { buf[idx] = WOLFSSL_EGD_NBLOCK; buf[idx + 1] = 255 - bytes; /* request 255 bytes from server */ @@ -37956,9 +37994,11 @@ int wolfSSL_RAND_egd(const char* nm) } ForceZero(buf, bytes); - #ifdef WOLFSSL_SMALL_STACK +#ifdef WOLFSSL_SMALL_STACK XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(buf, 256); +#endif close(fd); if (ret == WOLFSSL_SUCCESS) { diff --git a/src/tls.c b/src/tls.c index 8f9baf753..67ba488eb 100644 --- a/src/tls.c +++ b/src/tls.c @@ -157,6 +157,9 @@ int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen) } *hashLen = hashSz; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("TLS hasndshake hash", hash, hashSz); +#endif if (ret != 0) ret = BUILD_MSG_ERROR; @@ -226,6 +229,8 @@ int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH) WC_FREE_VAR(handshake_hash, ssl->heap); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(handshake_hash, HSHASH_SZ); #endif return ret; @@ -530,6 +535,8 @@ int MakeTlsMasterSecret(WOLFSSL* ssl) #ifdef WOLFSSL_SMALL_STACK XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST); + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(handshake_hash, HSHASH_SZ); #endif } else diff --git a/src/tls13.c b/src/tls13.c index 1ea3d0794..15936fa3e 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -352,6 +352,10 @@ int Tls13DeriveKey(WOLFSSL* ssl, byte* output, int outputLen, hash, hashOutSz, digestAlg); #endif PRIVATE_KEY_LOCK(); + +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("TLS 1.3 derived key", output, outputLen); +#endif return ret; PRAGMA_GCC_DIAG_POP; } @@ -1299,6 +1303,8 @@ end: ForceZero(key_dig, i); #ifdef WOLFSSL_SMALL_STACK XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key_dig, MAX_PRF_DIG); #endif return ret; @@ -1811,6 +1817,9 @@ static int ChaCha20Poly1305_Encrypt(WOLFSSL* ssl, byte* output, ret = wc_Chacha_Process(ssl->encrypt.chacha, poly, poly, sizeof(poly)); if (ret != 0) return ret; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("ChaCha20Poly1305_Encrypt poly", poly, sizeof(poly)); +#endif ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 1); if (ret != 0) return ret; @@ -1818,12 +1827,18 @@ static int ChaCha20Poly1305_Encrypt(WOLFSSL* ssl, byte* output, ret = wc_Chacha_Process(ssl->encrypt.chacha, output, input, sz); if (ret != 0) { ForceZero(poly, sizeof(poly)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, sizeof(poly)); + #endif return ret; } /* Set key for Poly1305. */ ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, sizeof(poly)); ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */ +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, sizeof(poly)); +#endif if (ret != 0) return ret; /* Add authentication code of encrypted data to end. */ @@ -1929,9 +1944,16 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, #endif #ifdef CIPHER_NONCE - if (ssl->encrypt.nonce == NULL) + if (ssl->encrypt.nonce == NULL) { ssl->encrypt.nonce = (byte*)XMALLOC(AEAD_NONCE_SZ, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (ssl->encrypt.nonce != NULL) { + wc_MemZero_Add("EncryptTls13 nonce", ssl->encrypt.nonce, + AEAD_NONCE_SZ); + } + #endif + } if (ssl->encrypt.nonce == NULL) return MEMORY_E; @@ -2064,6 +2086,12 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, ForceZero(ssl->encrypt.sanityCheck, sizeof(ssl->encrypt.sanityCheck)); #endif + #ifdef WOLFSSL_CHECK_MEM_ZERO + if ((ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null) && + (output != input) && (ret == 0)) { + wc_MemZero_Add("TLS 1.3 Encrypt plaintext", input, sz); + } + #endif #ifdef CIPHER_NONCE ForceZero(ssl->encrypt.nonce, AEAD_NONCE_SZ); @@ -2076,6 +2104,7 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, break; } + /* Reset state */ ssl->encrypt.state = CIPHER_STATE_BEGIN; @@ -2116,15 +2145,24 @@ static int ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output, ret = wc_Chacha_Process(ssl->decrypt.chacha, poly, poly, sizeof(poly)); if (ret != 0) return ret; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("ChaCha20Poly1305_Decrypt poly", poly, sizeof(poly)); +#endif ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 1); if (ret != 0) { ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */ + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, sizeof(poly)); + #endif return ret; } /* Set key for Poly1305. */ ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, sizeof(poly)); ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */ +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(poly, sizeof(poly)); +#endif if (ret != 0) return ret; /* Generate authentication tag for encrypted data. */ @@ -2249,9 +2287,16 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz, #endif #ifdef CIPHER_NONCE - if (ssl->decrypt.nonce == NULL) + if (ssl->decrypt.nonce == NULL) { ssl->decrypt.nonce = (byte*)XMALLOC(AEAD_NONCE_SZ, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (ssl->decrypt.nonce != NULL) { + wc_MemZero_Add("DecryptTls13 nonce", ssl->decrypt.nonce, + AEAD_NONCE_SZ); + } + #endif + } if (ssl->decrypt.nonce == NULL) return MEMORY_E; @@ -2353,6 +2398,12 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz, WOLFSSL_MSG("Decrypted data"); WOLFSSL_BUFFER(output, dataSz); #endif + #ifdef WOLFSSL_CHECK_MEM_ZERO + if ((ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null) && + (ret == 0)) { + wc_MemZero_Add("TLS 1.3 Decrypted data", output, sz); + } + #endif #ifdef CIPHER_NONCE ForceZero(ssl->decrypt.nonce, AEAD_NONCE_SZ); @@ -3096,6 +3147,12 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx) return ret; current = (PreSharedKey*)ext->data; +#ifdef WOLFSSL_CHECK_MEM_ZERO + if (current != NULL) { + wc_MemZero_Add("WritePSKBinders binderKey", binderKey, + sizeof(binderKey)); + } +#endif /* Calculate the binder for each identity based on previous handshake data. */ while (current != NULL) { @@ -3129,6 +3186,9 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx) } ForceZero(binderKey, sizeof(binderKey)); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(binderKey, sizeof(binderKey)); +#endif if (ret != 0) return ret; @@ -9777,6 +9837,11 @@ int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret, } ssl->buffers.tls13CookieSecret.buffer = newSecret; ssl->buffers.tls13CookieSecret.length = secretSz; + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wolfSSL_send_hrr_cookie secret", + ssl->buffers.tls13CookieSecret.buffer, + ssl->buffers.tls13CookieSecret.length); + #endif } /* If the supplied secret is NULL, randomly generate a new secret. */ diff --git a/tests/api.c b/tests/api.c index efda40247..c8112ad3e 100644 --- a/tests/api.c +++ b/tests/api.c @@ -19107,6 +19107,10 @@ static int test_wc_RsaKeyToDer (void) /* Try Public Key. */ genKey.type = 0; ret = wc_RsaKeyToDer(&genKey, der, FOURK_BUF); + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Put back to Private Key */ + genKey.type = 1; + #endif } if (ret == BAD_FUNC_ARG) { ret = 0; @@ -19126,6 +19130,10 @@ static int test_wc_RsaKeyToDer (void) /* Try Public Key. */ genKey.type = 0; ret = wc_RsaKeyToDer(&genKey, der, FOURK_BUF); + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Put back to Private Key */ + genKey.type = 1; + #endif } if (ret == USER_CRYPTO_ERROR) { ret = 0; diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 2151812a7..f9e5cfec0 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2983,6 +2983,9 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \ defined(WOLFSSL_AES_128) case 16: + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp)); + #endif while (1) { temp = rk[3]; @@ -3012,6 +3015,9 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \ defined(WOLFSSL_AES_192) case 24: + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp)); + #endif /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */ while (1) { @@ -3044,6 +3050,9 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \ defined(WOLFSSL_AES_256) case 32: + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp)); + #endif while (1) { temp = rk[ 7]; @@ -3154,6 +3163,9 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( #endif #ifdef WOLFSSL_IMX6_CAAM_BLOB ForceZero(local, sizeof(local)); + #endif + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(&temp, sizeof(temp)); #endif return ret; } @@ -4448,6 +4460,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv) sz--; } + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch, AES_BLOCK_SIZE); + #endif /* do as many block size ops as possible */ while (sz >= AES_BLOCK_SIZE) { #ifdef XTRANSFORM_AESCTRBLOCK @@ -4456,6 +4471,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv) ret = wc_AesEncrypt(aes, (byte*)aes->reg, scratch); if (ret != 0) { ForceZero(scratch, AES_BLOCK_SIZE); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(scratch, AES_BLOCK_SIZE); + #endif return ret; } xorbuf(scratch, in, AES_BLOCK_SIZE); @@ -4475,6 +4493,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv) ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp); if (ret != 0) { ForceZero(scratch, AES_BLOCK_SIZE); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(scratch, AES_BLOCK_SIZE); + #endif return ret; } IncrementAesCounter((byte*)aes->reg); @@ -4488,6 +4509,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv) } } + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(scratch, AES_BLOCK_SIZE); + #endif return 0; } @@ -10193,17 +10217,31 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B)); +#endif + ret = wc_AesEncrypt(aes, B, A); if (ret != 0) { ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A)); +#endif if (authInSz > 0) { ret = roll_auth(aes, authIn, authInSz, A); if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } } @@ -10212,6 +10250,10 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } } @@ -10224,6 +10266,10 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } xorbuf(authTag, A, authTagSz); @@ -10255,6 +10301,10 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } xorbuf(A, in, AES_BLOCK_SIZE); @@ -10270,6 +10320,10 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } xorbuf(A, in, inSz); @@ -10279,6 +10333,11 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); +#endif + return 0; } @@ -10336,6 +10395,11 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, B[AES_BLOCK_SIZE - 1 - i] = 0; B[15] = 1; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A)); + wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B)); +#endif + #ifdef WOLFSSL_AESNI if (haveAESNI && aes->use_aesni) { SAVE_VECTOR_REGISTERS(return _svr_ret;); @@ -10362,6 +10426,10 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } xorbuf(A, in, AES_BLOCK_SIZE); @@ -10377,6 +10445,10 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } xorbuf(A, in, oSz); @@ -10389,6 +10461,10 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } @@ -10408,6 +10484,10 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } @@ -10416,6 +10496,10 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } } @@ -10424,6 +10508,10 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } } @@ -10435,6 +10523,10 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (ret != 0) { ForceZero(A, sizeof(A)); ForceZero(B, sizeof(B)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); + #endif return ret; } xorbuf(A, B, authTagSz); @@ -10457,6 +10549,11 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, ForceZero(B, sizeof(B)); o = NULL; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(A, sizeof(A)); + wc_MemZero_Check(B, sizeof(B)); +#endif + return ret; } @@ -10698,6 +10795,9 @@ void wc_AesFree(Aes* aes) wc_psa_aes_free(aes); #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(aes, sizeof(Aes)); +#endif } @@ -12148,6 +12248,12 @@ static WARN_UNUSED_RESULT int S2V( if (ret == 0) #endif { + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Aes part is checked by wc_AesFree. */ + wc_MemZero_Add("wc_AesCmacGenerate cmac", + ((unsigned char *)cmac) + sizeof(Aes), + sizeof(Cmac) - sizeof(Aes)); + #endif xorbuf(tmp[0], data + (dataSz - AES_BLOCK_SIZE), AES_BLOCK_SIZE); ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL); @@ -12165,6 +12271,8 @@ static WARN_UNUSED_RESULT int S2V( if (cmac != NULL) { XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC); } + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(cmac, sizeof(Cmac)); #endif } else { diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 824736503..59b7a66e7 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5597,6 +5597,18 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, key->type = RSA_PRIVATE; +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("Decode RSA key d", &key->d); + mp_memzero_add("Decode RSA key p", &key->p); + mp_memzero_add("Decode RSA key q", &key->q); +#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \ + !defined(RSA_LOW_MEM)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) + mp_memzero_add("Decode RSA key dP", &key->dP); + mp_memzero_add("Decode RSA key dQ", &key->dQ); + mp_memzero_add("Decode RSA key u", &key->u); +#endif +#endif + if (GetInt(&key->n, input, inOutIdx, inSz) < 0 || GetInt(&key->e, input, inOutIdx, inSz) < 0 || #ifndef WOLFSSL_RSA_PUBLIC_ONLY @@ -6247,6 +6259,9 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz)) == 0) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_CheckPrivateKey privDer", privDer, privSz); + #endif wc_ecc_free(key_pair); ret = wc_ecc_init(key_pair); if (ret == 0) { @@ -6270,6 +6285,8 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, #ifdef WOLFSSL_SMALL_STACK XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC); + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(privDer, MAX_ECC_BYTES); #endif } else @@ -7142,6 +7159,11 @@ int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz, ret = 0; } } +#ifdef WOLFSSL_CHECK_MEM_ZERO + if (ret == 0) { + wc_MemZero_Add("TraditionalEnc pkcs8Key", pkcs8Key, pkcs8KeySz); + } +#endif if (ret == 0) { ret = wc_EncryptPKCS8Key(pkcs8Key, pkcs8KeySz, out, outSz, password, passwordSz, vPKCS, vAlgo, encAlgId, salt, saltSz, itt, rng, heap); @@ -20295,6 +20317,9 @@ int PemToDer(const unsigned char* buff, long longSz, int type, info->passwd_userdata); if (ret >= 0) { passwordSz = ret; + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("PEM password", password, passwordSz); + #endif /* convert and adjust length */ if (header == BEGIN_ENC_PRIV_KEY) { @@ -20381,6 +20406,8 @@ int PemToDer(const unsigned char* buff, long longSz, int type, #ifdef WOLFSSL_SMALL_STACK XFREE(password, heap, DYNAMIC_TYPE_STRING); + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(password, NAME_SZ); #endif } #endif /* WOLFSSL_ENCRYPTED_KEYS */ diff --git a/wolfcrypt/src/chacha20_poly1305.c b/wolfcrypt/src/chacha20_poly1305.c index 5ec856e99..26b75f74f 100644 --- a/wolfcrypt/src/chacha20_poly1305.c +++ b/wolfcrypt/src/chacha20_poly1305.c @@ -383,6 +383,11 @@ static WC_INLINE int wc_XChaCha20Poly1305_crypt_oneshot( key, (word32)key_len, 1)) < 0) goto out; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_XChaCha20Poly1305_crypt_oneshot aead", aead, + sizeof(ChaChaPoly_Aead)); +#endif + /* process the input in 16k pieces to accommodate src_lens that don't fit in a word32, * and to exploit hot cache for the input data. */ @@ -439,6 +444,8 @@ static WC_INLINE int wc_XChaCha20Poly1305_crypt_oneshot( #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) XFREE(aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(aead, sizeof(ChaChaPoly_Aead)); #endif return ret; diff --git a/wolfcrypt/src/cmac.c b/wolfcrypt/src/cmac.c index b5121d40b..aa80fef6d 100644 --- a/wolfcrypt/src/cmac.c +++ b/wolfcrypt/src/cmac.c @@ -278,6 +278,11 @@ int wc_AesCmacGenerate(byte* out, word32* outSz, return MEMORY_E; } #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + /* Aes part is checked by wc_AesFree. */ + wc_MemZero_Add("wc_AesCmacGenerate cmac", + ((unsigned char *)cmac) + sizeof(Aes), sizeof(Cmac) - sizeof(Aes)); +#endif ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL); if (ret == 0) { @@ -291,6 +296,8 @@ int wc_AesCmacGenerate(byte* out, word32* outSz, if (cmac) { XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC); } +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(cmac, sizeof(Cmac)); #endif return ret; diff --git a/wolfcrypt/src/curve25519.c b/wolfcrypt/src/curve25519.c index 16d6074e0..9f6423499 100644 --- a/wolfcrypt/src/curve25519.c +++ b/wolfcrypt/src/curve25519.c @@ -665,6 +665,10 @@ int wc_curve25519_init_ex(curve25519_key* key, void* heap, int devId) fe_init(); #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_curve25519_init_ex key->k", key->k, CURVE25519_KEYSIZE); +#endif + return 0; } @@ -688,6 +692,9 @@ void wc_curve25519_free(curve25519_key* key) XMEMSET(&key->p, 0, sizeof(key->p)); key->pubSet = 0; key->privSet = 0; +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(key, sizeof(curve25519_key)); +#endif } /* get key size */ diff --git a/wolfcrypt/src/curve448.c b/wolfcrypt/src/curve448.c index 6a084f134..19d45fdc8 100644 --- a/wolfcrypt/src/curve448.c +++ b/wolfcrypt/src/curve448.c @@ -684,6 +684,10 @@ int wc_curve448_init(curve448_key* key) XMEMSET(key, 0, sizeof(*key)); fe448_init(); + + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_curve448_init key->k", &key->k, CURVE448_KEY_SIZE); + #endif } return ret; @@ -701,6 +705,9 @@ void wc_curve448_free(curve448_key* key) XMEMSET(key->p, 0, sizeof(key->p)); key->pubSet = 0; key->privSet = 0; + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(key, sizeof(curve448_key)); + #endif } } diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index 917b49f9d..7df0622f9 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -1870,6 +1870,10 @@ int wc_Des3Init(Des3* des3, void* heap, int devId) ret = wolfAsync_DevCtxInit(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES, des3->heap, devId); #endif +#if defined(WOLFSSL_CHECK_MEM_ZERO) && (defined(WOLF_CRYPTO_CB) || \ + (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))) + wc_MemZero_Add("DES3 devKey", &des3->devKey, sizeof(des3->devKey)); +#endif return ret; } @@ -1887,6 +1891,9 @@ void wc_Des3Free(Des3* des3) (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) ForceZero(des3->devKey, sizeof(des3->devKey)); #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(des3, sizeof(Des3)); +#endif } #endif /* WOLFSSL_TI_CRYPT */ diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index fecddfdff..24cd6d2bc 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -1134,6 +1134,10 @@ static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv, return err; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("GeneratePrivateDh186 cBuf", cBuf, cSz); + mp_memzero_add("GeneratePrivateDh186 tmpX", tmpX); +#endif do { /* generate N+64 bits (c) from RBG into tmpX, making sure positive. * Hash_DRBG uses SHA-256 which matches maximum @@ -1194,6 +1198,8 @@ static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv, #ifdef WOLFSSL_SMALL_STACK XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH); XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + mp_memzero_check(tmpX); #endif return err; @@ -1721,6 +1727,9 @@ int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz, } if (ret == 0) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("wc_DhCheckPrivKey_ex x", x); + #endif if (prime != NULL) { if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY) ret = MP_READ_E; @@ -1759,6 +1768,8 @@ int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz, #ifdef WOLFSSL_SMALL_STACK XFREE(q, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + mp_memzero_check(x); #endif return ret; @@ -1837,6 +1848,9 @@ static int _ffc_pairwise_consistency_test(DhKey* key, ret = MP_READ_E; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("_ffc_pairwise_consistency_test privateKey", privateKey); +#endif /* Calculate checkKey = g^privateKey mod p */ if (ret == 0) { @@ -1892,6 +1906,8 @@ static int _ffc_pairwise_consistency_test(DhKey* key, XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH); XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + mp_memzero_check(privateKey); #endif return ret; @@ -2096,12 +2112,20 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) ret = MP_READ_E; +#ifdef WOLFSSL_CHECK_MEM_ZERO + if (ret == 0) + mp_memzero_add("wc_DhAgree_Sync x", x); +#endif if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) ret = MP_READ_E; if (ret == 0 && mp_exptmod(y, x, &key->p, z) != MP_OKAY) ret = MP_EXPTMOD_E; +#ifdef WOLFSSL_CHECK_MEM_ZERO + if (ret == 0) + mp_memzero_add("wc_DhAgree_Sync z", z); +#endif /* make sure z is not one (SP800-56A, 5.7.1.1) */ if (ret == 0 && (mp_cmp_d(z, 1) == MP_EQ)) @@ -2129,6 +2153,9 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif XFREE(y, key->heap, DYNAMIC_TYPE_DH); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + mp_memzero_check(x); + mp_memzero_check(z); #endif return ret; @@ -2242,6 +2269,9 @@ WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst) WOLFSSL_MSG("mp_copy error"); return ret; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("wc_DhKeyCopy dst->priv", &dst->priv); +#endif dst->heap = src->heap; @@ -2282,6 +2312,9 @@ int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz, havePriv = 0; } else { WOLFSSL_MSG("DH Private Key Set"); + #ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("wc_DhImportKeyPair key->priv", &key->priv); + #endif } } diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index e7f2bba48..bb547a1e3 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4418,6 +4418,12 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point, #endif } if (err == MP_OKAY) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x", + result->x); + mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y", + result->y); + #endif err = mp_montgomery_setup(curve->prime, &mp); } if (err == MP_OKAY) { @@ -4775,6 +4781,9 @@ int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order) /* make up random string */ err = wc_RNG_GenerateBlock(rng, buf, size); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_ecc_gen_k buf", buf, size); +#endif /* load random buffer data into k */ if (err == 0) @@ -4794,6 +4803,9 @@ int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order) } ForceZero(buf, ECC_MAXSIZE_GEN); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(buf, ECC_MAXSIZE_GEN); +#endif return err; #else @@ -5489,6 +5501,10 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) key->keyId = -1; #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("ECC k", &key->k); +#endif + return ret; } @@ -5926,7 +5942,7 @@ static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key) DYNAMIC_TYPE_ECC); } - if (key->sign_k) { + if (key->sign_k != NULL) { /* currently limiting to SHA256 for auto create */ if (mp_init(key->sign_k) != MP_OKAY || wc_ecc_gen_deterministic_k(in, inlen, @@ -5937,6 +5953,11 @@ static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key) key->sign_k = NULL; err = ECC_PRIV_KEY_E; } + #ifdef WOLFSSL_CHECK_MEM_ZERO + else { + mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k); + } + #endif } else { err = MEMORY_E; @@ -6001,6 +6022,11 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng, while (err == MP_ZERO_E); loop_check = 0; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + if (err == MP_OKAY) { + mp_memzero_add("ecc_sign_hash_sw b", b); + } +#endif for (; err == MP_OKAY;) { if (++loop_check > 64) { @@ -6046,6 +6072,11 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng, err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id, WC_ECC_FLAG_NONE); } + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (err == MP_OKAY) { + mp_memzero_add("ecc_sign_hash_sw k", &pubkey->k); + } + #endif #ifdef WOLFSSL_ASYNC_CRYPT /* for async do blocking wait here */ err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE); @@ -6112,6 +6143,8 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng, mp_forcezero(b); #ifdef WOLFSSL_SMALL_STACK XFREE(b, key->heap, DYNAMIC_TYPE_ECC); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + mp_memzero_check(b); #endif return err; @@ -6633,6 +6666,9 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, mp_init(z1); /* always init z1 and free z1 */ ret = mp_to_unsigned_bin_len(priv, x, qLen); if (ret == 0) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen); + #endif qbits = mp_count_bits(order); ret = mp_read_unsigned_bin(z1, hash, hashSz); } @@ -6766,6 +6802,8 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER); if (h1 != NULL) XFREE(h1, heap, DYNAMIC_TYPE_DIGEST); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(x, MAX_ECC_BYTES); #endif return ret; @@ -6916,6 +6954,10 @@ int wc_ecc_free(ecc_key* key) wc_ecc_free_curve(key->dp, key->heap); #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(key, sizeof(ecc_key)); +#endif + return 0; } @@ -7145,6 +7187,10 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, #else XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ); #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE); + wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE); +#endif /* get sizes */ lenA = mp_unsigned_bin_size(kA); @@ -7353,6 +7399,9 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, #ifndef WOLFSSL_NO_MALLOC XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER); XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(tB, ECC_BUFSIZE); + wc_MemZero_Check(tA, ECC_BUFSIZE); #endif return err; } @@ -11259,6 +11308,10 @@ static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a, if ((err = mp_copy(k, tk)) != MP_OKAY) goto done; +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("accel_fp_mul tk", tk); +#endif + /* if it's smaller than modulus we fine */ if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) { /* find order */ @@ -11306,6 +11359,9 @@ static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a, XMEMSET(kb, 0, KB_SIZE); if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE); + #endif /* let's reverse kb so it's little endian */ x = 0; y = mp_unsigned_bin_size(tk); @@ -11377,6 +11433,9 @@ done: XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER); XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER); XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(kb, KB_SIZE); + mp_memzero_check(tk); #endif #undef KB_SIZE @@ -11460,6 +11519,9 @@ static int accel_fp_mul2add(int idx1, int idx2, goto done; } } +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("accel_fp_mul2add tka", tka); +#endif /* if it's smaller than modulus we fine */ if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { @@ -11492,6 +11554,9 @@ static int accel_fp_mul2add(int idx1, int idx2, goto done; } } +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("accel_fp_mul2add tkb", tkb); +#endif /* get bitlen and round up to next multiple of FP_LUT */ bitlen = mp_unsigned_bin_size(modulus) << 3; @@ -11519,6 +11584,9 @@ static int accel_fp_mul2add(int idx1, int idx2, if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) { goto done; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE); +#endif /* let's reverse kb so it's little endian */ x = 0; @@ -11541,6 +11609,9 @@ static int accel_fp_mul2add(int idx1, int idx2, #endif XMEMSET(kb[1], 0, KB_SIZE); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE); +#endif if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) { x = 0; y = mp_unsigned_bin_size(tkb); @@ -11639,6 +11710,11 @@ done: XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER); XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER); XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(kb[1], KB_SIZE); + wc_MemZero_Check(kb[0], KB_SIZE); + mp_memzero_check(tkb); + mp_memzero_check(tka); #endif #undef KB_SIZE diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index e89e82e56..a68089e21 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -870,6 +870,10 @@ int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId) fe_init(); #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_ed25519_init_ex key->k", &key->k, sizeof(key->k)); +#endif + #ifdef WOLFSSL_ED25519_PERSISTENT_SHA return ed25519_hash_init(key, &key->sha); #else /* !WOLFSSL_ED25519_PERSISTENT_SHA */ @@ -897,6 +901,9 @@ void wc_ed25519_free(ed25519_key* key) #endif ForceZero(key, sizeof(ed25519_key)); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(key, sizeof(ed25519_key)); +#endif } diff --git a/wolfcrypt/src/ed448.c b/wolfcrypt/src/ed448.c index 2a2c41e59..ea092d18b 100644 --- a/wolfcrypt/src/ed448.c +++ b/wolfcrypt/src/ed448.c @@ -814,6 +814,10 @@ int wc_ed448_init_ex(ed448_key* key, void *heap, int devId) fe448_init(); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_ed448_init_ex key->k", &key->k, sizeof(key->k)); +#endif + #ifdef WOLFSSL_ED448_PERSISTENT_SHA return ed448_hash_init(key, &key->sha); #else /* !WOLFSSL_ED448_PERSISTENT_SHA */ @@ -841,6 +845,9 @@ void wc_ed448_free(ed448_key* key) ed448_hash_free(key, &key->sha); #endif ForceZero(key, sizeof(ed448_key)); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(key, sizeof(ed448_key)); + #endif } } diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 18b02c16f..8387ec21d 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -100,6 +100,12 @@ int wc_PRF(byte* result, word32 resLen, const byte* secret, } #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_PRF previous", previous, P_HASH_MAX_SIZE); + wc_MemZero_Add("wc_PRF current", current, P_HASH_MAX_SIZE); + wc_MemZero_Add("wc_PRF hmac", hmac, sizeof(Hmac)); +#endif + switch (hash) { #ifndef NO_MD5 case md5_mac: @@ -197,6 +203,10 @@ int wc_PRF(byte* result, word32 resLen, const byte* secret, XFREE(previous, heap, DYNAMIC_TYPE_DIGEST); XFREE(current, heap, DYNAMIC_TYPE_DIGEST); XFREE(hmac, heap, DYNAMIC_TYPE_HMAC); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(previous, P_HASH_MAX_SIZE); + wc_MemZero_Check(current, P_HASH_MAX_SIZE); + wc_MemZero_Check(hmac, sizeof(Hmac)); #endif return ret; @@ -258,6 +268,9 @@ int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret, labLen + seedLen, md5_mac, heap, devId)) == 0) { if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed, labLen + seedLen, sha_mac, heap, devId)) == 0) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_PRF_TLSv1 sha_result", sha_result, digLen); + #endif /* calculate XOR for TLSv1 PRF */ /* md5 result is placed directly in digest */ xorbuf(digest, sha_result, digLen); @@ -267,6 +280,8 @@ int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret, #ifdef WOLFSSL_SMALL_STACK XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(sha_result, MAX_PRF_DIG); #endif #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH) @@ -434,6 +449,10 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, XMEMCPY(&data[idx], info, infoLen); idx += infoLen; + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx); + #endif + #ifdef WOLFSSL_DEBUG_TLS WOLFSSL_MSG(" PRK"); WOLFSSL_BUFFER(prk, prkLen); @@ -450,6 +469,9 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, ForceZero(data, idx); + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(data, MAX_TLS13_HKDF_LABEL_SZ); + #endif return ret; } diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 8a0c8408e..b4d77a70b 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -120,6 +120,147 @@ int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf, } #ifndef WOLFSSL_STATIC_MEMORY +#ifdef WOLFSSL_CHECK_MEM_ZERO + +#ifndef WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN +/* Number of entries in table of addresses to check. */ +#define WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN 256 +#endif + +/* Alignment to maintain when adding length to allocated pointer. + * Intel x64 wants to use aligned loads of XMM registers. + */ +#define MEM_ALIGN 16 + +/* An address that is meant to be all zeros for its length. */ +typedef struct MemZero { + /* Name of address to check. */ + const char* name; + /* Address to check. */ + const void* addr; + /* Length of data that must be zero. */ + size_t len; +} MemZero; + +/* List of addresses to check. */ +static MemZero memZero[WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN]; +/* Next index to place address at. + * -1 indicates uninitialized. + * If nextIdx is equal to WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN then all entries + * have been used. + */ +static int nextIdx = -1; +/* Mutex to protect modifying list of addresses to check. */ +static wolfSSL_Mutex zeroMutex; + +/* Initialize the table of addresses and the mutex. + */ +void wc_MemZero_Init() +{ + /* Clear the table to more easily see what is valid. */ + XMEMSET(memZero, 0, sizeof(memZero)); + /* Initialize mutex. */ + wc_InitMutex(&zeroMutex); + /* Next index is first entry. */ + nextIdx = 0; +} + +/* Free the mutex and check we have not any uncheck addresses. + */ +void wc_MemZero_Free() +{ + /* Free mutex. */ + wc_FreeMutex(&zeroMutex); + /* Make sure we checked all addresses. */ + if (nextIdx > 0) { + int i; + fprintf(stderr, "[MEM_ZERO] Unseen: %d\n", nextIdx); + for (i = 0; i < nextIdx; i++) { + fprintf(stderr, " %s - %p:%ld\n", memZero[i].name, memZero[i].addr, + memZero[i].len); + } + } + /* Uninitialized value in next index. */ + nextIdx = -1; +} + +/* Add an address to check. + * + * @param [in] name Name of address to check. + * @param [in] addr Address that needs to be checked. + * @param [in] len Length of data that must be zero. + */ +void wc_MemZero_Add(const char* name, const void* addr, size_t len) +{ + /* Initialize if not done. */ + if (nextIdx == -1) { + wc_MemZero_Init(); + } + + /* Add an entry to the table while locked. */ + wc_LockMutex(&zeroMutex); + if (nextIdx < WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN) { + /* Fill in the next entry and update next index. */ + memZero[nextIdx].name = name; + memZero[nextIdx].addr = addr; + memZero[nextIdx].len = len; + nextIdx++; + } + else { + /* Abort when too many entries. */ + fprintf(stderr, "\n[MEM_ZERO] Too many addresses to check\n"); + fprintf(stderr, "[MEM_ZERO] WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN\n"); + abort(); + } + wc_UnLockMutex(&zeroMutex); +} + +/* Check the memory in the range of the address for memory that must be zero. + * + * @param [in] addr Start address of memory that is to be checked. + * @param [in] len Length of data associated with address. + */ +void wc_MemZero_Check(void* addr, size_t len) +{ + int i; + size_t j; + + wc_LockMutex(&zeroMutex); + /* Look at each address for overlap with address passes in. */ + for (i = 0; i < nextIdx; i++) { + if ((memZero[i].addr < addr) || + ((size_t)memZero[i].addr >= (size_t)addr + len)) { + /* Check address not part of memory to check. */ + continue; + } + + /* Address is in range of memory being freed - check each byte zero. */ + for (j = 0; j < memZero[i].len; j++) { + if (((unsigned char*)memZero[i].addr)[j] != 0) { + /* Byte not zero - abort! */ + fprintf(stderr, "\n[MEM_ZERO] %s:%p + %ld is not zero\n", + memZero[i].name, memZero[i].addr, j); + fprintf(stderr, "[MEM_ZERO] Checking %p:%ld\n", addr, len); + abort(); + break; + } + } + /* Update next index to write to. */ + nextIdx--; + if (nextIdx > 0) { + /* Remove entry. */ + XMEMCPY(memZero + i, memZero + i + 1, + sizeof(MemZero) * (nextIdx - i)); + /* Clear out top to make it easier to see what is to be checked. */ + XMEMSET(&memZero[nextIdx], 0, sizeof(MemZero)); + } + /* Need to check this index again with new data. */ + i--; + } + wc_UnLockMutex(&zeroMutex); +} +#endif /* WOLFSSL_CHECK_MEM_ZERO */ + #ifdef WOLFSSL_DEBUG_MEMORY void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line) #else @@ -128,6 +269,11 @@ void* wolfSSL_Malloc(size_t size) { void* res = 0; +#ifdef WOLFSSL_CHECK_MEM_ZERO + /* Space for requested size. */ + size += MEM_ALIGN; +#endif + if (malloc_function) { #ifdef WOLFSSL_DEBUG_MEMORY res = malloc_function(size, func, line); @@ -150,6 +296,16 @@ void* wolfSSL_Malloc(size_t size) #endif } +#ifdef WOLFSSL_CHECK_MEM_ZERO + /* Restore size to requested value. */ + size -= MEM_ALIGN; + if (res != NULL) { + /* Place size at front of allocated data and move pointer passed it. */ + *(size_t*)res = size; + res = ((unsigned char*)res) + MEM_ALIGN; + } +#endif + #ifdef WOLFSSL_DEBUG_MEMORY #if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY) fprintf(stderr, "Alloc: %p -> %u at %s:%u\n", res, (word32)size, func, line); @@ -200,6 +356,13 @@ void wolfSSL_Free(void *ptr) #endif #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + /* Move pointer back to originally allocated pointer. */ + ptr = ((unsigned char*)ptr) - MEM_ALIGN; + /* Check that the pointer is zero where required. */ + wc_MemZero_Check(((unsigned char*)ptr) + MEM_ALIGN, *(size_t*)ptr); +#endif + if (free_function) { #ifdef WOLFSSL_DEBUG_MEMORY free_function(ptr, func, line); @@ -222,6 +385,33 @@ void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int lin void* wolfSSL_Realloc(void *ptr, size_t size) #endif { +#ifdef WOLFSSL_CHECK_MEM_ZERO + /* Can't check data that has been freed during realloc. + * Manually allocated new memory, copy data and free original pointer. + */ +#ifdef WOLFSSL_DEBUG_MEMORY + void* res = wolfSSL_Malloc(size, func, line); +#else + void* res = wolfSSL_Malloc(size); +#endif + if (ptr != NULL) { + /* Copy the minimum of old and new size. */ + size_t copySize = *(size_t*)(((unsigned char*)ptr) - MEM_ALIGN); + if (size < copySize) { + copySize = size; + } + XMEMCPY(res, ptr, copySize); + /* Dispose of old pointer. */ + #ifdef WOLFSSL_DEBUG_MEMORY + wolfSSL_Free(ptr, func, line); + #else + wolfSSL_Free(ptr); + #endif + } + + /* Return new pointer with data copied into it. */ + return res; +#else void* res = 0; if (realloc_function) { @@ -240,6 +430,7 @@ void* wolfSSL_Realloc(void *ptr, size_t size) } return res; +#endif } #endif /* WOLFSSL_STATIC_MEMORY */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index fa688143e..03f5167cc 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -891,6 +891,14 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, ret = DRBG_CONT_FAILURE; if (ret == DRBG_SUCCESS) { +#ifdef WOLFSSL_CHECK_MEM_ZERO +#ifdef HAVE_HASHDRBG + struct DRBG_internal* drbg = (struct DRBG_internal*)rng->drbg; + wc_MemZero_Add("DRBG V", &drbg->V, sizeof(drbg->V)); + wc_MemZero_Add("DRBG C", &drbg->C, sizeof(drbg->C)); +#endif +#endif + rng->status = DRBG_OK; ret = 0; } @@ -1095,6 +1103,8 @@ int wc_FreeRng(WC_RNG* rng) #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY) XFREE(rng->drbg, rng->heap, DYNAMIC_TYPE_RNG); + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(rng->drbg, sizeof(DRBG_internal)); #endif rng->drbg = NULL; } diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 710781ee3..4954784b8 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -609,6 +609,10 @@ int wc_FreeRsaKey(RsaKey* key) KcapiRsa_Free(key); #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(key, sizeof(RsaKey)); +#endif + return ret; } @@ -633,6 +637,9 @@ static int _ifc_pairwise_consistency_test(RsaKey* key, WC_RNG* rng) return MEMORY_E; } XMEMSET(sig, 0, sigLen); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("Pairwise CT sig", sig, sigLen); +#endif plain = sig; #ifdef WOLFSSL_ASYNC_CRYPT @@ -735,6 +742,9 @@ int wc_CheckRsaKey(RsaKey* key) } /* Check p*q = n. */ if (ret == 0 ) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("RSA CheckKey tmp", tmp); + #endif if (mp_mul(&key->p, &key->q, tmp) != MP_OKAY) { ret = MP_EXPTMOD_E; } @@ -834,6 +844,8 @@ int wc_CheckRsaKey(RsaKey* key) #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_RSA); XFREE(rng, NULL, DYNAMIC_TYPE_RNG); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + mp_memzero_check(tmp); #endif return ret; @@ -1213,12 +1225,18 @@ static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, pkcsBlock[idx] = pkcsBlock[idx] ^ seed[i++]; idx++; } +#ifdef WOLFSSL_CHECK_MEM_ZERO + /* Seed must be zeroized now that it has been used. */ + wc_MemZero_Add("Pad OAEP seed", seed, hLen); +#endif /* Zeroize masking bytes so that padding can't be unmasked. */ ForceZero(seed, hLen); #ifdef WOLFSSL_SMALL_STACK XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(seed, hLen); #endif (void)padValue; @@ -1545,6 +1563,7 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, #else byte tmp[RSA_MAX_SIZE/8 + RSA_PSS_PAD_SZ]; #endif + /* no label is allowed, but catch if no label provided and length > 0 */ if (optLabel == NULL && labelLen > 0) { return BUFFER_E; @@ -1562,6 +1581,9 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, } #endif XMEMSET(tmp, 0, pkcsBlockLen); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("OAEP UnPad temp", tmp, pkcsBlockLen); +#endif /* find seedMask value */ if ((ret = RsaMGF(mgf, (byte*)(pkcsBlock + (hLen + 1)), @@ -1583,6 +1605,8 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, ForceZero(tmp, hLen); #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_RSA_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(tmp, hLen); #endif return ret; } @@ -1596,6 +1620,8 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, #ifdef WOLFSSL_SMALL_STACK /* done with use of tmp buffer */ XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(tmp, pkcsBlockLen); #endif /* advance idx to index of PS and msg separator, account for PS size of 0*/ @@ -2200,6 +2226,11 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, != MP_OKAY) { ERROR_OUT(MP_TO_E); } + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Seed must be zeroized now that it has been used. */ + wc_MemZero_Add("RSA Sync Priv Enc/Dec keyBuf", keyBuf + keyLen, + keyBufSz); + #endif } break; @@ -2505,6 +2536,12 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, if (ret == 0 && mp_read_unsigned_bin(tmp, in, inLen) != MP_OKAY) ret = MP_READ_E; +#ifdef WOLFSSL_CHECK_MEM_ZERO + if (ret == 0) { + mp_memzero_add("RSA sync tmp", tmp); + } +#endif + if (ret == 0) { switch(type) { #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY) @@ -2521,6 +2558,10 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, ret = MP_INVMOD_E; break; } + #ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("RSA sync rnd", rnd); + mp_memzero_add("RSA sync rndi", rndi); + #endif /* rnd = rnd^e */ #ifndef WOLFSSL_SP_MATH_ALL @@ -2580,6 +2621,13 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, clearb = 1; } + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (ret == 0) { + mp_memzero_add("RSA Sync tmpa", tmpa); + mp_memzero_add("RSA Sync tmpb", tmpb); + } + #endif + /* tmpa = tmp^dP mod p */ if (ret == 0 && mp_exptmod(tmp, &key->dP, &key->p, tmpa) != MP_OKAY) @@ -2624,6 +2672,9 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, #ifdef WOLFSSL_SMALL_STACK /* tmpb is allocated after tmpa. */ XFREE(tmpa, key->heap, DYNAMIC_TYPE_RSA); + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + mp_memzero_check(tmpb); + mp_memzero_check(tmpa); #endif } } /* tmpa/b scope */ @@ -2669,6 +2720,8 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, mp_forcezero(tmp); #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + mp_memzero_check(tmp); #endif #ifdef WC_RSA_BLINDING if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) { @@ -2677,6 +2730,11 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, } #ifdef WOLFSSL_SMALL_STACK XFREE(rnd, key->heap, DYNAMIC_TYPE_RSA); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) { + mp_memzero_check(rnd); + mp_memzero_check(rndi); + } #endif #endif /* WC_RSA_BLINDING */ return ret; @@ -4193,6 +4251,11 @@ static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size) if (ret == 0) ret = mp_sub(p, q, d); +#ifdef WOLFSSL_CHECK_MEM_ZERO + if (ret == 0) + mp_memzero_add("Comare PQ d", d); +#endif + #if !defined(WOLFSSL_SP_MATH) && (!defined(WOLFSSL_SP_MATH_ALL) || \ defined(WOLFSSL_SP_INT_NEGATIVE)) if (ret == 0) @@ -4218,6 +4281,9 @@ static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size) #else mp_forcezero(d); mp_clear(c); +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_check(d); +#endif #endif return ret; @@ -4342,6 +4408,9 @@ static int _CheckProbablePrime(mp_int* p, mp_int* q, mp_int* e, int nlen, /* 4.5,5.6 - Check that GCD(p-1, e) == 1 */ ret = mp_sub_d(prime, 1, tmp1); /* tmp1 = prime-1 */ if (ret != MP_OKAY) goto notOkay; +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("Check Probable Prime tmp1", tmp1); +#endif ret = mp_gcd(tmp1, e, tmp2); /* tmp2 = gcd(prime-1, e) */ if (ret != MP_OKAY) goto notOkay; ret = mp_cmp_d(tmp2, 1); @@ -4377,6 +4446,9 @@ notOkay: #else mp_forcezero(tmp1); mp_clear(tmp2); +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_check(tmp1); +#endif #endif return ret; @@ -4422,10 +4494,17 @@ int wc_CheckProbablePrime_ex(const byte* pRaw, word32 pRawSz, ret = mp_read_unsigned_bin(p, pRaw, pRawSz); if (ret == MP_OKAY) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("wc_CheckProbablePrime_ex p", p); + #endif if (qRaw != NULL) { ret = mp_read_unsigned_bin(q, qRaw, qRawSz); - if (ret == MP_OKAY) + if (ret == MP_OKAY) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_add("wc_CheckProbablePrime_ex q", q); + #endif Q = q; + } } } @@ -4460,6 +4539,10 @@ int wc_CheckProbablePrime_ex(const byte* pRaw, word32 pRawSz, mp_forcezero(p); mp_forcezero(q); mp_clear(e); +#ifdef WOLFSSL_CHECK_MEM_ZERO + mp_memzero_check(p); + mp_memzero_check(q); +#endif #endif return ret; @@ -4600,6 +4683,14 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) /* make p */ if (err == MP_OKAY) { + #ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("RSA gen buf", buf, primeSz); + mp_memzero_add("RSA gen p", p); + mp_memzero_add("RSA gen q", q); + mp_memzero_add("RSA gen tmp1", tmp1); + mp_memzero_add("RSA gen tmp2", tmp2); + mp_memzero_add("RSA gen tmp3", tmp3); + #endif isPrime = 0; i = 0; do { @@ -4786,6 +4877,17 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) if (err == MP_OKAY) key->type = RSA_PRIVATE; +#ifdef WOLFSSL_CHECK_MEM_ZERO + if (err == MP_OKAY) { + mp_memzero_add("Make RSA key d", &key->d); + mp_memzero_add("Make RSA key p", &key->p); + mp_memzero_add("Make RSA key q", &key->q); + mp_memzero_add("Make RSA key dP", &key->dP); + mp_memzero_add("Make RSA key dQ", &key->dQ); + mp_memzero_add("Make RSA key u", &key->u); + } +#endif + RESTORE_VECTOR_REGISTERS(); /* Last value p - 1. */ @@ -4829,6 +4931,12 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) XFREE(tmp2, key->heap, DYNAMIC_TYPE_RSA); if (tmp3) XFREE(tmp3, key->heap, DYNAMIC_TYPE_RSA); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + mp_memzero_check(p); + mp_memzero_check(q); + mp_memzero_check(tmp1); + mp_memzero_check(tmp2); + mp_memzero_check(tmp3); #endif return err; diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index e1231d5be..11a00169e 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -15980,4 +15980,26 @@ word32 CheckRunTimeFastMath(void) return SP_WORD_SIZE; } +#ifdef WOLFSSL_CHECK_MEM_ZERO +/* Add an MP to check. + * + * @param [in] name Name of address to check. + * @param [in] mp mp_int that needs to be checked. + */ +void sp_memzero_add(const char* name, mp_int* mp) +{ + wc_MemZero_Add(name, mp->dp, mp->size * sizeof(sp_digit)); +} + +/* Check the memory in the data pointer for memory that must be zero. + * + * @param [in] mp mp_int that needs to be checked. + */ +void sp_memzero_check(mp_int* mp) +{ + wc_MemZero_Check(mp->dp, mp->size * sizeof(sp_digit)); +} +#endif /* WOLFSSL_CHECK_MEM_ZERO */ + + #endif /* WOLFSSL_SP_MATH || WOLFSSL_SP_MATH_ALL */ diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index f9115f1c4..dfdd0929f 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -5895,4 +5895,16 @@ int mp_lshd (mp_int * a, int b) return fp_lshd(a, b); } +#ifdef WOLFSSL_CHECK_MEM_ZERO +void mp_memzero_add(const char* name, mp_int* a) +{ + wc_MemZero_Add(name, a->dp, sizeof(a->dp)); +} + +void mp_memzero_check(mp_int* a) +{ + wc_MemZero_Check(a->dp, sizeof(a->dp)); +} +#endif /* WOLFSSL_CHECK_MEM_ZERO */ + #endif /* USE_FAST_MATH */ diff --git a/wolfcrypt/src/wc_encrypt.c b/wolfcrypt/src/wc_encrypt.c index fa0ddd6eb..f1ea3b923 100644 --- a/wolfcrypt/src/wc_encrypt.c +++ b/wolfcrypt/src/wc_encrypt.c @@ -272,6 +272,9 @@ int wc_BufferKeyDecrypt(EncryptedInfo* info, byte* der, word32 derSz, return MEMORY_E; } #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_BufferKeyDecrypt key", key, WC_MAX_SYM_KEY_SIZE); +#endif (void)XMEMSET(key, 0, WC_MAX_SYM_KEY_SIZE); @@ -280,6 +283,8 @@ int wc_BufferKeyDecrypt(EncryptedInfo* info, byte* der, word32 derSz, info->keySz, hashType)) != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, WC_MAX_SYM_KEY_SIZE); #endif return ret; } @@ -300,6 +305,8 @@ int wc_BufferKeyDecrypt(EncryptedInfo* info, byte* der, word32 derSz, ForceZero(key, WC_MAX_SYM_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, WC_MAX_SYM_KEY_SIZE); #endif return ret; @@ -330,6 +337,9 @@ int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz, return MEMORY_E; } #endif /* WOLFSSL_SMALL_STACK */ +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_BufferKeyDecrypt key", key, WC_MAX_SYM_KEY_SIZE); +#endif (void)XMEMSET(key, 0, WC_MAX_SYM_KEY_SIZE); @@ -338,6 +348,8 @@ int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz, info->keySz, hashType)) != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, WC_MAX_SYM_KEY_SIZE); #endif return ret; } @@ -358,6 +370,8 @@ int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz, ForceZero(key, WC_MAX_SYM_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, WC_MAX_SYM_KEY_SIZE); #endif return ret; @@ -475,6 +489,9 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, if (key == NULL) return MEMORY_E; #endif +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_CryptKey key", key, PKCS_MAX_KEY_SIZE); +#endif switch (version) { #ifndef NO_HMAC @@ -499,6 +516,8 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif return UNICODE_SIZE_E; } @@ -524,6 +543,8 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif WOLFSSL_MSG("Unknown/Unsupported PKCS version"); return ALGO_ID_E; @@ -533,6 +554,8 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif return ret; } @@ -559,6 +582,8 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif return ret; } @@ -587,6 +612,8 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif return ret; } @@ -600,7 +627,10 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif + wc_Des3Free(&des); return ret; } if (enc) { @@ -609,10 +639,13 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, else { ret = wc_Des3_CbcDecrypt(&des, input, input, length); } + wc_Des3Free(&des); if (ret != 0) { ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif return ret; } @@ -674,6 +707,8 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif return ret; } @@ -697,6 +732,8 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif return ret; } @@ -709,6 +746,8 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif WOLFSSL_MSG("Unknown/Unsupported encrypt/decryption algorithm"); return ALGO_ID_E; @@ -717,6 +756,8 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ForceZero(key, PKCS_MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#elif defined(WOLFSSL_CHECK_MEM_ZERO) + wc_MemZero_Check(key, PKCS_MAX_KEY_SIZE); #endif return ret; diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index a0593f111..8a3bc1c29 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -132,6 +132,12 @@ int wolfCrypt_Init(void) if (initRefCount == 0) { WOLFSSL_ENTER("wolfCrypt_Init"); + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Initialize the mutex for access to the list of memory locations that + * must be freed. */ + wc_MemZero_Init(); + #endif + #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST { word32 rngMallocFail; @@ -423,6 +429,12 @@ int wolfCrypt_Cleanup(void) #if defined(WOLFSSL_LINUXKM_SIMD_X86) free_wolfcrypt_linuxkm_fpu_states(); #endif + + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Free the mutex for access to the list of memory locations that + * must be freed. */ + wc_MemZero_Free(); + #endif } return ret; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index a4349b86a..380f07737 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -39159,7 +39159,12 @@ WOLFSSL_TEST_SUBROUTINE int memcb_test(void) XFREE(b, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #ifndef WOLFSSL_STATIC_MEMORY +#ifndef WOLFSSL_CHECK_MEM_ZERO if (malloc_cnt != 1 || free_cnt != 1 || realloc_cnt != 1) +#else + /* Checking zeroized memory means realloc is a malloc and free. */ + if (malloc_cnt != 2 || free_cnt != 2 || realloc_cnt != 0) +#endif #else if (malloc_cnt != 0 || free_cnt != 0 || realloc_cnt != 0) #endif diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index b81009b67..64b79a61e 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -238,6 +238,14 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf, __cyg_profile_func_exit(void *func, void *caller); #endif /* WOLFSSL_STACK_LOG */ +#ifdef WOLFSSL_CHECK_MEM_ZERO +WOLFSSL_LOCAL void wc_MemZero_Init(void); +WOLFSSL_LOCAL void wc_MemZero_Free(void); +WOLFSSL_LOCAL void wc_MemZero_Add(const char* name, const void* addr, + size_t len); +WOLFSSL_LOCAL void wc_MemZero_Check(void* addr, size_t len); +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index 4492bdee9..627010298 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -908,6 +908,11 @@ MP_API int sp_lcm(sp_int* a, sp_int* b, sp_int* r); WOLFSSL_API word32 CheckRunTimeFastMath(void); +#ifdef WOLFSSL_CHECK_MEM_ZERO +WOLFSSL_LOCAL void sp_memzero_add(const char* name, mp_int* mp); +WOLFSSL_LOCAL void sp_memzero_check(mp_int* mp); +#endif + /* Map mp functions to SP math versions. */ /* Different name or signature. */ @@ -999,6 +1004,9 @@ WOLFSSL_API word32 CheckRunTimeFastMath(void); #define mp_gcd sp_gcd #define mp_lcm sp_lcm +#define mp_memzero_add sp_memzero_add +#define mp_memzero_check sp_memzero_check + #ifdef WOLFSSL_DEBUG_MATH #define mp_dump(d, a, v) sp_print(a, d) #endif diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index d562a8aab..5a478c697 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -856,6 +856,11 @@ MP_API int mp_abs(mp_int* a, mp_int* b); WOLFSSL_API word32 CheckRunTimeFastMath(void); +#ifdef WOLFSSL_CHECK_MEM_ZERO +void mp_memzero_add(const char* name, mp_int* a); +void mp_memzero_check(mp_int* a); +#endif + /* If user uses RSA, DH, DSA, or ECC math lib directly then fast math FP_SIZE must match, return 1 if a match otherwise 0 */ #define CheckFastMathSettings() (FP_SIZE == CheckRunTimeFastMath())