diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/security/tpm/tspi.h | 15 | ||||
-rw-r--r-- | src/security/tpm/tspi/tspi.c | 65 | ||||
-rw-r--r-- | src/security/tpm/tss_errors.h | 2 | ||||
-rw-r--r-- | src/security/vboot/Makefile.inc | 4 |
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) |