@@ -1054,6 +1054,14 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
10541054 return BAD_FUNC_ARG;
10551055 }
10561056
1057+ #ifdef WOLFSSL_CHECK_MEM_ZERO
1058+ /* Poison and register firstExpand before it is written so that any path
1059+ * below (all of which funnel through cleanup) is covered. */
1060+ XMEMSET(firstExpand, 0xff, sizeof(firstExpand));
1061+ wc_MemZero_Add("Tls13_Exporter firstExpand", firstExpand,
1062+ sizeof(firstExpand));
1063+ #endif
1064+
10571065 /* Derive-Secret(Secret, label, "") */
10581066 ret = Tls13HKDFExpandLabel(ssl, firstExpand, hashLen,
10591067 ssl->arrays->exporterSecret, hashLen,
@@ -1076,6 +1084,9 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
10761084 * Hash(context_value); wipe both before the stack frame is reclaimed. */
10771085 ForceZero(firstExpand, sizeof(firstExpand));
10781086 ForceZero(hashOut, sizeof(hashOut));
1087+ #ifdef WOLFSSL_CHECK_MEM_ZERO
1088+ wc_MemZero_Check(firstExpand, sizeof(firstExpand));
1089+ #endif
10791090 return ret;
10801091}
10811092#endif
@@ -1533,6 +1544,11 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
15331544 WC_ALLOC_VAR_EX(key_dig, byte, MAX_PRF_DIG, ssl->heap,
15341545 DYNAMIC_TYPE_DIGEST, return MEMORY_E);
15351546
1547+ #ifdef WOLFSSL_CHECK_MEM_ZERO
1548+ XMEMSET(key_dig, 0xff, MAX_PRF_DIG);
1549+ wc_MemZero_Add("DeriveTls13Keys key_dig", key_dig, MAX_PRF_DIG);
1550+ #endif
1551+
15361552 if (side == ENCRYPT_AND_DECRYPT_SIDE) {
15371553 provision = PROVISION_CLIENT_SERVER;
15381554 }
@@ -1665,7 +1681,8 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
16651681 WOLFSSL_SERVER_END);
16661682 if (ret != 0)
16671683 goto end;
1668- i += ssl->specs.iv_size;
1684+ /* Server IV is the last key material written to key_dig, so i is not
1685+ * advanced here; the whole buffer is zeroed at end regardless. */
16691686 }
16701687
16711688 /* Store keys and IVs but don't activate them. */
@@ -1717,7 +1734,9 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
17171734#endif /* WOLFSSL_DTLS13 */
17181735
17191736end:
1720- ForceZero(key_dig, (word32)i);
1737+ /* Zero the whole key_dig buffer (not just the i bytes derived) so no
1738+ * key-schedule material can linger in the unused tail. */
1739+ ForceZero(key_dig, MAX_PRF_DIG);
17211740#ifdef WOLFSSL_SMALL_STACK
17221741 XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST);
17231742#elif defined(WOLFSSL_CHECK_MEM_ZERO)
@@ -6523,6 +6542,13 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
65236542
65246543 (void)suite;
65256544
6545+ #ifdef WOLFSSL_CHECK_MEM_ZERO
6546+ /* Poison and register binderKey up front; every exit below (including the
6547+ * error paths) funnels through the cleanup label which zeroes it. */
6548+ XMEMSET(binderKey, 0xff, sizeof(binderKey));
6549+ wc_MemZero_Add("DoPreSharedKeys binderKey", binderKey, sizeof(binderKey));
6550+ #endif
6551+
65266552 ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
65276553 if (ext == NULL) {
65286554 WOLFSSL_MSG("No pre shared extension keys found");
@@ -6739,6 +6765,9 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
67396765cleanup:
67406766 ForceZero(binderKey, sizeof(binderKey));
67416767 ForceZero(binder, sizeof(binder));
6768+ #ifdef WOLFSSL_CHECK_MEM_ZERO
6769+ wc_MemZero_Check(binderKey, sizeof(binderKey));
6770+ #endif
67426771 WOLFSSL_LEAVE("DoPreSharedKeys", ret);
67436772
67446773 return ret;
0 commit comments