Merge pull request #5245 from SparkiDev/force_zero

Memory zeroization fixes
This commit is contained in:
David Garske
2022-06-15 11:16:04 -07:00
committed by GitHub
15 changed files with 256 additions and 124 deletions

View File

@@ -332,6 +332,8 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
else
ret = MEMORY_E;
}
/* Zero out Base16 encoded secret and other data. */
ForceZero(log, buffSz);
XFREE(log, ssl->heap, DYNAMIC_TYPE_SECRET);
return ret;
}
@@ -462,6 +464,8 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
else
ret = MEMORY_E;
}
/* Zero out Base16 encoded secret and other data. */
ForceZero(log, buffSz);
XFREE(log, ssl->heap, DYNAMIC_TYPE_SECRET);
return ret;
}
@@ -2376,6 +2380,9 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
#endif /* SINGLE_THREADED */
#ifndef NO_CERTS
if (ctx->privateKey != NULL && ctx->privateKey->buffer != NULL) {
ForceZero(ctx->privateKey->buffer, ctx->privateKey->length);
}
FreeDer(&ctx->privateKey);
#ifdef OPENSSL_ALL
wolfSSL_EVP_PKEY_free(ctx->privateKeyPKey);
@@ -2613,10 +2620,16 @@ void FreeCiphers(WOLFSSL* ssl)
XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
#endif
#ifdef HAVE_CHACHA
if (ssl->encrypt.chacha)
ForceZero(ssl->encrypt.chacha, sizeof(ChaCha));
if (ssl->decrypt.chacha)
ForceZero(ssl->decrypt.chacha, sizeof(ChaCha));
XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
#endif
#if defined(HAVE_POLY1305) && defined(HAVE_ONE_TIME_AUTH)
if (ssl->auth.poly1305)
ForceZero(ssl->auth.poly1305, sizeof(Poly1305));
XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
@@ -6238,6 +6251,7 @@ void FreeHandshakeHashes(WOLFSSL* ssl)
#if (defined(HAVE_ED25519) || defined(HAVE_ED448)) && \
!defined(WOLFSSL_NO_CLIENT_AUTH)
if (ssl->hsHashes->messages != NULL) {
ForceZero(ssl->hsHashes->messages, ssl->hsHashes->length);
XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES);
ssl->hsHashes->messages = NULL;
}
@@ -6728,7 +6742,7 @@ void FreeArrays(WOLFSSL* ssl, int keep)
ssl->session->sessionIDSz = ssl->arrays->sessionIDSz;
}
if (ssl->arrays->preMasterSecret) {
ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
ForceZero(ssl->arrays->preMasterSecret, ENCRYPT_LEN);
XFREE(ssl->arrays->preMasterSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
ssl->arrays->preMasterSecret = NULL;
}
@@ -7107,7 +7121,7 @@ void SSL_ResourceFree(WOLFSSL* ssl)
ssl->clientFinished_len = 0;
#endif
#ifndef NO_DH
if (ssl->buffers.serverDH_Priv.buffer) {
if (ssl->buffers.serverDH_Priv.buffer != NULL) {
ForceZero(ssl->buffers.serverDH_Priv.buffer,
ssl->buffers.serverDH_Priv.length);
}
@@ -7135,6 +7149,10 @@ void SSL_ResourceFree(WOLFSSL* ssl)
if (ssl->buffers.outputBuffer.dynamicFlag)
ShrinkOutputBuffer(ssl);
#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
if (ssl->buffers.tls13CookieSecret.buffer != NULL) {
ForceZero(ssl->buffers.tls13CookieSecret.buffer,
ssl->buffers.tls13CookieSecret.length);
}
XFREE(ssl->buffers.tls13CookieSecret.buffer, ssl->heap,
DYNAMIC_TYPE_COOKIE_PWD);
#endif
@@ -7148,6 +7166,10 @@ void SSL_ResourceFree(WOLFSSL* ssl)
XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
ssl->buffers.dtlsCtx.peer.sa = NULL;
#ifndef NO_WOLFSSL_SERVER
if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
ssl->buffers.dtlsCookieSecret.length);
}
XFREE(ssl->buffers.dtlsCookieSecret.buffer, ssl->heap,
DYNAMIC_TYPE_COOKIE_PWD);
#endif
@@ -8607,11 +8629,15 @@ static int EdDSA_Update(WOLFSSL* ssl, const byte* data, int sz)
byte* msgs;
if (ssl->options.cacheMessages) {
msgs = (byte*)XREALLOC(ssl->hsHashes->messages,
ssl->hsHashes->length + sz,
ssl->heap, DYNAMIC_TYPE_HASHES);
msgs = (byte*)XMALLOC(ssl->hsHashes->length + sz, ssl->heap,
DYNAMIC_TYPE_HASHES);
if (msgs == NULL)
ret = MEMORY_E;
if ((ret == 0) && (ssl->hsHashes->messages != NULL)) {
XMEMCPY(msgs, ssl->hsHashes->messages, ssl->hsHashes->length);
ForceZero(ssl->hsHashes->messages, ssl->hsHashes->length);
XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES);
}
if (ret == 0) {
ssl->hsHashes->messages = msgs;
XMEMCPY(msgs + ssl->hsHashes->length, data, sz);
@@ -9105,6 +9131,11 @@ retry:
void ShrinkOutputBuffer(WOLFSSL* ssl)
{
WOLFSSL_MSG("Shrinking output buffer");
if (IsEncryptionOn(ssl, 0)) {
ForceZero(ssl->buffers.outputBuffer.buffer -
ssl->buffers.outputBuffer.offset,
ssl->buffers.outputBuffer.bufferSize);
}
XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
@@ -9125,11 +9156,17 @@ void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree)
WOLFSSL_MSG("Shrinking input buffer");
if (!forcedFree && usedLength > 0)
if (!forcedFree && usedLength > 0) {
XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
usedLength);
}
if (IsEncryptionOn(ssl, 1) || forcedFree) {
ForceZero(ssl->buffers.inputBuffer.buffer -
ssl->buffers.inputBuffer.offset,
ssl->buffers.inputBuffer.bufferSize);
}
XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
@@ -9267,10 +9304,16 @@ static WC_INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size)
XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
ssl->buffers.outputBuffer.length);
if (ssl->buffers.outputBuffer.dynamicFlag)
if (ssl->buffers.outputBuffer.dynamicFlag) {
if (IsEncryptionOn(ssl, 0)) {
ForceZero(ssl->buffers.outputBuffer.buffer -
ssl->buffers.outputBuffer.offset,
ssl->buffers.outputBuffer.bufferSize);
}
XFREE(ssl->buffers.outputBuffer.buffer -
ssl->buffers.outputBuffer.offset, ssl->heap,
DYNAMIC_TYPE_OUT_BUFFER);
}
ssl->buffers.outputBuffer.dynamicFlag = 1;
#if WOLFSSL_GENERAL_ALIGNMENT > 0
@@ -9341,9 +9384,15 @@ int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength)
XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
ssl->buffers.inputBuffer.idx, usedLength);
if (ssl->buffers.inputBuffer.dynamicFlag)
if (ssl->buffers.inputBuffer.dynamicFlag) {
if (IsEncryptionOn(ssl, 1)) {
ForceZero(ssl->buffers.inputBuffer.buffer -
ssl->buffers.inputBuffer.offset,
ssl->buffers.inputBuffer.bufferSize);
}
XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
}
ssl->buffers.inputBuffer.dynamicFlag = 1;
#if defined(WOLFSSL_DTLS) || WOLFSSL_GENERAL_ALIGNMENT > 0
@@ -14406,6 +14455,7 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
{
ssl->options.cacheMessages = 0;
if ((ssl->hsHashes != NULL) && (ssl->hsHashes->messages != NULL)) {
ForceZero(ssl->hsHashes->messages, ssl->hsHashes->length);
XFREE(ssl->hsHashes->messages, ssl->heap,
DYNAMIC_TYPE_HASHES);
ssl->hsHashes->messages = NULL;
@@ -14492,6 +14542,7 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
{
ssl->options.cacheMessages = 0;
if ((ssl->hsHashes != NULL) && (ssl->hsHashes->messages != NULL)) {
ForceZero(ssl->hsHashes->messages, ssl->hsHashes->length);
XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES);
ssl->hsHashes->messages = NULL;
}
@@ -15423,6 +15474,7 @@ int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
/* 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));
return ret;
}
ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */
@@ -15589,6 +15641,7 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
/* 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));
return ret;
}
ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */
@@ -31485,8 +31538,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (idSz == 0) {
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->session->altSessionID,
ID_LEN);
if (ret != 0)
if (ret != 0) {
ForceZero(&it, sizeof(it));
return ret;
}
ssl->session->haveAltSessionID = 1;
id = ssl->session->altSessionID;
idSz = ID_LEN;
@@ -31510,6 +31565,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
(ssl->options.mask & WOLFSSL_OP_NO_TICKET) != 0)
#endif
) {
ForceZero(&it, sizeof(it));
ret = WOLFSSL_TICKET_RET_FATAL;
}
else {
@@ -31520,6 +31576,7 @@ 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) {
ForceZero(&it, sizeof(it));
ForceZero(et->enc_ticket, sizeof(it));
}
}

View File

@@ -6228,7 +6228,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
}
#endif /* WOLFSSL_TRUST_PEER_CERT */
else if (type == CERT_TYPE) {
if (ssl) {
if (ssl != NULL) {
/* Make sure previous is free'd */
if (ssl->buffers.weOwnCert) {
FreeDer(&ssl->buffers.certificate);
@@ -6243,7 +6243,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
#endif
ssl->buffers.weOwnCert = 1;
}
else if (ctx) {
else if (ctx != NULL) {
FreeDer(&ctx->certificate); /* Make sure previous is free'd */
#ifdef KEEP_OUR_CERT
if (ctx->ourCert) {
@@ -6256,15 +6256,19 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
}
}
else if (type == PRIVATEKEY_TYPE) {
if (ssl) {
if (ssl != NULL) {
/* Make sure previous is free'd */
if (ssl->buffers.weOwnKey) {
ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
FreeDer(&ssl->buffers.key);
}
ssl->buffers.key = der;
ssl->buffers.weOwnKey = 1;
}
else if (ctx) {
else if (ctx != NULL) {
if (ctx->privateKey != NULL && ctx->privateKey->buffer != NULL) {
ForceZero(ctx->privateKey->buffer, ctx->privateKey->length);
}
FreeDer(&ctx->privateKey);
ctx->privateKey = der;
}
@@ -6308,6 +6312,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
ret = ToTraditionalEnc(der->buffer, der->length,
password, passwordSz, &algId);
if (ret >= 0) {
ForceZero(der->buffer + ret, der->length - ret);
der->length = ret;
}
/* ignore failures and try parsing as unencrypted */
@@ -14971,6 +14976,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
if (ssl->buffers.weOwnKey) {
WOLFSSL_MSG("Unloading key");
ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
FreeDer(&ssl->buffers.key);
ssl->buffers.weOwnKey = 0;
}
@@ -19688,6 +19694,11 @@ void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data);
#endif
/* Make sure masterSecret is zeroed. */
ForceZero(session->masterSecret, SECRET_LEN);
/* Session ID is sensitive information too. */
ForceZero(session->sessionID, ID_LEN);
if (session->type == WOLFSSL_SESSION_TYPE_HEAP) {
XFREE(session, session->heap, DYNAMIC_TYPE_SESSION);
}

View File

@@ -170,21 +170,24 @@ int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
int ret;
const byte* side = NULL;
word32 hashSz = HSHASH_SZ;
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
#if !defined(WOLFSSL_ASYNC_CRYPT) || defined(WC_ASYNC_NO_HASH)
byte handshake_hash[HSHASH_SZ];
#else
WC_DECLARE_VAR(handshake_hash, byte, HSHASH_SZ, ssl->heap);
if (handshake_hash == NULL)
return MEMORY_E;
#else
byte handshake_hash[HSHASH_SZ];
#endif
ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
if (ret == 0) {
if (XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
if (XSTRNCMP((const char*)sender, (const char*)client,
SIZEOF_SENDER) == 0) {
side = tls_client;
else if (XSTRNCMP((const char*)sender, (const char*)server, SIZEOF_SENDER)
== 0)
}
else if (XSTRNCMP((const char*)sender, (const char*)server,
SIZEOF_SENDER) == 0) {
side = tls_server;
}
else {
ret = BAD_FUNC_ARG;
WOLFSSL_MSG("Unexpected sender value");
@@ -210,6 +213,7 @@ int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
ssl->heap, ssl->devId);
PRIVATE_KEY_LOCK();
}
ForceZero(handshake_hash, hashSz);
#else
/* Pseudo random function must be enabled in the configuration. */
ret = PRF_MISSING;
@@ -401,12 +405,12 @@ static int _MakeTlsMasterSecret(byte* ms, word32 msLen,
void* heap, int devId)
{
int ret;
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
#if !defined(WOLFSSL_ASYNC_CRYPT) || defined(WC_ASYNC_NO_HASH)
byte seed[SEED_LEN];
#else
WC_DECLARE_VAR(seed, byte, SEED_LEN, heap);
if (seed == NULL)
return MEMORY_E;
#else
byte seed[SEED_LEN];
#endif
XMEMCPY(seed, cr, RAN_LEN);
@@ -521,6 +525,7 @@ int MakeTlsMasterSecret(WOLFSSL* ssl)
handshake_hash, hashSz,
IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
ssl->heap, ssl->devId);
ForceZero(handshake_hash, hashSz);
}
#ifdef WOLFSSL_SMALL_STACK

View File

@@ -1258,12 +1258,14 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
WRITE_IV_LABEL_SZ, ssl->specs.mac_algorithm, 0);
if (ret != 0)
goto end;
i += ssl->specs.iv_size;
}
/* Store keys and IVs but don't activate them. */
ret = StoreKeys(ssl, key_dig, provision);
end:
ForceZero(key_dig, i);
#ifdef WOLFSSL_SMALL_STACK
XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST);
#endif
@@ -2051,8 +2053,10 @@ static int ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output,
if (ret != 0)
return ret;
ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 1);
if (ret != 0)
if (ret != 0) {
ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
return ret;
}
/* Set key for Poly1305. */
ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, sizeof(poly));
@@ -3003,7 +3007,7 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
*/
while (current != NULL) {
if ((ret = SetupPskKey(ssl, current, 1)) != 0)
return ret;
break;
#ifdef HAVE_SESSION_TICKET
if (current->resumption)
@@ -3014,23 +3018,27 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
ret = DeriveBinderKey(ssl, binderKey);
#endif
if (ret != 0)
return ret;
break;
/* Derive the Finished message secret. */
ret = DeriveFinishedSecret(ssl, binderKey,
ssl->keys.client_write_MAC_secret);
if (ret != 0)
return ret;
break;
/* Build the HMAC of the handshake message data = binder. */
ret = BuildTls13HandshakeHmac(ssl, ssl->keys.client_write_MAC_secret,
current->binder, &current->binderLen);
if (ret != 0)
return ret;
break;
current = current->next;
}
ForceZero(binderKey, sizeof(binderKey));
if (ret != 0)
return ret;
/* Data entered into extension, now write to message. */
ret = TLSX_PreSharedKey_WriteBinders((PreSharedKey*)ext->data, output + idx,
client_hello, &len);
@@ -8407,6 +8415,7 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
IsAtLeastTLSv1_3(ssl->version)) {
ssl->options.cacheMessages = 0;
if ((ssl->hsHashes != NULL) && (ssl->hsHashes->messages != NULL)) {
ForceZero(ssl->hsHashes->messages, ssl->hsHashes->length);
XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES);
ssl->hsHashes->messages = NULL;
}

View File

@@ -4454,8 +4454,10 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
XTRANSFORM_AESCTRBLOCK(aes, out, in);
#else
ret = wc_AesEncrypt(aes, (byte*)aes->reg, scratch);
if (ret != 0)
if (ret != 0) {
ForceZero(scratch, AES_BLOCK_SIZE);
return ret;
}
xorbuf(scratch, in, AES_BLOCK_SIZE);
XMEMCPY(out, scratch, AES_BLOCK_SIZE);
#endif
@@ -4471,8 +4473,10 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
/* handle non block size remaining and store unused byte count in left */
if (sz) {
ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
if (ret != 0)
if (ret != 0) {
ForceZero(scratch, AES_BLOCK_SIZE);
return ret;
}
IncrementAesCounter((byte*)aes->reg);
aes->left = AES_BLOCK_SIZE;
@@ -4718,8 +4722,12 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
if (!((len == 16) || (len == 24) || (len == 32)))
return BAD_FUNC_ARG;
if (aes == NULL)
if (aes == NULL) {
#ifdef WOLFSSL_IMX6_CAAM_BLOB
ForceZero(local, sizeof(local));
#endif
return BAD_FUNC_ARG;
}
#ifdef OPENSSL_EXTRA
XMEMSET(aes->aadH, 0, sizeof(aes->aadH));
@@ -10186,18 +10194,26 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
}
ret = wc_AesEncrypt(aes, B, A);
if (ret != 0)
if (ret != 0) {
ForceZero(B, sizeof(B));
return ret;
}
if (authInSz > 0) {
ret = roll_auth(aes, authIn, authInSz, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
}
if (inSz > 0) {
ret = roll_x(aes, in, inSz, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
}
XMEMCPY(authTag, A, authTagSz);
@@ -10205,8 +10221,11 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
for (i = 0; i < lenSz; i++)
B[AES_BLOCK_SIZE - 1 - i] = 0;
ret = wc_AesEncrypt(aes, B, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
xorbuf(authTag, A, authTagSz);
B[15] = 1;
@@ -10233,8 +10252,11 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
#endif
while (inSz >= AES_BLOCK_SIZE) {
ret = wc_AesEncrypt(aes, B, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
xorbuf(A, in, AES_BLOCK_SIZE);
XMEMCPY(out, A, AES_BLOCK_SIZE);
@@ -10245,14 +10267,17 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
}
if (inSz > 0) {
ret = wc_AesEncrypt(aes, B, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
xorbuf(A, in, inSz);
XMEMCPY(out, A, inSz);
}
ForceZero(A, AES_BLOCK_SIZE);
ForceZero(B, AES_BLOCK_SIZE);
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return 0;
}
@@ -10334,8 +10359,11 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
#endif
while (oSz >= AES_BLOCK_SIZE) {
ret = wc_AesEncrypt(aes, B, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
xorbuf(A, in, AES_BLOCK_SIZE);
XMEMCPY(o, A, AES_BLOCK_SIZE);
@@ -10346,8 +10374,11 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
}
if (inSz > 0) {
ret = wc_AesEncrypt(aes, B, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
xorbuf(A, in, oSz);
XMEMCPY(o, A, oSz);
}
@@ -10355,8 +10386,11 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
for (i = 0; i < lenSz; i++)
B[AES_BLOCK_SIZE - 1 - i] = 0;
ret = wc_AesEncrypt(aes, B, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
o = out;
oSz = inSz;
@@ -10371,26 +10405,38 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
}
ret = wc_AesEncrypt(aes, B, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
if (authInSz > 0) {
ret = roll_auth(aes, authIn, authInSz, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
}
if (inSz > 0) {
ret = roll_x(aes, o, oSz, A);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
}
B[0] = lenSz - 1;
for (i = 0; i < lenSz; i++)
B[AES_BLOCK_SIZE - 1 - i] = 0;
ret = wc_AesEncrypt(aes, B, B);
if (ret != 0)
if (ret != 0) {
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
return ret;
}
xorbuf(A, B, authTagSz);
if (ConstantCompare(A, authTag, authTagSz) != 0) {
@@ -10407,8 +10453,8 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
ret = AES_CCM_AUTH_E;
}
ForceZero(A, AES_BLOCK_SIZE);
ForceZero(B, AES_BLOCK_SIZE);
ForceZero(A, sizeof(A));
ForceZero(B, sizeof(B));
o = NULL;
return ret;

View File

@@ -31230,7 +31230,7 @@ int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
if (req == NULL)
return BAD_FUNC_ARG;
ForceZero(req, sizeof(OcspRequest));
XMEMSET(req, 0, sizeof(OcspRequest));
req->heap = heap;
if (cert) {

View File

@@ -242,6 +242,9 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz)
}
#if defined(WOLFSSL_HASH_KEEP)
/* TODO: msg is leaked if wc_CmacFinal() is not called
* e.g. when multiple calls to wc_CmacUpdate() and one fails but
* wc_CmacFinal() not called. */
if (cmac->msg != NULL) {
XFREE(cmac->msg, cmac->heap, DYNAMIC_TYPE_TMP_BUFFER);
cmac->msg = NULL;

View File

@@ -1754,7 +1754,7 @@ int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz,
}
}
mp_clear(x);
mp_forcezero(x);
mp_clear(q);
#ifdef WOLFSSL_SMALL_STACK
XFREE(q, key->heap, DYNAMIC_TYPE_DH);
@@ -2113,7 +2113,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
if (ret == 0)
*agreeSz = mp_unsigned_bin_size(z);
mp_clear(z);
mp_forcezero(z);
mp_clear(y);
mp_forcezero(x);
@@ -2299,7 +2299,7 @@ int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz,
mp_clear(&key->pub);
havePub = 0;
if (havePriv) {
mp_clear(&key->priv);
mp_forcezero(&key->priv);
havePriv = 0; /* set to 0 to error out with failed read pub */
}
} else {

View File

@@ -4438,6 +4438,8 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
}
*outlen = x;
mp_forcezero(result->x);
mp_forcezero(result->y);
wc_ecc_del_point_ex(result, private_key->heap);
wc_ecc_curve_free(curve);
@@ -4762,7 +4764,8 @@ int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
int err;
byte buf[ECC_MAXSIZE_GEN];
if (rng == NULL || size > ECC_MAXSIZE_GEN || k == NULL || order == NULL) {
if (rng == NULL || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
order == NULL) {
return BAD_FUNC_ARG;
}
@@ -4790,7 +4793,7 @@ int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
err = MP_ZERO_E;
}
ForceZero(buf, ECC_MAXSIZE);
ForceZero(buf, ECC_MAXSIZE_GEN);
return err;
#else
@@ -6106,7 +6109,7 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
#endif
mp_forcezero(&pubkey->k);
}
mp_clear(b);
mp_forcezero(b);
#ifdef WOLFSSL_SMALL_STACK
XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
#endif
@@ -6751,6 +6754,7 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
} while (ret == 0 && err != 0);
}
ForceZero(x, MAX_ECC_BYTES);
#ifdef WOLFSSL_SMALL_STACK
if (z1 != NULL)
XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
@@ -11367,7 +11371,7 @@ static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
done:
/* cleanup */
mp_clear(order);
mp_clear(tk);
mp_forcezero(tk);
#ifdef WOLFSSL_SMALL_STACK
XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
@@ -11616,8 +11620,8 @@ static int accel_fp_mul2add(int idx1, int idx2,
done:
/* cleanup */
mp_clear(tkb);
mp_clear(tka);
mp_forcezero(tkb);
mp_forcezero(tka);
mp_clear(order);
#ifdef WOLFSSL_SMALL_STACK

View File

@@ -229,7 +229,7 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
}
#endif
ret = wc_RNG_GenerateBlock(rng, key->k, ED25519_KEY_SIZE);
ret = wc_RNG_GenerateBlock(rng, key->k, ED25519_KEY_SIZE);
if (ret != 0)
return ret;

View File

@@ -208,26 +208,23 @@ int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,
word32 secLen, const byte* label, word32 labLen,
const byte* seed, word32 seedLen, void* heap, int devId)
{
int ret = 0;
word32 half = (secLen + 1) / 2;
int ret = 0;
word32 half = (secLen + 1) / 2;
const byte* md5_half;
const byte* sha_half;
byte* md5_result;
#ifdef WOLFSSL_SMALL_STACK
byte* md5_half;
byte* sha_half;
byte* md5_result;
byte* sha_result;
byte* sha_result;
#else
byte md5_half[MAX_PRF_HALF]; /* half is real size */
byte sha_half[MAX_PRF_HALF]; /* half is real size */
byte md5_result[MAX_PRF_DIG]; /* digLen is real size */
byte sha_result[MAX_PRF_DIG]; /* digLen is real size */
byte sha_result[MAX_PRF_DIG]; /* digLen is real size */
#endif
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
#if !defined(WOLFSSL_ASYNC_CRYPT) || defined(WC_ASYNC_NO_HASH)
byte labelSeed[MAX_PRF_LABSEED];
#else
WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);
if (labelSeed == NULL)
return MEMORY_E;
#else
byte labelSeed[MAX_PRF_LABSEED];
#endif
if (half > MAX_PRF_HALF ||
@@ -241,30 +238,18 @@ int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,
}
#ifdef WOLFSSL_SMALL_STACK
md5_half = (byte*)XMALLOC(MAX_PRF_HALF, heap, DYNAMIC_TYPE_DIGEST);
sha_half = (byte*)XMALLOC(MAX_PRF_HALF, heap, DYNAMIC_TYPE_DIGEST);
md5_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
sha_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
if (md5_half == NULL || sha_half == NULL || md5_result == NULL ||
sha_result == NULL) {
if (md5_half) XFREE(md5_half, heap, DYNAMIC_TYPE_DIGEST);
if (sha_half) XFREE(sha_half, heap, DYNAMIC_TYPE_DIGEST);
if (md5_result) XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST);
if (sha_result) XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
sha_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
if (sha_result == NULL) {
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
WC_FREE_VAR(labelSeed, heap);
#endif
return MEMORY_E;
}
#endif
XMEMSET(md5_result, 0, digLen);
XMEMSET(sha_result, 0, digLen);
XMEMCPY(md5_half, secret, half);
XMEMCPY(sha_half, secret + half - secLen % 2, half);
md5_half = secret;
sha_half = secret + half - secLen % 2;
md5_result = digest;
XMEMCPY(labelSeed, label, labLen);
XMEMCPY(labelSeed + labLen, seed, seedLen);
@@ -274,15 +259,13 @@ int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,
if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,
labLen + seedLen, sha_mac, heap, devId)) == 0) {
/* calculate XOR for TLSv1 PRF */
XMEMCPY(digest, md5_result, digLen);
/* md5 result is placed directly in digest */
xorbuf(digest, sha_result, digLen);
ForceZero(sha_result, digLen);
}
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(md5_half, heap, DYNAMIC_TYPE_DIGEST);
XFREE(sha_half, heap, DYNAMIC_TYPE_DIGEST);
XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST);
XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
#endif

View File

@@ -571,15 +571,17 @@ int wc_FreeRsaKey(RsaKey* key)
mp_forcezero(&key->p);
mp_forcezero(&key->d);
}
/* private part */
else {
/* private part */
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
mp_clear(&key->u);
mp_clear(&key->dQ);
mp_clear(&key->dP);
mp_clear(&key->u);
mp_clear(&key->dQ);
mp_clear(&key->dP);
#endif
mp_clear(&key->q);
mp_clear(&key->p);
mp_clear(&key->d);
mp_clear(&key->q);
mp_clear(&key->p);
mp_clear(&key->d);
}
#endif /* WOLFSSL_RSA_PUBLIC_ONLY */
/* public part */
@@ -825,7 +827,6 @@ int wc_CheckRsaKey(RsaKey* key)
}
mp_forcezero(tmp);
mp_clear(tmp);
RESTORE_VECTOR_REGISTERS();
@@ -1213,6 +1214,8 @@ static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,
idx++;
}
/* 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);
@@ -1541,7 +1544,6 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
byte* tmp = NULL;
#else
byte tmp[RSA_MAX_SIZE/8 + RSA_PSS_PAD_SZ];
XMEMSET(tmp, 0, 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) {
@@ -1578,6 +1580,7 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
/* get dbMask value */
if ((ret = RsaMGF(mgf, tmp, hLen, tmp + hLen,
pkcsBlockLen - hLen - 1, heap)) != 0) {
ForceZero(tmp, hLen);
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmp, NULL, DYNAMIC_TYPE_RSA_BUFFER);
#endif
@@ -1589,6 +1592,7 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
pkcsBlock[hLen + 1 + idx] = pkcsBlock[hLen + 1 + idx] ^ tmp[idx + hLen];
}
ForceZero(tmp, pkcsBlockLen);
#ifdef WOLFSSL_SMALL_STACK
/* done with use of tmp buffer */
XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
@@ -2611,11 +2615,14 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
if (tmpa != NULL)
#endif
{
if (cleara)
mp_clear(tmpa);
if (clearb)
mp_clear(tmpb);
if (cleara) {
mp_forcezero(tmpa);
}
if (clearb) {
mp_forcezero(tmpb);
}
#ifdef WOLFSSL_SMALL_STACK
/* tmpb is allocated after tmpa. */
XFREE(tmpa, key->heap, DYNAMIC_TYPE_RSA);
#endif
}
@@ -2659,14 +2666,14 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
*outLen = inLen;
#endif
mp_clear(tmp);
mp_forcezero(tmp);
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
#endif
#ifdef WC_RSA_BLINDING
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
mp_clear(rndi);
mp_clear(rnd);
mp_forcezero(rndi);
mp_forcezero(rnd);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(rnd, key->heap, DYNAMIC_TYPE_RSA);
@@ -4201,7 +4208,7 @@ static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size)
#ifdef WOLFSSL_SMALL_STACK
if (d != NULL) {
mp_clear(d);
mp_forcezero(d);
XFREE(d, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
}
if (c != NULL) {
@@ -4209,7 +4216,7 @@ static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size)
XFREE(c, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
}
#else
mp_clear(d);
mp_forcezero(d);
mp_clear(c);
#endif
@@ -4360,7 +4367,7 @@ notOkay:
#ifdef WOLFSSL_SMALL_STACK
if (tmp1 != NULL) {
mp_clear(tmp1);
mp_forcezero(tmp1);
XFREE(tmp1, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
}
if (tmp2 != NULL) {
@@ -4368,7 +4375,7 @@ notOkay:
XFREE(tmp2, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
}
#else
mp_clear(tmp1);
mp_forcezero(tmp1);
mp_clear(tmp2);
#endif
@@ -4438,11 +4445,11 @@ int wc_CheckProbablePrime_ex(const byte* pRaw, word32 pRawSz,
#ifdef WOLFSSL_SMALL_STACK
if (p != NULL) {
mp_clear(p);
mp_forcezero(p);
XFREE(p, NULL, DYNAMIC_TYPE_RSA_BUFFER);
}
if (q != NULL) {
mp_clear(q);
mp_forcezero(q);
XFREE(q, NULL, DYNAMIC_TYPE_RSA_BUFFER);
}
if (e != NULL) {
@@ -4450,8 +4457,8 @@ int wc_CheckProbablePrime_ex(const byte* pRaw, word32 pRawSz,
XFREE(e, NULL, DYNAMIC_TYPE_RSA_BUFFER);
}
#else
mp_clear(p);
mp_clear(q);
mp_forcezero(p);
mp_forcezero(q);
mp_clear(e);
#endif
@@ -4749,7 +4756,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
if (err == MP_OKAY)
err = mp_sub_d(p, 2, tmp3);
if (err == MP_OKAY) /* key->u = 1/q mod p = q^p-2 mod p */
err = mp_exptmod(q, tmp3 , p, &key->u);
err = mp_exptmod(q, tmp3, p, &key->u);
#endif
if (err == MP_OKAY)
err = mp_copy(p, &key->p);
@@ -4781,11 +4788,14 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
RESTORE_VECTOR_REGISTERS();
mp_clear(tmp1);
mp_clear(tmp2);
mp_clear(tmp3);
mp_clear(p);
mp_clear(q);
/* Last value p - 1. */
mp_forcezero(tmp1);
/* Last value q - 1. */
mp_forcezero(tmp2);
/* Last value p - 2. */
mp_forcezero(tmp3);
mp_forcezero(p);
mp_forcezero(q);
#ifndef WOLFSSL_NO_RSA_KEY_CHECK
/* Perform the pair-wise consistency test on the new key. */

View File

@@ -4517,7 +4517,8 @@ void sp_clear(sp_int* a)
*/
void sp_forcezero(sp_int* a)
{
ForceZero(a->dp, a->used * sizeof(sp_int_digit));
/* Ensure all data zeroized - data not zeroed when used decreases. */
ForceZero(a->dp, a->size * sizeof(sp_int_digit));
_sp_zero(a);
#ifdef HAVE_WOLF_BIGINT
wc_bigint_zero(&a->raw);

View File

@@ -297,6 +297,7 @@ int wc_BufferKeyDecrypt(EncryptedInfo* info, byte* der, word32 derSz,
info->iv);
#endif /* !NO_AES && HAVE_AES_CBC && HAVE_AES_DECRYPT */
ForceZero(key, WC_MAX_SYM_KEY_SIZE);
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
#endif
@@ -354,6 +355,7 @@ int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz,
info->iv);
#endif /* !NO_AES && HAVE_AES_CBC */
ForceZero(key, WC_MAX_SYM_KEY_SIZE);
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
#endif

View File

@@ -7804,6 +7804,7 @@ static int aes_key_size_test(void)
ret = 0; /* success */
out:
wc_AesFree(aes);
#ifdef WOLFSSL_SMALL_STACK
XFREE(aes, HEAP_HINT, DYNAMIC_TYPE_AES);
#endif