@@ -539,6 +539,44 @@ struct tpm2_log_hashes {
539539 struct tpm2_log_hash hashes [MAX_HASH_COUNT ];
540540};
541541
542+ struct tpm2_pcr_event_header {
543+ uint32_t pcrIndex ;
544+ uint32_t eventType ;
545+ uint32_t digestCount ;
546+ uint8_t digests [0 ];
547+ /*
548+ * Each hash is represented as:
549+ * struct {
550+ * uint16_t hashAlg;
551+ * uint8_t hash[size of hashAlg];
552+ * };
553+ */
554+ /* uint32_t eventSize; */
555+ /* uint8_t event[0]; */
556+ } __packed ;
557+
558+ struct tpm2_digest_sizes {
559+ uint16_t algId ;
560+ uint16_t digestSize ;
561+ } __packed ;
562+
563+ struct tpm2_spec_id_event {
564+ uint32_t pcrIndex ;
565+ uint32_t eventType ;
566+ uint8_t digest [20 ];
567+ uint32_t eventSize ;
568+ uint8_t signature [16 ];
569+ uint32_t platformClass ;
570+ uint8_t specVersionMinor ;
571+ uint8_t specVersionMajor ;
572+ uint8_t specErrata ;
573+ uint8_t uintnSize ;
574+ uint32_t digestCount ;
575+ struct tpm2_digest_sizes digestSizes [0 ]; /* variable number of members */
576+ /* uint8_t vendorInfoSize; */
577+ /* uint8_t vendorInfo[vendorInfoSize]; */
578+ } __packed ;
579+
542580#ifdef __EARLY_TPM__
543581
544582union tpm2_cmd_rsp {
@@ -759,15 +797,12 @@ static uint32_t tpm2_hash_extend(unsigned loc, uint8_t *buf, unsigned size,
759797 continue ;
760798 }
761799
762- if ( hash -> alg == TPM_ALG_SHA1 ) {
800+ if ( hash -> alg == TPM_ALG_SHA1 )
763801 sha1_hash (buf , size , hash -> data );
764- } else if ( hash -> alg == TPM_ALG_SHA256 ) {
802+ else if ( hash -> alg == TPM_ALG_SHA256 )
765803 sha256_hash (buf , size , hash -> data );
766- } else {
767- /* This is called "OneDigest" in TXT Software Development Guide. */
768- memset (hash -> data , 0 , size );
769- hash -> data [0 ] = 1 ;
770- }
804+ else
805+ /* create_log_event20() took care of initializing the digest. */ ;
771806
772807 if ( supported_hashes .count == MAX_HASH_COUNT ) {
773808 printk (XENLOG_ERR "Hit hash count implementation limit: %d\n" ,
@@ -787,6 +822,99 @@ static uint32_t tpm2_hash_extend(unsigned loc, uint8_t *buf, unsigned size,
787822
788823#endif /* __EARLY_TPM__ */
789824
825+ static struct heap_event_log_pointer_element2_1 * find_evt_log_ext_data (void )
826+ {
827+ struct txt_os_sinit_data * os_sinit ;
828+ struct txt_ext_data_element * ext_data ;
829+
830+ os_sinit = txt_os_sinit_data_start (__va (read_txt_reg (TXTCR_HEAP_BASE )));
831+ ext_data = (void * )((uint8_t * )os_sinit + sizeof (* os_sinit ));
832+
833+ /*
834+ * Find TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1 which is necessary to
835+ * know where to put the next entry.
836+ */
837+ while ( ext_data -> type != TXT_HEAP_EXTDATA_TYPE_END ) {
838+ if ( ext_data -> type == TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1 )
839+ break ;
840+ ext_data = (void * )& ext_data -> data [ext_data -> size ];
841+ }
842+
843+ if ( ext_data -> type == TXT_HEAP_EXTDATA_TYPE_END )
844+ return NULL ;
845+
846+ return (void * )& ext_data -> data [0 ];
847+ }
848+
849+ static struct tpm2_log_hashes
850+ create_log_event20 (struct tpm2_spec_id_event * evt_log , uint32_t evt_log_size ,
851+ uint32_t pcr , uint32_t type , uint8_t * data ,
852+ unsigned data_size )
853+ {
854+ struct tpm2_log_hashes log_hashes = {0 };
855+
856+ struct heap_event_log_pointer_element2_1 * log_ext_data ;
857+ struct tpm2_pcr_event_header * new_entry ;
858+ uint32_t entry_size ;
859+ unsigned i ;
860+ uint8_t * p ;
861+
862+ log_ext_data = find_evt_log_ext_data ();
863+ if ( log_ext_data == NULL )
864+ return log_hashes ;
865+
866+ entry_size = sizeof (* new_entry );
867+ for ( i = 0 ; i < evt_log -> digestCount ; ++ i ) {
868+ entry_size += sizeof (uint16_t ); /* hash type */
869+ entry_size += evt_log -> digestSizes [i ].digestSize ;
870+ }
871+ entry_size += sizeof (uint32_t ); /* data size field */
872+ entry_size += data_size ;
873+
874+ /*
875+ * Check if there is enough space left for new entry.
876+ * Note: it is possible to introduce a gap in event log if entry with big
877+ * data_size is followed by another entry with smaller data. Maybe we should
878+ * cap the event log size in such case?
879+ */
880+ if ( log_ext_data -> next_record_offset + entry_size > evt_log_size )
881+ return log_hashes ;
882+
883+ new_entry = (void * )((uint8_t * )evt_log + log_ext_data -> next_record_offset );
884+ log_ext_data -> next_record_offset += entry_size ;
885+
886+ new_entry -> pcrIndex = pcr ;
887+ new_entry -> eventType = type ;
888+ new_entry -> digestCount = evt_log -> digestCount ;
889+
890+ p = & new_entry -> digests [0 ];
891+ for ( i = 0 ; i < evt_log -> digestCount ; ++ i ) {
892+ uint16_t alg = evt_log -> digestSizes [i ].algId ;
893+ uint16_t size = evt_log -> digestSizes [i ].digestSize ;
894+
895+ * (uint16_t * )p = alg ;
896+ p += sizeof (uint16_t );
897+
898+ log_hashes .hashes [i ].alg = alg ;
899+ log_hashes .hashes [i ].size = size ;
900+ log_hashes .hashes [i ].data = p ;
901+ p += size ;
902+
903+ /* This is called "OneDigest" in TXT Software Development Guide. */
904+ memset (log_hashes .hashes [i ].data , 0 , size );
905+ log_hashes .hashes [i ].data [0 ] = 1 ;
906+ }
907+ log_hashes .count = evt_log -> digestCount ;
908+
909+ * (uint32_t * )p = data_size ;
910+ p += sizeof (uint32_t );
911+
912+ if ( data && data_size > 0 )
913+ memcpy (p , data , data_size );
914+
915+ return log_hashes ;
916+ }
917+
790918/************************** end of TPM2.0 specific ****************************/
791919
792920void tpm_hash_extend (unsigned loc , unsigned pcr , uint8_t * buf , unsigned size ,
@@ -811,25 +939,12 @@ void tpm_hash_extend(unsigned loc, unsigned pcr, uint8_t *buf, unsigned size,
811939
812940 tpm12_hash_extend (loc , buf , size , pcr , entry_digest );
813941 } else {
814- uint8_t sha1_digest [SHA1_DIGEST_SIZE ];
815- uint8_t sha256_digest [SHA256_DIGEST_SIZE ];
816942 uint32_t rc ;
817943
818- struct tpm2_log_hashes log_hashes = {
819- .count = 2 ,
820- .hashes = {
821- {
822- .alg = TPM_ALG_SHA1 ,
823- .size = SHA1_DIGEST_SIZE ,
824- .data = sha1_digest ,
825- },
826- {
827- .alg = TPM_ALG_SHA256 ,
828- .size = SHA256_DIGEST_SIZE ,
829- .data = sha256_digest ,
830- },
831- },
832- };
944+ struct tpm2_spec_id_event * evt_log = evt_log_addr ;
945+ struct tpm2_log_hashes log_hashes =
946+ create_log_event20 (evt_log , evt_log_size , pcr , type , log_data ,
947+ log_data_size );
833948
834949 rc = tpm2_hash_extend (loc , buf , size , pcr , & log_hashes );
835950 if ( rc != 0 ) {
0 commit comments