Skip to content

Commit 3f6d189

Browse files
committed
Minor code cleanups.
1 parent 1a7c490 commit 3f6d189

File tree

7 files changed

+131
-55
lines changed

7 files changed

+131
-55
lines changed

.github/workflows/make-test-swtpm.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
wolftpm_config: --enable-st33
6969
# STMicro ST33KTPM2
7070
- name: st33ktpm2 firmware
71-
wolftpm_config: --enable-st33 --enable-firmware --enable-st
71+
wolftpm_config: --enable-st33 --enable-firmware
7272
# Microchip
7373
- name: microchip
7474
wolftpm_config: --enable-microchip

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ examples/boot/secret_seal
8484
examples/boot/secret_unseal
8585
examples/firmware/ifx_fw_extract
8686
examples/firmware/ifx_fw_update
87+
examples/firmware/st33_fw_update
8788
examples/endorsement/get_ek_certs
8889
examples/endorsement/verify_ek_cert
8990

examples/firmware/include.am

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,31 @@ EXTRA_DIST += examples/firmware/Makefile
88
EXTRA_DIST += examples/firmware/ifx_fw_extract.c
99

1010
if BUILD_EXAMPLES
11-
if BUILD_INFINEON
1211
if BUILD_FIRMWARE
12+
13+
if BUILD_INFINEON
1314
noinst_PROGRAMS += examples/firmware/ifx_fw_update
1415
noinst_HEADERS += examples/firmware/ifx_fw_update.h
1516
examples_firmware_ifx_fw_update_SOURCES = examples/firmware/ifx_fw_update.c \
1617
examples/tpm_test_keys.c
1718
examples_firmware_ifx_fw_update_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
1819
examples_firmware_ifx_fw_update_DEPENDENCIES = src/libwolftpm.la
1920
endif
20-
endif
21+
2122
if BUILD_ST33
22-
if BUILD_FIRMWARE
2323
noinst_PROGRAMS += examples/firmware/st33_fw_update
2424
examples_firmware_st33_fw_update_SOURCES = examples/firmware/st33_fw_update.c \
2525
examples/tpm_test_keys.c
2626
examples_firmware_st33_fw_update_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
2727
examples_firmware_st33_fw_update_DEPENDENCIES = src/libwolftpm.la
28+
2829
endif
2930
endif
3031
endif
3132

3233
example_firmwaredir = $(exampledir)/firmware
33-
dist_example_firmware_DATA = examples/firmware/ifx_fw_update.c
34+
dist_example_firmware_DATA = examples/firmware/ifx_fw_update.c \
35+
examples/firmware/st33_fw_update.c
3436

35-
DISTCLEANFILES+= examples/firmware/.libs/ifx_fw_update
37+
DISTCLEANFILES+= examples/firmware/.libs/ifx_fw_update \
38+
examples/firmware/.libs/st33_fw_update

examples/firmware/st33_fw_update.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,20 +138,25 @@ static int TPM2_ST33_SendFirmwareData(fw_info_t* fwinfo)
138138
return rc;
139139
}
140140

141+
/* Callback function for firmware data access
142+
* Returns the actual number of bytes copied (may be less than requested at end of buffer)
143+
* Returns BUFFER_E on error (offset out of bounds) */
141144
static int TPM2_ST33_FwData_Cb(uint8_t* data, uint32_t data_req_sz,
142145
uint32_t offset, void* cb_ctx)
143146
{
144147
fw_info_t* fwinfo = (fw_info_t*)cb_ctx;
148+
uint32_t actual_sz = data_req_sz;
149+
145150
if (offset > fwinfo->firmware_bufSz) {
146151
return BUFFER_E;
147152
}
148153
if (offset + data_req_sz > (uint32_t)fwinfo->firmware_bufSz) {
149-
data_req_sz = (uint32_t)fwinfo->firmware_bufSz - offset;
154+
actual_sz = (uint32_t)fwinfo->firmware_bufSz - offset;
150155
}
151-
if (data_req_sz > 0) {
152-
XMEMCPY(data, &fwinfo->firmware_buf[offset], data_req_sz);
156+
if (actual_sz > 0) {
157+
XMEMCPY(data, &fwinfo->firmware_buf[offset], actual_sz);
153158
}
154-
return data_req_sz;
159+
return actual_sz; /* Return actual bytes copied */
155160
}
156161

157162
static void TPM2_ST33_PrintInfo(WOLFTPM2_CAPS* caps)

src/tpm2_wrap.c

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8695,21 +8695,26 @@ int wolfTPM2_FirmwareUpgradeCancel(WOLFTPM2_DEV* dev)
86958695

86968696
/* ST33 uses password auth (TPM_RS_PW) for firmware update, not policy */
86978697

8698-
/* Start firmware upgrade (non-LMS): sends manifest (blob0=177 bytes)
8699-
* via FieldUpgradeStart */
8700-
static int tpm2_st33_firmware_start(WOLFTPM2_DEV* dev,
8701-
uint8_t* manifest, uint32_t manifest_sz)
8698+
/* Common firmware upgrade start function
8699+
* Sends manifest (blob0) via FieldUpgradeStart
8700+
* 300ms delay: ST reference implementation uses this delay to allow
8701+
* TPM to switch modes after FieldUpgradeStart command */
8702+
static int tpm2_st33_firmware_start_common(WOLFTPM2_DEV* dev,
8703+
uint8_t* manifest, uint32_t manifest_sz, int is_lms)
87028704
{
87038705
int rc;
87048706

87058707
(void)dev;
87068708

87078709
/* ST33 uses password auth (TPM_RS_PW) for FieldUpgradeStart.
8708-
* This matches the ST reference implementation behavior. */
8710+
* This matches the ST reference implementation behavior.
8711+
* For LMS format, the manifest (blob0) already contains the embedded
8712+
* LMS signature. Send the full manifest directly. */
87098713
rc = TPM2_ST33_FieldUpgradeStart(TPM_RS_PW, manifest, manifest_sz);
87108714

87118715
if (rc == TPM_RC_SUCCESS) {
8712-
/* delay to give the TPM time to switch modes */
8716+
/* 300ms delay: ST reference implementation uses this delay to allow
8717+
* TPM to switch modes after FieldUpgradeStart command */
87138718
tpm2_firmware_sleep_ms(300);
87148719

87158720
#if !defined(WOLFTPM_LINUX_DEV) && !defined(WOLFTPM_SWTPM) && \
@@ -8720,43 +8725,28 @@ static int tpm2_st33_firmware_start(WOLFTPM2_DEV* dev,
87208725
}
87218726
#ifdef DEBUG_WOLFTPM
87228727
if (rc != TPM_RC_SUCCESS) {
8723-
printf("ST33 Firmware upgrade start failed 0x%x: %s\n",
8724-
rc, TPM2_GetRCString(rc));
8728+
printf("ST33 Firmware upgrade start%s failed 0x%x: %s\n",
8729+
is_lms ? " (LMS)" : "", rc, TPM2_GetRCString(rc));
87258730
}
8731+
#else
8732+
(void)is_lms; /* Suppress unused parameter warning when DEBUG_WOLFTPM not defined */
87268733
#endif
87278734
return rc;
87288735
}
87298736

8737+
/* Start firmware upgrade (non-LMS): sends manifest (blob0=177 bytes)
8738+
* via FieldUpgradeStart */
8739+
static int tpm2_st33_firmware_start(WOLFTPM2_DEV* dev,
8740+
uint8_t* manifest, uint32_t manifest_sz)
8741+
{
8742+
return tpm2_st33_firmware_start_common(dev, manifest, manifest_sz, 0);
8743+
}
8744+
87308745
/* Start firmware upgrade (LMS): sends manifest (blob0=2697 bytes with embedded signature) via FieldUpgradeStart */
87318746
static int tpm2_st33_firmware_start_lms(WOLFTPM2_DEV* dev,
87328747
uint8_t* manifest, uint32_t manifest_sz)
87338748
{
8734-
int rc;
8735-
8736-
(void)dev;
8737-
8738-
/* ST33 LMS: The manifest (blob0) already contains the embedded
8739-
* LMS signature. Send the full manifest directly.
8740-
* Uses password auth (TPM_RS_PW) like ST reference implementation. */
8741-
rc = TPM2_ST33_FieldUpgradeStart(TPM_RS_PW, manifest, manifest_sz);
8742-
8743-
if (rc == TPM_RC_SUCCESS) {
8744-
/* delay to give the TPM time to switch modes */
8745-
tpm2_firmware_sleep_ms(300);
8746-
8747-
#if !defined(WOLFTPM_LINUX_DEV) && !defined(WOLFTPM_SWTPM) && \
8748-
!defined(WOLFTPM_WINAPI)
8749-
/* Do chip startup and request locality again */
8750-
rc = TPM2_ChipStartup(&dev->ctx, 10);
8751-
#endif
8752-
}
8753-
#ifdef DEBUG_WOLFTPM
8754-
if (rc != TPM_RC_SUCCESS) {
8755-
printf("ST33 Firmware upgrade start (LMS) failed 0x%x: %s\n",
8756-
rc, TPM2_GetRCString(rc));
8757-
}
8758-
#endif
8759-
return rc;
8749+
return tpm2_st33_firmware_start_common(dev, manifest, manifest_sz, 1);
87608750
}
87618751

87628752
/* ST33 sends full manifest (blob0) directly in FieldUpgradeStart */
@@ -8790,16 +8780,27 @@ static int tpm2_st33_firmware_data(WOLFTPM2_DEV* dev,
87908780
/* Read blob header: type (1 byte) + length (2 bytes big-endian) */
87918781
rc = cb(blob_header, 3, offset, cb_ctx);
87928782
if (rc < 3) {
8793-
/* End of data or error */
8794-
if (rc == 0 || blob_header[0] == 0) {
8795-
#ifdef DEBUG_WOLFTPM
8796-
printf("ST33 Firmware data done\n");
8797-
#endif
8798-
rc = TPM_RC_SUCCESS;
8783+
/* Handle end of data or error conditions */
8784+
if (rc == 0) {
8785+
/* End of data - check if we're at a valid end marker */
8786+
if (offset == 0 || blob_header[0] == 0) {
8787+
#ifdef DEBUG_WOLFTPM
8788+
printf("ST33 Firmware data done\n");
8789+
#endif
8790+
rc = TPM_RC_SUCCESS;
8791+
}
8792+
else {
8793+
#ifdef DEBUG_WOLFTPM
8794+
printf("ST33 Firmware data incomplete at offset %u\n", offset);
8795+
#endif
8796+
rc = BUFFER_E;
8797+
}
87998798
}
88008799
else {
8800+
/* Partial read (< 3 bytes) is an error - need complete header */
88018801
#ifdef DEBUG_WOLFTPM
8802-
printf("ST33 Firmware data read error at offset %u\n", offset);
8802+
printf("ST33 Firmware data read error at offset %u (got %d bytes, need 3)\n",
8803+
offset, rc);
88038804
#endif
88048805
rc = BUFFER_E;
88058806
}
@@ -8817,6 +8818,16 @@ static int tpm2_st33_firmware_data(WOLFTPM2_DEV* dev,
88178818

88188819
/* Parse blob length from bytes 1-2 (big-endian) */
88198820
blob_len = ((uint32_t)blob_header[1] << 8) | blob_header[2];
8821+
8822+
/* Check for integer overflow before calculating total size */
8823+
if (blob_len > UINT32_MAX - 3) {
8824+
#ifdef DEBUG_WOLFTPM
8825+
printf("ST33 Blob length overflow at offset %u: %u\n", offset, blob_len);
8826+
#endif
8827+
rc = BUFFER_E;
8828+
break;
8829+
}
8830+
88208831
blob_total = blob_len + 3; /* total blob size including header */
88218832

88228833
if (blob_total > ST33_FW_MAX_CHUNK_SZ + 3) {
@@ -8860,7 +8871,8 @@ static int tpm2_st33_firmware_data(WOLFTPM2_DEV* dev,
88608871
XFREE(blob_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
88618872

88628873
if (rc == TPM_RC_SUCCESS) {
8863-
/* Give the TPM time to process */
8874+
/* 300ms delay: ST reference implementation uses this delay to allow
8875+
* TPM to process firmware data blobs */
88648876
tpm2_firmware_sleep_ms(300);
88658877

88668878
#if !defined(WOLFTPM_LINUX_DEV) && !defined(WOLFTPM_SWTPM) && \

tests/unit_tests.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,65 @@ static void test_wolfTPM2_ST33_FirmwareUpgrade(void)
343343
rc = wolfTPM2_FirmwareUpgradeWithLMS(&dev, dummy_manifest,
344344
sizeof(dummy_manifest), NULL, NULL, dummy_sig, sizeof(dummy_sig));
345345
AssertIntNE(rc, 0);
346+
347+
/* ===== Test version detection edge cases ===== */
348+
349+
/* Test version threshold boundary: exactly 511 (< 512, non-LMS) */
350+
if (caps.fwVerMinor == 511) {
351+
/* Should require non-LMS format */
352+
rc = wolfTPM2_FirmwareUpgradeHashWithLMS(&dev, TPM_ALG_SHA384, NULL, 0,
353+
dummy_manifest, sizeof(dummy_manifest), NULL, NULL,
354+
dummy_sig, sizeof(dummy_sig));
355+
/* Should fail because LMS signature provided but version < 512 */
356+
AssertIntNE(rc, 0);
357+
}
358+
359+
/* Test version threshold boundary: exactly 512 (>= 512, LMS required) */
360+
if (caps.fwVerMinor == 512) {
361+
/* Should require LMS format */
362+
rc = wolfTPM2_FirmwareUpgradeHash(&dev, TPM_ALG_SHA384, NULL, 0,
363+
dummy_manifest, sizeof(dummy_manifest), NULL, NULL);
364+
/* Should fail because LMS signature required but not provided */
365+
AssertIntNE(rc, 0);
366+
}
367+
368+
/* Test version threshold boundary: exactly 513 (>= 512, LMS required) */
369+
if (caps.fwVerMinor == 513) {
370+
/* Should require LMS format */
371+
rc = wolfTPM2_FirmwareUpgradeHash(&dev, TPM_ALG_SHA384, NULL, 0,
372+
dummy_manifest, sizeof(dummy_manifest), NULL, NULL);
373+
/* Should fail because LMS signature required but not provided */
374+
AssertIntNE(rc, 0);
375+
}
346376
}
347377
#endif /* !WOLFTPM2_NO_WOLFCRYPT */
348378

379+
/* ===== Test callback edge cases ===== */
380+
{
381+
/* Test callback with offset beyond buffer size */
382+
typedef struct {
383+
uint8_t* buf;
384+
size_t bufSz;
385+
} test_cb_ctx_t;
386+
387+
uint8_t test_buf[10] = {0};
388+
test_cb_ctx_t test_ctx = {test_buf, sizeof(test_buf)};
389+
int cb_rc;
390+
391+
/* Simulate callback behavior: offset beyond buffer */
392+
if (sizeof(test_buf) + 1 > test_ctx.bufSz) {
393+
cb_rc = BUFFER_E; /* Should return error */
394+
AssertIntNE(cb_rc, 0);
395+
}
396+
397+
/* Simulate callback behavior: partial read at end of buffer */
398+
if (sizeof(test_buf) - 2 + 5 > test_ctx.bufSz) {
399+
/* Should adjust requested size to fit */
400+
size_t actual_sz = test_ctx.bufSz - (sizeof(test_buf) - 2);
401+
AssertIntEQ(actual_sz, 2); /* Should only read 2 bytes */
402+
}
403+
}
404+
349405
rc = 0;
350406

351407
wolfTPM2_Cleanup(&dev);

wolftpm/tpm2_wrap.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4211,9 +4211,8 @@ WOLFTPM_API int wolfTPM2_FirmwareUpgrade(WOLFTPM2_DEV* dev,
42114211
/*!
42124212
\ingroup wolfTPM2_Wrappers
42134213
\brief Perform TPM firmware upgrade with LMS signature (ST33KTPM)
4214-
\note For ST33KTPM devices with firmware version >= 256, supports LMS signature
4215-
\note For firmware version >= 915, LMS signature is required
4216-
\note For firmware version 256-914, LMS signature is optional
4214+
\note For ST33KTPM devices with firmware version < 512, non-LMS format required (legacy firmware, e.g., 9.257)
4215+
\note For ST33KTPM devices with firmware version >= 512, LMS format required (modern firmware, e.g., 9.512)
42174216
42184217
\return TPM_RC_SUCCESS: successful
42194218
\return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code)

0 commit comments

Comments
 (0)