summaryrefslogtreecommitdiff
path: root/src/security/tpm/tspi
diff options
context:
space:
mode:
authorWerner Zeh <werner.zeh@siemens.com>2018-10-23 07:40:08 +0200
committerPhilipp Deppenwiese <zaolin.daisuki@gmail.com>2018-10-31 14:14:16 +0000
commit30cf14ff3fdd9fbbaa3ffb841359c2ee1a0bfcad (patch)
treefcce3ab226d884749d707697fcbcd1a873fd6eab /src/security/tpm/tspi
parent5220aeab6ef62e26f92e64ce4bab20d26e53420f (diff)
security/tpm: Add function to measure a region device
Add a new function which can hash a given region device and extend a PCR in the TPM with the result. The needed SHA algorithms are included from 3rdparty/vboot and thus not duplicated in the coreboot tree. For now VB2_LIB is not usable in postcar stage. Follow-up commits will add the ability to use the lib in postcar as well. Once this feature is ready, the library will be included in postcar stage to make this function available in every stage. Change-Id: I126cc3500fd039d63743db78002a04d201ab18aa Signed-off-by: Werner Zeh <werner.zeh@siemens.com> Reviewed-on: https://review.coreboot.org/29234 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Diffstat (limited to 'src/security/tpm/tspi')
-rw-r--r--src/security/tpm/tspi/tspi.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c
index 0b6f9bcff2..285f18dde2 100644
--- a/src/security/tpm/tspi/tspi.c
+++ b/src/security/tpm/tspi/tspi.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Copyright 2017 Facebook Inc.
+ * Copyright 2018 Siemens AG
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +22,10 @@
#include <security/tpm/tss.h>
#include <stdlib.h>
#include <string.h>
+#if IS_ENABLED(CONFIG_VBOOT)
+#include <vb2_api.h>
+#include <assert.h>
+#endif
#if IS_ENABLED(CONFIG_TPM1)
static uint32_t tpm1_invoke_state_machine(void)
@@ -214,3 +219,63 @@ uint32_t tpm_extend_pcr(int pcr, uint8_t *digest,
return TPM_SUCCESS;
}
+
+#if IS_ENABLED(CONFIG_VBOOT)
+uint32_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr,
+ const char *rname)
+{
+ uint8_t digest[TPM_PCR_MAX_LEN], digest_len;
+ uint8_t buf[HASH_DATA_CHUNK_SIZE];
+ uint32_t result, offset;
+ size_t len;
+ struct vb2_digest_context ctx;
+ enum vb2_hash_algorithm hash_alg;
+
+ if (!rdev || !rname)
+ return TPM_E_INVALID_ARG;
+ result = tlcl_lib_init();
+ if (result != TPM_SUCCESS) {
+ printk(BIOS_ERR, "TPM: Can't initialize library.\n");
+ return result;
+ }
+ if (IS_ENABLED(CONFIG_TPM1))
+ hash_alg = VB2_HASH_SHA1;
+ else /* CONFIG_TPM2 */
+ hash_alg = VB2_HASH_SHA256;
+
+ digest_len = vb2_digest_size(hash_alg);
+ assert(digest_len <= sizeof(digest));
+ if (vb2_digest_init(&ctx, hash_alg)) {
+ printk(BIOS_ERR, "TPM: Error initializing hash.\n");
+ return TPM_E_HASH_ERROR;
+ }
+ /*
+ * Though one can mmap the full needed region on x86 this is not the
+ * case for e.g. ARM. In order to make this code as universal as
+ * possible across different platforms read the data to hash in chunks.
+ */
+ for (offset = 0; offset < region_device_sz(rdev); offset += len) {
+ len = MIN(sizeof(buf), region_device_sz(rdev) - offset);
+ if (rdev_readat(rdev, buf, offset, len) < 0) {
+ printk(BIOS_ERR, "TPM: Not able to read region %s.\n",
+ rname);
+ return TPM_E_READ_FAILURE;
+ }
+ if (vb2_digest_extend(&ctx, buf, len)) {
+ printk(BIOS_ERR, "TPM: Error extending hash.\n");
+ return TPM_E_HASH_ERROR;
+ }
+ }
+ if (vb2_digest_finalize(&ctx, digest, digest_len)) {
+ printk(BIOS_ERR, "TPM: Error finalizing hash.\n");
+ return TPM_E_HASH_ERROR;
+ }
+ result = tpm_extend_pcr(pcr, digest, digest_len, rname);
+ if (result != TPM_SUCCESS) {
+ printk(BIOS_ERR, "TPM: Extending hash into PCR failed.\n");
+ return result;
+ }
+ printk(BIOS_DEBUG, "TPM: Measured %s into PCR %d\n", rname, pcr);
+ return TPM_SUCCESS;
+}
+#endif /* VBOOT */