summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/security/tpm/tspi.h15
-rw-r--r--src/security/tpm/tspi/tspi.c65
-rw-r--r--src/security/tpm/tss_errors.h2
-rw-r--r--src/security/vboot/Makefile.inc4
4 files changed, 86 insertions, 0 deletions
diff --git a/src/security/tpm/tspi.h b/src/security/tpm/tspi.h
index e4ddefcdd3..d69b97695d 100644
--- a/src/security/tpm/tspi.h
+++ b/src/security/tpm/tspi.h
@@ -3,6 +3,7 @@
*
* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Copyright 2018 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
@@ -19,6 +20,10 @@
#include <security/tpm/tss.h>
#include <commonlib/tcpa_log_serialized.h>
+#include <commonlib/region.h>
+
+#define TPM_PCR_MAX_LEN 64
+#define HASH_DATA_CHUNK_SIZE 1024
/**
* Add table entry for cbmem TCPA log.
@@ -51,4 +56,14 @@ uint32_t tpm_clear_and_reenable(void);
*/
uint32_t tpm_setup(int s3flag);
+/**
+ * Measure a given region device and extend given PCR with the result.
+ * @param *rdev Pointer to the region device to measure
+ * @param pcr Index of the PCR which will be extended by this measure
+ * @param *rname Name of the region that is measured
+ * @return TPM error code in case of error otherwise TPM_SUCCESS
+ */
+uint32_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr,
+ const char *rname);
+
#endif /* TSPI_H_ */
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 */
diff --git a/src/security/tpm/tss_errors.h b/src/security/tpm/tss_errors.h
index e2f1486315..c80ffa15f3 100644
--- a/src/security/tpm/tss_errors.h
+++ b/src/security/tpm/tss_errors.h
@@ -38,5 +38,7 @@
#define TPM_E_READ_EMPTY ((uint32_t)0x00005009) /* vboot local */
#define TPM_E_READ_FAILURE ((uint32_t)0x0000500a) /* vboot local */
#define TPM_E_NV_DEFINED ((uint32_t)0x0000500b) /* vboot local */
+#define TPM_E_INVALID_ARG ((uint32_t)0x0000500c)
+#define TPM_E_HASH_ERROR ((uint32_t)0x0000500d)
#endif /* TSS_ERRORS_H_ */
diff --git a/src/security/vboot/Makefile.inc b/src/security/vboot/Makefile.inc
index c9dd39f3f4..704b6c92b9 100644
--- a/src/security/vboot/Makefile.inc
+++ b/src/security/vboot/Makefile.inc
@@ -107,7 +107,11 @@ $(1)-srcs += $$(VB2_LIB_$(1))
endef # vboot-for-stage
+CFLAGS_common += -I3rdparty/vboot/firmware/2lib/include
+
$(eval $(call vboot-for-stage,verstage))
+$(eval $(call vboot-for-stage,bootblock))
+$(eval $(call vboot-for-stage,ramstage))
ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y)