summaryrefslogtreecommitdiff
path: root/firmware/lib/tpm_lite/tlcl.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/lib/tpm_lite/tlcl.c')
-rw-r--r--firmware/lib/tpm_lite/tlcl.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c
index 14acf966..59dd1208 100644
--- a/firmware/lib/tpm_lite/tlcl.c
+++ b/firmware/lib/tpm_lite/tlcl.c
@@ -548,3 +548,74 @@ uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version) {
return TPM_SUCCESS;
}
+
+static void ParseIFXFirmwarePackage(uint8_t** cursor,
+ TPM_IFX_FIRMWAREPACKAGE* firmware_package) {
+
+ FromTpmUint32(*cursor, &firmware_package->FwPackageIdentifier);
+ *cursor += sizeof(firmware_package->FwPackageIdentifier);
+ FromTpmUint32(*cursor, &firmware_package->Version);
+ *cursor += sizeof(firmware_package->Version);
+ FromTpmUint32(*cursor, &firmware_package->StaleVersion);
+ *cursor += sizeof(firmware_package->StaleVersion);
+}
+
+uint32_t TlclIFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO* info) {
+ uint32_t vendor;
+ uint64_t firmware_version;
+ uint32_t result = TlclGetVersion(&vendor, &firmware_version);
+ if (result != TPM_SUCCESS) {
+ return result;
+ }
+ if (vendor != 0x49465800) {
+ return TPM_E_BAD_ORDINAL;
+ }
+
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ result = TlclSendReceive(tpm_ifx_fieldupgradeinforequest2_cmd.buffer,
+ response, sizeof(response));
+ if (result != TPM_SUCCESS) {
+ return result;
+ }
+
+ uint8_t* cursor = response + kTpmResponseHeaderLength;
+
+ uint16_t size;
+ FromTpmUint16(cursor, &size);
+ cursor += sizeof(size);
+
+ /* Comments below indicate skipped fields of unknown purpose that are
+ * marked "internal" in the firmware updater source. */
+ cursor += sizeof(uint16_t); /* internal1 */
+ FromTpmUint16(cursor, &info->wMaxDataSize);
+ cursor += sizeof(info->wMaxDataSize);
+ cursor += sizeof(uint16_t); /* sSecurityModuleLogic.internal1 */
+ cursor += sizeof(uint32_t); /* sSecurityModuleLogic.internal2 */
+ cursor += sizeof(uint8_t[34]); /* sSecurityModuleLogic.internal3 */
+ ParseIFXFirmwarePackage(&cursor, &info->sBootloaderFirmwarePackage);
+ uint16_t fw_entry_count;
+ FromTpmUint16(cursor, &fw_entry_count);
+ cursor += sizeof(fw_entry_count);
+ if (fw_entry_count > ARRAY_SIZE(info->sFirmwarePackages)) {
+ return TPM_E_IOERROR;
+ }
+ uint16_t i;
+ for (i = 0; i < fw_entry_count; ++i) {
+ ParseIFXFirmwarePackage(&cursor, &info->sFirmwarePackages[i]);
+ }
+ FromTpmUint16(cursor, &info->wSecurityModuleStatus);
+ cursor += sizeof(info->wSecurityModuleStatus);
+ ParseIFXFirmwarePackage(&cursor, &info->sProcessFirmwarePackage);
+ cursor += sizeof(uint16_t); /* internal6 */
+ cursor += sizeof(uint8_t[6]); /* internal7 */
+ FromTpmUint16(cursor, &info->wFieldUpgradeCounter);
+ cursor += sizeof(info->wFieldUpgradeCounter);
+
+ uint32_t parsed_bytes = cursor - response;
+ VbAssert(parsed_bytes <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ if (parsed_bytes > kTpmResponseHeaderLength + sizeof(size) + size) {
+ return TPM_E_IOERROR;
+ }
+
+ return result;
+}