summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/include/tlcl.h13
-rw-r--r--firmware/include/tpm1_tss_constants.h59
-rw-r--r--firmware/lib/tpm_lite/include/tlcl_structures.h11
-rw-r--r--firmware/lib/tpm_lite/tlcl.c52
-rw-r--r--tests/tlcl_tests.c85
-rw-r--r--utility/tlcl_generator.c24
6 files changed, 223 insertions, 21 deletions
diff --git a/firmware/include/tlcl.h b/firmware/include/tlcl.h
index a2a6308e..1b08ec9c 100644
--- a/firmware/include/tlcl.h
+++ b/firmware/include/tlcl.h
@@ -272,6 +272,19 @@ uint32_t TlclTakeOwnership(uint8_t enc_owner_auth[TPM_RSA_2048_LEN],
uint8_t enc_srk_auth[TPM_RSA_2048_LEN],
uint8_t owner_auth[TPM_AUTH_DATA_LEN]);
+/**
+ * Create a delegation family with the specified [family_label].
+ */
+uint32_t TlclCreateDelegationFamily(uint8_t family_label);
+
+/**
+ * Read the delegation family table. Entries are stored in [table]. The size of
+ * the family table array must be specified in [table_size]. [table_size] gets
+ * updated to indicate actual number of table entries available.
+ */
+uint32_t TlclReadDelegationFamilyTable(TPM_FAMILY_TABLE_ENTRY *table,
+ uint32_t* table_size);
+
#endif /* TPM2_MODE */
#endif /* CHROMEOS_ENVIRONMENT */
diff --git a/firmware/include/tpm1_tss_constants.h b/firmware/include/tpm1_tss_constants.h
index 572d5c61..e91ccf6f 100644
--- a/firmware/include/tpm1_tss_constants.h
+++ b/firmware/include/tpm1_tss_constants.h
@@ -46,6 +46,10 @@ typedef uint32_t TPM_COMMAND_CODE;
typedef uint16_t TPM_PHYSICAL_PRESENCE;
typedef uint16_t TPM_STARTUP_TYPE;
typedef uint32_t TPM_CAPABILITY_AREA;
+typedef uint8_t TPM_FAMILY_LABEL;
+typedef uint32_t TPM_FAMILY_ID;
+typedef uint32_t TPM_FAMILY_VERIFICATION;
+typedef uint32_t TPM_FAMILY_FLAGS;
#define TPM_CAP_FLAG ((uint32_t) 0x00000004)
#define TPM_CAP_FLAG_PERMANENT ((uint32_t) 0x00000108)
@@ -70,6 +74,8 @@ typedef uint32_t TPM_CAPABILITY_AREA;
#define TPM_ET_OWNER ((uint32_t) 0x02)
+#define TPM_FAMILY_CREATE ((uint32_t) 0x00000001)
+
#define TPM_ST_CLEAR ((uint16_t) 0x0001)
#define TPM_ST_STATE ((uint16_t) 0x0002)
#define TPM_ST_DEACTIVATED ((uint16_t) 0x0003)
@@ -177,6 +183,15 @@ typedef struct tdTPM_NONCE
uint8_t nonce[TPM_SHA1BASED_NONCE_LEN];
} TPM_NONCE;
+typedef struct tdTPM_FAMILY_TABLE_ENTRY
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_FAMILY_LABEL familyLabel;
+ TPM_FAMILY_ID familyID;
+ TPM_FAMILY_VERIFICATION verificationCount;
+ TPM_FAMILY_FLAGS flags;
+} TPM_FAMILY_TABLE_ENTRY;
+
typedef struct tdTPM_IFX_FIRMWAREPACKAGE {
uint32_t FwPackageIdentifier;
uint32_t Version;
@@ -203,26 +218,28 @@ typedef struct tdTPM_NV_AUTH_POLICY
/* Ordinals */
-#define TPM_ORD_ContinueSelfTest ((uint32_t) 0x00000053)
-#define TPM_ORD_Extend ((uint32_t) 0x00000014)
-#define TPM_ORD_FieldUpgrade ((uint32_t) 0x000000AA)
-#define TPM_ORD_ForceClear ((uint32_t) 0x0000005D)
-#define TPM_ORD_GetCapability ((uint32_t) 0x00000065)
-#define TPM_ORD_GetRandom ((uint32_t) 0x00000046)
-#define TPM_ORD_NV_DefineSpace ((uint32_t) 0x000000CC)
-#define TPM_ORD_NV_ReadValue ((uint32_t) 0x000000CF)
-#define TPM_ORD_NV_WriteValue ((uint32_t) 0x000000CD)
-#define TPM_ORD_OIAP ((uint32_t) 0x0000000A)
-#define TPM_ORD_OSAP ((uint32_t) 0x0000000B)
-#define TPM_ORD_PcrRead ((uint32_t) 0x00000015)
-#define TPM_ORD_PhysicalEnable ((uint32_t) 0x0000006F)
-#define TPM_ORD_PhysicalDisable ((uint32_t) 0x00000070)
-#define TSC_ORD_PhysicalPresence ((uint32_t) 0x4000000A)
-#define TPM_ORD_PhysicalSetDeactivated ((uint32_t) 0x00000072)
-#define TPM_ORD_ReadPubek ((uint32_t) 0x0000007C)
-#define TPM_ORD_SaveState ((uint32_t) 0x00000098)
-#define TPM_ORD_SelfTestFull ((uint32_t) 0x00000050)
-#define TPM_ORD_Startup ((uint32_t) 0x00000099)
-#define TPM_ORD_TakeOwnership ((uint32_t) 0x0000000D)
+#define TPM_ORD_ContinueSelfTest ((uint32_t) 0x00000053)
+#define TPM_ORD_Delegate_Manage ((uint32_t) 0x000000D2)
+#define TPM_ORD_Delegate_ReadTable ((uint32_t) 0x000000DB)
+#define TPM_ORD_Extend ((uint32_t) 0x00000014)
+#define TPM_ORD_FieldUpgrade ((uint32_t) 0x000000AA)
+#define TPM_ORD_ForceClear ((uint32_t) 0x0000005D)
+#define TPM_ORD_GetCapability ((uint32_t) 0x00000065)
+#define TPM_ORD_GetRandom ((uint32_t) 0x00000046)
+#define TPM_ORD_NV_DefineSpace ((uint32_t) 0x000000CC)
+#define TPM_ORD_NV_ReadValue ((uint32_t) 0x000000CF)
+#define TPM_ORD_NV_WriteValue ((uint32_t) 0x000000CD)
+#define TPM_ORD_OIAP ((uint32_t) 0x0000000A)
+#define TPM_ORD_OSAP ((uint32_t) 0x0000000B)
+#define TPM_ORD_PcrRead ((uint32_t) 0x00000015)
+#define TPM_ORD_PhysicalEnable ((uint32_t) 0x0000006F)
+#define TPM_ORD_PhysicalDisable ((uint32_t) 0x00000070)
+#define TSC_ORD_PhysicalPresence ((uint32_t) 0x4000000A)
+#define TPM_ORD_PhysicalSetDeactivated ((uint32_t) 0x00000072)
+#define TPM_ORD_ReadPubek ((uint32_t) 0x0000007C)
+#define TPM_ORD_SaveState ((uint32_t) 0x00000098)
+#define TPM_ORD_SelfTestFull ((uint32_t) 0x00000050)
+#define TPM_ORD_Startup ((uint32_t) 0x00000099)
+#define TPM_ORD_TakeOwnership ((uint32_t) 0x0000000D)
#endif /* ! __VBOOT_REFERENCE_FIRMWARE_INCLUDE_TPM1_TSS_CONSTANTS_H */
diff --git a/firmware/lib/tpm_lite/include/tlcl_structures.h b/firmware/lib/tpm_lite/include/tlcl_structures.h
index 73ed889e..a3772328 100644
--- a/firmware/lib/tpm_lite/include/tlcl_structures.h
+++ b/firmware/lib/tpm_lite/include/tlcl_structures.h
@@ -1,5 +1,16 @@
/* This file is automatically generated */
+const struct s_tpm_delegate_read_table_cmd{
+ uint8_t buffer[10];
+} tpm_delegate_read_table_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xdb, },
+};
+
+const struct s_tpm_create_delegation_family_cmd{
+ uint8_t buffer[23];
+ uint16_t familyLabel;
+} tpm_create_delegation_family_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x17, 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, },
+22, };
+
const struct s_tpm_takeownership_cmd{
uint8_t buffer[624];
uint16_t encOwnerAuth;
diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c
index fe82bd71..37d0fe20 100644
--- a/firmware/lib/tpm_lite/tlcl.c
+++ b/firmware/lib/tpm_lite/tlcl.c
@@ -1215,4 +1215,56 @@ uint32_t TlclTakeOwnership(uint8_t enc_owner_auth[TPM_RSA_2048_LEN],
return TPM_SUCCESS;
}
+uint32_t TlclCreateDelegationFamily(uint8_t family_label)
+{
+ struct s_tpm_create_delegation_family_cmd cmd;
+ memcpy(&cmd, &tpm_create_delegation_family_cmd, sizeof(cmd));
+ cmd.buffer[tpm_create_delegation_family_cmd.familyLabel] = family_label;
+ return Send(cmd.buffer);
+}
+
+uint32_t TlclReadDelegationFamilyTable(TPM_FAMILY_TABLE_ENTRY *table,
+ uint32_t* table_size)
+{
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint32_t result = TlclSendReceive(tpm_delegate_read_table_cmd.buffer,
+ response, sizeof(response));
+ if (result != TPM_SUCCESS) {
+ return result;
+ }
+
+ uint32_t size;
+ FromTpmUint32(response + sizeof(uint16_t), &size);
+ if (size < kTpmRequestHeaderLength + sizeof(uint32_t) ||
+ size > sizeof(response)) {
+ return TPM_E_INVALID_RESPONSE;
+ }
+
+ const uint8_t* cursor = response + kTpmRequestHeaderLength;
+ uint32_t table_bytes = ReadTpmUint32(&cursor);
+
+ if (table_bytes > size - (cursor - response)) {
+ return TPM_E_INVALID_RESPONSE;
+ }
+
+ uint32_t table_entries = table_bytes / sizeof(TPM_FAMILY_TABLE_ENTRY);
+ int i;
+ for (i = 0; i < table_entries; ++i) {
+ if (i >= *table_size || !table) {
+ result = TPM_E_BUFFER_SIZE;
+ break;
+ }
+
+ table[i].tag = ReadTpmUint16(&cursor);
+ table[i].familyLabel = *cursor++;
+ table[i].familyID = ReadTpmUint32(&cursor);
+ table[i].verificationCount = ReadTpmUint32(&cursor);
+ table[i].flags = ReadTpmUint32(&cursor);
+ }
+
+ *table_size = table_entries;
+
+ return result;
+}
+
#endif /* CHROMEOS_ENVIRONMENT */
diff --git a/tests/tlcl_tests.c b/tests/tlcl_tests.c
index 65c48f50..b7f288a3 100644
--- a/tests/tlcl_tests.c
+++ b/tests/tlcl_tests.c
@@ -991,6 +991,91 @@ void TakeOwnershipTest(void) {
sizeof(take_ownership_response));
}
+/**
+ * Test ReadDelegationFamilyTable
+ */
+void ReadDelegationFamilyTableTest(void) {
+ uint8_t response[] = {
+ 0x00, 0xc4, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x25,
+ 0x17, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x42,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+
+ TPM_FAMILY_TABLE_ENTRY table[20];
+ uint32_t table_size;
+
+ ResetMocks();
+ calls[0].rsp = response;
+ calls[0].rsp_size = sizeof(response);
+ table_size = 8;
+ TEST_EQ(TlclReadDelegationFamilyTable(table, &table_size),
+ TPM_SUCCESS, "ReadDelegationFamilyTable");
+ TEST_EQ(calls[0].req_cmd, TPM_ORD_Delegate_ReadTable, " cmd");
+ TEST_EQ(table_size, 2, " table_size");
+ TEST_EQ(table[0].tag, 0x25, " table[0].tag");
+ TEST_EQ(table[0].familyLabel, 0x17, " table[0].familyLabel");
+ TEST_EQ(table[0].familyID, 0x4f, " table[0].familyID");
+ TEST_EQ(table[0].verificationCount, 0x1,
+ " table[0].verificationCount");
+ TEST_EQ(table[0].flags, 0x2, " table[0].flags");
+ TEST_EQ(table[1].tag, 0x25, " table[1].tag");
+ TEST_EQ(table[1].familyLabel, 0x42, " table[1].familyLabel");
+ TEST_EQ(table[1].familyID, 0x50, " table[1].familyID");
+ TEST_EQ(table[1].verificationCount, 0x1,
+ " table[1].verificationCount");
+ TEST_EQ(table[1].flags, 0x0, " table[1].flags");
+
+ /* Test that required table size is returned if more space required. */
+ ResetMocks();
+ calls[0].rsp = response;
+ calls[0].rsp_size = sizeof(response);
+ table_size = 1;
+ TEST_EQ(TlclReadDelegationFamilyTable(table, &table_size),
+ TPM_E_BUFFER_SIZE, "ReadDelegationFamilyTable");
+ TEST_EQ(calls[0].req_cmd, TPM_ORD_Delegate_ReadTable, " cmd");
+ TEST_EQ(table_size, 2, " table_size");
+
+ /* Test that an overlong response gets caught. */
+ ResetMocks();
+ calls[0].rsp = response;
+ calls[0].rsp_size = sizeof(response);
+ ToTpmUint32(response + sizeof(uint16_t), TPM_LARGE_ENOUGH_COMMAND_SIZE +
+ 1);
+ TEST_EQ(TlclReadDelegationFamilyTable(table, &table_size),
+ TPM_E_INVALID_RESPONSE,
+ "ReadDelegationFamilyTable - too long response");
+ TEST_EQ(calls[0].req_cmd, TPM_ORD_Delegate_ReadTable, " cmd");
+ ToTpmUint32(response + sizeof(uint16_t), sizeof(response));
+
+ /* Test that a short response gets caught. */
+ ResetMocks();
+ calls[0].rsp = response;
+ calls[0].rsp_size = sizeof(response);
+ ToTpmUint32(response + sizeof(uint16_t),
+ kTpmRequestHeaderLength + sizeof(uint32_t) - 1);
+ TEST_EQ(TlclReadDelegationFamilyTable(table, &table_size),
+ TPM_E_INVALID_RESPONSE,
+ "ReadDelegationFamilyTable - too short response");
+ TEST_EQ(calls[0].req_cmd, TPM_ORD_Delegate_ReadTable, " cmd");
+ ToTpmUint32(response + sizeof(uint16_t), sizeof(response));
+
+ /* Test that long table size in response gets caught. */
+ ResetMocks();
+ calls[0].rsp = response;
+ calls[0].rsp_size = sizeof(response);
+ table_size = 20;
+ ToTpmUint32(response + kTpmResponseHeaderLength,
+ TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ TEST_EQ(TlclReadDelegationFamilyTable(table, &table_size),
+ TPM_E_INVALID_RESPONSE,
+ "ReadDelegationFamilyTable - overlong family table");
+ TEST_EQ(calls[0].req_cmd, TPM_ORD_Delegate_ReadTable, " cmd");
+ ToTpmUint32(response + kTpmResponseHeaderLength, 0x1e);
+}
+
int main(void)
{
TlclTest();
diff --git a/utility/tlcl_generator.c b/utility/tlcl_generator.c
index bb3301f0..c545bed1 100644
--- a/utility/tlcl_generator.c
+++ b/utility/tlcl_generator.c
@@ -495,6 +495,28 @@ Command* BuildTakeOwnershipCommand(void) {
return cmd;
}
+Command* BuildCreateDelegationFamilyCommand(void) {
+ int size = kTpmRequestHeaderLength + 3 * sizeof(uint32_t) + sizeof(uint8_t);
+ Command* cmd = newCommand(TPM_ORD_Delegate_Manage, size);
+ cmd->name = "tpm_create_delegation_family_cmd";
+ AddInitializedField(cmd, kTpmRequestHeaderLength, sizeof(uint32_t),
+ 0 /* familyID */);
+ AddInitializedField(cmd, kTpmRequestHeaderLength + sizeof(uint32_t),
+ sizeof(uint32_t), TPM_FAMILY_CREATE);
+ AddInitializedField(cmd, kTpmRequestHeaderLength + 2 * sizeof(uint32_t),
+ sizeof(uint32_t), sizeof(uint8_t) /* opDataSize */);
+ AddVisibleField(cmd, "familyLabel",
+ kTpmRequestHeaderLength + 3 * sizeof(uint32_t));
+ return cmd;
+}
+
+Command* BuildReadDelegationFamilyTableCommand(void) {
+ Command* cmd =
+ newCommand(TPM_ORD_Delegate_ReadTable, kTpmRequestHeaderLength);
+ cmd->name = "tpm_delegate_read_table_cmd";
+ return cmd;
+}
+
/* Output the fields of a structure.
*/
void OutputFields(Field* fld) {
@@ -621,6 +643,8 @@ Command* (*builders[])(void) = {
BuildOIAPCommand,
BuildOSAPCommand,
BuildTakeOwnershipCommand,
+ BuildCreateDelegationFamilyCommand,
+ BuildReadDelegationFamilyTableCommand,
};
static void FreeFields(Field* fld) {