Skip to content

Commit 4b9b735

Browse files
committed
Add abstraction to lms version
1 parent 7964756 commit 4b9b735

File tree

5 files changed

+143
-329
lines changed

5 files changed

+143
-329
lines changed

examples/firmware/README.md

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -107,48 +107,35 @@ KeyGroupId 0x7, FwCounter 1253 (254 same)
107107

108108
## ST33 Firmware Update
109109

110-
### Firmware Version Requirements
110+
### Firmware Format Auto-Detection
111111

112-
ST33KTPM firmware update uses a simplified two-state model matching ST's reference implementation:
112+
ST33KTPM firmware update automatically detects the required format based on TPM firmware version:
113113

114-
- **Legacy firmware (< 512, e.g., 9.257)**: Non-LMS format required
115-
- Non-LMS path only
116-
- LMS format is rejected
114+
- **Legacy firmware (< 512, e.g., 9.257)**: Non-LMS format
115+
- Manifest size: 177 bytes
117116
- Generation 1 firmware (ECC-only)
118117

119-
- **Modern firmware (>= 512, e.g., 9.512)**: LMS format required
120-
- LMS path only
121-
- LMS signature is required (embedded in manifest)
118+
- **Modern firmware (>= 512, e.g., 9.512)**: LMS format
119+
- Manifest size: 2697 bytes (includes embedded LMS signature)
122120
- Generation 2 firmware (LMS mandatory)
123121

124-
The firmware version is automatically detected by checking `fwVerMinor` from the TPM capabilities. The version threshold is:
125-
- **512 (0x0200)**: ST policy enforcement threshold - Generation 2 starts here, LMS becomes mandatory
126-
127-
Version breakdown:
128-
- **9.257 (0x0101)**: Legacy ECC-only firmware (Generation 1)
129-
- **9.512 (0x0200)**: First modern firmware with LMS mandatory requirement (Generation 2)
130-
131-
This simplified model matches ST's reference implementation behavior, which uses separate tools for Generation 1 (< 512) vs Generation 2 (>= 512) firmware.
122+
The firmware version is automatically detected from `fwVerMinor` in TPM capabilities. The correct manifest size is determined automatically - no manual format selection is needed.
132123

133124
### Updating the firmware
134125

135-
The `st33_fw_update` tool uses the manifest and firmware data files.
126+
The `st33_fw_update` tool automatically detects the firmware format.
136127

137128
```sh
138129
# Help
139130
./st33_fw_update --help
140131
ST33 Firmware Update Usage:
141132
./st33_fw_update (get info)
142133
./st33_fw_update --abandon (cancel)
143-
./st33_fw_update <firmware.fi> [--lms]
144-
145-
Options:
146-
--lms: Use LMS format (2697 byte manifest with embedded signature)
147-
Default is non-LMS format (177 byte manifest)
134+
./st33_fw_update <firmware.fi>
148135

149-
Note: LMS format requirements:
150-
- Firmware < 512: Non-LMS format required (legacy firmware, e.g., 9.257)
151-
- Firmware >= 512: LMS format required (modern firmware, e.g., 9.512)
136+
Firmware format is auto-detected from TPM firmware version:
137+
- Firmware < 512: Non-LMS format (177 byte manifest)
138+
- Firmware >= 512: LMS format (2697 byte manifest with embedded signature)
152139

153140
# Run without arguments to display the current firmware information
154141
./st33_fw_update
@@ -160,17 +147,17 @@ Firmware version details: Major=9, Minor=257, Vendor=0x0
160147
Hardware: ST33K (legacy firmware, Generation 1)
161148
Firmware update: Non-LMS format required
162149

163-
# Run with non-LMS firmware file (for legacy firmware < 512)
150+
# Run with firmware file (format auto-detected from TPM version)
164151
./st33_fw_update TPM_ST33KTPM2X_00090200_V1.fi
165152
ST33 Firmware Update Tool
166153
Firmware File: TPM_ST33KTPM2X_00090200_V1.fi
167-
Format: Non-LMS (V1)
168154
TPM2: Caps 0x30000415, Did 0x0003, Vid 0x104a, Rid 0x 1
169155
TPM2_Startup pass
170156
Mfg STM (2), Vendor ST33KTPM2X, Fw 9.257 (0x0)
171157
Firmware version details: Major=9, Minor=257, Vendor=0x0
172158
Hardware: ST33K (legacy firmware, Generation 1)
173159
Firmware update: Non-LMS format required
160+
Format: Non-LMS (from TPM firmware version)
174161
Firmware Update:
175162
Total file size: 364290 bytes
176163
Manifest (blob0): 177 bytes
@@ -179,17 +166,17 @@ Firmware Update:
179166
Firmware update completed successfully.
180167
Please reset or power cycle the TPM.
181168

182-
# Run with LMS firmware file (for modern firmware >= 512)
183-
./st33_fw_update ST33KTPM2X_FAC_00090200_V2.fi --lms
169+
# Example with LMS firmware (Generation 2 TPM, firmware >= 512)
170+
./st33_fw_update ST33KTPM2X_FAC_00090200_V2.fi
184171
ST33 Firmware Update Tool
185172
Firmware File: ST33KTPM2X_FAC_00090200_V2.fi
186-
Format: LMS (V2)
187173
TPM2: Caps 0x30000415, Did 0x0003, Vid 0x104a, Rid 0x 3
188174
TPM2_Startup pass
189175
Mfg STM (2), Vendor ST33KTPM2X, Fw 9.512 (0x0)
190176
Firmware version details: Major=9, Minor=512, Vendor=0x0
191177
Hardware: ST33K (modern firmware, Generation 2)
192178
Firmware update: LMS format required
179+
Format: LMS (from TPM firmware version)
193180
Firmware Update:
194181
Total file size: 360092 bytes
195182
Manifest (blob0): 2697 bytes

examples/firmware/st33_fw_update.c

Lines changed: 43 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,9 @@ static void usage(void)
4747
printf("ST33 Firmware Update Usage:\n");
4848
printf("\t./st33_fw_update (get info)\n");
4949
printf("\t./st33_fw_update --abandon (cancel)\n");
50-
printf("\t./st33_fw_update <firmware.fi> [--lms]\n");
51-
printf("\nOptions:\n");
52-
printf(" --lms: Use LMS format (2697 byte manifest with embedded signature)\n");
53-
printf(" Default is non-LMS format (177 byte manifest)\n");
54-
printf("\nNote: LMS format requirements:\n");
55-
printf(" - Firmware < 512: Non-LMS format required (legacy firmware, e.g., 9.257)\n");
56-
printf(" - Firmware >= 512: LMS format required (modern firmware, e.g., 9.512)\n");
57-
printf("\nFirmware file format:\n");
58-
printf(" - Non-LMS (.fi V1): First 177 bytes = manifest, rest = firmware data\n");
59-
printf(" - LMS (.fi V2): First 2697 bytes = manifest (with LMS sig), rest = firmware\n");
50+
printf("\t./st33_fw_update <firmware.fi>\n");
51+
printf("\nFirmware format is auto-detected from the TPM firmware version.\n");
52+
printf("Just provide the correct .fi file for your TPM and it will be handled automatically.\n");
6053
}
6154

6255
typedef struct {
@@ -66,7 +59,6 @@ typedef struct {
6659
size_t fi_bufSz;
6760
size_t manifest_bufSz;
6861
size_t firmware_bufSz;
69-
int use_lms; /* 1 = LMS format, 0 = non-LMS format */
7062
int in_upgrade_mode; /* 1 = continuing from upgrade mode */
7163
} fw_info_t;
7264

@@ -185,11 +177,10 @@ int TPM2_ST33_Firmware_Update(void* userCtx, int argc, char *argv[])
185177
const char* fi_file = NULL;
186178
fw_info_t fwinfo;
187179
int abandon = 0;
188-
int lms_state = 0; /* 0=UNSUPPORTED, 1=CAPABLE, 2=REQUIRED */
189-
int i;
190180
size_t blob0_size;
191181

192182
XMEMSET(&fwinfo, 0, sizeof(fwinfo));
183+
XMEMSET(&caps, 0, sizeof(caps));
193184

194185
if (argc >= 2) {
195186
if (XSTRCMP(argv[1], "-?") == 0 ||
@@ -203,19 +194,12 @@ int TPM2_ST33_Firmware_Update(void* userCtx, int argc, char *argv[])
203194
}
204195
else {
205196
fi_file = argv[1];
206-
/* Parse optional --lms flag */
207-
for (i = 2; i < argc; i++) {
208-
if (XSTRCMP(argv[i], "--lms") == 0) {
209-
fwinfo.use_lms = 1;
210-
}
211-
}
212197
}
213198
}
214199

215200
printf("ST33 Firmware Update Tool\n");
216201
if (fi_file != NULL) {
217202
printf("\tFirmware File: %s\n", fi_file);
218-
printf("\tFormat: %s\n", fwinfo.use_lms ? "LMS (V2)" : "Non-LMS (V1)");
219203
}
220204

221205
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
@@ -271,15 +255,6 @@ int TPM2_ST33_Firmware_Update(void* userCtx, int argc, char *argv[])
271255
goto exit;
272256
}
273257

274-
/* Two-state model: < 512 requires non-LMS (legacy firmware, e.g., 9.257),
275-
* >= 512 requires LMS (modern firmware, LMS required, e.g., 9.512) */
276-
if (caps.fwVerMinor < 512) {
277-
lms_state = 0; /* Non-LMS path only (legacy firmware, Generation 1) */
278-
}
279-
else {
280-
lms_state = 1; /* LMS path only (modern firmware, LMS required, Generation 2) */
281-
}
282-
283258
if (abandon) {
284259
printf("Firmware Update Abandon:\n");
285260
rc = wolfTPM2_FirmwareUpgradeCancel(&dev);
@@ -299,39 +274,49 @@ int TPM2_ST33_Firmware_Update(void* userCtx, int argc, char *argv[])
299274
goto exit;
300275
}
301276

302-
/* Handle LMS signature requirements (skip check in upgrade mode) */
303-
if (!fwinfo.in_upgrade_mode) {
304-
if (lms_state == 0) {
305-
/* Legacy firmware (< 512): reject LMS format */
306-
if (fwinfo.use_lms) {
307-
printf("\nError: LMS format specified but firmware "
308-
"version < 512 requires non-LMS.\n");
309-
printf("This device (fwVerMinor < 512) must use "
310-
"non-LMS firmware format.\n");
311-
rc = BAD_FUNC_ARG;
312-
goto exit;
277+
load_firmware:
278+
/* Determine blob0 (manifest) size based on firmware version.
279+
* In upgrade mode (caps not available), auto-detect from file size. */
280+
if (fwinfo.in_upgrade_mode) {
281+
/* In upgrade mode, we don't have caps. Load file first to detect format. */
282+
rc = loadFile(fi_file, &fwinfo.fi_buf, &fwinfo.fi_bufSz);
283+
if (rc != 0) {
284+
printf("Failed to load firmware file: %s\n", fi_file);
285+
goto exit;
286+
}
287+
/* Auto-detect format from file size: LMS files are larger due to
288+
* 2697 byte manifest vs 177 byte manifest */
289+
if (fwinfo.fi_bufSz > ST33_BLOB0_SIZE_LMS + 1000) {
290+
/* File large enough to potentially be LMS format.
291+
* Check if blob header at LMS offset looks valid. */
292+
if (fwinfo.fi_buf[ST33_BLOB0_SIZE_LMS] != 0 &&
293+
fwinfo.fi_buf[ST33_BLOB0_SIZE_LMS] != 0xFF) {
294+
blob0_size = ST33_BLOB0_SIZE_LMS;
295+
printf("\tFormat: LMS (auto-detected from file)\n");
296+
}
297+
else {
298+
blob0_size = ST33_BLOB0_SIZE_NON_LMS;
299+
printf("\tFormat: Non-LMS (auto-detected from file)\n");
313300
}
314301
}
315302
else {
316-
/* Modern firmware (>= 512): require LMS format */
317-
if (!fwinfo.use_lms) {
318-
printf("\nError: Firmware version >= 512 requires LMS format.\n");
319-
printf("Please use --lms option with LMS firmware file.\n");
320-
rc = BAD_FUNC_ARG;
321-
goto exit;
322-
}
303+
blob0_size = ST33_BLOB0_SIZE_NON_LMS;
304+
printf("\tFormat: Non-LMS (auto-detected from file)\n");
323305
}
324306
}
325-
326-
load_firmware:
327-
/* Determine blob0 (manifest) size based on format */
328-
blob0_size = fwinfo.use_lms ? ST33_BLOB0_SIZE_LMS : ST33_BLOB0_SIZE_NON_LMS;
329-
330-
/* Load the complete .fi file */
331-
rc = loadFile(fi_file, &fwinfo.fi_buf, &fwinfo.fi_bufSz);
332-
if (rc != 0) {
333-
printf("Failed to load firmware file: %s\n", fi_file);
334-
goto exit;
307+
else {
308+
/* Normal mode: determine format from firmware version */
309+
blob0_size = (caps.fwVerMinor >= 512) ?
310+
ST33_BLOB0_SIZE_LMS : ST33_BLOB0_SIZE_NON_LMS;
311+
printf("\tFormat: %s (from TPM firmware version)\n",
312+
(caps.fwVerMinor >= 512) ? "LMS" : "Non-LMS");
313+
314+
/* Load the complete .fi file */
315+
rc = loadFile(fi_file, &fwinfo.fi_buf, &fwinfo.fi_bufSz);
316+
if (rc != 0) {
317+
printf("Failed to load firmware file: %s\n", fi_file);
318+
goto exit;
319+
}
335320
}
336321

337322
/* Validate file size */
@@ -358,15 +343,8 @@ int TPM2_ST33_Firmware_Update(void* userCtx, int argc, char *argv[])
358343
printf("Sending firmware data (TPM already in upgrade mode)...\n");
359344
rc = TPM2_ST33_SendFirmwareData(&fwinfo);
360345
}
361-
else if (fwinfo.use_lms) {
362-
/* LMS path - manifest contains embedded LMS signature */
363-
rc = wolfTPM2_FirmwareUpgradeWithLMS(&dev,
364-
fwinfo.manifest_buf, (uint32_t)fwinfo.manifest_bufSz,
365-
TPM2_ST33_FwData_Cb, &fwinfo,
366-
fwinfo.manifest_buf, (uint32_t)fwinfo.manifest_bufSz);
367-
}
368346
else {
369-
/* Non-LMS path */
347+
/* Normal mode - use unified API which auto-detects format from manifest size */
370348
rc = wolfTPM2_FirmwareUpgrade(&dev,
371349
fwinfo.manifest_buf, (uint32_t)fwinfo.manifest_bufSz,
372350
TPM2_ST33_FwData_Cb, &fwinfo);

0 commit comments

Comments
 (0)