Add support for sealing/unsealing a secret with auth.

pull/388/head
David Garske 2023-10-24 11:16:10 -07:00 committed by Daniele Lacamera
parent 0f5b5abf5f
commit 758eda1ad4
7 changed files with 105 additions and 29 deletions

View File

@ -16,7 +16,10 @@ on:
rot-args:
required: false
type: string
authstr:
keyauthstr:
required: false
type: string
sealauthstr:
required: false
type: string
@ -59,7 +62,7 @@ jobs:
- name: Write TPM ROT to TPM
run: |
./tools/tpm/rot -write ${{inputs.rot-args}} -auth="${{inputs.authstr}}"
./tools/tpm/rot -write ${{inputs.rot-args}} -auth="${{inputs.keyauthstr}}"
- name: Create a PCR Policy
run: |
@ -69,7 +72,7 @@ jobs:
- name: Build wolfboot
run: |
make ${{inputs.make-args}} WOLFBOOT_TPM_KEYSTORE_AUTH="${{inputs.authstr}}"
make ${{inputs.make-args}} WOLFBOOT_TPM_KEYSTORE_AUTH="${{inputs.keykeyauthstr}}" WOLFBOOT_TPM_SEAL_AUTH="${{inputs.sealauthstr}}"
- name: Run wolfBoot
run: |

View File

@ -65,7 +65,7 @@ jobs:
arch: host
config-file: ./config/examples/sim-tpm-keystore.config
make-args: SIGN=ECC256 HASH=SHA256
authstr: TestAuth
keyauthstr: TestAuth
sim_tpm_keystore_ecc384:
uses: ./.github/workflows/test-build-sim-tpm.yml
@ -74,7 +74,7 @@ jobs:
config-file: ./config/examples/sim-tpm-keystore.config
make-args: SIGN=ECC384 HASH=SHA384
rot-args: -sha384
authstr: TestAuth
keyauthstr: TestAuth
sim_tpm_keystore_rsa2048:
uses: ./.github/workflows/test-build-sim-tpm.yml
@ -82,7 +82,7 @@ jobs:
arch: host
config-file: ./config/examples/sim-tpm-keystore.config
make-args: SIGN=RSA2048 HASH=SHA256
authstr: TestAuth
keyauthstr: TestAuth
sim_tpm_keystore_noauth_ecc256:
@ -114,7 +114,8 @@ jobs:
arch: host
config-file: ./config/examples/sim-tpm-seal.config
make-args: SIGN=ECC256 HASH=SHA256 POLICY_FILE=policy.bin
authstr: TestAuth
keyauthstr: TestAuth
sealauthstr: SealAuth
sim_tpm_seal_ecc384:
uses: ./.github/workflows/test-build-sim-tpm.yml
@ -123,7 +124,8 @@ jobs:
config-file: ./config/examples/sim-tpm-seal.config
make-args: SIGN=ECC384 HASH=SHA384 POLICY_FILE=policy.bin
rot-args: -sha384
authstr: TestAuth
keyauthstr: TestAuth
sealauthstr: SealAuth
sim_tpm_seal_rsa2048:
uses: ./.github/workflows/test-build-sim-tpm.yml
@ -132,4 +134,32 @@ jobs:
config-file: ./config/examples/sim-tpm-seal.config
# use larger image header size for two 2048-bit signatures
make-args: SIGN=RSA2048ENC HASH=SHA256 POLICY_FILE=policy.bin IMAGE_HEADER_SIZE=1024
authstr: TestAuth
keyauthstr: TestAuth
sealauthstr: SealAuth
sim_tpm_seal_noauth_ecc256:
uses: ./.github/workflows/test-build-sim-tpm.yml
with:
arch: host
config-file: ./config/examples/sim-tpm-seal.config
make-args: SIGN=ECC256 HASH=SHA256 POLICY_FILE=policy.bin
keyauthstr: TestAuth
sim_tpm_seal_noauth_ecc384:
uses: ./.github/workflows/test-build-sim-tpm.yml
with:
arch: host
config-file: ./config/examples/sim-tpm-seal.config
make-args: SIGN=ECC384 HASH=SHA384 POLICY_FILE=policy.bin
rot-args: -sha384
keyauthstr: TestAuth
sim_tpm_seal_noauth_rsa2048:
uses: ./.github/workflows/test-build-sim-tpm.yml
with:
arch: host
config-file: ./config/examples/sim-tpm-seal.config
# use larger image header size for two 2048-bit signatures
make-args: SIGN=RSA2048ENC HASH=SHA256 POLICY_FILE=policy.bin IMAGE_HEADER_SIZE=1024
keyauthstr: TestAuth

View File

@ -29,6 +29,7 @@ MEASURED_PCR_A?=16
# Sealing a secret into TPM based on external PCR policy signed by the sign tool
WOLFBOOT_TPM_SEAL?=1
WOLFBOOT_TPM_SEAL_NV_BASE=0x01400300
#WOLFBOOT_TPM_SEAL_AUTH?=SealAuth
# TPM Logging
#CFLAGS_EXTRA+=-DDEBUG_WOLFTPM

View File

@ -15,6 +15,7 @@ In wolfBoot we support TPM based root of trust, sealing/unsealing, cryptographic
| `MEASURED_PCR_A=16` | `WOLFBOOT_MEASURED_PCR_A=16` | The PCR index to use. See [docs/measured_boot.md](/docs/measured_boot.md). |
| `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 |
## Root of Trust (ROT)
@ -36,14 +37,14 @@ The wolfBoot image is hashed and extended to the indicated PCR. This can be used
See the wolfTPM Sealing/Unsealing example [here](https://github.com/wolfSSL/wolfTPM/tree/secret_seal/examples/boot#secure-boot-encryption-key-storage)
Known PCR values must be signed to seal/unseal a secret. The signature for the authorization policy resides in the signed header using the `--policy` argument.
If a signed policy is not in the header then a value cannot be sealed. Instead the PCR(s) and a digest to sign will be printed for use with the sign tool.
If a signed policy is not in the header then a value cannot be sealed. Instead the PCR(s) values and a PCR policy digest will be printed to sign. You can use `./tools/keytools/sign` or `./tools/tpm/policy_sign` to sign the policy externally.
This exposes two new wolfBoot API's for sealing and unsealing data with blob stored to NV index:
```c
int wolfBoot_seal(uint8_t* pubkey_hint, uint8_t* policy, uint16_t policySz,
int index, const uint8_t* secret, int secret_sz);
int wolfBoot_unseal(uint8_t* pubkey_hint, uint8_t* policy, uint16_t policySz,
int index, uint8_t* secret, int* secret_sz);
int wolfBoot_seal_auth(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
int index, const uint8_t* secret, int secret_sz, const byte* auth, int authSz);
int wolfBoot_unseal_auth(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
int index, uint8_t* secret, int* secret_sz, const byte* auth, int authSz);
```
By default this index will be based on an NV Index at `(0x01400300 + index)`.
@ -62,7 +63,8 @@ NOTE: The TPM's RSA verify requires ASN.1 encoding, so use SIGN=RSA2048ENC
% ./tools/tpm/policy_create -pcr=0
# if ROT enabled
% ./tools/tpm/rot -write [-auth=TestAuth]
% make clean && make POLICY_FILE=policy.bin
% make clean
$ make POLICY_FILE=policy.bin [WOLFBOOT_TPM_KEYSTORE_AUTH=TestAuth] [WOLFBOOT_TPM_SEAL_AUTH=SealAuth]
% ./wolfboot.elf get_version
Simulator assigned ./internal_flash.dd to base 0x103378000

View File

@ -72,10 +72,14 @@ int wolfBoot_get_policy(struct wolfBoot_image* img,
int wolfBoot_seal(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
int index, const uint8_t* secret, int secret_sz);
int wolfBoot_seal_auth(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
int index, const uint8_t* secret, int secret_sz, const uint8_t* auth, int authSz);
int wolfBoot_seal_blob(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
WOLFTPM2_KEYBLOB* seal_blob, const uint8_t* secret, int secret_sz);
int wolfBoot_unseal(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
int index, uint8_t* secret, int* secret_sz);
int wolfBoot_unseal_auth(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
int index, uint8_t* secret, int* secret_sz, const uint8_t* auth, int authSz);
int wolfBoot_unseal_blob(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
WOLFTPM2_KEYBLOB* seal_blob, uint8_t* secret, int* secret_sz);
@ -102,7 +106,7 @@ int wolfBoot_tpm2_extend(uint8_t pcrIndex, uint8_t* hash, int line);
/* debugging */
void wolfBoot_print_hexstr(const unsigned char* bin, unsigned long sz,
unsigned long maxLine);
void wolfBoot_print_bin(const byte* buffer, word32 length);
void wolfBoot_print_bin(const uint8_t* buffer, uint32_t length);
#else

View File

@ -28,6 +28,9 @@ endif
ifeq ($(WOLFBOOT_TPM_SEAL),1)
WOLFTPM:=1
CFLAGS+=-D"WOLFBOOT_TPM_SEAL"
ifneq ($(WOLFBOOT_TPM_SEAL_AUTH),)
CFLAGS+=-DWOLFBOOT_TPM_SEAL_AUTH='"$(WOLFBOOT_TPM_SEAL_AUTH)"'
endif
ifneq ($(WOLFBOOT_TPM_SEAL_NV_BASE),)
CFLAGS+=-D"WOLFBOOT_TPM_SEAL_NV_BASE=$(WOLFBOOT_TPM_SEAL_NV_BASE)"
endif

View File

@ -605,9 +605,9 @@ int wolfBoot_store_blob(TPMI_RH_NV_AUTH authHandle, uint32_t nvIndex,
nvSz = (uint32_t)sizeof(blob->pub.size) + blob->pub.size;
nvSz += (uint32_t)sizeof(blob->priv.size) + blob->priv.size;
/* Create NV - no auth required, blob encrypted by TPM already */
/* Create NV */
rc = wolfTPM2_NVCreateAuth(&wolftpm_dev, &parent, &nv,
nv.handle.hndl, nvAttributes, nvSz, NULL, 0);
nv.handle.hndl, nvAttributes, nvSz, auth, authSz);
if (rc == TPM_RC_NV_DEFINED) {
/* allow use of existing handle - ignore this error */
rc = 0;
@ -739,7 +739,8 @@ int wolfBoot_delete_blob(TPMI_RH_NV_AUTH authHandle, uint32_t nvIndex,
}
/* The secret is sealed based on a policy authorization from a public key. */
int wolfBoot_seal_blob(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
int wolfBoot_seal_blob(const uint8_t* pubkey_hint,
const uint8_t* policy, uint16_t policySz,
WOLFTPM2_KEYBLOB* seal_blob, const uint8_t* secret, int secret_sz)
{
int rc;
@ -801,8 +802,9 @@ int wolfBoot_seal_blob(const uint8_t* pubkey_hint, const uint8_t* policy, uint16
/* Create a new key for sealing using external signing auth */
wolfTPM2_GetKeyTemplate_KeySeal(&template, pcrAlg);
rc = wolfTPM2_CreateKeySeal_ex(&wolftpm_dev, seal_blob,
&wolftpm_srk.handle, &template, NULL, 0, pcrAlg, NULL, 0,
secret, secret_sz);
&wolftpm_srk.handle, &template,
seal_blob->handle.auth.buffer, seal_blob->handle.auth.size,
pcrAlg, NULL, 0, secret, secret_sz);
}
wolfTPM2_UnloadHandle(&wolftpm_dev, &policy_session.handle);
@ -813,8 +815,10 @@ int wolfBoot_seal_blob(const uint8_t* pubkey_hint, const uint8_t* policy, uint16
/* Index (0-X) determines location in NV from WOLFBOOT_TPM_SEAL_NV_BASE to
* store sealed blob */
int wolfBoot_seal(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
int index, const uint8_t* secret, int secret_sz)
int wolfBoot_seal_auth(const uint8_t* pubkey_hint,
const uint8_t* policy, uint16_t policySz,
int index, const uint8_t* secret, int secret_sz,
const uint8_t* auth, int authSz)
{
int rc;
WOLFTPM2_KEYBLOB seal_blob;
@ -822,6 +826,9 @@ int wolfBoot_seal(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t po
memset(&seal_blob, 0, sizeof(seal_blob));
seal_blob.handle.auth.size = authSz;
XMEMCPY(seal_blob.handle.auth.buffer, auth, authSz);
/* creates a sealed keyed hash object (not loaded to TPM) */
rc = wolfBoot_seal_blob(pubkey_hint, policy, policySz, &seal_blob,
secret, secret_sz);
@ -841,8 +848,7 @@ int wolfBoot_seal(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t po
rc = wolfBoot_store_blob(TPM_RH_PLATFORM,
WOLFBOOT_TPM_SEAL_NV_BASE + index,
nvAttributes, &seal_blob,
NULL, 0 /* auth is not required as blob is already encrypted */
nvAttributes, &seal_blob, auth, authSz
);
}
if (rc != 0) {
@ -851,6 +857,19 @@ int wolfBoot_seal(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t po
}
return rc;
}
int wolfBoot_seal(const uint8_t* pubkey_hint,
const uint8_t* policy, uint16_t policySz,
int index, const uint8_t* secret, int secret_sz)
{
const char* auth = NULL;
int authSz = 0;
#ifdef WOLFBOOT_TPM_SEAL_AUTH
auth = WOLFBOOT_TPM_SEAL_AUTH;
authSz = (int)strlen(auth);
#endif
return wolfBoot_seal_auth(pubkey_hint, policy, policySz, index,
secret, secret_sz, (const uint8_t*)auth, authSz);
}
/* The unseal requires a signed policy from HDR_POLICY_SIGNATURE */
int wolfBoot_unseal_blob(const uint8_t* pubkey_hint,
@ -999,8 +1018,10 @@ int wolfBoot_unseal_blob(const uint8_t* pubkey_hint,
return rc;
}
int wolfBoot_unseal(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t policySz,
int index, uint8_t* secret, int* secret_sz)
int wolfBoot_unseal_auth(const uint8_t* pubkey_hint,
const uint8_t* policy, uint16_t policySz,
int index, uint8_t* secret, int* secret_sz,
const uint8_t* auth, int authSz)
{
int rc;
WOLFTPM2_KEYBLOB seal_blob;
@ -1008,8 +1029,7 @@ int wolfBoot_unseal(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t
memset(&seal_blob, 0, sizeof(seal_blob));
rc = wolfBoot_read_blob(WOLFBOOT_TPM_SEAL_NV_BASE + index, &seal_blob,
NULL, 0 /* auth is not required as sealed blob is already encrypted */
);
auth, authSz);
if (rc == 0) {
rc = wolfBoot_unseal_blob(pubkey_hint, policy, policySz, &seal_blob,
secret, secret_sz);
@ -1026,6 +1046,19 @@ int wolfBoot_unseal(const uint8_t* pubkey_hint, const uint8_t* policy, uint16_t
}
return rc;
}
int wolfBoot_unseal(const uint8_t* pubkey_hint,
const uint8_t* policy, uint16_t policySz,
int index, uint8_t* secret, int* secret_sz)
{
const char* auth = NULL;
int authSz = 0;
#ifdef WOLFBOOT_TPM_SEAL_AUTH
auth = WOLFBOOT_TPM_SEAL_AUTH;
authSz = (int)strlen(auth);
#endif
return wolfBoot_unseal_auth(pubkey_hint, policy, policySz, index,
secret, secret_sz, (const uint8_t*)auth, authSz);
}
#endif /* WOLFBOOT_TPM_SEAL */
#if (defined(WOLFBOOT_TPM_KEYSTORE) || defined(WOLFBOOT_TPM_SEAL)) && \