Skip to content

Commit

Permalink
wolfTPM Support for sealing/unsealing based on a PCR that is signed e…
Browse files Browse the repository at this point in the history
…xternally. Use an external key to sign a PCR digest. Allows a new signed policy to be sent with updates to continue allowing a sealed secret to be unsealed when PCR's change. This resolves the issue with PCR brittleness.
  • Loading branch information
dgarske committed Aug 30, 2023
1 parent 5b7e50a commit a152603
Show file tree
Hide file tree
Showing 29 changed files with 1,966 additions and 2,241 deletions.
6 changes: 3 additions & 3 deletions .gitignore
Expand Up @@ -48,6 +48,7 @@ examples/pcr/quote
examples/pcr/read_pcr
examples/pcr/extend
examples/pcr/policy
examples/pcr/policy_sign
examples/pcr/reset
examples/timestamp/clock_set
examples/management/flush
Expand All @@ -64,18 +65,17 @@ examples/keygen/external_import
examples/nvram/store
examples/nvram/read
examples/nvram/counter
examples/nvram/seal_policy_auth_nv
examples/nvram/seal_policy_auth_nv_external
examples/gpio/gpio_config
examples/gpio/gpio_set
examples/gpio/gpio_read
examples/gpio/gpio_nuvoton
examples/seal/seal
examples/seal/unseal
examples/seal/seal_policy_auth
examples/attestation/make_credential
examples/attestation/activate_credential
examples/boot/secure_rot
examples/boot/secret_seal
examples/boot/secret_unseal

# Generated Cert Files
certs/ca-*.pem
Expand Down
46 changes: 9 additions & 37 deletions examples/README.md
Expand Up @@ -450,45 +450,17 @@ mySecretMessage

After a successful unsealing, the data is stored into a new file. If no filename is provided, the `unseal` tool stores the data in `unseal.bin`.

### Sealing data to the TPM with policy authorization
### Sealing secret based on PCR(s) with policy signed by external key

Data can also be sealed to the TPM, either to NVM or regular, with policy authorization. ./examples/seal/seal\_policy\_auth.c shows an example of how to seal data to the TPM using the wolfTPM2\_SealWithAuthKey function and unseal with wolfTPM2\_UnsealWithAuthSig. These functions call wolfTPM2\_PolicyPCR to add the PCR values to the policyDigest and TPM2\_PolicyAuthorize to sign the digest with either an ecc or rsa key. ./examples/nvram/seal\_policy\_auth\_nv.c is similar but seals to the data to NVM and uses TPM2\_PolicyAuthorizeNV to keep the policyDigest in NVM so it persists in between boots. ./examples/nvram/seal\_policy\_auth\_nv\_external.c works the same way but it shows how to use a key generated from outside wolfTPM, currently only supports ecc256 keys
See [examples/boot/README.md](/examples/boot/README.md)


## Secure Boot

### TPM based root of trust

See [examples/boot/README.md](/examples/boot/README.md)

```
$ ./examples/seal/seal_policy_auth -ecc -aes 16
Example for sealing data to the TPM with policy authorization
PCR Indicies:16
Use Parameter Encryption: CFB
wolfTPM2_Init: success
TPM2_StartAuthSession: sessionHandle 0x3000000
Loading SRK: Storage 0x81000200 (282 bytes)
ECC template
Loaded sealBlob to 0x80000002
TPM2_StartAuthSession: sessionHandle 0x3000000
Usealed secret matches!
$ ./examples/nvram/seal_policy_auth_nv -ecc -aes 16
Example for sealing data to NV memory with policy authorization
PCR Indicies:16
Use Parameter Encryption: CFB
wolfTPM2_Init: success
TPM2_StartAuthSession: sessionHandle 0x3000000
Loading SRK: Storage 0x81000200 (282 bytes)
ECC template
TPM2_StartAuthSession: sessionHandle 0x3000000
Usealed secret matches!
$ ./examples/nvram/seal_policy_auth_nv_external -ecc -aes 16
Warning: Unrecognized option: -ecc
Example for sealing data to NV memory with policy authorization
PCR Indicies:16
Use Parameter Encryption: CFB
wolfTPM2_Init: success
Loading SRK: Storage 0x81000200 (282 bytes)
TPM2_StartAuthSession: sessionHandle 0x3000000
TPM2_StartAuthSession: sessionHandle 0x3000000
Usealed secret matches!
```

## GPIO Control

Expand Down
44 changes: 39 additions & 5 deletions examples/boot/README.md
Expand Up @@ -8,9 +8,9 @@ Design for storage of public key based root of trust into TPM:
4) WolfBoot still has the public key internally and programs the TPM with the NV if not populated.
5) The NV is locked and created under the platform hierarchy

Exammple:
Example:

```
```sh
$ ./examples/boot/secure_rot -write=../wolfBoot/wolfboot_signing_public_key.der -lock
TPM2: Caps 0x00000000, Did 0x0000, Vid 0x0000, Rid 0x 0
TPM2_Startup pass
Expand Down Expand Up @@ -44,6 +44,40 @@ TPM2_FlushContext: Closed handle 0x2000000

# Secure Boot Encryption Key Storage

TODO:
* Sealing based on PCR's and key?
* RSA encrypt/decrypt?
To seal a secret to PCR's without having the "brittleness" issue we use an external key to sign the state of the PCR(s).

Tools:
* `./examples/pcr/policy_sign`: Signs a digest for a PCR policy. Outputs the signature and also generates a policy authorization digest for the public key (-outpolicy)
* `./examples/boot/secret_seal`: Seals a secret using the authorization policy digest for the public key. If no secret provided a random value is generated and sealed.
* `./examples/boot/secret_unseal`: Unseals a secret using the sign authorization policy and the public key.

Example for created a signed PCR policy:
```sh
# Extend "aaa" to test PCR 16
echo aaa > aaa.bin
./examples/pcr/reset 16
./examples/pcr/extend 16 aaa.bin

# RSA Sign this PCR (result to pcrsig.bin) - also creates policyauth.bin based on public key
./examples/pcr/policy_sign -pcr=16 -rsa -key=./certs/example-rsa2048-key.der -out=pcrsig.bin -outpolicy=policyauth.bin
# OR
# ECC Sign
./examples/pcr/policy_sign -pcr=16 -ecc -key=./certs/example-ecc256-key.der -out=pcrsig.bin -outpolicy=policyauth.bin
```
Example for creating a sealed secret using that signed policy based on public key:

```sh
# Create a keyed hash sealed object using the policy authorization for the public key
./examples/boot/secret_seal -policy=policyauth.bin -out=sealblob.bin
# OR
# Provide the public key for policy authorization (instead of -policy=)
./examples/boot/secret_seal -rsa -publickey=./certs/example-rsa2048-key-pub.der -out=sealblob.bin
./examples/boot/secret_seal -ecc -publickey=./certs/example-ecc256-key-pub.der -out=sealblob.bin
```

Example for unsealing:
```sh
# Unseal using public key
./examples/boot/secret_unseal -pcr=16 -pcrsig=pcrsig.bin -rsa -publickey=./certs/example-rsa2048-key-pub.der -seal=sealblob.bin
./examples/boot/secret_unseal -pcr=16 -pcrsig=pcrsig.bin -ecc -publickey=./certs/example-ecc256-key-pub.der -seal=sealblob.bin
```
2 changes: 2 additions & 0 deletions examples/boot/boot.h
Expand Up @@ -27,6 +27,8 @@
#endif

int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[]);
int TPM2_Boot_SecretSeal_Example(void* userCtx, int argc, char *argv[]);
int TPM2_Boot_SecretUnseal_Example(void* userCtx, int argc, char *argv[]);

#ifdef __cplusplus
} /* extern "C" */
Expand Down
23 changes: 20 additions & 3 deletions examples/boot/include.am
Expand Up @@ -2,15 +2,32 @@
# All paths should be given relative to the root

if BUILD_EXAMPLES
noinst_PROGRAMS += examples/boot/secure_rot
noinst_HEADERS += examples/boot/boot.h

noinst_PROGRAMS += examples/boot/secure_rot
examples_boot_secure_rot_SOURCES = examples/boot/secure_rot.c \
examples/tpm_test_keys.c
examples_boot_secure_rot_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_boot_secure_rot_DEPENDENCIES = src/libwolftpm.la

noinst_PROGRAMS += examples/boot/secret_seal
examples_boot_secret_seal_SOURCES = examples/boot/secret_seal.c \
examples/tpm_test_keys.c
examples_boot_secret_seal_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_boot_secret_seal_DEPENDENCIES = src/libwolftpm.la

noinst_PROGRAMS += examples/boot/secret_unseal
examples_boot_secret_unseal_SOURCES = examples/boot/secret_unseal.c \
examples/tpm_test_keys.c
examples_boot_secret_unseal_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_boot_secret_unseal_DEPENDENCIES = src/libwolftpm.la
endif

example_bootdir = $(exampledir)/boot
dist_example_boot_DATA = examples/boot/secure_rot.c
dist_example_boot_DATA = examples/boot/secure_rot.c \
examples/boot/secret_seal.c \
examples/boot/secret_unseal.c

DISTCLEANFILES+= examples/boot/.libs/secure_rot
DISTCLEANFILES+= examples/boot/.libs/secure_rot \
examples/boot/.libs/secret_seal \
examples/boot/.libs/secret_unseal

0 comments on commit a152603

Please sign in to comment.