Advance SPDM receive sequence after auth and harden size checks

pull/604/head
Aidan Garske 2026-09-10 14:05:48 -07:00
parent 58d0fa65fb
commit 1d8ea0cfd2
3 changed files with 24 additions and 13 deletions

View File

@ -183,7 +183,8 @@ int TPM2_IoCb(TPM2_CTX* ctx, INT32 isRead, UINT32 addr,
(void)userCtx;
#endif
#else
if (buf == NULL || size == 0 || size > MAX_SPI_FRAMESIZE) {
if (buf == NULL || size == 0 ||
size > (UINT16)(sizeof(txBuf) - TPM_TIS_HEADER_SZ)) {
ret = BAD_FUNC_ARG;
}
else {

View File

@ -55,6 +55,18 @@ static int wolfSPDM_BuildSimpleMsg(WOLFSPDM_CTX* ctx, byte msgCode,
return WOLFSPDM_SUCCESS;
}
/* KEY_EXCHANGE request size: 8-byte header, 32-byte RandomData, and two ECC
* coordinates, plus a config-specific OpaqueData block. Keep
* WOLFSPDM_KEYEX_OPAQUE_SZ in sync with the OpaqueData written below. */
#define WOLFSPDM_KEYEX_FIXED_SZ (40 + 2 * WOLFSPDM_ECC_KEY_SIZE)
#ifdef WOLFSPDM_NUVOTON
#define WOLFSPDM_KEYEX_OPAQUE_SZ 14
#elif defined(WOLFSPDM_NATIONS)
#define WOLFSPDM_KEYEX_OPAQUE_SZ 2
#else
#define WOLFSPDM_KEYEX_OPAQUE_SZ 22
#endif
int wolfSPDM_BuildKeyExchange(WOLFSPDM_CTX* ctx, byte* buf, word32* bufSz)
{
word32 offset = 0;
@ -64,15 +76,9 @@ int wolfSPDM_BuildKeyExchange(WOLFSPDM_CTX* ctx, byte* buf, word32* bufSz)
word32 pubKeyYSz = sizeof(pubKeyY);
int rc;
/* Require exactly the encoded request size: 40-byte fixed header, two ECC
* coordinates, and the config-specific OpaqueData block */
#ifdef WOLFSPDM_NUVOTON
SPDM_CHECK_BUILD_ARGS(ctx, buf, bufSz, 40 + 2 * WOLFSPDM_ECC_KEY_SIZE + 14);
#elif defined(WOLFSPDM_NATIONS)
SPDM_CHECK_BUILD_ARGS(ctx, buf, bufSz, 40 + 2 * WOLFSPDM_ECC_KEY_SIZE + 2);
#else
SPDM_CHECK_BUILD_ARGS(ctx, buf, bufSz, 40 + 2 * WOLFSPDM_ECC_KEY_SIZE + 22);
#endif
/* Require exactly the encoded request size */
SPDM_CHECK_BUILD_ARGS(ctx, buf, bufSz,
WOLFSPDM_KEYEX_FIXED_SZ + WOLFSPDM_KEYEX_OPAQUE_SZ);
rc = wolfSPDM_GenerateEphemeralKey(ctx);
if (rc == WOLFSPDM_SUCCESS)

View File

@ -294,6 +294,13 @@ int wolfSPDM_DecryptInternal(WOLFSPDM_CTX* ctx,
wolfSPDM_DebugPrint(ctx, "AES-GCM decrypt failed: %d\n", rc);
ret = WOLFSPDM_E_DECRYPT_FAIL;
}
else {
/* Record is authenticated (tag verified) so the peer has advanced;
* advance now. A forged record fails the tag and never reaches
* here, and a later payload parse error stays fatal without
* desyncing the sequence. */
ctx->rspSeqNum++;
}
}
if (aesInit) {
wc_AesFree(&aes);
@ -336,9 +343,6 @@ int wolfSPDM_DecryptInternal(WOLFSPDM_CTX* ctx,
}
if (ret == WOLFSPDM_SUCCESS) {
/* Advance the receive counter only after authentication and payload
* validation succeed, so a forged record cannot desync the sequence */
ctx->rspSeqNum++;
wolfSPDM_DebugPrint(ctx, "Decrypted %u bytes -> %u bytes\n",
encSz, *plainSz);
}