aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorIlias Apalodimas2024-06-23 14:48:18 +0300
committerHeinrich Schuchardt2024-06-30 13:58:31 +0200
commite7505b3b8bcd1bca2d30291367713f442b453c41 (patch)
treed9263a8c0375e4e8db0c896a286506e8d725a7ea /lib
parentcba3fa90240df783cb040f25833dd420f7f39f16 (diff)
tpm: allow the user to select the compiled algorithms
Simon reports that after enabling all algorithms on the TPM some boards fail since they don't have enough storage to accommodate the ~5KB growth. The choice of hash algorithms is determined by the platform and the TPM configuration. Failing to cap a PCR in a bank which the platform left active is a security vulnerability. It might allow unsealing of secrets if an attacker can replay a good set of measurements into an unused bank. If MEASURED_BOOT or EFI_TCG2_PROTOCOL is enabled our Kconfig will enable all supported hashing algorithms. We still want to allow users to add a TPM and not enable measured boot via EFI or bootm though and at the same time, control the compiled algorithms for size reasons. So let's add a function tpm2_allow_extend() which checks the TPM active PCRs banks against the one U-Boot was compiled with. We only allow extending PCRs if the algorithms selected during build match the TPM configuration. It's worth noting that this is only added for TPM2.0, since TPM1.2 is lacking a lot of code at the moment to read the available PCR banks. We unconditionally enable SHA1 when a TPM is selected, which is the only hashing algorithm v1.2 supports. Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Simon Glass <sjg@chromium.org> # chromebook-link
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig6
-rw-r--r--lib/tpm-v2.c40
2 files changed, 40 insertions, 6 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index 189e6eb31aa..b3baa4b85b0 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -439,9 +439,6 @@ config TPM
depends on DM
imply DM_RNG
select SHA1
- select SHA256
- select SHA384
- select SHA512
help
This enables support for TPMs which can be used to provide security
features for your board. The TPM can be connected via LPC or I2C
@@ -449,6 +446,9 @@ config TPM
command to interactive the TPM. Driver model support is provided
for the low-level TPM interface, but only one TPM is supported at
a time by the TPM library.
+ For size reasons only SHA1 is selected which is supported on TPM1.2.
+ If you want a fully functional TPM enable all hashing algorithms.
+ If you enabled measured boot all hashing algorithms are selected.
config SPL_TPM
bool "Trusted Platform Module (TPM) Support in SPL"
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 36aace03cf4..59e6cbafafa 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -196,6 +196,11 @@ u32 tpm2_pcr_extend(struct udevice *dev, u32 index, u32 algorithm,
if (!digest)
return -EINVAL;
+
+ if (!tpm2_allow_extend(dev)) {
+ log_err("Cannot extend PCRs if all the TPM enabled algorithms are not supported\n");
+ return -EINVAL;
+ }
/*
* Fill the command structure starting from the first buffer:
* - the digest
@@ -409,11 +414,10 @@ int tpm2_get_pcr_info(struct udevice *dev, struct tpml_pcr_selection *pcrs)
pcrs->count = get_unaligned_be32(response);
/*
- * We only support 5 algorithms for now so check against that
+ * We only support 4 algorithms for now so check against that
* instead of TPM2_NUM_PCR_BANKS
*/
- if (pcrs->count > ARRAY_SIZE(hash_algo_list) ||
- pcrs->count < 1) {
+ if (pcrs->count > 4 || pcrs->count < 1) {
printf("%s: too many pcrs: %u\n", __func__, pcrs->count);
return -EMSGSIZE;
}
@@ -880,3 +884,33 @@ const char *tpm2_algorithm_name(enum tpm2_algorithms algo)
return "";
}
+u16 tpm2_algorithm_to_len(enum tpm2_algorithms algo)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) {
+ if (hash_algo_list[i].hash_alg == algo)
+ return hash_algo_list[i].hash_len;
+ }
+
+ return 0;
+}
+
+bool tpm2_allow_extend(struct udevice *dev)
+{
+ struct tpml_pcr_selection pcrs;
+ size_t i;
+ int rc;
+
+ rc = tpm2_get_pcr_info(dev, &pcrs);
+ if (rc)
+ return false;
+
+ for (i = 0; i < pcrs.count; i++) {
+ if (tpm2_is_active_pcr(&pcrs.selection[i]) &&
+ !tpm2_algorithm_to_len(pcrs.selection[i].hash))
+ return false;
+ }
+
+ return true;
+}