@@ -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 */
87318746static 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 ) && \
0 commit comments