@@ -1505,10 +1505,26 @@ int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen, byte* secret)
15051505 * hash The hash result - verify data.
15061506 * returns length of verify data generated.
15071507 */
1508+ #if defined(WOLFSSL_ASYNC_REINVOKE) && !defined(NO_HMAC)
1509+ /* Release the held transcript Hmac and its resume state. */
1510+ void Tls13FreeHsHmac(WOLFSSL* ssl)
1511+ {
1512+ if (ssl->hsHmac != NULL) {
1513+ wc_HmacFree(ssl->hsHmac);
1514+ XFREE(ssl->hsHmac, ssl->heap, DYNAMIC_TYPE_HMAC);
1515+ ssl->hsHmac = NULL;
1516+ }
1517+ ssl->hsHmacStep = 0;
1518+ ssl->hsHmacOut = NULL;
1519+ }
1520+ #endif /* WOLFSSL_ASYNC_REINVOKE && !NO_HMAC */
1521+
15081522static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash,
15091523 word32* pHashSz)
15101524{
1525+ #ifndef WOLFSSL_ASYNC_REINVOKE
15111526 WC_DECLARE_VAR(verifyHmac, Hmac, 1, 0);
1527+ #endif
15121528 int hashType = WC_SHA256;
15131529 int hashSz = WC_SHA256_DIGEST_SIZE;
15141530 int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
@@ -1561,6 +1577,51 @@ static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash,
15611577 WOLFSSL_BUFFER(hash, hashSz);
15621578#endif
15631579
1580+ #ifdef WOLFSSL_ASYNC_REINVOKE
1581+ /* Held on the SSL object so a crypto callback WC_PENDING_E resumes by
1582+ * re-invoking the same Hmac with identical arguments; the transcript
1583+ * hash input is recomputed deterministically by the caller's retry.
1584+ * Bound to the output buffer: a replayed caller that computes several
1585+ * HMACs (the PSK binder list) must not resume one request against
1586+ * another's key, so a different output discards the held state. */
1587+ if (ssl->hsHmac != NULL && ssl->hsHmacOut != hash)
1588+ Tls13FreeHsHmac(ssl);
1589+ if (ssl->hsHmac == NULL) {
1590+ ssl->hsHmac = (Hmac*)XMALLOC(sizeof(Hmac), ssl->heap,
1591+ DYNAMIC_TYPE_HMAC);
1592+ if (ssl->hsHmac == NULL)
1593+ return MEMORY_E;
1594+ ret = wc_HmacInit(ssl->hsHmac, ssl->heap, ssl->devId);
1595+ if (ret != 0) {
1596+ Tls13FreeHsHmac(ssl);
1597+ return ret;
1598+ }
1599+ ssl->hsHmacStep = 0;
1600+ ssl->hsHmacOut = hash;
1601+ }
1602+ /* Armed before the operations, matching the HKDF helpers. */
1603+ ret = Tls13KdfAsyncInit(ssl);
1604+ if (ret != 0) {
1605+ Tls13FreeHsHmac(ssl);
1606+ return ret;
1607+ }
1608+ if (ssl->hsHmacStep == 0) {
1609+ ret = wc_HmacSetKey(ssl->hsHmac, hashType, key,
1610+ ssl->specs.hash_size);
1611+ if (ret == 0)
1612+ ssl->hsHmacStep = 1;
1613+ }
1614+ if (ret == 0 && ssl->hsHmacStep == 1) {
1615+ ret = wc_HmacUpdate(ssl->hsHmac, hash, (word32)hashSz);
1616+ if (ret == 0)
1617+ ssl->hsHmacStep = 2;
1618+ }
1619+ if (ret == 0 && ssl->hsHmacStep == 2)
1620+ ret = wc_HmacFinal(ssl->hsHmac, hash);
1621+ if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
1622+ return wolfSSL_AsyncPush(ssl, &ssl->kdfAsyncDev);
1623+ Tls13FreeHsHmac(ssl);
1624+ #else
15641625 WC_ALLOC_VAR_EX(verifyHmac, Hmac, 1, NULL, DYNAMIC_TYPE_HMAC,
15651626 return MEMORY_E);
15661627
@@ -1576,6 +1637,7 @@ static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash,
15761637 }
15771638
15781639 WC_FREE_VAR_EX(verifyHmac, NULL, DYNAMIC_TYPE_HMAC);
1640+ #endif /* WOLFSSL_ASYNC_REINVOKE */
15791641
15801642#ifdef WOLFSSL_DEBUG_TLS
15811643 WOLFSSL_MSG(" Hash");
@@ -14031,6 +14093,7 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
1403114093static int ExpectedResumptionSecret(WOLFSSL* ssl)
1403214094{
1403314095 int ret;
14096+ int saveRet = 0;
1403414097 word32 finishedSz = 0;
1403514098 byte mac[WC_MAX_DIGEST_SIZE];
1403614099 Digest digest;
@@ -14094,6 +14157,9 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl)
1409414157
1409514158 /* Restore the hash inline with currently seen messages. */
1409614159restore:
14160+ /* The restore result must not mask the error that got here, or a
14161+ * WC_PENDING_E would be reported as success with the derive skipped. */
14162+ saveRet = ret;
1409714163 switch (ssl->specs.mac_algorithm) {
1409814164 #ifndef NO_SHA256
1409914165 case sha256_mac:
@@ -14124,6 +14190,8 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl)
1412414190 break;
1412514191 #endif
1412614192 }
14193+ if (saveRet != 0)
14194+ ret = saveRet;
1412714195
1412814196 ForceZero(mac, sizeof(mac));
1412914197 return ret;
0 commit comments