@@ -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+
6090static 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
0 commit comments