summaryrefslogtreecommitdiff
path: root/firmware/lib/tpm_lite/tlcl.c
diff options
context:
space:
mode:
authorMattias Nissler <mnissler@chromium.org>2017-07-07 10:26:43 +0200
committerMattias Nissler <mnissler@chromium.org>2017-09-08 19:43:52 +0000
commitaab52651d3df11c6a7908e1d07bd81a98d38bea7 (patch)
tree7a465f21160f542ea860f316aedf0039c65577d7 /firmware/lib/tpm_lite/tlcl.c
parent8b71425257d251858410de71efcf389df8b200d2 (diff)
downloadvboot-aab52651d3df11c6a7908e1d07bd81a98d38bea7.tar.gz
Add support for IFX FieldUpgradeInfoRequest2 commandstabilize-9765.76.Bstabilize-9765.65.Brelease-R61-9765.B
Add tpm_lite library support for the IFX specific TPM_FieldUpgrade subcommand "FieldUpgradeInfoRequest2". Expose this via tpmc so it can be used from shell scripts. BRANCH=none BUG=chromium:728130 TEST=Builds and tpmc ifxfieldupgradeinfo prints plausible results. Reviewed-on: https://chromium-review.googlesource.com/562772 Commit-Ready: Mattias Nissler <mnissler@chromium.org> Tested-by: Mattias Nissler <mnissler@chromium.org> Reviewed-by: Mattias Nissler <mnissler@chromium.org> BUG=chromium:761803 Change-Id: I80cf4d82de34e5010393918df2a317ea62e17095 Reviewed-on: https://chromium-review.googlesource.com/657427 Reviewed-by: Mattias Nissler <mnissler@chromium.org> Tested-by: Mattias Nissler <mnissler@chromium.org>
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;
+}