@@ -963,4 +963,200 @@ void __stdcall tpm_extend_mbi(uint32_t *mbi)
963963 tpm_hash_extend (DRTM_LOC , DRTM_DATA_PCR , (uint8_t * )mbi , * mbi ,
964964 TXT_EVTYPE_SLAUNCH , NULL , 0 );
965965}
966+ #else
967+ static struct slr_table * slr_get_table (void )
968+ {
969+ struct txt_os_mle_data * os_mle ;
970+ struct slr_table * slrt ;
971+
972+ os_mle = txt_os_mle_data_start (__va (read_txt_reg (TXTCR_HEAP_BASE )));
973+
974+ map_l2 (os_mle -> slrt , PAGE_SIZE );
975+ slrt = __va (os_mle -> slrt );
976+
977+ if ( slrt -> magic != SLR_TABLE_MAGIC )
978+ panic ("SLRT has invalid magic value: %#08x!\n" , slrt -> magic );
979+ /* XXX: are newer revisions allowed? */
980+ if ( slrt -> revision != SLR_TABLE_REVISION )
981+ panic ("SLRT is of unsupported revision: %#04x!\n" , slrt -> revision );
982+ if ( slrt -> architecture != SLR_INTEL_TXT )
983+ panic ("SLRT is for unexpected architecture: %#04x!\n" ,
984+ slrt -> architecture );
985+ if ( slrt -> size > slrt -> max_size )
986+ panic ("SLRT is larger than its max size: %#08x > %#08x!\n" ,
987+ slrt -> size , slrt -> max_size );
988+
989+ if ( slrt -> size > PAGE_SIZE )
990+ map_l2 (os_mle -> slrt , slrt -> size );
991+
992+ return slrt ;
993+ }
994+
995+ void tpm_measure_slrt (void )
996+ {
997+ struct slr_table * slrt = slr_get_table ();
998+
999+ if ( slrt -> revision == 1 ) {
1000+ /* In revision one of the SLRT, only Intel info table is measured. */
1001+ struct slr_entry_intel_info * intel_info =
1002+ (void * )slr_next_entry_by_tag (slrt , NULL , SLR_ENTRY_INTEL_INFO );
1003+ if ( intel_info == NULL )
1004+ panic ("SLRT is missing Intel-specific information!\n" );
1005+
1006+ tpm_hash_extend (DRTM_LOC , DRTM_DATA_PCR , (uint8_t * )intel_info ,
1007+ sizeof (* intel_info ), TXT_EVTYPE_SLAUNCH , NULL , 0 );
1008+ } else {
1009+ /*
1010+ * slr_get_table() checks that the revision is valid, so we must not
1011+ * get here unless the code is wrong.
1012+ */
1013+ panic ("Unhandled SLRT revision: %d!\n" , slrt -> revision );
1014+ }
1015+ }
1016+
1017+ static struct slr_entry_policy * slr_get_policy (struct slr_table * slrt )
1018+ {
1019+ struct slr_entry_policy * policy ;
1020+
1021+ policy = (struct slr_entry_policy * )
1022+ slr_next_entry_by_tag (slrt , NULL , SLR_ENTRY_DRTM_POLICY );
1023+ if (policy == NULL )
1024+ panic ("SLRT is missing DRTM policy!\n" );
1025+
1026+ /* XXX: are newer revisions allowed? */
1027+ if ( policy -> revision != SLR_POLICY_REVISION )
1028+ panic ("DRTM policy in SLRT is of unsupported revision: %#04x!\n" ,
1029+ slrt -> revision );
1030+
1031+ return policy ;
1032+ }
1033+
1034+ static void check_drtm_policy (struct slr_table * slrt ,
1035+ struct slr_entry_policy * policy ,
1036+ struct slr_policy_entry * policy_entry ,
1037+ const multiboot_info_t * mbi )
1038+ {
1039+ uint32_t i ;
1040+ module_t * mods ;
1041+ uint32_t num_mod_entries ;
1042+
1043+ if ( policy -> nr_entries < 2 )
1044+ panic ("DRTM policy in SLRT contains less than 2 entries (%d)!\n" ,
1045+ policy -> nr_entries );
1046+
1047+ /* MBI policy entry must be the first one, so that measuring order matches
1048+ * policy order. */
1049+ if ( policy_entry [0 ].entity_type != SLR_ET_MULTIBOOT2_INFO )
1050+ panic ("First entry of DRTM policy in SLRT is not MBI: %#04x!\n" ,
1051+ policy_entry [0 ].entity_type );
1052+ if ( policy_entry [0 ].pcr != DRTM_DATA_PCR )
1053+ panic ("MBI was measured to %d instead of %d PCR!\n" , DRTM_DATA_PCR ,
1054+ policy_entry [0 ].pcr );
1055+
1056+ /* SLRT policy entry must be the second one. */
1057+ if ( policy_entry [1 ].entity_type != SLR_ET_SLRT )
1058+ panic ("Second entry of DRTM policy in SLRT is not SLRT: %#04x!\n" ,
1059+ policy_entry [1 ].entity_type );
1060+ if ( policy_entry [1 ].pcr != DRTM_DATA_PCR )
1061+ panic ("SLRT was measured to %d instead of %d PCR!\n" , DRTM_DATA_PCR ,
1062+ policy_entry [1 ].pcr );
1063+ if ( policy_entry [1 ].entity != (uint64_t )__pa (slrt ) )
1064+ panic ("SLRT address (%#08lx) differes from its DRTM entry (%#08lx)\n" ,
1065+ __pa (slrt ), policy_entry [1 ].entity );
1066+
1067+ mods = __va (mbi -> mods_addr );
1068+ for ( i = 0 ; i < mbi -> mods_count ; i ++ ) {
1069+ uint16_t j ;
1070+ uint64_t start = mods [i ].mod_start ;
1071+ uint64_t size = mods [i ].mod_end - mods [i ].mod_start ;
1072+
1073+ for ( j = 0 ; j < policy -> nr_entries ; j ++ ) {
1074+ if ( policy_entry [j ].entity_type != SLR_ET_MULTIBOOT2_MODULE )
1075+ continue ;
1076+
1077+ if ( policy_entry [j ].entity == start &&
1078+ policy_entry [j ].size == size )
1079+ break ;
1080+ }
1081+
1082+ if ( j >= policy -> nr_entries ) {
1083+ panic ("Couldn't find Multiboot module \"%s\" (at %d) in DRTM of Secure Launch\n" ,
1084+ (const char * )__va (mods [i ].string ), i );
1085+ }
1086+ }
1087+
1088+ num_mod_entries = 0 ;
1089+ for ( i = 0 ; i < policy -> nr_entries ; i ++ ) {
1090+ if ( policy_entry [i ].entity_type == SLR_ET_MULTIBOOT2_MODULE )
1091+ num_mod_entries ++ ;
1092+ }
1093+
1094+ if ( mbi -> mods_count != num_mod_entries ) {
1095+ panic ("Unexpected number of Multiboot modules: %d instead of %d\n" ,
1096+ (int )mbi -> mods_count , (int )num_mod_entries );
1097+ }
1098+ }
1099+
1100+ void tpm_process_drtm_policy (const multiboot_info_t * mbi )
1101+ {
1102+ struct slr_table * slrt ;
1103+ struct slr_entry_policy * policy ;
1104+ struct slr_policy_entry * policy_entry ;
1105+ uint16_t i ;
1106+
1107+ slrt = slr_get_table ();
1108+
1109+ policy = slr_get_policy (slrt );
1110+ policy_entry = (struct slr_policy_entry * )
1111+ ((uint8_t * )policy + sizeof (* policy ));
1112+
1113+ check_drtm_policy (slrt , policy , policy_entry , mbi );
1114+ /* MBI was measured in tpm_extend_mbi(). */
1115+ policy_entry [0 ].flags |= SLR_POLICY_FLAG_MEASURED ;
1116+ /* SLRT was measured in tpm_measure_slrt(). */
1117+ policy_entry [1 ].flags |= SLR_POLICY_FLAG_MEASURED ;
1118+
1119+ for ( i = 2 ; i < policy -> nr_entries ; i ++ ) {
1120+ uint64_t start = policy_entry [i ].entity ;
1121+ uint64_t size = policy_entry [i ].size ;
1122+
1123+ /* No already measured entries are expected here. */
1124+ if ( policy_entry [i ].flags & SLR_POLICY_FLAG_MEASURED )
1125+ panic ("DRTM entry at %d was measured out of order!\n" , i );
1126+
1127+ switch ( policy_entry [i ].entity_type ) {
1128+ case SLR_ET_MULTIBOOT2_INFO :
1129+ panic ("Duplicated MBI entry in DRTM of Secure Launch at %d\n" , i );
1130+ case SLR_ET_SLRT :
1131+ panic ("Duplicated SLRT entry in DRTM of Secure Launch at %d\n" , i );
1132+
1133+ case SLR_ET_UNSPECIFIED :
1134+ case SLR_ET_BOOT_PARAMS :
1135+ case SLR_ET_SETUP_DATA :
1136+ case SLR_ET_CMDLINE :
1137+ case SLR_ET_UEFI_MEMMAP :
1138+ case SLR_ET_RAMDISK :
1139+ case SLR_ET_MULTIBOOT2_MODULE :
1140+ case SLR_ET_TXT_OS2MLE :
1141+ /* Measure this entry below. */
1142+ break ;
1143+
1144+ case SLR_ET_UNUSED :
1145+ /* Skip this entry. */
1146+ continue ;
1147+ }
1148+
1149+ if ( policy_entry [i ].flags & SLR_POLICY_IMPLICIT_SIZE )
1150+ panic ("Unexpected implicitly-sized DRTM entry of Secure Launch at %d\n" ,
1151+ i );
1152+
1153+ map_l2 (start , size );
1154+ tpm_hash_extend (DRTM_LOC , policy_entry [i ].pcr , __va (start ), size ,
1155+ TXT_EVTYPE_SLAUNCH , (uint8_t * )policy_entry [i ].evt_info ,
1156+ strnlen (policy_entry [i ].evt_info ,
1157+ TPM_EVENT_INFO_LENGTH ));
1158+
1159+ policy_entry [i ].flags |= SLR_POLICY_FLAG_MEASURED ;
1160+ }
1161+ }
9661162#endif
0 commit comments