mirror of https://github.com/wolfSSL/wolfBoot.git
Add support for sealing/unsealing a secret with auth.
parent
0f5b5abf5f
commit
758eda1ad4
|
@ -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: |
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
14
docs/TPM.md
14
docs/TPM.md
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
59
src/tpm.c
59
src/tpm.c
|
@ -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)) && \
|
||||
|
|
Loading…
Reference in New Issue