<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>