Skip to content

Commit f7967fc

Browse files
committed
wolfBoot_unseal_auth(): secretSz is now in/out param
The caller is now required to pass the available space in buffer. The actual size of the unsealed secret is returned. F/442
1 parent cea7f5d commit f7967fc

5 files changed

Lines changed: 257 additions & 7 deletions

File tree

docs/TPM.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ int wolfBoot_unseal_auth(const uint8_t* pubkey_hint, const uint8_t* policy, uint
4747
int index, uint8_t* secret, int* secret_sz, const byte* auth, int authSz);
4848
```
4949
50+
For `wolfBoot_unseal_auth()`, `*secret_sz` is an in/out parameter: set it to the
51+
capacity of `secret` before the call, and on success it is updated to the
52+
number of bytes unsealed.
53+
5054
By default this index will be based on an NV Index at `(0x01400300 + index)`.
5155
The default NV base can be overridden with `WOLFBOOT_TPM_SEAL_NV_BASE`.
5256

src/tpm.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,7 @@ int wolfBoot_unseal_blob(const uint8_t* pubkey_hint,
935935
const uint8_t* auth, int authSz)
936936
{
937937
int rc, i;
938+
int secret_capacity;
938939
WOLFTPM2_SESSION policy_session;
939940
uint32_t key_type;
940941
TPM_ALG_ID pcrAlg = WOLFBOOT_TPM_PCR_ALG;
@@ -959,8 +960,13 @@ int wolfBoot_unseal_blob(const uint8_t* pubkey_hint,
959960
return -1;
960961
}
961962

963+
secret_capacity = *secret_sz;
962964
*secret_sz = 0; /* init */
963965

966+
if (secret_capacity < 0) {
967+
return BAD_FUNC_ARG;
968+
}
969+
964970
/* extract pcrMask and populate PCR selection array */
965971
memcpy(&pcrMask, policy, sizeof(pcrMask));
966972
memset(pcrArray, 0, sizeof(pcrArray));
@@ -1079,8 +1085,14 @@ int wolfBoot_unseal_blob(const uint8_t* pubkey_hint,
10791085
rc = TPM2_Unseal(&unsealIn, &unsealOut);
10801086
}
10811087
if (rc == 0) {
1082-
*secret_sz = unsealOut.outData.size;
1083-
memcpy(secret, unsealOut.outData.buffer, *secret_sz);
1088+
if (unsealOut.outData.size > WOLFBOOT_MAX_SEAL_SZ ||
1089+
(int)unsealOut.outData.size > secret_capacity) {
1090+
rc = BUFFER_E;
1091+
}
1092+
else {
1093+
*secret_sz = unsealOut.outData.size;
1094+
memcpy(secret, unsealOut.outData.buffer, *secret_sz);
1095+
}
10841096
}
10851097

10861098
wolfTPM2_UnloadHandle(&wolftpm_dev, &seal_blob->handle);

src/update_flash.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,7 +1206,7 @@ int wolfBoot_unlock_disk(void)
12061206
int ret;
12071207
struct wolfBoot_image img;
12081208
uint8_t secret[WOLFBOOT_MAX_SEAL_SZ];
1209-
int secretSz;
1209+
int secretSz = sizeof(secret);
12101210
uint8_t* policy = NULL, *pubkey_hint = NULL;
12111211
uint16_t policySz = 0;
12121212
int nvIndex = 0; /* where the sealed blob is stored in NV */
@@ -1249,7 +1249,7 @@ int wolfBoot_unlock_disk(void)
12491249
}
12501250
if (ret == 0) {
12511251
uint8_t secretCheck[WOLFBOOT_MAX_SEAL_SZ];
1252-
int secretCheckSz = 0;
1252+
int secretCheckSz = sizeof(secretCheck);
12531253

12541254
/* unseal again to make sure it works */
12551255
memset(secretCheck, 0, sizeof(secretCheck));

src/x86/ahci.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ static int sata_create_and_seal_unlock_secret(const uint8_t *pubkey_hint,
272272
int *secret_size)
273273
{
274274
uint8_t secret_check[WOLFBOOT_MAX_SEAL_SZ];
275-
int secret_check_sz;
275+
int secret_check_sz = sizeof(secret_check);
276276
int ret;
277277

278278
if (*secret_size < ATA_UNLOCK_DISK_KEY_SZ)
@@ -797,4 +797,3 @@ void sata_disable(uint32_t base)
797797

798798
}
799799
#endif /* AHCI_H_ */
800-

tools/unit-tests/unit-tpm-blob.c

Lines changed: 236 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@
2424

2525
enum mock_mode {
2626
MOCK_OVERSIZE_PUB,
27-
MOCK_OVERSIZE_PRIV
27+
MOCK_OVERSIZE_PRIV,
28+
MOCK_UNSEAL_OVERSIZE
2829
};
2930

3031
static enum mock_mode current_mode;
3132
static int nvread_calls;
3233
static int oversized_pub_read_attempted;
3334
static int oversized_priv_read_attempted;
35+
static uint8_t test_hdr[64];
36+
static uint8_t test_modulus[256];
37+
static uint8_t test_exponent_der[] = { 0xAA, 0x01, 0x00, 0x01, 0x7B };
3438

3539
int wolfBoot_printf(const char* fmt, ...)
3640
{
@@ -47,6 +51,205 @@ int wolfTPM2_SetAuthHandle(WOLFTPM2_DEV* dev, int index,
4751
return 0;
4852
}
4953

54+
int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index,
55+
WOLFTPM2_SESSION* tpmSession, TPMA_SESSION sessionAttributes)
56+
{
57+
(void)dev;
58+
(void)index;
59+
(void)tpmSession;
60+
(void)sessionAttributes;
61+
return 0;
62+
}
63+
64+
int wolfTPM2_UnsetAuthSession(WOLFTPM2_DEV* dev, int index,
65+
WOLFTPM2_SESSION* tpmSession)
66+
{
67+
(void)dev;
68+
(void)index;
69+
(void)tpmSession;
70+
return 0;
71+
}
72+
73+
int wolfTPM2_SetAuthHandleName(WOLFTPM2_DEV* dev, int index,
74+
const WOLFTPM2_HANDLE* handle)
75+
{
76+
(void)dev;
77+
(void)index;
78+
(void)handle;
79+
return 0;
80+
}
81+
82+
int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
83+
WOLFTPM2_KEY* tpmKey, WOLFTPM2_HANDLE* bind, TPM_SE sesType,
84+
int encDecAlg)
85+
{
86+
(void)dev;
87+
(void)tpmKey;
88+
(void)bind;
89+
(void)sesType;
90+
(void)encDecAlg;
91+
session->handle.hndl = 1;
92+
return 0;
93+
}
94+
95+
int wolfTPM2_LoadKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEYBLOB* keyBlob,
96+
WOLFTPM2_HANDLE* parent)
97+
{
98+
(void)dev;
99+
(void)parent;
100+
keyBlob->handle.hndl = 2;
101+
return 0;
102+
}
103+
104+
int wolfTPM2_UnloadHandle(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle)
105+
{
106+
(void)dev;
107+
(void)handle;
108+
return 0;
109+
}
110+
111+
int wolfTPM2_LoadEccPublicKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* pubKey,
112+
int curveID, const byte* qx, word32 qxSz, const byte* qy, word32 qySz)
113+
{
114+
(void)dev;
115+
(void)pubKey;
116+
(void)curveID;
117+
(void)qx;
118+
(void)qxSz;
119+
(void)qy;
120+
(void)qySz;
121+
return 0;
122+
}
123+
124+
int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
125+
const byte** n, word32* nSz, const byte** e, word32* eSz)
126+
{
127+
(void)input;
128+
(void)inSz;
129+
130+
*inOutIdx = 0;
131+
*n = test_modulus;
132+
*nSz = sizeof(test_modulus);
133+
*e = &test_exponent_der[1];
134+
*eSz = 3;
135+
return 0;
136+
}
137+
138+
int wolfTPM2_LoadRsaPublicKey_ex(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
139+
const byte* rsaPub, word32 rsaPubSz, word32 exponent,
140+
TPM_ALG_ID scheme, TPMI_ALG_HASH hashAlg)
141+
{
142+
(void)dev;
143+
(void)key;
144+
(void)rsaPub;
145+
(void)rsaPubSz;
146+
(void)exponent;
147+
(void)scheme;
148+
(void)hashAlg;
149+
return 0;
150+
}
151+
152+
int wolfTPM2_VerifyHashTicket(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
153+
const byte* sig, int sigSz, const byte* digest, int digestSz,
154+
TPMI_ALG_SIG_SCHEME sigAlg, TPMI_ALG_HASH hashAlg,
155+
TPMT_TK_VERIFIED* checkTicket)
156+
{
157+
(void)dev;
158+
(void)key;
159+
(void)sig;
160+
(void)sigSz;
161+
(void)digest;
162+
(void)digestSz;
163+
(void)sigAlg;
164+
(void)hashAlg;
165+
(void)checkTicket;
166+
return 0;
167+
}
168+
169+
int wolfTPM2_GetPolicyDigest(WOLFTPM2_DEV* dev, TPM_HANDLE sessionHandle,
170+
byte* policyDigest, word32* policyDigestSz)
171+
{
172+
(void)dev;
173+
(void)sessionHandle;
174+
memset(policyDigest, 0x11, *policyDigestSz);
175+
return 0;
176+
}
177+
178+
int wolfTPM2_PolicyPCR(WOLFTPM2_DEV* dev, TPM_HANDLE sessionHandle,
179+
TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz)
180+
{
181+
(void)dev;
182+
(void)sessionHandle;
183+
(void)pcrAlg;
184+
(void)pcrArray;
185+
(void)pcrArraySz;
186+
return 0;
187+
}
188+
189+
int wolfTPM2_PolicyAuthorize(WOLFTPM2_DEV* dev, TPM_HANDLE sessionHandle,
190+
const TPM2B_PUBLIC* pub, const TPMT_TK_VERIFIED* checkTicket,
191+
const byte* pcrDigest, word32 pcrDigestSz,
192+
const byte* policyRef, word32 policyRefSz)
193+
{
194+
(void)dev;
195+
(void)sessionHandle;
196+
(void)pub;
197+
(void)checkTicket;
198+
(void)pcrDigest;
199+
(void)pcrDigestSz;
200+
(void)policyRef;
201+
(void)policyRefSz;
202+
return 0;
203+
}
204+
205+
int wolfTPM2_PolicyRefMake(TPM_ALG_ID pcrAlg, byte* digest, word32* digestSz,
206+
const byte* policyRef, word32 policyRefSz)
207+
{
208+
(void)pcrAlg;
209+
(void)digest;
210+
(void)digestSz;
211+
(void)policyRef;
212+
(void)policyRefSz;
213+
return 0;
214+
}
215+
216+
TPM_RC TPM2_Unseal(Unseal_In* in, Unseal_Out* out)
217+
{
218+
(void)in;
219+
220+
if (current_mode != MOCK_UNSEAL_OVERSIZE) {
221+
ck_abort_msg("Unexpected TPM2_Unseal call in mode %d", current_mode);
222+
}
223+
224+
out->outData.size = 16;
225+
memset(out->outData.buffer, 0x5A, out->outData.size);
226+
return 0;
227+
}
228+
229+
int keyslot_id_by_sha(const uint8_t* pubkey_hint)
230+
{
231+
(void)pubkey_hint;
232+
return 0;
233+
}
234+
235+
uint32_t keystore_get_key_type(int id)
236+
{
237+
ck_assert_int_eq(id, 0);
238+
return AUTH_KEY_RSA2048;
239+
}
240+
241+
uint8_t *keystore_get_buffer(int id)
242+
{
243+
ck_assert_int_eq(id, 0);
244+
return test_hdr;
245+
}
246+
247+
int keystore_get_size(int id)
248+
{
249+
ck_assert_int_eq(id, 0);
250+
return (int)sizeof(test_hdr);
251+
}
252+
50253
const char* TPM2_GetRCString(int rc)
51254
{
52255
(void)rc;
@@ -109,6 +312,8 @@ static void setup(void)
109312
nvread_calls = 0;
110313
oversized_pub_read_attempted = 0;
111314
oversized_priv_read_attempted = 0;
315+
memset(test_hdr, 0x22, sizeof(test_hdr));
316+
memset(test_modulus, 0x33, sizeof(test_modulus));
112317
}
113318

114319
START_TEST(test_wolfBoot_read_blob_rejects_oversized_public_area)
@@ -127,6 +332,35 @@ START_TEST(test_wolfBoot_read_blob_rejects_oversized_public_area)
127332
}
128333
END_TEST
129334

335+
START_TEST(test_wolfBoot_unseal_blob_rejects_output_larger_than_capacity)
336+
{
337+
struct {
338+
uint8_t secret[8];
339+
uint8_t canary[8];
340+
} output;
341+
WOLFTPM2_KEYBLOB blob;
342+
uint8_t pubkey_hint[WOLFBOOT_SHA_DIGEST_SIZE] = {0};
343+
uint8_t policy[sizeof(uint32_t) + 4] = {0};
344+
int secret_sz;
345+
int rc;
346+
int i;
347+
348+
memset(&blob, 0, sizeof(blob));
349+
memset(&output, 0xA5, sizeof(output));
350+
current_mode = MOCK_UNSEAL_OVERSIZE;
351+
secret_sz = (int)sizeof(output.secret);
352+
353+
rc = wolfBoot_unseal_blob(pubkey_hint, policy, sizeof(policy), &blob,
354+
output.secret, &secret_sz, NULL, 0);
355+
356+
ck_assert_int_eq(rc, BUFFER_E);
357+
ck_assert_int_eq(secret_sz, 0);
358+
for (i = 0; i < (int)sizeof(output.canary); i++) {
359+
ck_assert_uint_eq(output.canary[i], 0xA5);
360+
}
361+
}
362+
END_TEST
363+
130364
START_TEST(test_wolfBoot_read_blob_rejects_oversized_private_area)
131365
{
132366
WOLFTPM2_KEYBLOB blob;
@@ -154,6 +388,7 @@ static Suite *tpm_blob_suite(void)
154388
tcase_add_checked_fixture(tc, setup, NULL);
155389
tcase_add_test(tc, test_wolfBoot_read_blob_rejects_oversized_public_area);
156390
tcase_add_test(tc, test_wolfBoot_read_blob_rejects_oversized_private_area);
391+
tcase_add_test(tc, test_wolfBoot_unseal_blob_rejects_output_larger_than_capacity);
157392
suite_add_tcase(s, tc);
158393
return s;
159394
}

0 commit comments

Comments
 (0)