Skip to content

Commit

Permalink
Fixes based on peer review. Add output of signed policy to file (appe…
Browse files Browse the repository at this point in the history
…nd .sig). Tested successfully with multiple PCRs. In example unlock_disk extend PCR with random value after unseal to prevent unsealing after boot.
  • Loading branch information
dgarske committed Sep 11, 2023
1 parent 27ae089 commit cdde12c
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 16 deletions.
1 change: 1 addition & 0 deletions docs/Signing.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ Provides a PCR mask and digest to be signed and included in the header. The sign
By default the file should contain a 4-byte PCR mask and SHA2-256 PCR digest to be signed.
If using `--manual-sign` then the file should contain the 4-byte PCR mask and signature.
The PCR mask and signature will be included in the `HDR_POLICY_SIGNATURE` header tag.
A copy of the final signed policy (including 4 byte PCR mask) will be output to `[inputname].sig`.
Note: This may require increasing the `IMAGE_HEADER_SIZE` as two signatures will be stored in the header.

#### Three-steps signing using external provisioning tools
Expand Down
1 change: 1 addition & 0 deletions docs/TPM.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ In wolfBoot we support TPM based root of trust, sealing/unsealing, cryptographic
| `WOLFBOOT_TPM_VERIFY=1` | `WOLFBOOT_TPM_VERIFY` | Enables cryptographic offloading for RSA2048 and ECC256/384 to the TPM. |
| `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_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. |
Expand Down
3 changes: 3 additions & 0 deletions include/tpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ int wolfBoot_read_blob(uint32_t nvIndex, WOLFTPM2_KEYBLOB* blob,
int wolfBoot_store_blob(TPMI_RH_NV_AUTH authHandle, uint32_t nvIndex,
word32 nvAttributes, WOLFTPM2_KEYBLOB* blob,
const uint8_t* auth, uint32_t authSz);

uint32_t wolfBoot_tpm_pcrmask_sel(uint32_t pcrMask, uint8_t* pcrArray,
uint32_t pcrArraySz);
#endif

#ifdef WOLFBOOT_MEASURED_BOOT
Expand Down
16 changes: 8 additions & 8 deletions src/tpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,20 +467,20 @@ int wolfBoot_get_pcr_active(uint8_t pcrAlg, uint32_t* pcrMask, uint8_t pcrMax)
return rc;
}

static void tpm_mask_sel_pcr(uint32_t pcrMask, uint8_t* pcrArray,
uint32_t* pcrArraySz)
uint32_t wolfBoot_tpm_pcrmask_sel(uint32_t pcrMask, uint8_t* pcrArray,
uint32_t pcrArraySz)
{
int i;
*pcrArraySz = 0;
uint32_t pcrArraySzAct = 0;
for (i=0; i<IMPLEMENTATION_PCR; i++) {
if (pcrMask & (1 << i)) {
pcrArray[(*pcrArraySz)++] = i;
/* make sure we have room */
if (*pcrArraySz >= PCR_SELECT_MAX*2) {
pcrArray[pcrArraySzAct++] = i;
if (pcrArraySzAct < pcrArraySz) { /* make sure we have room */
break;
}
}
}
return pcrArraySzAct;
}

int wolfBoot_build_policy(uint8_t pcrAlg, uint32_t pcrMask,
Expand All @@ -497,7 +497,7 @@ int wolfBoot_build_policy(uint8_t pcrAlg, uint32_t pcrMask,

/* populate PCR selection array */
memset(pcrArray, 0, sizeof(pcrArray));
tpm_mask_sel_pcr(pcrMask, pcrArray, &pcrArraySz);
pcrArraySz = wolfBoot_tpm_pcrmask_sel(pcrMask, pcrArray, sizeof(pcrArray));

/* Create a Policy PCR digest to sign externally */
memcpy(policy, (uint8_t*)&pcrMask, sizeof(pcrMask));
Expand Down Expand Up @@ -858,7 +858,7 @@ int wolfBoot_unseal_blob(struct wolfBoot_image* img, WOLFTPM2_KEYBLOB* seal_blob
/* extract pcrMask and populate PCR selection array */
memcpy(&pcrMask, hdr, sizeof(pcrMask));
memset(pcrArray, 0, sizeof(pcrArray));
tpm_mask_sel_pcr(pcrMask, pcrArray, &pcrArraySz);
pcrArraySz = wolfBoot_tpm_pcrmask_sel(pcrMask, pcrArray, sizeof(pcrArray));

/* skip to signature */
hdr += sizeof(pcrMask);
Expand Down
18 changes: 18 additions & 0 deletions src/update_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,24 @@ int wolfBoot_unlock_disk(void)
wolfBoot_printf("unlock disk failed! %d (%s)\n",
ret, wolfTPM2_GetRCString(ret));
}

/* Extend a PCR from the mask to prevent future unsealing */
{
uint32_t pcrMask;
uint32_t pcrArraySz;
uint8_t pcrArray[1];
/* random value to extend the first PCR mask */
const uint8_t digest[WOLFBOOT_TPM_PCR_DIG_SZ] = {
0xEA, 0xA7, 0x5C, 0xF6, 0x91, 0x7C, 0x77, 0x91,
0xC5, 0x33, 0x16, 0x6D, 0x74, 0xFF, 0xCE, 0xCD,
0x27, 0xE3, 0x47, 0xF6, 0x82, 0x1D, 0x4B, 0xB1,
0x32, 0x70, 0x88, 0xFC, 0x69, 0xFF, 0x6C, 0x02,
};
memcpy(&pcrMask, policy, sizeof(pcrMask));
pcrArraySz = wolfBoot_tpm_pcrmask_sel(pcrMask, pcrArray, sizeof(pcrArray));
wolfBoot_tpm2_extend(pcrArray[0], (uint8_t*)digest, __LINE__);
}

TPM2_ForceZero(secret, sizeof(secretSz));
return ret;
}
Expand Down
11 changes: 10 additions & 1 deletion tools/keytools/sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,7 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
}
}
else {
/* in manual mode PCR signature */
/* in manual mode remainder is PCR signature */
io_sz = (int)fread(policy, 1, CMD.policy_sz, f);
fclose(f);
if (io_sz <= 0) {
Expand All @@ -1233,6 +1233,15 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
}
CMD.policy_sz = io_sz;
}

/* save copy of signed policy including 4 byte header to file */
snprintf((char*)buf, sizeof(buf), "%s.sig", CMD.policy_file);
printf("Saving policy signature to %s\n", (char*)buf);
f = fopen((char*)buf, "w+b");
if (f != NULL) {
fwrite(policy, 1, CMD.policy_sz + sizeof(uint32_t), f);
fclose(f);
}
}

#ifdef DEBUG_SIGNTOOL
Expand Down
15 changes: 8 additions & 7 deletions tools/tpm/policy_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,20 +109,20 @@ static void printHexString(const unsigned char* bin, unsigned long sz,
printf("\n");
}

static void tpm_mask_sel_pcr(uint32_t pcrMask, uint8_t* pcrArray,
uint32_t* pcrArraySz)
uint32_t wolfBoot_tpm_pcrmask_sel(uint32_t pcrMask, uint8_t* pcrArray,
uint32_t pcrArraySz)
{
int i;
*pcrArraySz = 0;
uint32_t pcrArraySzAct = 0;
for (i=0; i<IMPLEMENTATION_PCR; i++) {
if (pcrMask & (1 << i)) {
pcrArray[(*pcrArraySz)++] = i;
/* make sure we have room */
if (*pcrArraySz >= PCR_SELECT_MAX*2) {
pcrArray[pcrArraySzAct++] = i;
if (pcrArraySzAct < pcrArraySz) { /* make sure we have room */
break;
}
}
}
return pcrArraySzAct;
}

int TPM2_PCR_Policy_Create(TPM_ALG_ID pcrAlg,
Expand Down Expand Up @@ -263,7 +263,8 @@ int main(int argc, char *argv[])
pcrArray[pcrArraySz++] = DEFAULT_PCR;
}
else {
tpm_mask_sel_pcr(pcrMask, pcrArray, &pcrArraySz);
pcrArraySz = wolfBoot_tpm_pcrmask_sel(pcrMask,
pcrArray, sizeof(pcrArray));
}
}

Expand Down

0 comments on commit cdde12c

Please sign in to comment.