@@ -166,8 +166,12 @@ static int cmd_update_xmodem(const char *args);
166166static int cmd_reboot (const char * args );
167167#ifdef WOLFBOOT_TPM
168168static int cmd_tpm_info (const char * args );
169+ #ifdef WOLFTPM_MFG_IDENTITY
169170static int cmd_tpm_idevid (const char * args );
170171static int cmd_tpm_iak (const char * args );
172+ static int cmd_tpm_signed_timestamp (const char * args );
173+ static int cmd_tpm_quote (const char * args );
174+ #endif
171175#endif
172176
173177
@@ -197,8 +201,12 @@ struct console_command COMMANDS[] =
197201 {cmd_reboot , "reboot" , "reboot the system" },
198202#ifdef WOLFBOOT_TPM
199203 {cmd_tpm_info , "tpm" , "get TPM capabilities" },
204+ #ifdef WOLFTPM_MFG_IDENTITY
200205 {cmd_tpm_idevid , "idevid" , "show Initial Device Identification (IDevID) certificate" },
201206 {cmd_tpm_iak , "iak" , "show Initial Attestation Identification (IAK) certificate" },
207+ {cmd_tpm_signed_timestamp , "signed_timestamp" , "TPM IAK signed timestamp attestation report" },
208+ {cmd_tpm_quote , "quote" , "TPM IAK signed PCR(s) attestation report" },
209+ #endif
202210#endif
203211 {NULL , "" , "" }
204212};
@@ -782,9 +790,8 @@ static int cmd_tpm_info(const char *args)
782790 /* Read measured boot PCR */
783791 if (rc == 0 ) {
784792 char algName [24 ];
785- printf ("Measured boot: PCR %s %d\r\n" ,
786- wolfBoot_tpm2_get_alg_name (WOLFBOOT_TPM_PCR_ALG , algName , sizeof (algName )),
787- WOLFBOOT_MEASURED_PCR_A );
793+ printf ("Measured boot: PCR %d - %s\r\n" , WOLFBOOT_MEASURED_PCR_A ,
794+ wolfBoot_tpm2_get_alg_name (WOLFBOOT_TPM_PCR_ALG , algName , sizeof (algName )));
788795 hashSz = 0 ;
789796 rc = wolfBoot_tpm2_read_pcr (WOLFBOOT_MEASURED_PCR_A , hashBuf , & hashSz );
790797 if (rc == 0 ) {
@@ -807,6 +814,7 @@ static int cmd_tpm_info(const char *args)
807814 return rc ;
808815}
809816
817+ #ifdef WOLFTPM_MFG_IDENTITY
810818static int cmd_tpm_idevid (const char * args )
811819{
812820 int rc ;
@@ -819,6 +827,11 @@ static int cmd_tpm_idevid(const char *args)
819827 printf ("IDevID Handle 0x%x\r\n" , (unsigned int )handle );
820828 print_hex (cert , certSz , 1 );
821829 }
830+ else {
831+ char error [100 ];
832+ printf ("TPM error 0x%x: %s\r\n" ,
833+ rc , wolfBoot_tpm2_get_rc_string (rc , error , sizeof (error )));
834+ }
822835 return rc ;
823836}
824837
@@ -834,8 +847,126 @@ static int cmd_tpm_iak(const char *args)
834847 printf ("IAK Handle 0x%x\r\n" , (unsigned int )handle );
835848 print_hex (cert , certSz , 1 );
836849 }
850+ else {
851+ char error [100 ];
852+ printf ("TPM error 0x%x: %s\r\n" ,
853+ rc , wolfBoot_tpm2_get_rc_string (rc , error , sizeof (error )));
854+ }
837855 return rc ;
838856}
857+
858+ static int cmd_tpm_signed_timestamp (const char * args )
859+ {
860+ int rc ;
861+ WOLFTPM2_KEY aik ;
862+ GetTime_Out getTime ;
863+ TPMS_ATTEST timeAttest ;
864+
865+ rc = wolfBoot_tpm2_get_aik (& aik , NULL , 0 );
866+ if (rc == 0 ) {
867+ rc = wolfBoot_tpm2_get_timestamp (& aik , & getTime );
868+ }
869+ if (rc == 0 ) {
870+ rc = wolfBoot_tpm2_parse_attest (& getTime .timeInfo , & timeAttest );
871+ }
872+ if (rc == 0 ) {
873+ if (timeAttest .magic != TPM_GENERATED_VALUE ) {
874+ printf ("\tError, attested data not generated by the TPM = 0x%X\n" ,
875+ (unsigned int )timeAttest .magic );
876+ }
877+
878+ printf ("TPM with signature attests (type 0x%x):\n" , timeAttest .type );
879+ /* time value in milliseconds that advances while the TPM is powered */
880+ printf ("\tTPM uptime since last power-up (in ms): %lu\n" ,
881+ (unsigned long )timeAttest .attested .time .time .time );
882+ /* time value in milliseconds that advances while the TPM is powered */
883+ printf ("\tTPM clock, total time the TPM has been on (in ms): %lu\n" ,
884+ (unsigned long )timeAttest .attested .time .time .clockInfo .clock );
885+ /* number of occurrences of TPM Reset since the last TPM2_Clear() */
886+ printf ("\tReset Count: %u\n" ,
887+ (unsigned int )timeAttest .attested .time .time .clockInfo .resetCount );
888+ /* number of times that TPM2_Shutdown() or _TPM_Hash_Start have occurred since the last TPM Reset or TPM2_Clear(). */
889+ printf ("\tRestart Count: %u\n" ,
890+ (unsigned int )timeAttest .attested .time .time .clockInfo .restartCount );
891+ /* This parameter is set to YES when the value reported in Clock is guaranteed to be unique for the current Owner */
892+ printf ("\tClock Safe: %u\n" ,
893+ timeAttest .attested .time .time .clockInfo .safe );
894+ /* a TPM vendor-specific value indicating the version number of the firmware */
895+ printf ("\tFirmware Version (vendor specific): 0x%lX\n" ,
896+ (unsigned long )timeAttest .attested .time .firmwareVersion );
897+ }
898+
899+ if (rc != 0 ) {
900+ char error [100 ];
901+ printf ("TPM get timestamp error 0x%x: %s\r\n" ,
902+ rc , wolfBoot_tpm2_get_rc_string (rc , error , sizeof (error )));
903+ }
904+
905+ return rc ;
906+ }
907+
908+ static int cmd_tpm_quote (const char * args )
909+ {
910+ int rc ;
911+ WOLFTPM2_KEY aik ;
912+ Quote_Out quoteResult ;
913+ TPMS_ATTEST quoteAttest ;
914+ uint8_t pcrArray [1 ];
915+ uint32_t pcrArraySz = 0 ;
916+ char algName [24 ];
917+
918+ #ifdef WOLFBOOT_MEASURED_PCR_A
919+ pcrArray [0 ] = WOLFBOOT_MEASURED_PCR_A ;
920+ pcrArraySz ++ ;
921+ #else
922+ pcrArray [0 ] = 16 ; /* test PCR */
923+ pcrArraySz ++ ;
924+ #endif
925+
926+ rc = wolfBoot_tpm2_get_aik (& aik , NULL , 0 );
927+ if (rc == 0 ) {
928+ rc = wolfBoot_tpm2_quote (& aik , pcrArray , pcrArraySz , & quoteResult );
929+ }
930+ if (rc == 0 ) {
931+ rc = wolfBoot_tpm2_parse_attest (& quoteResult .quoted , & quoteAttest );
932+ }
933+ if (rc == 0 ) {
934+ TPMT_SIGNATURE * sig = & quoteResult .signature ;
935+ printf ("TPM with signature attests (type 0x%x):\n" , quoteAttest .type );
936+ printf ("\tTPM signed %lu count of PCRs\n" ,
937+ (unsigned long )quoteAttest .attested .quote .pcrSelect .count );
938+
939+ printf ("\tPCR digest:\n" );
940+ print_hex (quoteAttest .attested .quote .pcrDigest .buffer ,
941+ quoteAttest .attested .quote .pcrDigest .size , 0 );
942+
943+ printf ("\tTPM generated %s signature:\n" ,
944+ wolfBoot_tpm2_get_alg_name (sig -> sigAlg , algName , sizeof (algName )));
945+ printf ("\tHash algorithm: %s\n" ,
946+ wolfBoot_tpm2_get_alg_name (sig -> signature .any .hashAlg , algName , sizeof (algName )));
947+ switch (sig -> sigAlg ) {
948+ case TPM_ALG_ECDSA :
949+ case TPM_ALG_ECDAA :
950+ printf ("\tR size: %d\n" , sig -> signature .ecdsa .signatureR .size );
951+ print_hex (sig -> signature .ecdsa .signatureR .buffer , sig -> signature .ecdsa .signatureR .size , 0 );
952+ printf ("\tS size: %d\n" , sig -> signature .ecdsa .signatureS .size );
953+ print_hex (sig -> signature .ecdsa .signatureS .buffer , sig -> signature .ecdsa .signatureS .size , 0 );
954+ break ;
955+ case TPM_ALG_RSASSA :
956+ case TPM_ALG_RSAPSS :
957+ printf ("\tSignature size: %d\n" , sig -> signature .rsassa .sig .size );
958+ print_hex (sig -> signature .rsassa .sig .buffer , sig -> signature .rsassa .sig .size , 0 );
959+ break ;
960+ };
961+ }
962+ else {
963+ char error [100 ];
964+ printf ("TPM quote error 0x%x: %s\r\n" , rc ,
965+ wolfBoot_tpm2_get_rc_string (rc , error , sizeof (error )));
966+ }
967+ return rc ;
968+ }
969+ #endif /* WOLFTPM_MFG_IDENTITY */
839970#endif /* WOLFBOOT_TPM */
840971
841972
@@ -965,6 +1096,11 @@ void main(void)
9651096 printf ("Version : 0x%lx\r\n" , app_version );
9661097 printf ("========================\r\n" );
9671098
1099+ cmd_info (NULL );
1100+ #ifdef WOLFBOOT_TPM
1101+ cmd_tpm_info (NULL );
1102+ #endif
1103+
9681104 console_loop ();
9691105
9701106 while (1 )
0 commit comments