diff --git a/docs/TPM.md b/docs/TPM.md index bd45537c1..f95d31d90 100644 --- a/docs/TPM.md +++ b/docs/TPM.md @@ -15,7 +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 | +| `WOLFBOOT_TPM_SEAL_AUTH=secret` | `WOLFBOOT_TPM_SEAL_AUTH` | Password for sealing/unsealing secrets, if omitted the PCR policy will be used | ## Root of Trust (ROT) diff --git a/include/tpm.h b/include/tpm.h index a70c7902d..af35d9b1b 100644 --- a/include/tpm.h +++ b/include/tpm.h @@ -52,6 +52,8 @@ extern WOLFTPM2_KEY wolftpm_srk; int wolfBoot_tpm2_init(void); void wolfBoot_tpm2_deinit(void); +int wolfBoot_tpm2_clear(void); + #if defined(WOLFBOOT_TPM_VERIFY) || defined(WOLFBOOT_TPM_SEAL) int wolfBoot_load_pubkey(const uint8_t* pubkey_hint, WOLFTPM2_KEY* pubKey, TPM_ALG_ID* pAlg); @@ -83,6 +85,7 @@ int wolfBoot_unseal_auth(const uint8_t* pubkey_hint, const uint8_t* policy, uint 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, const uint8_t* auth, int authSz); +int wolfBoot_delete_seal(int index); int wolfBoot_read_blob(uint32_t nvIndex, WOLFTPM2_KEYBLOB* blob, const uint8_t* auth, uint32_t authSz); int wolfBoot_store_blob(TPMI_RH_NV_AUTH authHandle, uint32_t nvIndex, diff --git a/lib/wolfTPM b/lib/wolfTPM index 7c079dd3f..bc1415d0d 160000 --- a/lib/wolfTPM +++ b/lib/wolfTPM @@ -1 +1 @@ -Subproject commit 7c079dd3f0e40539519101cffd0c27c5d6c1777c +Subproject commit bc1415d0da8e882723cb1a4b2aca0764afa6aac0 diff --git a/src/tpm.c b/src/tpm.c index d6c7049f0..7c3f19219 100644 --- a/src/tpm.c +++ b/src/tpm.c @@ -591,8 +591,12 @@ int wolfBoot_store_blob(TPMI_RH_NV_AUTH authHandle, uint32_t nvIndex, memset(&nv, 0, sizeof(nv)); nv.handle.hndl = nvIndex; - nv.handle.auth.size = authSz; - memcpy(nv.handle.auth.buffer, auth, authSz); + if (authSz > 0) { + if (auth == NULL) + return BAD_FUNC_ARG; + nv.handle.auth.size = authSz; + memcpy(nv.handle.auth.buffer, auth, authSz); + } parent.hndl = authHandle; @@ -667,8 +671,12 @@ int wolfBoot_read_blob(uint32_t nvIndex, WOLFTPM2_KEYBLOB* blob, memset(&nv, 0, sizeof(nv)); nv.handle.hndl = nvIndex; - nv.handle.auth.size = authSz; - memcpy(nv.handle.auth.buffer, auth, authSz); + if (authSz > 0) { + if (auth == NULL) + return BAD_FUNC_ARG; + nv.handle.auth.size = authSz; + memcpy(nv.handle.auth.buffer, auth, authSz); + } wolfTPM2_SetAuthHandle(&wolftpm_dev, 0, &nv.handle); pos = 0; @@ -722,8 +730,12 @@ int wolfBoot_delete_blob(TPMI_RH_NV_AUTH authHandle, uint32_t nvIndex, memset(&nv, 0, sizeof(nv)); nv.handle.hndl = nvIndex; - nv.handle.auth.size = authSz; - memcpy(nv.handle.auth.buffer, auth, authSz); + if (authSz > 0) { + if (auth == NULL) + return BAD_FUNC_ARG; + nv.handle.auth.size = authSz; + memcpy(nv.handle.auth.buffer, auth, authSz); + } parent.hndl = authHandle; @@ -788,6 +800,8 @@ int wolfBoot_seal_blob(const uint8_t* pubkey_hint, /* build authorization policy based on public key */ /* digest here is input and output, must be zero'd */ uint32_t digestSz = TPM2_GetHashDigestSize(pcrAlg); + /* Create a new key for sealing using external signing auth */ + wolfTPM2_GetKeyTemplate_KeySeal(&template, pcrAlg); memset(template.authPolicy.buffer, 0, digestSz); rc = wolfTPM2_PolicyAuthorizeMake(pcrAlg, &authKey.pub, template.authPolicy.buffer, &digestSz, NULL, 0); @@ -800,8 +814,15 @@ int wolfBoot_seal_blob(const uint8_t* pubkey_hint, wolfBoot_print_hexstr(template.authPolicy.buffer, template.authPolicy.size, 0); #endif - /* Create a new key for sealing using external signing auth */ - wolfTPM2_GetKeyTemplate_KeySeal(&template, pcrAlg); + + if (auth != NULL && authSz > 0) { + /* allow password based sealing */ + template.objectAttributes |= TPMA_OBJECT_userWithAuth; + } + else { + /* disable password based sealing, require policy */ + template.objectAttributes &= ~TPMA_OBJECT_userWithAuth; + } rc = wolfTPM2_CreateKeySeal_ex(&wolftpm_dev, seal_blob, &wolftpm_srk.handle, &template, auth, authSz, pcrAlg, NULL, 0, secret, secret_sz); @@ -813,6 +834,12 @@ int wolfBoot_seal_blob(const uint8_t* pubkey_hint, return rc; } +int wolfBoot_delete_seal(int index) +{ + return wolfBoot_delete_blob(TPM_RH_PLATFORM, + WOLFBOOT_TPM_SEAL_NV_BASE + index, NULL, 0); +} + /* Index (0-X) determines location in NV from WOLFBOOT_TPM_SEAL_NV_BASE to * store sealed blob */ int wolfBoot_seal_auth(const uint8_t* pubkey_hint, @@ -982,15 +1009,15 @@ int wolfBoot_unseal_blob(const uint8_t* pubkey_hint, rc = wolfTPM2_PolicyAuthorize(&wolftpm_dev, policy_session.handle.hndl, &authKey.pub, &checkTicket, pcrDigest, pcrDigestSz, policyRef, policyRefSz); - } - else { - /* A failure here means the signed policy did not match expected policy. - * Use this PCR mask and policy digest with the sign tool --policy= - * argument to sign */ - wolfBoot_printf("Policy signature failed!\n"); - wolfBoot_printf("Expected PCR Mask (0x%08x) and PCR Policy (%d)\n", - pcrMask, policyDigestSz); - wolfBoot_print_hexstr(policyDigest, policyDigestSz, 0); + if (rc != 0) { + /* A failure here means the signed policy did not match expected + * policy. Use this PCR mask and policy digest with the sign tool + * --policy= argument to sign */ + wolfBoot_printf("Policy signature failed!\n"); + wolfBoot_printf("Expected PCR Mask (0x%08x) and PCR Policy (%d)\n", + pcrMask, policyDigestSz); + wolfBoot_print_hexstr(policyDigest, policyDigestSz, 0); + } } /* done with authorization public key */ @@ -1005,9 +1032,21 @@ int wolfBoot_unseal_blob(const uint8_t* pubkey_hint, wolfBoot_printf("Loaded seal blob to 0x%x\n", (uint32_t)seal_blob->handle.hndl); #endif - seal_blob->handle.auth.size = authSz; - memcpy(seal_blob->handle.auth.buffer, auth, authSz); - wolfTPM2_SetAuthHandle(&wolftpm_dev, 0, &seal_blob->handle); + + /* if using password auth, set it otherwise use policy auth */ + if (auth != NULL && authSz > 0) { + seal_blob->handle.auth.size = authSz; + memcpy(seal_blob->handle.auth.buffer, auth, authSz); + wolfTPM2_SetAuthHandle(&wolftpm_dev, 0, &seal_blob->handle); + } + else { + /* use the policy session for unseal */ + rc = wolfTPM2_SetAuthSession(&wolftpm_dev, 0, &policy_session, + (TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | + TPMA_SESSION_continueSession)); + /* set the sealed object name 0 (required) */ + wolfTPM2_SetAuthHandleName(&wolftpm_dev, 0, &seal_blob->handle); + } /* unseal */ unsealIn.itemHandle = seal_blob->handle.hndl; @@ -1216,6 +1255,20 @@ void wolfBoot_tpm2_deinit(void) wolfTPM2_Cleanup(&wolftpm_dev); } +/** + * @brief Clear the content of the TPM2 device. + * + * This function clears the TPM2 device and remove all stored secrets. + * + * @return BAD_FUNC_ARG if any of the underlying functions has passed an invalid + * argument, e.g. wolftpm_dev is not initialized + * @return TPM_RC_SUCCESS in case of success + */ +int wolfBoot_tpm2_clear(void) +{ + return wolfTPM2_Clear(&wolftpm_dev); +} + #ifdef WOLFBOOT_TPM_KEYSTORE /* check root of trust based on key_slot (index) and public key hint */