Conversation
9c0208f to
eae465e
Compare
b186ecc to
f529484
Compare
…_examples.sh and tpm2_tools_test.sh to make test for fwtpm as well
src/fwtpm/fwtpm_nv.c
Outdated
| pkt.pos = 2; /* skip size we already read */ | ||
| TPM2_Packet_ParsePublic(&pkt, &pub2b); | ||
| XMEMCPY(pub, &pub2b.publicArea, sizeof(TPMT_PUBLIC)); | ||
| *pos += pubSz; |
There was a problem hiding this comment.
This calls TPM2_Packet_ParsePublic which parses the size again. I think restoring might corrupt saved records. Please verify with a test
| /* Check if journal has space */ | ||
| if (ctx->nvWritePos + entrySize > hal->maxSize) { | ||
| /* Compact and retry */ | ||
| rc = FWTPM_NV_Save(ctx); |
There was a problem hiding this comment.
cyclic recursion seems possible between FWTPM_NV_Save and FwNvAppendEntry if compacting is not sufficient the functions will keep calling each other
src/fwtpm/fwtpm_command.c
Outdated
| FwFlushAllSessions(ctx); | ||
| } | ||
|
|
||
| FWTPM_NV_Save(ctx); |
There was a problem hiding this comment.
Return value is discarded here, this functions will return success regardless of FWTPM_NV_Save result. Review error handling in this function.
- Fixed LE/BE endianness mismatch in FwNvMarshalPublic/FwNvUnmarshalPublic - Added nvCompacting guard to prevent infinite recursion between FwNvAppendEntry and FWTPM_NV_Save - Check FWTPM_NV_Save return value in FwCmd_Shutdown and other callers - Reinitialize hash context per iteration in TPM2_KDFe_ex for multi-block derivation - Align packet->pos to inSensSize boundary in ParseSensitiveCreate - Clean up wolfCrypt resources if FWTPM_NV_Init fails in FWTPM_Init - Reset g_initialized on fuzzer reinit failure - Fix configure.ac so --enable-swtpm=uart doesn't force TIS mode - Update README command count from 103/91% to 105/93%
- Fixed memory leak in FwComputeRpHash — initialized rc = 0, added FWTPM_FREE_VAR(hashCtx) before both early returns to prevent heap leak under WOLFTPM_SMALL_STACK - Removed static from eccUniqueBuf in FwCmd_CreatePrimary — eliminates thread-safety risk and stale data persistence across calls (132-byte buffer is fine on stack) - Initialized rc = TPM_RC_SUCCESS in FWTPM_ProcessCommand — prevents use of uninitialized variable - Added XMEMSET(cmdAuths, 0, sizeof(cmdAuths)) in FWTPM_ProcessCommand — zeroes auth struct array to prevent use of garbage data on partial parse - Added auth-parse error check — if auth area parsing fails (e.g. TPM_RC_AUTHSIZE), returns error response instead of falling through to command dispatch - Moved pwSz/avSz into inner scope — declared where actually used instead of function scope - Added TPM2_ForceZero(&bindAuth, ...) in FwCmd_StartAuthSession — zeroizes hierarchy auth secrets before scope exit - Fixed NV handle mask consistency — changed == NV_INDEX_FIRST to == (NV_INDEX_FIRST & 0xFF000000) to match style elsewhere - Added wc_HmacInit() in FwWrapPrivate — call wc_HmacInit before wc_HmacSetKey, matching pattern used in FwComputeSessionHmac and FwDeriveWrapKey - Added wc_HmacInit() in FwUnwrapPrivate — same fix for the unwrap path - Fixed UART (void)port suppression — removed erroneous cast that hid the fact port is used later - Added NULL check before atoi(port) — prevents undefined behavior if port is NULL - Restored idx >= inputSz bounds check in TPM2_ASN_DecodeX509Cert — defense-in-depth against OOB read on malformed certificates - Restored *sigSz < 3 minimum in TPM2_ASN_RsaUnpadPkcsv15 — valid PKCS#1 v1.5 needs at least 0x00|0x01|0xFF - Fixed summary alignment — consistent column spacing for fwTPM output lines
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 60 out of 62 changed files in this pull request and generated 10 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (rc >= 0) { | ||
| if (len <= 0 || idx >= (word32)inputSz) { | ||
| if (idx >= (word32)inputSz) { | ||
| rc = TPM_RC_VALUE; | ||
| } | ||
| } |
There was a problem hiding this comment.
In TPM2_ASN_DecodeX509Cert(), the new check only guards idx >= inputSz but no longer rejects a zero/negative len returned by TPM2_ASN_GetHeader() for the version wrapper. If len is 0, the subsequent input[idx] check may end up validating the next field's tag as the version INTEGER and mis-parse the certificate structure. Consider restoring the len <= 0 validation (and/or validating idx + len <= inputSz) before continuing.
| TPM2_Packet_ParseU16(packet, &wireSize); | ||
| copySz = wireSize; | ||
| if (copySz > maxBufSz) { | ||
| copySz = maxBufSz; | ||
| } |
There was a problem hiding this comment.
TPM2_Packet_ParseU16Buf() never checks that wireSize fits within the remaining packet (packet->size - packet->pos). Since TPM2_Packet_ParseBytes() always advances packet->pos by the requested size (even when truncating the copy), a malformed response can push pos beyond packet->size and make later parsing silently incorrect. Consider clamping the skip/copy to remaining bytes and/or returning an error when wireSize exceeds what’s left in the packet.
| /* Open existing shared memory file */ | ||
| fd = open(FWTPM_TIS_SHM_PATH, O_RDWR); | ||
| if (fd < 0) { | ||
| #ifdef DEBUG_WOLFTPM | ||
| printf("fwTPM HAL: open(%s) failed: %d (%s)\n", |
There was a problem hiding this comment.
FWTPM_TIS_ClientConnect() opens the shared-memory backing file in /tmp without hardening flags or verification. Since the server creates this path with O_NOFOLLOW and 0600 permissions, consider using O_NOFOLLOW (and ideally O_CLOEXEC) on the client too, and/or fstat() validation (regular file, expected mode/owner) to reduce symlink/hijack risk.
| uses: actions/checkout@master | ||
|
|
||
| - name: Checkout wolfSSL | ||
| uses: actions/checkout@master |
There was a problem hiding this comment.
This workflow uses actions/checkout@master, which is a moving ref and less reproducible than a version tag (e.g. @v4) or a pinned SHA. Since other workflows in this PR already use actions/checkout@v4, consider switching these steps to @v4 (or pinning to a commit) to reduce supply-chain risk and improve determinism.
| uses: actions/checkout@master | |
| - name: Checkout wolfSSL | |
| uses: actions/checkout@master | |
| uses: actions/checkout@v4 | |
| - name: Checkout wolfSSL | |
| uses: actions/checkout@v4 |
| if test "x$ENABLED_FWTPM_ONLY" = "xyes" | ||
| then | ||
| ENABLED_FWTPM=yes | ||
| ENABLED_EXAMPLES=no | ||
| ENABLED_WRAPPER=no |
There was a problem hiding this comment.
--enable-fwtpm-only sets ENABLED_FWTPM=yes after the --enable-fwtpm validation block, so the wolfCrypt requirement check won’t run for fwtpm-only builds. This can turn a configuration error (e.g. --enable-fwtpm-only --disable-wolfcrypt) into a later compile-time failure instead of a clear configure-time error. Consider sharing/moving the fwTPM validation so it applies to both options.
| int TPM2_AesCfbEncrypt( | ||
| const byte* key, int keySz, | ||
| const byte* iv, | ||
| byte* data, word32 dataSz) | ||
| { |
There was a problem hiding this comment.
TPM2_AesCfbEncrypt()/TPM2_AesCfbDecrypt() are exported APIs but don’t validate inputs (e.g., key/data can be NULL, and keySz can be an unsupported size). These pointers/sizes are passed directly into wc_AesSetKey/wc_AesCfb* and can lead to NULL deref or unexpected behavior. Consider returning BAD_FUNC_ARG when required pointers are NULL (or when dataSz>0 with data==NULL) and validating keySz is 16/24/32.
| int TPM2_HmacCompute( | ||
| TPMI_ALG_HASH hashAlg, | ||
| const byte* key, word32 keySz, | ||
| const byte* data, word32 dataSz, | ||
| const byte* data2, word32 data2Sz, |
There was a problem hiding this comment.
TPM2_HmacCompute() does not validate required pointers before calling wolfCrypt (e.g., digest is passed to wc_HmacFinal unconditionally, and data is passed to wc_HmacUpdate even when dataSz > 0). As a public API this can crash on NULL inputs. Consider adding BAD_FUNC_ARG checks for NULL digest, and for (data==NULL && dataSz>0), plus similar validation for expected in TPM2_HmacVerify().
| int TPM2_HashCompute( | ||
| TPMI_ALG_HASH hashAlg, | ||
| const byte* data, word32 dataSz, | ||
| byte* digest, word32* digestSz) | ||
| { |
There was a problem hiding this comment.
TPM2_HashCompute() calls wc_Hash(..., digest, ...) without validating digest (or data when dataSz > 0). Since this is an exported API, a NULL digest/data can cause a crash. Consider returning BAD_FUNC_ARG when required pointers are NULL (and when dataSz>0 with data==NULL).
| WOLFTPM_API int TPM2_AesCfbEncrypt( | ||
| const byte* key, int keySz, | ||
| const byte* iv, | ||
| byte* data, word32 dataSz); | ||
|
|
There was a problem hiding this comment.
tpm2_crypto.h declares these AES/HMAC helpers unconditionally, but the corresponding implementations are compiled out when wolfCrypt or the primitive is disabled (e.g. WOLFTPM2_NO_WOLFCRYPT or NO_AES). That can leave callers with compile-time prototypes but missing link-time symbols. Consider either guarding these declarations with the same feature macros as the .c file, or providing stub implementations that return NOT_COMPILED_IN when disabled.
| WOLFTPM_API int TPM2_HmacCompute( | ||
| TPMI_ALG_HASH hashAlg, | ||
| const byte* key, word32 keySz, | ||
| const byte* data, word32 dataSz, | ||
| const byte* data2, word32 data2Sz, |
There was a problem hiding this comment.
Similarly, TPM2_HmacCompute/TPM2_HmacVerify are declared unconditionally here, but their implementations are compiled out when NO_HMAC (or WOLFTPM2_NO_WOLFCRYPT) is set. This can cause link errors in feature-disabled builds (including unit tests that compile against these prototypes). Consider guarding these declarations with #if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_HMAC) or adding stub implementations that return NOT_COMPILED_IN.
Summary
TPM2_Packet_ParseU16Bufvariant for safer response parsingfwTPM Server
Core TPM 2.0 command processing in
src/fwtpm/:fwtpm_command.c— 105 command handlers with full auth, sessions, parameter encryptionfwtpm_nv.c— TLV journal NV storage (file-based default, HAL-abstracted for flash)fwtpm_io.c— Socket transport (mssim + swtpm protocol auto-detection)fwtpm_tis.c/fwtpm_tis_shm.c— TIS register interface via POSIX shared memoryfwtpm_crypto.c— Key generation, sign/verify, seed encrypt/decrypt helpersBuild:
./configure --enable-fwtpm && makeExample: wolfSSL/wolftpm-examples#1
Primary Key Derivation (TPM 2.0 Part 1 Section 26)
UART Transport (
--enable-swtpm=uart)New transport option for wolfTPM client library to communicate with embedded fwTPM over serial:
./configure --enable-swtpm=uart— uses termios serial I/O instead of TCP socketsTPM2_SWTPM_HOSTenv var selects serial device at runtimeTesting
scripts/tpm2_tools_test.sh)examples/run_examples.sh)tests/fuzz/)scripts/fwtpm_emu_test.sh)