Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/TPM.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ In wolfBoot we support TPM based root of trust, sealing/unsealing, cryptographic
| `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_BASE=0x` | `WOLFBOOT_TPM_KEYSTORE_NV_BASE=0x` | NV index in platform range 0x1400000 - 0x17FFFFF. |
| `WOLFBOOT_TPM_KEYSTORE_AUTH=secret` | `WOLFBOOT_TPM_KEYSTORE_AUTH` | Password for NV access |
| `MEASURED_BOOT=1` | `WOLFBOOT_MEASURED_BOOT` | Enable measured boot. Extend PCR with wolfBoot hash. |
| `MEASURED_BOOT=1` | `WOLFBOOT_MEASURED_BOOT` | Enable measured boot. Extends PCR with a hash of the wolfBoot bootloader code. |
| `MEASURED_PCR_A=16` | `WOLFBOOT_MEASURED_PCR_A=16` | The PCR index to use. See [docs/measured_boot.md](/docs/measured_boot.md). |
| `MEASURED_BOOT_APP_PARTITION=1` | `WOLFBOOT_MEASURED_BOOT_APP_PARTITION` | Legacy: measure the boot (application) partition instead of wolfBoot code. |
| `WOLFBOOT_TPM_SEAL=1` | `WOLFBOOT_TPM_SEAL` | Enables support for sealing/unsealing based on PCR policy signed externally. |
| `WOLFBOOT_TPM_SEAL_NV_BASE=0x01400300` | `WOLFBOOT_TPM_SEAL_NV_BASE` | To override the default sealed blob storage location in the platform hierarchy. |
| `WOLFBOOT_TPM_SEAL_AUTH=secret` | `WOLFBOOT_TPM_SEAL_AUTH` | Password for sealing/unsealing secrets, if omitted the PCR policy will be used |
Expand All @@ -30,7 +31,9 @@ NOTE: The TPM's RSA verify requires ASN.1 encoding, so use SIGN=RSA2048ENC

## 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. Enabled with `WOLFBOOT_MEASURED_BOOT` and exposes API `wolfBoot_tpm2_extend`.
The wolfBoot bootloader code 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. Enabled with `WOLFBOOT_MEASURED_BOOT` and exposes API `wolfBoot_tpm2_extend`.

By default, the measurement covers wolfBoot's own code region (from `_start_text` to `_stored_data` linker symbols). To use the legacy behavior of measuring the boot (application) partition instead, set `MEASURED_BOOT_APP_PARTITION=1`.

## Sealing and Unsealing a secret

Expand Down
15 changes: 10 additions & 5 deletions docs/measured_boot.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ Having TPM measurements provide a way for the firmware or Operating System(OS),
like Windows or Linux, to know that the software loaded before it gained control
over system, is trustworthy and not modified.

In wolfBoot the concept is simplified to measuring a single component, the main
firmware image. However, this can easily be extended by using more PCR registers.
In wolfBoot the concept is simplified to measuring a single component, the
wolfBoot bootloader code itself. This ensures the bootloader has not been
tampered with before it verifies and loads the application. However, this can
easily be extended by using more PCR registers.

To use the legacy behavior of measuring the boot (application) partition instead
of wolfBoot's own code, set `MEASURED_BOOT_APP_PARTITION=1` in your config.

## Configuration

Expand Down Expand Up @@ -81,6 +86,6 @@ MEASURED_PCR_A?=16
### Code

wolfBoot offers out-of-the-box solution. There is zero need of the developer to touch wolfBoot code
in order to use measured boot. If you would want to check the code, then look in `src/image.c` and
more specifically the `measure_boot()` function. There you would find several TPM2 native API calls
to wolfTPM. For more information about wolfTPM you can check its GitHub repository.
in order to use measured boot. If you would want to check the code, then look in `src/tpm.c` and
more specifically the `self_hash()` and `measure_boot()` functions. There you would find several TPM2
native API calls to wolfTPM. For more information about wolfTPM you can check its GitHub repository.
2 changes: 2 additions & 0 deletions hal/x86_fsp_qemu.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ SECTIONS
_end_wolfboot = .;
} > RAM

_stored_data = _end_text;

_fsp_size = _end_fsp_s - _start_fsp_s;
.bss WOLFBOOT_LOAD_BASE + SIZEOF(.text) (NOLOAD):
{
Expand Down
1 change: 1 addition & 0 deletions hal/x86_fsp_qemu_stage1.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ SECTIONS

.bootloader WOLFBOOT_ORIGIN :
{
_start_text = .;
KEEP(*(.boot*))
*(.text*)
*(.rodata*)
Expand Down
1 change: 1 addition & 0 deletions hal/x86_fsp_tgl.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ SECTIONS
_end_wolfboot = .;
}

_stored_data = _end_text;
_fsp_size = _end_fsp_s - _start_fsp_s;
.bss WOLFBOOT_LOAD_BASE + SIZEOF(.text) (NOLOAD):
{
Expand Down
1 change: 1 addition & 0 deletions hal/x86_fsp_tgl_stage1.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ SECTIONS

.bootloader WOLFBOOT_ORIGIN :
{
_start_text = .;
KEEP(./tgl_fsp.o(.boot))
KEEP(*(.boot*))
KEYSTORE_START = .;
Expand Down
3 changes: 3 additions & 0 deletions options.mk
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ ifeq ($(MEASURED_BOOT),1)
WOLFTPM:=1
CFLAGS+=-D"WOLFBOOT_MEASURED_BOOT"
CFLAGS+=-D"WOLFBOOT_MEASURED_PCR_A=$(MEASURED_PCR_A)"
ifeq ($(MEASURED_BOOT_APP_PARTITION),1)
CFLAGS+=-D"WOLFBOOT_MEASURED_BOOT_APP_PARTITION"
endif
endif

## TPM keystore
Expand Down
47 changes: 36 additions & 11 deletions src/tpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,13 +229,35 @@ static int TPM2_IoCb(TPM2_CTX* ctx, const uint8_t* txBuf, uint8_t* rxBuf,

#ifdef WOLFBOOT_MEASURED_BOOT

#ifndef WOLFBOOT_NO_PARTITIONS
#if defined(WOLFBOOT_MEASURED_BOOT_APP_PARTITION) || defined(STAGE1_AUTH)
/* measure the boot (application) partition */
#ifndef WOLFBOOT_NO_PARTITIONS
#define SELF_HASH_ADDR ((uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS)
#define SELF_HASH_SZ ((uint32_t)WOLFBOOT_PARTITION_SIZE)
#endif
#elif defined(ARCH_SIM)
/* Simulator: no linker script, use bootloader partition region */
#if defined(WOLFBOOT_PARTITION_BOOT_ADDRESS) && defined(ARCH_FLASH_OFFSET)
#define SELF_HASH_ADDR ((uintptr_t)ARCH_FLASH_OFFSET)
#define SELF_HASH_SZ ((uint32_t)((uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS - \
(uintptr_t)ARCH_FLASH_OFFSET))
#endif
#else
/* Default: measure wolfBoot's own code using linker script symbols */
extern unsigned int _start_text;
extern unsigned int _stored_data;
#define SELF_HASH_ADDR ((uintptr_t)&_start_text)
#define SELF_HASH_SZ ((uint32_t)((uintptr_t)&_stored_data - \
(uintptr_t)&_start_text))
#endif

#ifdef SELF_HASH_ADDR
#ifdef WOLFBOOT_HASH_SHA256
#include <wolfssl/wolfcrypt/sha256.h>
static int self_sha256(uint8_t *hash)
{
uintptr_t p = (uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
uint32_t sz = (uint32_t)WOLFBOOT_PARTITION_SIZE;
uintptr_t p = SELF_HASH_ADDR;
uint32_t sz = SELF_HASH_SZ;
uint32_t blksz, position = 0;
wc_Sha256 sha256_ctx;

Expand All @@ -244,7 +266,8 @@ static int self_sha256(uint8_t *hash)
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (position + blksz > sz)
blksz = sz - position;
#if defined(EXT_FLASH) && defined(NO_XIP)
#if defined(EXT_FLASH) && defined(NO_XIP) && \
defined(WOLFBOOT_MEASURED_BOOT_APP_PARTITION)
rc = ext_flash_read(p, ext_hash_block, WOLFBOOT_SHA_BLOCK_SIZE);
if (rc != WOLFBOOT_SHA_BLOCK_SIZE)
return -1;
Expand All @@ -264,8 +287,8 @@ static int self_sha256(uint8_t *hash)
#include <wolfssl/wolfcrypt/sha512.h>
static int self_sha384(uint8_t *hash)
{
uintptr_t p = (uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
uint32_t sz = (uint32_t)WOLFBOOT_PARTITION_SIZE;
uintptr_t p = SELF_HASH_ADDR;
uint32_t sz = SELF_HASH_SZ;
uint32_t blksz, position = 0;
wc_Sha384 sha384_ctx;

Expand All @@ -274,7 +297,8 @@ static int self_sha384(uint8_t *hash)
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (position + blksz > sz)
blksz = sz - position;
#if defined(EXT_FLASH) && defined(NO_XIP)
#if defined(EXT_FLASH) && defined(NO_XIP) && \
defined(WOLFBOOT_MEASURED_BOOT_APP_PARTITION)
rc = ext_flash_read(p, ext_hash_block, WOLFBOOT_SHA_BLOCK_SIZE);
if (rc != WOLFBOOT_SHA_BLOCK_SIZE)
return -1;
Expand All @@ -290,7 +314,7 @@ static int self_sha384(uint8_t *hash)
return 0;
}
#endif /* HASH type */
#endif /* WOLFBOOT_NO_PARTITIONS */
#endif /* SELF_HASH_ADDR */

/**
* @brief Extends a PCR in the TPM with a hash.
Expand Down Expand Up @@ -1434,8 +1458,9 @@ int wolfBoot_tpm2_init(void)
}
#endif /* WOLFBOOT_TPM_KEYSTORE | WOLFBOOT_TPM_SEAL */

#if defined(WOLFBOOT_MEASURED_BOOT) && !defined(WOLFBOOT_NO_PARTITIONS)
/* hash wolfBoot and extend PCR */
#if defined(WOLFBOOT_MEASURED_BOOT) && defined(SELF_HASH_ADDR)
/* measured boot: hash wolfBoot code (or boot partition if
* WOLFBOOT_MEASURED_BOOT_APP_PARTITION) and extend PCR */
if (rc == 0) {
rc = self_hash(digest);
if (rc == 0) {
Expand All @@ -1445,7 +1470,7 @@ int wolfBoot_tpm2_init(void)
wolfBoot_printf("Error %d performing wolfBoot measurement!\n", rc);
}
}
#endif /* defined(WOLFBOOT_MEASURED_BOOT) && !defined(WOLFBOOT_NO_PARTITIONS) */
#endif /* WOLFBOOT_MEASURED_BOOT && SELF_HASH_ADDR */

return rc;
}
Expand Down
Loading