From b05c7ab980a2da30e482516df1192dd9099daede Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 16 Aug 2023 11:53:02 -0700 Subject: [PATCH] Measure wolfBoot, not application. Added TPM docs. --- docs/TPM.md | 31 ++++++++++++++++ include/wolfboot/wolfboot.h | 2 ++ src/image.c | 71 +++++++++++++++++++++++++++++++------ 3 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 docs/TPM.md diff --git a/docs/TPM.md b/docs/TPM.md new file mode 100644 index 00000000..78671862 --- /dev/null +++ b/docs/TPM.md @@ -0,0 +1,31 @@ +# wolfBoot TPM support + +In wolfBoot we support TPM based root of trust, sealing/unsealing, cryptographic offloading and measured boot using a TPM. + +## Build Options + +| Config Option | Preprocessor Macro | Description | +| ------------- | ------------------ | ----------------------------------- | +| `WOLFTPM=1` | `WOLFBOOT_TPM` | Enables wolfTPM support and cryptographic offloading for RSA2048 and ECC256/384 | +| `WOLFBOOT_TPM_KEYSTORE=1` | `WOLFBOOT_TPM_KEYSTORE` | Enables TPM based root of trust. NV Index must store a hash of the trusted public key. | +| `WOLFBOOT_TPM_KEYSTORE_NV_INDEX=0x` | `WOLFBOOT_TPM_KEYSTORE_NV_INDEX=0x` | NV index in platform range 0x1400000 - 0x17FFFFF | +| `MEASURED_BOOT=1` | `WOLFBOOT_MEASURED_BOOT` | Enable measured boot. Extend PCR with wolfBoot hash. | +| `MEASURED_PCR_A=16` | `WOLFBOOT_MEASURED_PCR_A=16` | The PCR index to use. See [docs/measured_boot.md](/docs/measured_boot.md) | + +## Root of Trust (ROT) + +See wolfTPM Secure Root of Trust (ROT) example [here](https://github.com/wolfSSL/wolfTPM/tree/master/examples/boot). + +The design uses a platform NV handle that has been locked. The NV stores a hash of the public key. It is recommended to supply a derived "authentication" value to prevent TPM tampering. This authentication value is encrypted on the bus. + +## Cryptographic offloading + +The RSA2048 and ECC256/384 bit verification can be offloaded to a TPM for code size reduction or performance improvement. + +## Measured Boot + +The wolfBoot image is hashed and extended to the indicated PCR. This can be used later in the application to prove the boot process was not tampered with. + +## Sealing and Unsealing a secret + +API's for this will be available soon. diff --git a/include/wolfboot/wolfboot.h b/include/wolfboot/wolfboot.h index 4dc16f23..499b788c 100644 --- a/include/wolfboot/wolfboot.h +++ b/include/wolfboot/wolfboot.h @@ -133,6 +133,7 @@ extern "C" { # define WOLFBOOT_SHA_DIGEST_SIZE (32) # define image_hash image_sha256 # define key_hash key_sha256 + # define self_hash self_sha256 #elif defined(WOLFBOOT_HASH_SHA384) # ifndef WOLFBOOT_SHA_BLOCK_SIZE # define WOLFBOOT_SHA_BLOCK_SIZE (256) @@ -141,6 +142,7 @@ extern "C" { # define WOLFBOOT_SHA_DIGEST_SIZE (48) # define image_hash image_sha384 # define key_hash key_sha384 + # define self_hash self_sha384 #elif defined(WOLFBOOT_HASH_SHA3_384) # ifndef WOLFBOOT_SHA_BLOCK_SIZE # define WOLFBOOT_SHA_BLOCK_SIZE (128) diff --git a/src/image.c b/src/image.c index c34068d2..cfaca69b 100644 --- a/src/image.c +++ b/src/image.c @@ -442,6 +442,30 @@ static uint8_t *get_img_hdr(struct wolfBoot_image *img) #if defined(WOLFBOOT_HASH_SHA256) #include + +#ifdef WOLFBOOT_MEASURED_BOOT +static int self_sha256(uint8_t *hash) +{ + void *p = (void*)WOLFBOOT_PARTITION_BOOT_ADDRESS; + uint32_t sz = (uint32_t)WOLFBOOT_PARTITION_SIZE; + uint32_t blksz, position = 0; + wc_Sha256 sha256_ctx; + + wc_InitSha256(&sha256_ctx); + do { + blksz = WOLFBOOT_SHA_BLOCK_SIZE; + if (position + blksz > sz) + blksz = sz - position; + wc_Sha256Update(&sha256_ctx, p, blksz); + position += blksz; + p += blksz; + } while (position < sz); + wc_Sha256Final(&sha256_ctx, hash); + + return 0; +} +#endif /* WOLFBOOT_MEASURED_BOOT */ + static int image_sha256(struct wolfBoot_image *img, uint8_t *hash) { uint8_t *stored_sha, *end_sha; @@ -508,8 +532,31 @@ static void key_sha256(uint8_t key_slot, uint8_t *hash) #endif /* SHA2-256 */ #if defined(WOLFBOOT_HASH_SHA384) - #include + +#ifdef WOLFBOOT_MEASURED_BOOT +static int self_sha384(uint8_t *hash) +{ + void *p = (void*)WOLFBOOT_PARTITION_BOOT_ADDRESS; + uint32_t sz = (uint32_t)WOLFBOOT_PARTITION_SIZE; + uint32_t blksz, position = 0; + wc_Sha384 sha384_ctx; + + wc_InitSha384(&sha384_ctx); + do { + blksz = WOLFBOOT_SHA_BLOCK_SIZE; + if (position + blksz > sz) + blksz = sz - position; + wc_Sha384Update(&sha384_ctx, p, blksz); + position += blksz; + p += blksz; + } while (position < sz); + wc_Sha384Final(&sha384_ctx, hash); + + return 0; +} +#endif /* WOLFBOOT_MEASURED_BOOT */ + static int image_sha384(struct wolfBoot_image *img, uint8_t *hash) { uint8_t *stored_sha, *end_sha; @@ -782,7 +829,7 @@ static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, } #endif /* !ARCH_SIM */ -#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_MEASURED_BOOT) +#ifdef WOLFBOOT_MEASURED_BOOT #define measure_boot(hash) wolfBoot_tpm2_extend((hash), __LINE__) static int wolfBoot_tpm2_extend(uint8_t* hash, int line) { @@ -899,6 +946,17 @@ int wolfBoot_tpm2_init(void) } #endif +#ifdef WOLFBOOT_MEASURED_BOOT + /* hash wolfBoot and extend PCR */ + rc = self_hash(digest); + if (rc == 0) { + rc = measure_boot(digest); + } + if (rc != 0) { + wolfBoot_printf("Error %d performing wolfBoot measurement!\n", rc); + } +#endif + return rc; } @@ -1082,15 +1140,6 @@ int wolfBoot_verify_integrity(struct wolfBoot_image *img) return -1; if (image_hash(img, digest) != 0) return -1; -#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_MEASURED_BOOT) - /* - * TPM measurement must be performed regardless of the - * verification outcome afterwards, because the purpose - * of a Measured Boot is to record the current boot state - */ - if (measure_boot(digest) != 0) - return -1; -#endif if (memcmp(digest, stored_sha, stored_sha_len) != 0) return -1; img->sha_ok = 1;