summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2025-01-09 11:10:18 -0600
committerTom Rini <[email protected]>2025-01-09 11:11:27 -0600
commit38a371110308ebeb277e20531a7b698b7981bbfa (patch)
tree3df777f4f0092c9a7b784cd99d6c153ee5f8e4bd /include
parente13e0a921f444cc12127c8a497dcc476f1268939 (diff)
parente587b6a8441f39015bda64d61ee5add142bcebb8 (diff)
Merge tag 'tpm-master-07012025' of https://source.denx.de/u-boot/custodians/u-boot-tpm
A few changes for the TPM subsystem wrt to EventLong creation and measurements. Generally speaking it's insecure for a TPM to not cap all the active PCRs when performing measurements. Up to now we had code querying the active PCR banks on the fly and reason whether it should perform a measurement or not. Since a TPM requires a reset to change the active PCR banks, it's easier and faster to store them in an array in the device private data and check against that. This relates to an interesting feature some bootloaders have. For example TF-A can't extend a PCR since it has no TPM drivers, but can produce an EventLog that U-Boot can replay on the hardware once that comes up. The supported hash algorithms of the TF-A generated Eventlog are generated at compile time. When trying to replay an EventLog the TPM active PCR banks and the created EventLog algorithms must agree. We used to report an error but that changed in commit 97707f12fdab ("tpm: Support boot measurements"). This PR also brings up the old behavior and an error is reported now while printing a human readable list of the mismatched algorithms.
Diffstat (limited to 'include')
-rw-r--r--include/tpm-common.h16
-rw-r--r--include/tpm-v2.h99
-rw-r--r--include/tpm_tcg2.h12
3 files changed, 94 insertions, 33 deletions
diff --git a/include/tpm-common.h b/include/tpm-common.h
index 1ba81386ce1..bfb84a931d1 100644
--- a/include/tpm-common.h
+++ b/include/tpm-common.h
@@ -43,11 +43,19 @@ enum tpm_version {
};
/**
+ * define TPM2_NUM_PCR_BANKS - number of PCR banks
+ * The value 16 can be found in the current standard
+ * TCG TSS 2.0 Overview and Common Structures Specification 1.0, rev 10
+ */
+#define TPM2_NUM_PCR_BANKS 16
+
+/**
* struct tpm_chip_priv - Information about a TPM, stored by the uclass
*
- * These values must be set up by the device's probe() method before
+ * Some of hese values must be set up by the device's probe() method before
* communcation is attempted. If the device has an xfer() method, this is
* not needed. There is no need to set up @buf.
+ * The active_banks is only valid for TPMv2 after the device is initialized.
*
* @version: TPM stack to be used
* @duration_ms: Length of each duration type in milliseconds
@@ -55,6 +63,8 @@ enum tpm_version {
* @buf: Buffer used during the exchanges with the chip
* @pcr_count: Number of PCR per bank
* @pcr_select_min: Minimum size in bytes of the pcrSelect array
+ * @active_bank_count: Number of active PCR banks
+ * @active_banks: Array of active PCRs
* @plat_hier_disabled: Platform hierarchy has been disabled (TPM is locked
* down until next reboot)
*/
@@ -68,6 +78,10 @@ struct tpm_chip_priv {
/* TPM v2 specific data */
uint pcr_count;
uint pcr_select_min;
+#if IS_ENABLED(CONFIG_TPM_V2)
+ u8 active_bank_count;
+ u32 active_banks[TPM2_NUM_PCR_BANKS];
+#endif
bool plat_hier_disabled;
};
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 4fd19c52fd7..65681464b37 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -6,6 +6,11 @@
* Copyright (c) 2020 Linaro
* Copyright (c) 2018 Bootlin
*
+ * The structures are described in
+ * Trusted Platform Module Library Part 2: Structures
+ * http://tcg.tjn.chef.causewaynow.com/resource/tpm-library-specification/
+ *
+ * C header files are listed in
* https://trustedcomputinggroup.org/resource/tss-overview-common-structures-specification/
*
* Author: Miquel Raynal <[email protected]>
@@ -34,16 +39,6 @@ struct udevice;
#define TPM2_HDR_LEN 10
-/*
- * We deviate from this draft of the specification by increasing the value of
- * TPM2_NUM_PCR_BANKS from 3 to 16 to ensure compatibility with TPM2
- * implementations that have enabled a larger than typical number of PCR
- * banks. This larger value for TPM2_NUM_PCR_BANKS is expected to be included
- * in a future revision of the specification.
- */
-#define TPM2_NUM_PCR_BANKS 16
-
-/* Definition of (UINT32) TPM2_CAP Constants */
#define TPM2_CAP_PCRS 0x00000005U
#define TPM2_CAP_TPM_PROPERTIES 0x00000006U
@@ -55,20 +50,43 @@ struct udevice;
#define TPM2_PT_MAX_COMMAND_SIZE (u32)(TPM2_PT_FIXED + 30)
#define TPM2_PT_MAX_RESPONSE_SIZE (u32)(TPM2_PT_FIXED + 31)
-/* TPMS_TAGGED_PROPERTY Structure */
+/**
+ * struct tpms_tagged_property - TPMS_TAGGED_PROPERTY structure
+ *
+ * This structure is returned by TPM2_GetCapability() to report
+ * a u32 property value.
+ *
+ * @property: property identifier
+ * @value: value of the property
+ */
struct tpms_tagged_property {
u32 property;
u32 value;
} __packed;
-/* TPMS_PCR_SELECTION Structure */
+/**
+ * struct tpms_pcr_selection - TPMS_PCR_SELECTION structure
+ *
+ * This structure allows to specify a hash algorithm and a list of
+ * selected PCRs. A PCR is selected by setting the related bit in
+ * @pcr_select to 1.
+ *
+ * @hash: hash algorithm associated with the selection
+ * @size_of_select: size in bytes of the @pcr_select array
+ * @pcr_select: bit map of selected PCRs
+ */
struct tpms_pcr_selection {
u16 hash;
u8 size_of_select;
u8 pcr_select[TPM2_PCR_SELECT_MAX];
} __packed;
-/* TPML_PCR_SELECTION Structure */
+/**
+ * struct tpml_pcr_selection - TPML_PCR_SELECTION structure
+ *
+ * @count: number of selection structures, may be zero
+ * @selection: list of selections
+ */
struct tpml_pcr_selection {
u32 count;
struct tpms_pcr_selection selection[TPM2_NUM_PCR_BANKS];
@@ -268,6 +286,7 @@ struct digest_info {
u16 hash_alg;
u32 hash_mask;
u16 hash_len;
+ bool supported;
};
/* Algorithm Registry */
@@ -278,38 +297,50 @@ struct digest_info {
#define TCG2_BOOT_HASH_ALG_SM3_256 0x00000010
static const struct digest_info hash_algo_list[] = {
-#if IS_ENABLED(CONFIG_SHA1)
{
"sha1",
TPM2_ALG_SHA1,
TCG2_BOOT_HASH_ALG_SHA1,
TPM2_SHA1_DIGEST_SIZE,
- },
+#if IS_ENABLED(CONFIG_SHA1)
+ true,
+#else
+ false,
#endif
-#if IS_ENABLED(CONFIG_SHA256)
+ },
{
"sha256",
TPM2_ALG_SHA256,
TCG2_BOOT_HASH_ALG_SHA256,
TPM2_SHA256_DIGEST_SIZE,
- },
+#if IS_ENABLED(CONFIG_SHA256)
+ true,
+#else
+ false,
#endif
-#if IS_ENABLED(CONFIG_SHA384)
+ },
{
"sha384",
TPM2_ALG_SHA384,
TCG2_BOOT_HASH_ALG_SHA384,
TPM2_SHA384_DIGEST_SIZE,
- },
+#if IS_ENABLED(CONFIG_SHA384)
+ true,
+#else
+ false,
#endif
-#if IS_ENABLED(CONFIG_SHA512)
+ },
{
"sha512",
TPM2_ALG_SHA512,
TCG2_BOOT_HASH_ALG_SHA512,
TPM2_SHA512_DIGEST_SIZE,
- },
+#if IS_ENABLED(CONFIG_SHA512)
+ true,
+#else
+ false,
#endif
+ },
};
/* NV index attributes */
@@ -705,6 +736,14 @@ enum tpm2_algorithms tpm2_name_to_algorithm(const char *name);
const char *tpm2_algorithm_name(enum tpm2_algorithms);
/**
+ * tpm2_algorithm_supported() - Check if the algorithm supported by U-Boot
+ *
+ * @algorithm_id: algorithm defined in enum tpm2_algorithms
+ * Return: true if supported, otherwise false
+ */
+bool tpm2_algorithm_supported(enum tpm2_algorithms algo);
+
+/**
* tpm2_algorithm_to_len() - Return an algorithm length for supported algorithm id
*
* @algorithm_id: algorithm defined in enum tpm2_algorithms
@@ -732,20 +771,28 @@ u16 tpm2_algorithm_to_len(enum tpm2_algorithms algo);
*/
/**
- * tpm2_allow_extend() - Check if extending PCRs is allowed and safe
+ * tpm2_check_active_banks() - Check if the active PCR banks are supported by
+ * our configuration
*
* @dev: TPM device
* Return: true if allowed
*/
-bool tpm2_allow_extend(struct udevice *dev);
+bool tpm2_check_active_banks(struct udevice *dev);
/**
- * tpm2_is_active_pcr() - check the pcr_select. If at least one of the PCRs
- * supports the algorithm add it on the active ones
+ * tpm2_is_active_bank() - check the pcr_select. If at least one of the PCRs
+ * supports the algorithm add it on the active ones
*
* @selection: PCR selection structure
* Return: True if the algorithm is active
*/
-bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection);
+bool tpm2_is_active_bank(struct tpms_pcr_selection *selection);
+
+/**
+ * tpm2_print_active_banks() - Print the active TPM PCRs
+ *
+ * @dev: TPM device
+ */
+void tpm2_print_active_banks(struct udevice *dev);
#endif /* __TPM_V2_H */
diff --git a/include/tpm_tcg2.h b/include/tpm_tcg2.h
index 6519004cc41..eb6afe49e77 100644
--- a/include/tpm_tcg2.h
+++ b/include/tpm_tcg2.h
@@ -94,17 +94,17 @@ struct tcg_pcr_event {
} __packed;
/**
- * tcg2_get_pcr_info() - get the supported, active PCRs and number of banks
+ * tcg2_get_pcr_info() - get the supported, active banks and number of banks
*
* @dev: TPM device
- * @supported_pcr: bitmask with the algorithms supported
- * @active_pcr: bitmask with the active algorithms
- * @pcr_banks: number of PCR banks
+ * @supported_bank: bitmask with the algorithms supported
+ * @active_bank: bitmask with the active algorithms
+ * @bank_num: number of PCR banks
*
* @return 0 on success, code of operation or negative errno on failure
*/
-int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
- u32 *pcr_banks);
+int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_bank, u32 *active_bank,
+ u32 *bank_num);
/**
* Crypto Agile Log Entry Format