<p>Philipp Deppenwiese <strong>merged</strong> this change.</p><p><a href="https://review.coreboot.org/29234">View Change</a></p><div style="white-space:pre-wrap">Approvals:
build bot (Jenkins): Verified
Philipp Deppenwiese: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">security/tpm: Add function to measure a region device<br><br>Add a new function which can hash a given region device and extend a PCR<br>in the TPM with the result. The needed SHA algorithms are included from<br>3rdparty/vboot and thus not duplicated in the coreboot tree.<br><br>For now VB2_LIB is not usable in postcar stage. Follow-up commits will<br>add the ability to use the lib in postcar as well. Once this feature is<br>ready, the library will be included in postcar stage to make this<br>function available in every stage.<br><br>Change-Id: I126cc3500fd039d63743db78002a04d201ab18aa<br>Signed-off-by: Werner Zeh <werner.zeh@siemens.com><br>Reviewed-on: https://review.coreboot.org/29234<br>Tested-by: build bot (Jenkins) <no-reply@coreboot.org><br>Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com><br>---<br>M src/security/tpm/tspi.h<br>M src/security/tpm/tspi/tspi.c<br>M src/security/tpm/tss_errors.h<br>M src/security/vboot/Makefile.inc<br>4 files changed, 86 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/security/tpm/tspi.h b/src/security/tpm/tspi.h</span><br><span>index e4ddefc..d69b976 100644</span><br><span>--- a/src/security/tpm/tspi.h</span><br><span>+++ b/src/security/tpm/tspi.h</span><br><span>@@ -3,6 +3,7 @@</span><br><span> *</span><br><span> * Copyright (c) 2013 The Chromium OS Authors. All rights reserved.</span><br><span> * Copyright 2018 Facebook Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Siemens AG</span><br><span> *</span><br><span> * This program is free software; you can redistribute it and/or modify</span><br><span> * it under the terms of the GNU General Public License as published by</span><br><span>@@ -19,6 +20,10 @@</span><br><span> </span><br><span> #include <security/tpm/tss.h></span><br><span> #include <commonlib/tcpa_log_serialized.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <commonlib/region.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define TPM_PCR_MAX_LEN 64</span><br><span style="color: hsl(120, 100%, 40%);">+#define HASH_DATA_CHUNK_SIZE 1024</span><br><span> </span><br><span> /**</span><br><span> * Add table entry for cbmem TCPA log.</span><br><span>@@ -51,4 +56,14 @@</span><br><span> */</span><br><span> uint32_t tpm_setup(int s3flag);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Measure a given region device and extend given PCR with the result.</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param *rdev Pointer to the region device to measure</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param pcr Index of the PCR which will be extended by this measure</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param *rname Name of the region that is measured</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return TPM error code in case of error otherwise TPM_SUCCESS</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr,</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *rname);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif /* TSPI_H_ */</span><br><span>diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c</span><br><span>index 0b6f9bc..285f18d 100644</span><br><span>--- a/src/security/tpm/tspi/tspi.c</span><br><span>+++ b/src/security/tpm/tspi/tspi.c</span><br><span>@@ -3,6 +3,7 @@</span><br><span> *</span><br><span> * Copyright (c) 2013 The Chromium OS Authors. All rights reserved.</span><br><span> * Copyright 2017 Facebook Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Siemens AG</span><br><span> *</span><br><span> * This program is free software; you can redistribute it and/or modify</span><br><span> * it under the terms of the GNU General Public License as published by</span><br><span>@@ -21,6 +22,10 @@</span><br><span> #include <security/tpm/tss.h></span><br><span> #include <stdlib.h></span><br><span> #include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#if IS_ENABLED(CONFIG_VBOOT)</span><br><span style="color: hsl(120, 100%, 40%);">+#include <vb2_api.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span> </span><br><span> #if IS_ENABLED(CONFIG_TPM1)</span><br><span> static uint32_t tpm1_invoke_state_machine(void)</span><br><span>@@ -214,3 +219,63 @@</span><br><span> </span><br><span> return TPM_SUCCESS;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if IS_ENABLED(CONFIG_VBOOT)</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr,</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *rname)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t digest[TPM_PCR_MAX_LEN], digest_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t buf[HASH_DATA_CHUNK_SIZE];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t result, offset;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t len;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct vb2_digest_context ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum vb2_hash_algorithm hash_alg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!rdev || !rname)</span><br><span style="color: hsl(120, 100%, 40%);">+ return TPM_E_INVALID_ARG;</span><br><span style="color: hsl(120, 100%, 40%);">+ result = tlcl_lib_init();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (result != TPM_SUCCESS) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_ERR, "TPM: Can't initialize library.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return result;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (IS_ENABLED(CONFIG_TPM1))</span><br><span style="color: hsl(120, 100%, 40%);">+ hash_alg = VB2_HASH_SHA1;</span><br><span style="color: hsl(120, 100%, 40%);">+ else /* CONFIG_TPM2 */</span><br><span style="color: hsl(120, 100%, 40%);">+ hash_alg = VB2_HASH_SHA256;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ digest_len = vb2_digest_size(hash_alg);</span><br><span style="color: hsl(120, 100%, 40%);">+ assert(digest_len <= sizeof(digest));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (vb2_digest_init(&ctx, hash_alg)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_ERR, "TPM: Error initializing hash.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return TPM_E_HASH_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Though one can mmap the full needed region on x86 this is not the</span><br><span style="color: hsl(120, 100%, 40%);">+ * case for e.g. ARM. In order to make this code as universal as</span><br><span style="color: hsl(120, 100%, 40%);">+ * possible across different platforms read the data to hash in chunks.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (offset = 0; offset < region_device_sz(rdev); offset += len) {</span><br><span style="color: hsl(120, 100%, 40%);">+ len = MIN(sizeof(buf), region_device_sz(rdev) - offset);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rdev_readat(rdev, buf, offset, len) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_ERR, "TPM: Not able to read region %s.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rname);</span><br><span style="color: hsl(120, 100%, 40%);">+ return TPM_E_READ_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (vb2_digest_extend(&ctx, buf, len)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_ERR, "TPM: Error extending hash.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return TPM_E_HASH_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (vb2_digest_finalize(&ctx, digest, digest_len)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_ERR, "TPM: Error finalizing hash.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return TPM_E_HASH_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ result = tpm_extend_pcr(pcr, digest, digest_len, rname);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (result != TPM_SUCCESS) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_ERR, "TPM: Extending hash into PCR failed.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return result;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "TPM: Measured %s into PCR %d\n", rname, pcr);</span><br><span style="color: hsl(120, 100%, 40%);">+ return TPM_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* VBOOT */</span><br><span>diff --git a/src/security/tpm/tss_errors.h b/src/security/tpm/tss_errors.h</span><br><span>index e2f1486..c80ffa1 100644</span><br><span>--- a/src/security/tpm/tss_errors.h</span><br><span>+++ b/src/security/tpm/tss_errors.h</span><br><span>@@ -38,5 +38,7 @@</span><br><span> #define TPM_E_READ_EMPTY ((uint32_t)0x00005009) /* vboot local */</span><br><span> #define TPM_E_READ_FAILURE ((uint32_t)0x0000500a) /* vboot local */</span><br><span> #define TPM_E_NV_DEFINED ((uint32_t)0x0000500b) /* vboot local */</span><br><span style="color: hsl(120, 100%, 40%);">+#define TPM_E_INVALID_ARG ((uint32_t)0x0000500c)</span><br><span style="color: hsl(120, 100%, 40%);">+#define TPM_E_HASH_ERROR ((uint32_t)0x0000500d)</span><br><span> </span><br><span> #endif /* TSS_ERRORS_H_ */</span><br><span>diff --git a/src/security/vboot/Makefile.inc b/src/security/vboot/Makefile.inc</span><br><span>index c9dd39f..704b6c9 100644</span><br><span>--- a/src/security/vboot/Makefile.inc</span><br><span>+++ b/src/security/vboot/Makefile.inc</span><br><span>@@ -107,7 +107,11 @@</span><br><span> </span><br><span> endef # vboot-for-stage</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+CFLAGS_common += -I3rdparty/vboot/firmware/2lib/include</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> $(eval $(call vboot-for-stage,verstage))</span><br><span style="color: hsl(120, 100%, 40%);">+$(eval $(call vboot-for-stage,bootblock))</span><br><span style="color: hsl(120, 100%, 40%);">+$(eval $(call vboot-for-stage,ramstage))</span><br><span> </span><br><span> ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y)</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/29234">change 29234</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/29234"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I126cc3500fd039d63743db78002a04d201ab18aa </div>
<div style="display:none"> Gerrit-Change-Number: 29234 </div>
<div style="display:none"> Gerrit-PatchSet: 10 </div>
<div style="display:none"> Gerrit-Owner: Werner Zeh <werner.zeh@siemens.com> </div>
<div style="display:none"> Gerrit-Reviewer: Aaron Durbin <adurbin@chromium.org> </div>
<div style="display:none"> Gerrit-Reviewer: Julius Werner <jwerner@chromium.org> </div>
<div style="display:none"> Gerrit-Reviewer: Patrick Georgi <pgeorgi@google.com> </div>
<div style="display:none"> Gerrit-Reviewer: Paul Menzel <paulepanter@users.sourceforge.net> </div>
<div style="display:none"> Gerrit-Reviewer: Philipp Deppenwiese <zaolin.daisuki@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Werner Zeh <werner.zeh@siemens.com> </div>
<div style="display:none"> Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org> </div>