Philipp Deppenwiese has uploaded this change for review. ( https://review.coreboot.org/23711
Change subject: security/tpm: Add SW hash functions for measurements ......................................................................
security/tpm: Add SW hash functions for measurements
* Make SW measurements first class citizen. * Add kconfig option TPM hardware accerlated hashes.
Change-Id: Ice8a0de0294fe619ff725dc5126319fc2bc657ad Signed-off-by: Philipp Deppenwiese zaolin@das-labor.org --- M src/security/crypto/Makefile.inc M src/security/tpm/Kconfig M src/security/tpm/tspi/tspi.c 3 files changed, 72 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/11/23711/1
diff --git a/src/security/crypto/Makefile.inc b/src/security/crypto/Makefile.inc index b1c5cfc..97040f9 100644 --- a/src/security/crypto/Makefile.inc +++ b/src/security/crypto/Makefile.inc @@ -3,19 +3,19 @@ verstage-$(CONFIG_CRYPTO_HASH_SHA1) += hash/sha1.c romstage-$(CONFIG_CRYPTO_HASH_SHA1) += hash/sha1.c ramstage-$(CONFIG_CRYPTO_HASH_SHA1) += hash/sha1.c -smm-$(CONFIG_CRYPTO_HASH_SHA1) += hash/sha1.c +postcar-$(CONFIG_CRYPTO_HASH_SHA1) += hash/sha1.c
verstage-$(CONFIG_CRYPTO_HASH_SHA256) += hash/sha256.c romstage-$(CONFIG_CRYPTO_HASH_SHA256) += hash/sha256.c ramstage-$(CONFIG_CRYPTO_HASH_SHA256) += hash/sha256.c -smm-$(CONFIG_CRYPTO_HASH_SHA256) += hash/sha256.c +postcar-$(CONFIG_CRYPTO_HASH_SHA256) += hash/sha256.c
verstage-$(CONFIG_CRYPTO_HASH_SHA512) += hash/sha512.c romstage-$(CONFIG_CRYPTO_HASH_SHA512) += hash/sha512.c ramstage-$(CONFIG_CRYPTO_HASH_SHA512) += hash/sha512.c -smm-$(CONFIG_CRYPTO_HASH_SHA512) += hash/sha512.c +postcar-$(CONFIG_CRYPTO_HASH_SHA512) += hash/sha512.c
verstage-$(CONFIG_CRYPTO_HASH) += hash/hash.c romstage-$(CONFIG_CRYPTO_HASH) += hash/hash.c ramstage-$(CONFIG_CRYPTO_HASH) += hash/hash.c -smm-$(CONFIG_CRYPTO_HASH) += hash/hash.c +postcar-$(CONFIG_CRYPTO_HASH) += hash/hash.c diff --git a/src/security/tpm/Kconfig b/src/security/tpm/Kconfig index 47c37ce..7f8a2e9 100644 --- a/src/security/tpm/Kconfig +++ b/src/security/tpm/Kconfig @@ -81,4 +81,11 @@ help Deactivate TPM by issuing deactivate command.
+config TPM_HW_HASHES + bool "Enable TPM HW hashes" + default n + depends on (TPM1 || TPM2) + help + Enables hardware accerlated hashes. A TPM HW feature. + endmenu # Trusted Platform Module (tpm) diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c index 8d11148..f4c3520 100644 --- a/src/security/tpm/tspi/tspi.c +++ b/src/security/tpm/tspi/tspi.c @@ -17,6 +17,7 @@ #include <console/cbmem_console.h> #include <console/console.h> #include <reset.h> +#include <security/crypto/hash.h> #include <security/tpm/tspi.h> #include <security/tpm/tss.h> #include <stdlib.h> @@ -176,7 +177,7 @@ }
uint32_t tpm_measure_region(int pcr, const struct region_device *rd, - const char *name) + const char *name) { uint8_t block[TPM_HASH_MAX_COUNT]; uint8_t digest[TPM_PCR_MAX_LENGTH]; @@ -192,6 +193,7 @@ return result; }
+#if IS_ENABLED(CONFIG_TPM_HW_HASHES) result = tlcl_hash_start(&data_max_length); if (result != TPM_SUCCESS) { printk(BIOS_ERR, "TPM: TPM_Hash_Start returned error: %u.\n", @@ -240,6 +242,64 @@ result); return result; } +#else + struct digest_context dc; + data_max_length = 1024; + + if (IS_ENABLED(CONFIG_TPM1)) { + digest_init(&dc, HASH_SHA1); + digest_length = SHA1_DIGEST_SIZE; + } else if (IS_ENABLED(CONFIG_TPM2)) { + digest_init(&dc, HASH_SHA256); + digest_length = SHA256_DIGEST_SIZE; + } + + hash_rounds = (region_device_sz(rd) / data_max_length); + for (i = 0; i < hash_rounds; i++) { + if (rdev_readat(rd, block, (i * data_max_length), + data_max_length) < 0) + return TPM_E_IOERROR; + result = digest_extend(&dc, block, data_max_length); + if (result != SUCCESS) { + printk(BIOS_ERR, + "CRYPTO: digest_extend returned error: %u.\n", + result); + return result; + } + } + + hash_rest = (region_device_sz(rd) % data_max_length); + if (hash_rest > 0) { + size_t hash_complete = + ((hash_rest / TPM_HASH_MIN_COUNT) * TPM_HASH_MIN_COUNT); + + if (rdev_readat(rd, block, (hash_rounds * data_max_length), + hash_complete) < 0) + return TPM_E_IOERROR; + result = digest_extend(&dc, block, hash_complete); + if (result != SUCCESS) { + printk(BIOS_ERR, + "CRYPTO: digest_extend returned error: %u.\n", + result); + return result; + } + + result = digest_extend(&dc, block, TPM_HASH_MIN_COUNT); + if (result != SUCCESS) { + printk(BIOS_ERR, + "CRYPTO: digest_extend returned error: %u.\n", + result); + return result; + } + } + + result = digest_finalize(&dc, digest, digest_length); + if (result != SUCCESS) { + printk(BIOS_ERR, + "CRYPTO: digest_finalize returned error: %u.\n", result); + return result; + } +#endif
result = tlcl_extend(pcr, digest, NULL); if (result != TPM_SUCCESS) {