Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 15 additions & 43 deletions src/tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -4121,41 +4121,22 @@ TPM_RC TPM2_Encapsulate(Encapsulate_In* in, Encapsulate_Out* out)
rc = TPM2_SendCommandAuth(ctx, &packet, &info);
if (rc == TPM_RC_SUCCESS) {
UINT32 paramSz = 0;
UINT16 wireSize;
UINT16 wireSize2;

if (st == TPM_ST_SESSIONS) {
TPM2_Packet_ParseU32(&packet, &paramSz);
}

/* Parse sharedSecret with bounds checking */
TPM2_Packet_ParseU16(&packet, &wireSize);
out->sharedSecret.size = wireSize;
if (out->sharedSecret.size >
(UINT16)sizeof(out->sharedSecret.buffer)) {
out->sharedSecret.size =
(UINT16)sizeof(out->sharedSecret.buffer);
}
TPM2_Packet_ParseBytes(&packet, out->sharedSecret.buffer,
out->sharedSecret.size);
if (wireSize > out->sharedSecret.size) {
TPM2_Packet_ParseBytes(&packet, NULL,
wireSize - out->sharedSecret.size);
}

/* Parse ciphertext with bounds checking */
TPM2_Packet_ParseU16(&packet, &wireSize2);
out->ciphertext.size = wireSize2;
if (out->ciphertext.size >
(UINT16)sizeof(out->ciphertext.buffer)) {
out->ciphertext.size =
(UINT16)sizeof(out->ciphertext.buffer);
rc = TPM2_Packet_ParseU16BufStrict(&packet,
&out->sharedSecret.size, out->sharedSecret.buffer,
(UINT16)sizeof(out->sharedSecret.buffer));
if (rc == TPM_RC_SUCCESS) {
rc = TPM2_Packet_ParseU16BufStrict(&packet,
&out->ciphertext.size, out->ciphertext.buffer,
(UINT16)sizeof(out->ciphertext.buffer));
Comment thread
aidangarske marked this conversation as resolved.
}
TPM2_Packet_ParseBytes(&packet, out->ciphertext.buffer,
out->ciphertext.size);
if (wireSize2 > out->ciphertext.size) {
TPM2_Packet_ParseBytes(&packet, NULL,
wireSize2 - out->ciphertext.size);
if (rc != TPM_RC_SUCCESS) {
TPM2_ForceZero(&out->sharedSecret, sizeof(out->sharedSecret));
out->ciphertext.size = 0;
}
Comment thread
aidangarske marked this conversation as resolved.
}

Expand Down Expand Up @@ -4197,23 +4178,14 @@ TPM_RC TPM2_Decapsulate(Decapsulate_In* in, Decapsulate_Out* out)
rc = TPM2_SendCommandAuth(ctx, &packet, &info);
if (rc == TPM_RC_SUCCESS) {
UINT32 paramSz = 0;
UINT16 wireSize;

TPM2_Packet_ParseU32(&packet, &paramSz);

/* Parse sharedSecret with bounds checking */
TPM2_Packet_ParseU16(&packet, &wireSize);
out->sharedSecret.size = wireSize;
if (out->sharedSecret.size >
(UINT16)sizeof(out->sharedSecret.buffer)) {
out->sharedSecret.size =
(UINT16)sizeof(out->sharedSecret.buffer);
}
TPM2_Packet_ParseBytes(&packet, out->sharedSecret.buffer,
out->sharedSecret.size);
if (wireSize > out->sharedSecret.size) {
TPM2_Packet_ParseBytes(&packet, NULL,
wireSize - out->sharedSecret.size);
rc = TPM2_Packet_ParseU16BufStrict(&packet,
&out->sharedSecret.size, out->sharedSecret.buffer,
(UINT16)sizeof(out->sharedSecret.buffer));
if (rc != TPM_RC_SUCCESS) {
TPM2_ForceZero(&out->sharedSecret, sizeof(out->sharedSecret));
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/tpm2_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,28 @@ void TPM2_Packet_ParseU16Buf(TPM2_Packet* packet, UINT16* size, byte* buf,
}
}

/* Parse a UINT16-prefixed buffer, failing with TPM_RC_SIZE instead of
* truncating when the size exceeds maxBufSz or the bytes left in the packet. */
int TPM2_Packet_ParseU16BufStrict(TPM2_Packet* packet, UINT16* size,
byte* buf, UINT16 maxBufSz)
{
UINT16 wireSize = 0;

if (packet == NULL || size == NULL || buf == NULL)
return BAD_FUNC_ARG;
Comment thread
aidangarske marked this conversation as resolved.

*size = 0;
TPM2_Packet_ParseU16(packet, &wireSize);
if (packet->overflow || wireSize > maxBufSz ||
(int)wireSize > packet->size - packet->pos) {
packet->overflow = 1;
return TPM_RC_SIZE;
}
TPM2_Packet_ParseBytes(packet, buf, wireSize);
*size = wireSize;
return TPM_RC_SUCCESS;
}

void TPM2_Packet_MarkU16(TPM2_Packet* packet, int* markSz)
{
if (packet) {
Expand Down
27 changes: 27 additions & 0 deletions src/tpm2_wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -6727,6 +6727,23 @@ int wolfTPM2_VerifyDigestSignature(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
}
#endif /* WOLFTPM_MLDSA_VERIFY */

#if defined(WOLFTPM_MLKEM_ENCAP) || defined(WOLFTPM_MLKEM_DECAP)
#define WOLFTPM2_MLKEM_SS_SZ 32
#endif

#ifdef WOLFTPM_MLKEM_ENCAP
/* FIPS 203 ciphertext size for the parameter set, or 0 if unknown */
static int MlKemCiphertextSize(TPMI_MLKEM_PARAMETER_SET parameterSet)
{
switch (parameterSet) {
case TPM_MLKEM_512: return 768;
case TPM_MLKEM_768: return 1088;
case TPM_MLKEM_1024: return 1568;
default: return 0;
}
}
Comment thread
aidangarske marked this conversation as resolved.
#endif /* WOLFTPM_MLKEM_ENCAP */

#ifdef WOLFTPM_MLKEM_ENCAP
int wolfTPM2_Encapsulate(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
byte* ciphertext, int* ciphertextSz, byte* sharedSecret, int* sharedSecretSz)
Expand All @@ -6745,6 +6762,12 @@ int wolfTPM2_Encapsulate(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,

XMEMSET(&encapsulateOut, 0, sizeof(encapsulateOut));
rc = TPM2_Encapsulate(&encapsulateIn, &encapsulateOut);
if (rc == TPM_RC_SUCCESS && key->pub.publicArea.type == TPM_ALG_MLKEM &&
((int)encapsulateOut.ciphertext.size != MlKemCiphertextSize(
key->pub.publicArea.parameters.mlkemDetail.parameterSet) ||
encapsulateOut.sharedSecret.size != WOLFTPM2_MLKEM_SS_SZ)) {
rc = TPM_RC_SIZE;
}
if (rc == TPM_RC_SUCCESS) {
if (*ciphertextSz >= (int)encapsulateOut.ciphertext.size) {
XMEMCPY(ciphertext, encapsulateOut.ciphertext.buffer, encapsulateOut.ciphertext.size);
Expand Down Expand Up @@ -6799,6 +6822,10 @@ int wolfTPM2_Decapsulate(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,

XMEMSET(&decapsulateOut, 0, sizeof(decapsulateOut));
rc = TPM2_Decapsulate(&decapsulateIn, &decapsulateOut);
if (rc == TPM_RC_SUCCESS && key->pub.publicArea.type == TPM_ALG_MLKEM &&
decapsulateOut.sharedSecret.size != WOLFTPM2_MLKEM_SS_SZ) {
rc = TPM_RC_SIZE;
}
if (rc == TPM_RC_SUCCESS) {
if (*sharedSecretSz >= (int)decapsulateOut.sharedSecret.size) {
XMEMCPY(sharedSecret, decapsulateOut.sharedSecret.buffer, decapsulateOut.sharedSecret.size);
Expand Down
46 changes: 46 additions & 0 deletions tests/unit_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -4517,6 +4517,51 @@ static void test_TPM2_ParseSpdmSessionInfo_Truncated(void)
}
#endif /* WOLFTPM_SPDM */

static void test_TPM2_Packet_ParseU16BufStrict(void)
{
byte field[] = { 0x00, 0x04, 0x11, 0x22, 0x33, 0x44 };
byte out[8];
TPM2_Packet packet;
UINT16 size;
int rc;

XMEMSET(&packet, 0, sizeof(packet));
XMEMSET(out, 0, sizeof(out));
packet.buf = field;
packet.size = (int)sizeof(field);
rc = TPM2_Packet_ParseU16BufStrict(&packet, &size, out, 4);
AssertIntEQ(rc, TPM_RC_SUCCESS);
AssertIntEQ(size, 4);
AssertIntEQ(out[3], 0x44);
AssertIntEQ(packet.pos, packet.size);

/* Larger than the destination: rejected, not truncated */
XMEMSET(&packet, 0, sizeof(packet));
packet.buf = field;
packet.size = (int)sizeof(field);
rc = TPM2_Packet_ParseU16BufStrict(&packet, &size, out, 3);
AssertIntEQ(rc, TPM_RC_SIZE);
AssertIntEQ(size, 0);

/* Larger than the bytes left in the response */
XMEMSET(&packet, 0, sizeof(packet));
packet.buf = field;
packet.size = (int)sizeof(field) - 1;
rc = TPM2_Packet_ParseU16BufStrict(&packet, &size, out, sizeof(out));
AssertIntEQ(rc, TPM_RC_SIZE);
AssertIntEQ(size, 0);

/* Size field itself truncated */
XMEMSET(&packet, 0, sizeof(packet));
packet.buf = field;
packet.size = 1;
rc = TPM2_Packet_ParseU16BufStrict(&packet, &size, out, sizeof(out));
AssertIntEQ(rc, TPM_RC_SIZE);
AssertIntEQ(size, 0);

printf("Test TPM Wrapper:\tParseU16BufStrict:\t\tPassed\n");
}

/* TPM2_Packet_ParsePoint must resync to outerStart + point->size so a
* malformed wire blob with inner x.size / y.size disagreement can't
* desynchronize subsequent fields. */
Expand Down Expand Up @@ -9940,6 +9985,7 @@ int unit_tests(int argc, char *argv[])
test_wolfTPM2_PolicyTransportSPDMMake();
test_TPM2_ParseSpdmSessionInfo_Truncated();
#endif
test_TPM2_Packet_ParseU16BufStrict();
test_wolfTPM2_Init();
test_wolfTPM2_OpenExisting();
test_wolfTPM2_GetCapabilities();
Expand Down
2 changes: 2 additions & 0 deletions wolftpm/tpm2_packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ WOLFTPM_TEST_API int TPM2_ParseSpdmSessionInfo(TPM2_Packet* packet,
*/
WOLFTPM_LOCAL void TPM2_Packet_ParseU16Buf(TPM2_Packet* packet, UINT16* size,
byte* buf, UINT16 maxBufSz);
WOLFTPM_TEST_API int TPM2_Packet_ParseU16BufStrict(TPM2_Packet* packet,
Comment thread
aidangarske marked this conversation as resolved.
UINT16* size, byte* buf, UINT16 maxBufSz);
WOLFTPM_LOCAL void TPM2_Packet_MarkU16(TPM2_Packet* packet, int* markSz);
WOLFTPM_LOCAL int TPM2_Packet_PlaceU16(TPM2_Packet* packet, int markSz);
WOLFTPM_LOCAL void TPM2_Packet_MarkU32(TPM2_Packet* packet, int* markSz);
Expand Down
Loading