Measure wolfBoot, not application. Added TPM docs.

pull/345/head
David Garske 2023-08-16 11:53:02 -07:00 committed by Daniele Lacamera
parent d05672ea64
commit b05c7ab980
3 changed files with 93 additions and 11 deletions

31
docs/TPM.md 100644
View File

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

View File

@ -133,6 +133,7 @@ extern "C" {
# define WOLFBOOT_SHA_DIGEST_SIZE (32) # define WOLFBOOT_SHA_DIGEST_SIZE (32)
# define image_hash image_sha256 # define image_hash image_sha256
# define key_hash key_sha256 # define key_hash key_sha256
# define self_hash self_sha256
#elif defined(WOLFBOOT_HASH_SHA384) #elif defined(WOLFBOOT_HASH_SHA384)
# ifndef WOLFBOOT_SHA_BLOCK_SIZE # ifndef WOLFBOOT_SHA_BLOCK_SIZE
# define WOLFBOOT_SHA_BLOCK_SIZE (256) # define WOLFBOOT_SHA_BLOCK_SIZE (256)
@ -141,6 +142,7 @@ extern "C" {
# define WOLFBOOT_SHA_DIGEST_SIZE (48) # define WOLFBOOT_SHA_DIGEST_SIZE (48)
# define image_hash image_sha384 # define image_hash image_sha384
# define key_hash key_sha384 # define key_hash key_sha384
# define self_hash self_sha384
#elif defined(WOLFBOOT_HASH_SHA3_384) #elif defined(WOLFBOOT_HASH_SHA3_384)
# ifndef WOLFBOOT_SHA_BLOCK_SIZE # ifndef WOLFBOOT_SHA_BLOCK_SIZE
# define WOLFBOOT_SHA_BLOCK_SIZE (128) # define WOLFBOOT_SHA_BLOCK_SIZE (128)

View File

@ -442,6 +442,30 @@ static uint8_t *get_img_hdr(struct wolfBoot_image *img)
#if defined(WOLFBOOT_HASH_SHA256) #if defined(WOLFBOOT_HASH_SHA256)
#include <wolfssl/wolfcrypt/sha256.h> #include <wolfssl/wolfcrypt/sha256.h>
#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) static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
{ {
uint8_t *stored_sha, *end_sha; uint8_t *stored_sha, *end_sha;
@ -508,8 +532,31 @@ static void key_sha256(uint8_t key_slot, uint8_t *hash)
#endif /* SHA2-256 */ #endif /* SHA2-256 */
#if defined(WOLFBOOT_HASH_SHA384) #if defined(WOLFBOOT_HASH_SHA384)
#include <wolfssl/wolfcrypt/sha512.h> #include <wolfssl/wolfcrypt/sha512.h>
#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) static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
{ {
uint8_t *stored_sha, *end_sha; 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 */ #endif /* !ARCH_SIM */
#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_MEASURED_BOOT) #ifdef WOLFBOOT_MEASURED_BOOT
#define measure_boot(hash) wolfBoot_tpm2_extend((hash), __LINE__) #define measure_boot(hash) wolfBoot_tpm2_extend((hash), __LINE__)
static int wolfBoot_tpm2_extend(uint8_t* hash, int line) static int wolfBoot_tpm2_extend(uint8_t* hash, int line)
{ {
@ -899,6 +946,17 @@ int wolfBoot_tpm2_init(void)
} }
#endif #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; return rc;
} }
@ -1082,15 +1140,6 @@ int wolfBoot_verify_integrity(struct wolfBoot_image *img)
return -1; return -1;
if (image_hash(img, digest) != 0) if (image_hash(img, digest) != 0)
return -1; 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) if (memcmp(digest, stored_sha, stored_sha_len) != 0)
return -1; return -1;
img->sha_ok = 1; img->sha_ok = 1;