Skip to content

Commit e742385

Browse files
authored
Merge pull request wolfSSL#375 from dgarske/seal_cleanups
TPM sealing cleanups
2 parents 389e12f + eb2978a commit e742385

File tree

4 files changed

+103
-59
lines changed

4 files changed

+103
-59
lines changed

docs/TPM.md

+27-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ NOTE: The TPM's RSA verify requires ASN.1 encoding, so use SIGN=RSA2048ENC
6161
% ./tools/tpm/pcr_extend 0 aaa.bin
6262
% ./tools/tpm/policy_create -pcr=0
6363
# if ROT enabled
64-
% ./tools/tpm/rot -write
64+
% ./tools/tpm/rot -write [-auth=TestAuth]
6565
% make clean && make POLICY_FILE=policy.bin
6666
6767
% ./wolfboot.elf get_version
@@ -168,7 +168,31 @@ Building firmware with the policy digest to sign:
168168
% make POLICY_FILE=policy.bin
169169
```
170170
171-
OR manually using:
171+
OR manually sign the policy using the `tools/tpm/policy_sign` or `tools/keytools/sign` tools.
172+
These tools do not need access to a TPM, they are signing a policy digest. The result is a 32-bit PCR mask + signature.
173+
174+
Sign with policy_sign tool:
175+
176+
```sh
177+
% ./tools/tpm/policy_sign -pcr=0 -pcrdigest=eca4e8eda468b8667244ae972b8240d3244ea72341b2bf2383e79c66643bbecc
178+
Sign PCR Policy Tool
179+
Signing Algorithm: ECC256
180+
PCR Index(s) (SHA256): 0
181+
Policy Signing Key: wolfboot_signing_private_key.der
182+
PCR Digest (32 bytes):
183+
eca4e8eda468b8667244ae972b8240d3244ea72341b2bf2383e79c66643bbecc
184+
PCR Policy Digest (32 bytes):
185+
2d401eb05f45ba2b15c35f628b5896cc7de9745bb6e722363e2dbee804e0500f
186+
PCR Policy Digest (w/PolicyRef) (32 bytes):
187+
749b3139ece21449a7828f11ee05303b0473ff1a26cf41d6f9ff28b24c717f02
188+
PCR Mask (0x1) and Policy Signature (68 bytes):
189+
01000000
190+
5b5f875b3f7ce78b5935abe4fc5a4d8a6e87c4b4ac0836fbab909e232b6d7ca2
191+
3ecfc6be723b695b951ba2886d3c7b83ab2f8cc0e96d766bc84276eaf3f213ee
192+
Wrote PCR Mask + Signature (68 bytes) to policy.bin.sig
193+
```
194+
195+
Sign using the signing key tool:
172196
173197
```sh
174198
% ./tools/keytools/sign --ecc256 --policy policy.bin test-app/image.elf wolfboot_signing_private_key.der 1
@@ -186,5 +210,6 @@ Calculating SHA256 digest...
186210
Signing the digest...
187211
Opening policy file policy.bin
188212
Signing the policy digest...
213+
Saving policy signature to policy.bin.sig
189214
Output image(s) successfully created.
190215
```

src/tpm.c

+8
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,10 @@ int wolfBoot_seal_blob(const uint8_t* pubkey_hint, const uint8_t* policy, uint16
763763
/* get public key for policy authorization */
764764
rc = wolfBoot_load_pubkey(pubkey_hint, &authKey, &alg);
765765

766+
#ifdef WOLFBOOT_DEBUG_TPM
767+
wolfBoot_printf("Seal: Pub Key %d\n", alg);
768+
#endif
769+
766770
/* The handle for the public key if not needed, so unload it.
767771
* For seal only a populated TPM2B_PUBLIC is required */
768772
wolfTPM2_UnloadHandle(&wolftpm_dev, &authKey.handle);
@@ -885,6 +889,10 @@ int wolfBoot_unseal_blob(const uint8_t* pubkey_hint,
885889
memset(pcrArray, 0, sizeof(pcrArray));
886890
pcrArraySz = wolfBoot_tpm_pcrmask_sel(pcrMask, pcrArray, sizeof(pcrArray));
887891

892+
#ifdef WOLFBOOT_DEBUG_TPM
893+
wolfBoot_printf("Unseal: PCR mask 0x%x (sz %d)\n", pcrMask, pcrArraySz);
894+
#endif
895+
888896
/* skip to signature */
889897
policy += sizeof(pcrMask);
890898
policySz -= sizeof(pcrMask);

src/update_flash.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ int wolfBoot_unlock_disk(void)
655655

656656

657657
/* Extend a PCR from the mask to prevent future unsealing */
658+
#if !defined(ARCH_SIM) && !defined(WOLFBOOT_NO_UNSEAL_PCR_EXTEND)
658659
{
659660
uint32_t pcrMask;
660661
uint32_t pcrArraySz;
@@ -670,8 +671,8 @@ int wolfBoot_unlock_disk(void)
670671
pcrArraySz = wolfBoot_tpm_pcrmask_sel(pcrMask,
671672
pcrArray, sizeof(pcrArray)); /* get first PCR from mask */
672673
wolfBoot_tpm2_extend(pcrArray[0], (uint8_t*)digest, __LINE__);
673-
}
674-
674+
}
675+
#endif
675676
}
676677
else {
677678
wolfBoot_printf("unlock disk failed! %d (%s)\n",

tools/tpm/policy_sign.c

+65-55
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,31 @@
2424
*/
2525

2626

27-
#include "wolfssl/wolfcrypt/types.h"
28-
#include <wolftpm/tpm2.h>
29-
#include <wolftpm/tpm2_wrap.h>
30-
31-
#include <stdio.h>
3227

33-
#include <hal/tpm_io.h>
28+
#include <wolfssl/wolfcrypt/settings.h>
29+
#include <wolfssl/wolfcrypt/ecc.h>
3430
#include <wolfssl/wolfcrypt/hash.h>
31+
#include <wolftpm/tpm2_wrap.h>
32+
#include "tpm.h"
33+
34+
/* Default PCR (test) */
35+
#define DEFAULT_PCR 16
3536

3637
/* Prefer SHA2-256 for PCR's, and all TPM 2.0 devices support it */
3738
#define USE_PCR_ALG TPM_ALG_SHA256
38-
enum sign_alg {
39-
ECC256 = 0,
40-
};
4139

4240
static void usage(void)
4341
{
4442
printf("Expected usage:\n");
45-
printf("./examples/pcr/policy_sign [-ecc256] [-key=pem/der] [-pcr] [-pcrdisgest] [-outpolicy=] policy_file\n");
46-
printf("* -ecc256: Use ECC256P1 key\n");
47-
printf("* -key=keyfile: Private key to sign PCR policy (PEM or DER)\n");
48-
printf("* -pcr=index: PCR index < 24 (multiple can be supplied) (default 0)\n");
43+
printf("./examples/pcr/policy_sign [-ecc256/-ecc384] [-key=pem/der] [-pcr=] [-pcrdigest=] [-policydigest=][-outpolicy=]\n");
44+
printf("* -ecc256/-ecc384: Key type (currently only ECC) (default SECP256R1)\n");
45+
printf("* -key=keyfile: Private key to sign PCR policy (PEM or DER) (default wolfboot_signing_private_key.der)\n");
46+
printf("* -pcr=index: PCR index < 24 (multiple can be supplied) (default %d)\n", DEFAULT_PCR);
4947
printf("* -pcrdigest=hexstr: PCR Digest (default=Read actual PCR's)\n");
50-
printf("* -out=file: Signature file (default policy.bin.sig)\n");
48+
printf("* -policydigest=hexstr: Policy Digest (policy based on PCR digest and PCR(s)\n");
49+
printf("* -outpolicy=file: Signature file (default policy.bin.sig)\n");
50+
printf("Example:\n");
51+
printf("\t./tools/tpm/policy_sign -ecc256 -pcr=0 -pcrdigest=eca4e8eda468b8667244ae972b8240d3244ea72341b2bf2383e79c66643bbecc\n");
5152
}
5253

5354

@@ -98,8 +99,8 @@ static int loadFile(const char* fname, byte** buf, size_t* bufLen)
9899
}
99100

100101
/* Function to sign policy with external key */
101-
static int PolicySign(enum sign_alg alg, const char* keyFile, byte* hash,
102-
word32 hashSz, byte* sig, word32* sigSz)
102+
static int PolicySign(int alg, const char* keyFile, byte* hash, word32 hashSz,
103+
byte* sig, word32* sigSz)
103104
{
104105
int rc = 0;
105106
byte* buf = NULL;
@@ -114,8 +115,8 @@ static int PolicySign(enum sign_alg alg, const char* keyFile, byte* hash,
114115
#endif
115116
} key;
116117

117-
XMEMSET(&key, 0, sizeof(key));
118-
XMEMSET(&rng, 0, sizeof(rng));
118+
memset(&key, 0, sizeof(key));
119+
memset(&rng, 0, sizeof(rng));
119120

120121
rc = wc_InitRng(&rng);
121122
if (rc != 0) {
@@ -124,20 +125,21 @@ static int PolicySign(enum sign_alg alg, const char* keyFile, byte* hash,
124125
}
125126

126127
rc = loadFile(keyFile, &buf, &bufSz);
127-
if (rc == 0 && alg == ECC256) {
128+
if (rc == 0 && (alg == ECC_SECP256R1 || alg == ECC_SECP384R1)) {
129+
word32 keySz = 32;
130+
if (alg == ECC_SECP384R1)
131+
keySz = 48;
128132
rc = wc_ecc_init(&key.ecc);
129133
if (rc == 0) {
130134
rc = wc_ecc_import_unsigned(&key.ecc, buf,
131-
(buf) + 32, buf + 64,
132-
ECC_SECP256R1);
135+
(buf) + keySz, buf + (keySz*2), alg);
133136
if (rc == 0) {
134137
mp_int r, s;
135138
rc = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL);
136139
if (rc == 0) {
137140
rc = wc_ecc_sign_hash_ex(hash, hashSz, &rng, &key.ecc, &r, &s);
138141
}
139142
if (rc == 0) {
140-
word32 keySz = key.ecc.dp->size;
141143
mp_to_unsigned_bin(&r, sig);
142144
mp_to_unsigned_bin(&s, sig + keySz);
143145
mp_clear(&r);
@@ -231,10 +233,10 @@ int policy_sign(int argc, char *argv[])
231233
int i;
232234
int rc = -1;
233235
TPM_ALG_ID pcrAlg = USE_PCR_ALG;
234-
enum sign_alg alg;
236+
int alg = ECC_SECP256R1;
235237
byte pcrArray[PCR_SELECT_MAX*2];
236238
word32 pcrArraySz = 0;
237-
const char* keyFile = NULL;
239+
const char* keyFile = "wolfboot_signing_private_key.der";
238240
const char* outPolicyFile = "policy.bin.sig";
239241
byte pcrDigest[WC_MAX_DIGEST_SIZE];
240242
word32 pcrDigestSz = 0;
@@ -257,7 +259,10 @@ int policy_sign(int argc, char *argv[])
257259
}
258260
while (argc > 1) {
259261
if (XSTRCMP(argv[argc-1], "-ecc256") == 0) {
260-
alg = ECC256;
262+
alg = ECC_SECP256R1;
263+
}
264+
else if (XSTRCMP(argv[argc-1], "-ecc384") == 0) {
265+
alg = ECC_SECP384R1;
261266
}
262267
else if (strncmp(argv[argc-1], "-pcr=", strlen("-pcr=")) == 0) {
263268
const char* pcrStr = argv[argc-1] + strlen("-pcr=");
@@ -310,7 +315,18 @@ int policy_sign(int argc, char *argv[])
310315
argc--;
311316
}
312317

313-
printf("Sign PCR Policy Example\n");
318+
printf("Sign PCR Policy Tool\n");
319+
320+
if (pcrArraySz == 0) {
321+
pcrArray[pcrArraySz] = DEFAULT_PCR;
322+
pcrArraySz++;
323+
}
324+
325+
printf("Signing Algorithm: %s\n",
326+
(alg == ECC_SECP256R1) ? "ECC256" :
327+
(alg == ECC_SECP384R1) ? "ECC384" :
328+
"Unknown"
329+
);
314330

315331
printf("PCR Index(s) (%s): ", TPM2_GetAlgName(pcrAlg));
316332
for (i = 0; i < (int)pcrArraySz; i++) {
@@ -327,20 +343,18 @@ int policy_sign(int argc, char *argv[])
327343
printf("Policy Signing Key: %s\n", keyFile);
328344
}
329345

330-
/* PCR Hash - Use provided hash or read PCR's and get hash */
346+
/* PCR Hash - Use provided PCR digest or Policy digest */
331347
if (pcrDigestSz == 0 && digestSz == 0) {
332-
printf("Error: Specificy PCR's or Policy hash!\n");
333-
goto exit;
334-
}
335-
336-
if (pcrDigestSz > 0) {
337-
printf("PCR Digest (%d bytes):\n", pcrDigestSz);
338-
printHexString(pcrDigest, pcrDigestSz, pcrDigestSz);
348+
printf("Error: Must supply either PCR or Policy digest!\n");
349+
usage();
350+
return -1;
339351
}
352+
printf("PCR Digest (%d bytes):\n", pcrDigestSz);
353+
printHexString(pcrDigest, pcrDigestSz, pcrDigestSz);
340354

341355
if (digestSz == 0) {
342-
/* Build PCR Policy to Sign */
343-
XMEMSET(digest, 0, sizeof(digest));
356+
/* If not supplied, build PCR Policy to Sign */
357+
memset(digest, 0, sizeof(digest));
344358
digestSz = TPM2_GetHashDigestSize(pcrAlg);
345359
rc = wolfTPM2_PolicyPCRMake(pcrAlg, pcrArray, pcrArraySz,
346360
pcrDigest, pcrDigestSz, digest, &digestSz);
@@ -358,28 +372,24 @@ int policy_sign(int argc, char *argv[])
358372
printHexString(digest, digestSz, digestSz);
359373

360374
/* Sign the PCR policy (use private key provided or do externally) */
361-
if (keyFile != NULL) {
362-
rc = PolicySign(alg, keyFile, digest, digestSz, sig, &sigSz);
375+
rc = PolicySign(alg, keyFile, digest, digestSz, sig, &sigSz);
376+
if (rc == 0) {
377+
pcrMask = 0;
378+
for (i = 0; i < (int)pcrArraySz; i++)
379+
pcrMask |= (1 << pcrArray[i]);
380+
381+
memcpy(policy, &pcrMask, sizeof(pcrMask));
382+
memcpy(policy + sizeof(pcrMask), sig, sigSz);
383+
printf("PCR Mask (0x%x) and Policy Signature (%d bytes):\n",
384+
(int)pcrMask, (int)(sigSz + sizeof(pcrMask)));
385+
printHexString(policy, sizeof(pcrMask), 0);
386+
printHexString(policy + sizeof(pcrMask), sigSz, 32);
387+
rc = writeBin(outPolicyFile, policy, sigSz+sizeof(pcrMask));
363388
if (rc == 0) {
364-
pcrMask = 0;
365-
for (i = 0; i < (int)pcrArraySz; i++)
366-
pcrMask |= (1 << pcrArray[i]);
367-
368-
memcpy(policy, &pcrMask, sizeof(pcrMask));
369-
memcpy(policy + sizeof(pcrMask), sig, sigSz);
370-
printf("PCR Mask (0x%x) and Policy Signature (%d bytes):\n", (int)pcrMask,
371-
(int)(sigSz + sizeof(pcrMask)));
372-
printHexString(policy, sigSz+sizeof(pcrMask), 32);
373-
rc = writeBin(outPolicyFile, policy, sigSz+sizeof(pcrMask));
389+
printf("Wrote PCR Mask + Signature (%d bytes) to %s\n",
390+
(int)(sigSz + sizeof(pcrMask)), outPolicyFile);
374391
}
375392
}
376-
else {
377-
/* Print policy hash to sign externally and exit early */
378-
printf("No private key to sign policy!\n");
379-
printf("Externally sign the PCR Policy digest\n");
380-
rc = 0;
381-
goto exit;
382-
}
383393

384394
exit:
385395
if (rc != 0) {

0 commit comments

Comments
 (0)