Skip to content

Commit 438c63e

Browse files
authored
Merge pull request #455 from dgarske/ek_certs
Improve get_ek_certs to handle indices
2 parents 529e02b + b7e0bf6 commit 438c63e

3 files changed

Lines changed: 164 additions & 4 deletions

File tree

examples/endorsement/get_ek_certs.c

Lines changed: 146 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,36 @@ static void usage(void)
5757
printf("./examples/endorsement/get_ek_certs\n");
5858
}
5959

60+
#ifdef DEBUG_WOLFTPM
61+
/* Decode and display NV attributes - only in debug mode */
62+
static void show_nv_attributes(TPMA_NV attr)
63+
{
64+
printf(" Attributes:");
65+
if (attr & TPMA_NV_PPWRITE) printf(" PPWRITE");
66+
if (attr & TPMA_NV_OWNERWRITE) printf(" OWNERWRITE");
67+
if (attr & TPMA_NV_AUTHWRITE) printf(" AUTHWRITE");
68+
if (attr & TPMA_NV_POLICYWRITE) printf(" POLICYWRITE");
69+
if (attr & TPMA_NV_POLICY_DELETE) printf(" POLICY_DELETE");
70+
if (attr & TPMA_NV_WRITELOCKED) printf(" WRITELOCKED");
71+
if (attr & TPMA_NV_WRITEALL) printf(" WRITEALL");
72+
if (attr & TPMA_NV_WRITEDEFINE) printf(" WRITEDEFINE");
73+
if (attr & TPMA_NV_WRITE_STCLEAR) printf(" WRITE_STCLEAR");
74+
if (attr & TPMA_NV_GLOBALLOCK) printf(" GLOBALLOCK");
75+
if (attr & TPMA_NV_PPREAD) printf(" PPREAD");
76+
if (attr & TPMA_NV_OWNERREAD) printf(" OWNERREAD");
77+
if (attr & TPMA_NV_AUTHREAD) printf(" AUTHREAD");
78+
if (attr & TPMA_NV_POLICYREAD) printf(" POLICYREAD");
79+
if (attr & TPMA_NV_NO_DA) printf(" NO_DA");
80+
if (attr & TPMA_NV_ORDERLY) printf(" ORDERLY");
81+
if (attr & TPMA_NV_CLEAR_STCLEAR) printf(" CLEAR_STCLEAR");
82+
if (attr & TPMA_NV_READLOCKED) printf(" READLOCKED");
83+
if (attr & TPMA_NV_WRITTEN) printf(" WRITTEN");
84+
if (attr & TPMA_NV_PLATFORMCREATE) printf(" PLATFORMCREATE");
85+
if (attr & TPMA_NV_READ_STCLEAR) printf(" READ_STCLEAR");
86+
printf("\n");
87+
}
88+
#endif
89+
6090
static void dump_hex_bytes(const byte* buf, word32 sz)
6191
{
6292
word32 i;
@@ -229,15 +259,129 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
229259
for (nvIdx=0; nvIdx<(int)handles.count; nvIdx++) {
230260
nvIndex = handles.handle[nvIdx];
231261

232-
XMEMSET(&nv, 0, sizeof(nv)); /* Must reset the NV for each read */
262+
XMEMSET(&nv, 0, sizeof(nv)); /* Reset NV handle for each index */
233263
XMEMSET(certBuf, 0, sizeof(certBuf));
234264

235265
printf("TCG Handle 0x%x\n", nvIndex);
236266

237267
/* Get Endorsement Public Key template using NV index */
238268
rc = wolfTPM2_GetKeyTemplate_EKIndex(nvIndex, &publicTemplate);
239269
if (rc != 0) {
240-
printf("EK Index 0x%08x not valid\n", nvIndex);
270+
const char* indexType = "Unknown";
271+
word32 offset;
272+
273+
/* Identify the type of NV index based on offset */
274+
if (nvIndex < TPM_20_TCG_NV_SPACE) {
275+
indexType = "Non-TCG (below TCG NV space)";
276+
}
277+
else {
278+
offset = nvIndex - TPM_20_TCG_NV_SPACE;
279+
280+
if (offset >= 0x2 && offset <= 0xC) {
281+
indexType = "EK Low Range";
282+
if (offset == 0x2) indexType = "EK Low Range (RSA 2048 Cert)";
283+
else if (offset == 0x3) indexType = "EK Low Range (RSA 2048 Nonce)";
284+
else if (offset == 0x4) indexType = "EK Low Range (RSA 2048 Template)";
285+
else if (offset == 0xA) indexType = "EK Low Range (ECC P256 Cert)";
286+
else if (offset == 0xB) indexType = "EK Low Range (ECC P256 Nonce)";
287+
else if (offset == 0xC) indexType = "EK Low Range (ECC P256 Template)";
288+
}
289+
else if (offset >= 0x12 && offset < 0x100) {
290+
indexType = "EK High Range";
291+
if (offset == 0x12) indexType = "EK High Range (RSA 2048 Cert)";
292+
else if (offset == 0x14) indexType = "EK High Range (ECC P256 Cert)";
293+
else if (offset == 0x16) indexType = "EK High Range (ECC P384 Cert)";
294+
else if (offset == 0x18) indexType = "EK High Range (ECC P521 Cert)";
295+
else if (offset == 0x1A) indexType = "EK High Range (ECC SM2 Cert)";
296+
else if (offset == 0x1C) indexType = "EK High Range (RSA 3072 Cert)";
297+
else if (offset == 0x1E) indexType = "EK High Range (RSA 4096 Cert)";
298+
else if ((offset & 1) == 0) indexType = "EK High Range (Cert, even index)";
299+
else indexType = "EK High Range (Template, odd index)";
300+
}
301+
else if (offset >= 0x100 && offset < 0x200) {
302+
indexType = "EK Certificate Chain";
303+
}
304+
else if (offset == (TPM2_NV_EK_POLICY_SHA256 - TPM_20_TCG_NV_SPACE)) {
305+
indexType = "EK Policy Index (SHA256)";
306+
}
307+
else if (offset == (TPM2_NV_EK_POLICY_SHA384 - TPM_20_TCG_NV_SPACE)) {
308+
indexType = "EK Policy Index (SHA384)";
309+
}
310+
else if (offset == (TPM2_NV_EK_POLICY_SHA512 - TPM_20_TCG_NV_SPACE)) {
311+
indexType = "EK Policy Index (SHA512)";
312+
}
313+
else if (offset == (TPM2_NV_EK_POLICY_SM3_256 - TPM_20_TCG_NV_SPACE)) {
314+
indexType = "EK Policy Index (SM3_256)";
315+
}
316+
else if (nvIndex > TPM_20_TCG_NV_SPACE + 0x7FFF) {
317+
indexType = "Vendor-specific (beyond TCG range)";
318+
}
319+
}
320+
321+
printf("NV Index 0x%08x: %s (not a recognized EK certificate index)\n",
322+
nvIndex, indexType);
323+
324+
/* Try to read the NV public info to show what it contains */
325+
rc = wolfTPM2_NVReadPublic(&dev, nvIndex, &nvPublic);
326+
if (rc == 0) {
327+
const char* hashName = TPM2_GetAlgName(nvPublic.nameAlg);
328+
int isPolicyDigest = 0;
329+
int showData = 0;
330+
331+
#ifdef DEBUG_WOLFTPM
332+
printf(" NV Size: %u bytes, Attributes: 0x%08x, Name Alg: %s\n",
333+
nvPublic.dataSize, (unsigned int)nvPublic.attributes, hashName);
334+
show_nv_attributes(nvPublic.attributes);
335+
showData = 1; /* Always show data in debug mode */
336+
#else
337+
printf(" NV Size: %u bytes, Name Alg: %s\n",
338+
nvPublic.dataSize, hashName);
339+
#endif
340+
341+
/* Check if this looks like a policy digest based on size and hash */
342+
if ((nvPublic.dataSize == 32 && nvPublic.nameAlg == TPM_ALG_SHA256) ||
343+
(nvPublic.dataSize == 48 && nvPublic.nameAlg == TPM_ALG_SHA384) ||
344+
(nvPublic.dataSize == 64 && nvPublic.nameAlg == TPM_ALG_SHA512) ||
345+
(nvPublic.dataSize == 32 && nvPublic.nameAlg == TPM_ALG_SM3_256)) {
346+
printf(" Type: Policy digest (%s hash)\n", hashName);
347+
isPolicyDigest = 1;
348+
showData = 1; /* Always show policy digests */
349+
}
350+
else if (nvPublic.dataSize > 100) {
351+
printf(" Type: Certificate or template\n");
352+
}
353+
else if (nvPublic.dataSize > 32) {
354+
printf(" Type: Data (%u bytes)\n", nvPublic.dataSize);
355+
}
356+
else {
357+
printf(" Type: Small data (%u bytes)\n", nvPublic.dataSize);
358+
#ifdef DEBUG_WOLFTPM
359+
showData = 1;
360+
#endif
361+
}
362+
363+
/* Read and display data if appropriate */
364+
if (showData && nvPublic.dataSize > 0) {
365+
certSz = nvPublic.dataSize;
366+
if (certSz > sizeof(certBuf)) {
367+
certSz = sizeof(certBuf);
368+
}
369+
370+
rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, certBuf, &certSz, 0);
371+
if (rc == 0) {
372+
if (nvPublic.dataSize <= 32 || isPolicyDigest) {
373+
printf(" Data (%u bytes):\n", certSz);
374+
dump_hex_bytes(certBuf, certSz);
375+
}
376+
else {
377+
printf(" First 32 bytes:\n");
378+
dump_hex_bytes(certBuf, (certSz > 32) ? 32 : certSz);
379+
}
380+
}
381+
}
382+
}
383+
384+
rc = 0; /* Reset error code to continue processing */
241385
continue;
242386
}
243387

src/tpm2_wrap.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6445,10 +6445,20 @@ int wolfTPM2_GetKeyTemplate_EKIndex(word32 nvIndex,
64456445
TPM_ECC_CURVE curveID = TPM_ECC_NONE;
64466446
uint32_t keyBits = 0;
64476447
int highRange = 0;
6448+
word32 offset;
64486449

6449-
/* validate index is in NV EK range */
6450+
/* Validate index is in TCG NV space */
64506451
if (nvIndex < TPM_20_TCG_NV_SPACE ||
6451-
nvIndex > TPM_20_TCG_NV_SPACE + 0x1FF) {
6452+
nvIndex > TPM_20_TCG_NV_SPACE + 0x7FFF) {
6453+
return BAD_FUNC_ARG;
6454+
}
6455+
6456+
offset = nvIndex - TPM_20_TCG_NV_SPACE;
6457+
6458+
/* Reject indices in dead zones that cannot produce valid templates:
6459+
* - Between High Range (0x1FF) and Policy Indices (0x7F01)
6460+
* - After Policy Indices (0x7F04) */
6461+
if ((offset > 0x1FF && offset < 0x7F01) || offset > 0x7F04) {
64526462
return BAD_FUNC_ARG;
64536463
}
64546464

wolftpm/tpm2.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,12 @@ typedef struct TPM2_AUTH_SESSION {
17081708
/* EK Certificate Chains (0x100 - 0x1FF) - Not common */
17091709
#define TPM2_NV_EK_CHAIN (TPM_20_TCG_NV_SPACE + 0x100)
17101710

1711+
/* EK Policy Indices for PolicyAuthorizeNV (0x7F01 - 0x7F04) */
1712+
#define TPM2_NV_EK_POLICY_SHA256 (TPM_20_TCG_NV_SPACE + 0x7F01)
1713+
#define TPM2_NV_EK_POLICY_SHA384 (TPM_20_TCG_NV_SPACE + 0x7F02)
1714+
#define TPM2_NV_EK_POLICY_SHA512 (TPM_20_TCG_NV_SPACE + 0x7F03)
1715+
#define TPM2_NV_EK_POLICY_SM3_256 (TPM_20_TCG_NV_SPACE + 0x7F04)
1716+
17111717
/* Predetermined TPM 2.0 Endorsement policy auth templates */
17121718
/* SHA256 (Low Range) */
17131719
static const BYTE TPM_20_EK_AUTH_POLICY[] = {

0 commit comments

Comments
 (0)