Tcg2Dxe.c 94 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700
  1. /** @file
  2. This module implements Tcg2 Protocol.
  3. Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
  4. (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <PiDxe.h>
  8. #include <IndustryStandard/Acpi.h>
  9. #include <IndustryStandard/PeImage.h>
  10. #include <IndustryStandard/TcpaAcpi.h>
  11. #include <Guid/GlobalVariable.h>
  12. #include <Guid/HobList.h>
  13. #include <Guid/TcgEventHob.h>
  14. #include <Guid/EventGroup.h>
  15. #include <Guid/EventExitBootServiceFailed.h>
  16. #include <Guid/ImageAuthentication.h>
  17. #include <Guid/TpmInstance.h>
  18. #include <Protocol/DevicePath.h>
  19. #include <Protocol/MpService.h>
  20. #include <Protocol/VariableWrite.h>
  21. #include <Protocol/Tcg2Protocol.h>
  22. #include <Protocol/TrEEProtocol.h>
  23. #include <Protocol/ResetNotification.h>
  24. #include <Library/DebugLib.h>
  25. #include <Library/BaseMemoryLib.h>
  26. #include <Library/UefiRuntimeServicesTableLib.h>
  27. #include <Library/UefiDriverEntryPoint.h>
  28. #include <Library/HobLib.h>
  29. #include <Library/UefiBootServicesTableLib.h>
  30. #include <Library/BaseLib.h>
  31. #include <Library/MemoryAllocationLib.h>
  32. #include <Library/PrintLib.h>
  33. #include <Library/Tpm2CommandLib.h>
  34. #include <Library/PcdLib.h>
  35. #include <Library/UefiLib.h>
  36. #include <Library/Tpm2DeviceLib.h>
  37. #include <Library/HashLib.h>
  38. #include <Library/PerformanceLib.h>
  39. #include <Library/ReportStatusCodeLib.h>
  40. #include <Library/Tcg2PhysicalPresenceLib.h>
  41. #define PERF_ID_TCG2_DXE 0x3120
  42. typedef struct {
  43. CHAR16 *VariableName;
  44. EFI_GUID *VendorGuid;
  45. } VARIABLE_TYPE;
  46. #define TCG2_DEFAULT_MAX_COMMAND_SIZE 0x1000
  47. #define TCG2_DEFAULT_MAX_RESPONSE_SIZE 0x1000
  48. typedef struct {
  49. EFI_GUID *EventGuid;
  50. EFI_TCG2_EVENT_LOG_FORMAT LogFormat;
  51. } TCG2_EVENT_INFO_STRUCT;
  52. TCG2_EVENT_INFO_STRUCT mTcg2EventInfo[] = {
  53. {&gTcgEventEntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2},
  54. {&gTcgEvent2EntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2},
  55. };
  56. #define TCG_EVENT_LOG_AREA_COUNT_MAX 2
  57. typedef struct {
  58. EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat;
  59. EFI_PHYSICAL_ADDRESS Lasa;
  60. UINT64 Laml;
  61. UINTN EventLogSize;
  62. UINT8 *LastEvent;
  63. BOOLEAN EventLogStarted;
  64. BOOLEAN EventLogTruncated;
  65. } TCG_EVENT_LOG_AREA_STRUCT;
  66. typedef struct _TCG_DXE_DATA {
  67. EFI_TCG2_BOOT_SERVICE_CAPABILITY BsCap;
  68. TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];
  69. BOOLEAN GetEventLogCalled[TCG_EVENT_LOG_AREA_COUNT_MAX];
  70. TCG_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];
  71. EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable[TCG_EVENT_LOG_AREA_COUNT_MAX];
  72. } TCG_DXE_DATA;
  73. TCG_DXE_DATA mTcgDxeData = {
  74. {
  75. sizeof (EFI_TCG2_BOOT_SERVICE_CAPABILITY), // Size
  76. { 1, 1 }, // StructureVersion
  77. { 1, 1 }, // ProtocolVersion
  78. EFI_TCG2_BOOT_HASH_ALG_SHA1, // HashAlgorithmBitmap
  79. EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2, // SupportedEventLogs
  80. TRUE, // TPMPresentFlag
  81. TCG2_DEFAULT_MAX_COMMAND_SIZE, // MaxCommandSize
  82. TCG2_DEFAULT_MAX_RESPONSE_SIZE, // MaxResponseSize
  83. 0, // ManufacturerID
  84. 0, // NumberOfPCRBanks
  85. 0, // ActivePcrBanks
  86. },
  87. };
  88. UINTN mBootAttempts = 0;
  89. CHAR16 mBootVarName[] = L"BootOrder";
  90. VARIABLE_TYPE mVariableType[] = {
  91. {EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid},
  92. {EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid},
  93. {EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid},
  94. {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},
  95. {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},
  96. };
  97. EFI_HANDLE mImageHandle;
  98. /**
  99. Measure PE image into TPM log based on the authenticode image hashing in
  100. PE/COFF Specification 8.0 Appendix A.
  101. Caution: This function may receive untrusted input.
  102. PE/COFF image is external input, so this function will validate its data structure
  103. within this image buffer before use.
  104. Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().
  105. @param[in] PCRIndex TPM PCR index
  106. @param[in] ImageAddress Start address of image buffer.
  107. @param[in] ImageSize Image size
  108. @param[out] DigestList Digest list of this image.
  109. @retval EFI_SUCCESS Successfully measure image.
  110. @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
  111. @retval other error value
  112. **/
  113. EFI_STATUS
  114. MeasurePeImageAndExtend (
  115. IN UINT32 PCRIndex,
  116. IN EFI_PHYSICAL_ADDRESS ImageAddress,
  117. IN UINTN ImageSize,
  118. OUT TPML_DIGEST_VALUES *DigestList
  119. );
  120. /**
  121. This function dump raw data.
  122. @param Data raw data
  123. @param Size raw data size
  124. **/
  125. VOID
  126. InternalDumpData (
  127. IN UINT8 *Data,
  128. IN UINTN Size
  129. )
  130. {
  131. UINTN Index;
  132. for (Index = 0; Index < Size; Index++) {
  133. DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index]));
  134. }
  135. }
  136. /**
  137. This function initialize TCG_PCR_EVENT2_HDR for EV_NO_ACTION Event Type other than EFI Specification ID event
  138. The behavior is defined by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types
  139. @param[in, out] NoActionEvent Event Header of EV_NO_ACTION Event
  140. @param[in] EventSize Event Size of the EV_NO_ACTION Event
  141. **/
  142. VOID
  143. InitNoActionEvent (
  144. IN OUT TCG_PCR_EVENT2_HDR *NoActionEvent,
  145. IN UINT32 EventSize
  146. )
  147. {
  148. UINT32 DigestListCount;
  149. TPMI_ALG_HASH HashAlgId;
  150. UINT8 *DigestBuffer;
  151. DigestBuffer = (UINT8 *)NoActionEvent->Digests.digests;
  152. DigestListCount = 0;
  153. NoActionEvent->PCRIndex = 0;
  154. NoActionEvent->EventType = EV_NO_ACTION;
  155. //
  156. // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0
  157. //
  158. ZeroMem (&NoActionEvent->Digests, sizeof(NoActionEvent->Digests));
  159. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
  160. HashAlgId = TPM_ALG_SHA1;
  161. CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
  162. DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
  163. DigestListCount++;
  164. }
  165. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
  166. HashAlgId = TPM_ALG_SHA256;
  167. CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
  168. DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
  169. DigestListCount++;
  170. }
  171. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
  172. HashAlgId = TPM_ALG_SHA384;
  173. CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
  174. DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
  175. DigestListCount++;
  176. }
  177. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
  178. HashAlgId = TPM_ALG_SHA512;
  179. CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
  180. DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
  181. DigestListCount++;
  182. }
  183. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
  184. HashAlgId = TPM_ALG_SM3_256;
  185. CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
  186. DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
  187. DigestListCount++;
  188. }
  189. //
  190. // Set Digests Count
  191. //
  192. WriteUnaligned32 ((UINT32 *)&NoActionEvent->Digests.count, DigestListCount);
  193. //
  194. // Set Event Size
  195. //
  196. WriteUnaligned32((UINT32 *)DigestBuffer, EventSize);
  197. }
  198. /**
  199. This function dump raw data with colume format.
  200. @param Data raw data
  201. @param Size raw data size
  202. **/
  203. VOID
  204. InternalDumpHex (
  205. IN UINT8 *Data,
  206. IN UINTN Size
  207. )
  208. {
  209. UINTN Index;
  210. UINTN Count;
  211. UINTN Left;
  212. #define COLUME_SIZE (16 * 2)
  213. Count = Size / COLUME_SIZE;
  214. Left = Size % COLUME_SIZE;
  215. for (Index = 0; Index < Count; Index++) {
  216. DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));
  217. InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);
  218. DEBUG ((EFI_D_INFO, "\n"));
  219. }
  220. if (Left != 0) {
  221. DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));
  222. InternalDumpData (Data + Index * COLUME_SIZE, Left);
  223. DEBUG ((EFI_D_INFO, "\n"));
  224. }
  225. }
  226. /**
  227. Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
  228. Caller is responsible to free LocationBuf.
  229. @param[out] LocationBuf Returns Processor Location Buffer.
  230. @param[out] Num Returns processor number.
  231. @retval EFI_SUCCESS Operation completed successfully.
  232. @retval EFI_UNSUPPORTED MpService protocol not found.
  233. **/
  234. EFI_STATUS
  235. GetProcessorsCpuLocation (
  236. OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf,
  237. OUT UINTN *Num
  238. )
  239. {
  240. EFI_STATUS Status;
  241. EFI_MP_SERVICES_PROTOCOL *MpProtocol;
  242. UINTN ProcessorNum;
  243. UINTN EnabledProcessorNum;
  244. EFI_PROCESSOR_INFORMATION ProcessorInfo;
  245. EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
  246. UINTN Index;
  247. Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol);
  248. if (EFI_ERROR (Status)) {
  249. //
  250. // MP protocol is not installed
  251. //
  252. return EFI_UNSUPPORTED;
  253. }
  254. Status = MpProtocol->GetNumberOfProcessors(
  255. MpProtocol,
  256. &ProcessorNum,
  257. &EnabledProcessorNum
  258. );
  259. if (EFI_ERROR(Status)){
  260. return Status;
  261. }
  262. Status = gBS->AllocatePool(
  263. EfiBootServicesData,
  264. sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
  265. (VOID **) &ProcessorLocBuf
  266. );
  267. if (EFI_ERROR(Status)){
  268. return Status;
  269. }
  270. //
  271. // Get each processor Location info
  272. //
  273. for (Index = 0; Index < ProcessorNum; Index++) {
  274. Status = MpProtocol->GetProcessorInfo(
  275. MpProtocol,
  276. Index,
  277. &ProcessorInfo
  278. );
  279. if (EFI_ERROR(Status)){
  280. FreePool(ProcessorLocBuf);
  281. return Status;
  282. }
  283. //
  284. // Get all Processor Location info & measure
  285. //
  286. CopyMem(
  287. &ProcessorLocBuf[Index],
  288. &ProcessorInfo.Location,
  289. sizeof(EFI_CPU_PHYSICAL_LOCATION)
  290. );
  291. }
  292. *LocationBuf = ProcessorLocBuf;
  293. *Num = ProcessorNum;
  294. return Status;
  295. }
  296. /**
  297. The EFI_TCG2_PROTOCOL GetCapability function call provides protocol
  298. capability information and state information.
  299. @param[in] This Indicates the calling context
  300. @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY
  301. structure and sets the size field to the size of the structure allocated.
  302. The callee fills in the fields with the EFI protocol capability information
  303. and the current EFI TCG2 state information up to the number of fields which
  304. fit within the size of the structure passed in.
  305. @retval EFI_SUCCESS Operation completed successfully.
  306. @retval EFI_DEVICE_ERROR The command was unsuccessful.
  307. The ProtocolCapability variable will not be populated.
  308. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
  309. The ProtocolCapability variable will not be populated.
  310. @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
  311. It will be partially populated (required Size field will be set).
  312. **/
  313. EFI_STATUS
  314. EFIAPI
  315. Tcg2GetCapability (
  316. IN EFI_TCG2_PROTOCOL *This,
  317. IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability
  318. )
  319. {
  320. DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability ...\n"));
  321. if ((This == NULL) || (ProtocolCapability == NULL)) {
  322. return EFI_INVALID_PARAMETER;
  323. }
  324. DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size));
  325. DEBUG ((DEBUG_VERBOSE, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));
  326. if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) {
  327. //
  328. // Handle the case that firmware support 1.1 but OS only support 1.0.
  329. //
  330. if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) ||
  331. ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) {
  332. if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) {
  333. CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0));
  334. ProtocolCapability->Size = sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0);
  335. ProtocolCapability->StructureVersion.Major = 1;
  336. ProtocolCapability->StructureVersion.Minor = 0;
  337. ProtocolCapability->ProtocolVersion.Major = 1;
  338. ProtocolCapability->ProtocolVersion.Minor = 0;
  339. DEBUG ((EFI_D_ERROR, "TreeGetCapability (Compatible) - %r\n", EFI_SUCCESS));
  340. return EFI_SUCCESS;
  341. }
  342. }
  343. ProtocolCapability->Size = mTcgDxeData.BsCap.Size;
  344. return EFI_BUFFER_TOO_SMALL;
  345. }
  346. CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size);
  347. DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability - %r\n", EFI_SUCCESS));
  348. return EFI_SUCCESS;
  349. }
  350. /**
  351. This function dump PCR event.
  352. @param[in] EventHdr TCG PCR event structure.
  353. **/
  354. VOID
  355. DumpEvent (
  356. IN TCG_PCR_EVENT_HDR *EventHdr
  357. )
  358. {
  359. UINTN Index;
  360. DEBUG ((EFI_D_INFO, " Event:\n"));
  361. DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", EventHdr->PCRIndex));
  362. DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", EventHdr->EventType));
  363. DEBUG ((EFI_D_INFO, " Digest - "));
  364. for (Index = 0; Index < sizeof(TCG_DIGEST); Index++) {
  365. DEBUG ((EFI_D_INFO, "%02x ", EventHdr->Digest.digest[Index]));
  366. }
  367. DEBUG ((EFI_D_INFO, "\n"));
  368. DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventHdr->EventSize));
  369. InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize);
  370. }
  371. /**
  372. This function dump TCG_EfiSpecIDEventStruct.
  373. @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
  374. **/
  375. VOID
  376. DumpTcgEfiSpecIdEventStruct (
  377. IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct
  378. )
  379. {
  380. TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
  381. UINTN Index;
  382. UINT8 *VendorInfoSize;
  383. UINT8 *VendorInfo;
  384. UINT32 NumberOfAlgorithms;
  385. DEBUG ((EFI_D_INFO, " TCG_EfiSpecIDEventStruct:\n"));
  386. DEBUG ((EFI_D_INFO, " signature - '"));
  387. for (Index = 0; Index < sizeof(TcgEfiSpecIdEventStruct->signature); Index++) {
  388. DEBUG ((EFI_D_INFO, "%c", TcgEfiSpecIdEventStruct->signature[Index]));
  389. }
  390. DEBUG ((EFI_D_INFO, "'\n"));
  391. DEBUG ((EFI_D_INFO, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct->platformClass));
  392. DEBUG ((EFI_D_INFO, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct->specVersionMajor, TcgEfiSpecIdEventStruct->specVersionMinor, TcgEfiSpecIdEventStruct->specErrata));
  393. DEBUG ((EFI_D_INFO, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct->uintnSize));
  394. CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(NumberOfAlgorithms));
  395. DEBUG ((EFI_D_INFO, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms));
  396. DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));
  397. for (Index = 0; Index < NumberOfAlgorithms; Index++) {
  398. DEBUG ((EFI_D_INFO, " digest(%d)\n", Index));
  399. DEBUG ((EFI_D_INFO, " algorithmId - 0x%04x\n", DigestSize[Index].algorithmId));
  400. DEBUG ((EFI_D_INFO, " digestSize - 0x%04x\n", DigestSize[Index].digestSize));
  401. }
  402. VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];
  403. DEBUG ((EFI_D_INFO, " VendorInfoSize - 0x%02x\n", *VendorInfoSize));
  404. VendorInfo = VendorInfoSize + 1;
  405. DEBUG ((EFI_D_INFO, " VendorInfo - "));
  406. for (Index = 0; Index < *VendorInfoSize; Index++) {
  407. DEBUG ((EFI_D_INFO, "%02x ", VendorInfo[Index]));
  408. }
  409. DEBUG ((EFI_D_INFO, "\n"));
  410. }
  411. /**
  412. This function get size of TCG_EfiSpecIDEventStruct.
  413. @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
  414. **/
  415. UINTN
  416. GetTcgEfiSpecIdEventStructSize (
  417. IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct
  418. )
  419. {
  420. TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
  421. UINT8 *VendorInfoSize;
  422. UINT32 NumberOfAlgorithms;
  423. CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(NumberOfAlgorithms));
  424. DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));
  425. VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];
  426. return sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (NumberOfAlgorithms * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8) + (*VendorInfoSize);
  427. }
  428. /**
  429. This function dump PCR event 2.
  430. @param[in] TcgPcrEvent2 TCG PCR event 2 structure.
  431. **/
  432. VOID
  433. DumpEvent2 (
  434. IN TCG_PCR_EVENT2 *TcgPcrEvent2
  435. )
  436. {
  437. UINTN Index;
  438. UINT32 DigestIndex;
  439. UINT32 DigestCount;
  440. TPMI_ALG_HASH HashAlgo;
  441. UINT32 DigestSize;
  442. UINT8 *DigestBuffer;
  443. UINT32 EventSize;
  444. UINT8 *EventBuffer;
  445. DEBUG ((EFI_D_INFO, " Event:\n"));
  446. DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", TcgPcrEvent2->PCRIndex));
  447. DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", TcgPcrEvent2->EventType));
  448. DEBUG ((EFI_D_INFO, " DigestCount: 0x%08x\n", TcgPcrEvent2->Digest.count));
  449. DigestCount = TcgPcrEvent2->Digest.count;
  450. HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;
  451. DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;
  452. for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {
  453. DEBUG ((EFI_D_INFO, " HashAlgo : 0x%04x\n", HashAlgo));
  454. DEBUG ((EFI_D_INFO, " Digest(%d): ", DigestIndex));
  455. DigestSize = GetHashSizeFromAlgo (HashAlgo);
  456. for (Index = 0; Index < DigestSize; Index++) {
  457. DEBUG ((EFI_D_INFO, "%02x ", DigestBuffer[Index]));
  458. }
  459. DEBUG ((EFI_D_INFO, "\n"));
  460. //
  461. // Prepare next
  462. //
  463. CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH));
  464. DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH);
  465. }
  466. DEBUG ((EFI_D_INFO, "\n"));
  467. DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH);
  468. CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize));
  469. DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventSize));
  470. EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);
  471. InternalDumpHex (EventBuffer, EventSize);
  472. }
  473. /**
  474. This function returns size of TCG PCR event 2.
  475. @param[in] TcgPcrEvent2 TCG PCR event 2 structure.
  476. @return size of TCG PCR event 2.
  477. **/
  478. UINTN
  479. GetPcrEvent2Size (
  480. IN TCG_PCR_EVENT2 *TcgPcrEvent2
  481. )
  482. {
  483. UINT32 DigestIndex;
  484. UINT32 DigestCount;
  485. TPMI_ALG_HASH HashAlgo;
  486. UINT32 DigestSize;
  487. UINT8 *DigestBuffer;
  488. UINT32 EventSize;
  489. UINT8 *EventBuffer;
  490. DigestCount = TcgPcrEvent2->Digest.count;
  491. HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;
  492. DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;
  493. for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {
  494. DigestSize = GetHashSizeFromAlgo (HashAlgo);
  495. //
  496. // Prepare next
  497. //
  498. CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH));
  499. DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH);
  500. }
  501. DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH);
  502. CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize));
  503. EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);
  504. return (UINTN)EventBuffer + EventSize - (UINTN)TcgPcrEvent2;
  505. }
  506. /**
  507. This function dump event log.
  508. @param[in] EventLogFormat The type of the event log for which the information is requested.
  509. @param[in] EventLogLocation A pointer to the memory address of the event log.
  510. @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
  511. address of the start of the last entry in the event log in memory.
  512. @param[in] FinalEventsTable A pointer to the memory address of the final event table.
  513. **/
  514. VOID
  515. DumpEventLog (
  516. IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
  517. IN EFI_PHYSICAL_ADDRESS EventLogLocation,
  518. IN EFI_PHYSICAL_ADDRESS EventLogLastEntry,
  519. IN EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable
  520. )
  521. {
  522. TCG_PCR_EVENT_HDR *EventHdr;
  523. TCG_PCR_EVENT2 *TcgPcrEvent2;
  524. TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
  525. UINTN NumberOfEvents;
  526. DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));
  527. switch (EventLogFormat) {
  528. case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
  529. EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;
  530. while ((UINTN)EventHdr <= EventLogLastEntry) {
  531. DumpEvent (EventHdr);
  532. EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);
  533. }
  534. if (FinalEventsTable == NULL) {
  535. DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n"));
  536. } else {
  537. DEBUG ((EFI_D_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));
  538. DEBUG ((EFI_D_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));
  539. DEBUG ((EFI_D_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));
  540. EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)(FinalEventsTable + 1);
  541. for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {
  542. DumpEvent (EventHdr);
  543. EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);
  544. }
  545. }
  546. break;
  547. case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
  548. //
  549. // Dump first event
  550. //
  551. EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;
  552. DumpEvent (EventHdr);
  553. TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)(EventHdr + 1);
  554. DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct);
  555. TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgEfiSpecIdEventStruct + GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct));
  556. while ((UINTN)TcgPcrEvent2 <= EventLogLastEntry) {
  557. DumpEvent2 (TcgPcrEvent2);
  558. TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));
  559. }
  560. if (FinalEventsTable == NULL) {
  561. DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n"));
  562. } else {
  563. DEBUG ((EFI_D_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));
  564. DEBUG ((EFI_D_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));
  565. DEBUG ((EFI_D_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));
  566. TcgPcrEvent2 = (TCG_PCR_EVENT2 *)(UINTN)(FinalEventsTable + 1);
  567. for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {
  568. DumpEvent2 (TcgPcrEvent2);
  569. TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));
  570. }
  571. }
  572. break;
  573. }
  574. return ;
  575. }
  576. /**
  577. The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to
  578. retrieve the address of a given event log and its last entry.
  579. @param[in] This Indicates the calling context
  580. @param[in] EventLogFormat The type of the event log for which the information is requested.
  581. @param[out] EventLogLocation A pointer to the memory address of the event log.
  582. @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
  583. address of the start of the last entry in the event log in memory.
  584. @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
  585. have exceeded the area allocated for events, this value is set to TRUE.
  586. Otherwise, the value will be FALSE and the Event Log will be complete.
  587. @retval EFI_SUCCESS Operation completed successfully.
  588. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
  589. (e.g. asking for an event log whose format is not supported).
  590. **/
  591. EFI_STATUS
  592. EFIAPI
  593. Tcg2GetEventLog (
  594. IN EFI_TCG2_PROTOCOL *This,
  595. IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
  596. OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
  597. OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,
  598. OUT BOOLEAN *EventLogTruncated
  599. )
  600. {
  601. UINTN Index;
  602. DEBUG ((EFI_D_INFO, "Tcg2GetEventLog ... (0x%x)\n", EventLogFormat));
  603. if (This == NULL) {
  604. return EFI_INVALID_PARAMETER;
  605. }
  606. for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
  607. if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {
  608. break;
  609. }
  610. }
  611. if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) {
  612. return EFI_INVALID_PARAMETER;
  613. }
  614. if ((mTcg2EventInfo[Index].LogFormat & mTcgDxeData.BsCap.SupportedEventLogs) == 0) {
  615. return EFI_INVALID_PARAMETER;
  616. }
  617. if (!mTcgDxeData.BsCap.TPMPresentFlag) {
  618. if (EventLogLocation != NULL) {
  619. *EventLogLocation = 0;
  620. }
  621. if (EventLogLastEntry != NULL) {
  622. *EventLogLastEntry = 0;
  623. }
  624. if (EventLogTruncated != NULL) {
  625. *EventLogTruncated = FALSE;
  626. }
  627. return EFI_SUCCESS;
  628. }
  629. if (EventLogLocation != NULL) {
  630. *EventLogLocation = mTcgDxeData.EventLogAreaStruct[Index].Lasa;
  631. DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLocation - %x)\n", *EventLogLocation));
  632. }
  633. if (EventLogLastEntry != NULL) {
  634. if (!mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted) {
  635. *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;
  636. } else {
  637. *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].LastEvent;
  638. }
  639. DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry));
  640. }
  641. if (EventLogTruncated != NULL) {
  642. *EventLogTruncated = mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated;
  643. DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated));
  644. }
  645. DEBUG ((EFI_D_INFO, "Tcg2GetEventLog - %r\n", EFI_SUCCESS));
  646. // Dump Event Log for debug purpose
  647. if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) {
  648. DumpEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry, mTcgDxeData.FinalEventsTable[Index]);
  649. }
  650. //
  651. // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored
  652. // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.
  653. //
  654. mTcgDxeData.GetEventLogCalled[Index] = TRUE;
  655. return EFI_SUCCESS;
  656. }
  657. /**
  658. Add a new entry to the Event Log.
  659. @param[in, out] EventLogPtr Pointer to the Event Log data.
  660. @param[in, out] LogSize Size of the Event Log.
  661. @param[in] MaxSize Maximum size of the Event Log.
  662. @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
  663. @param[in] NewEventHdrSize New event header size.
  664. @param[in] NewEventData Pointer to the new event data.
  665. @param[in] NewEventSize New event data size.
  666. @retval EFI_SUCCESS The new event log entry was added.
  667. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
  668. **/
  669. EFI_STATUS
  670. TcgCommLogEvent (
  671. IN OUT UINT8 **EventLogPtr,
  672. IN OUT UINTN *LogSize,
  673. IN UINTN MaxSize,
  674. IN VOID *NewEventHdr,
  675. IN UINT32 NewEventHdrSize,
  676. IN UINT8 *NewEventData,
  677. IN UINT32 NewEventSize
  678. )
  679. {
  680. UINTN NewLogSize;
  681. if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) {
  682. return EFI_OUT_OF_RESOURCES;
  683. }
  684. NewLogSize = NewEventHdrSize + NewEventSize;
  685. if (NewLogSize > MAX_ADDRESS - *LogSize) {
  686. return EFI_OUT_OF_RESOURCES;
  687. }
  688. if (NewLogSize + *LogSize > MaxSize) {
  689. DEBUG ((EFI_D_INFO, " MaxSize - 0x%x\n", MaxSize));
  690. DEBUG ((EFI_D_INFO, " NewLogSize - 0x%x\n", NewLogSize));
  691. DEBUG ((EFI_D_INFO, " LogSize - 0x%x\n", *LogSize));
  692. DEBUG ((EFI_D_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));
  693. return EFI_OUT_OF_RESOURCES;
  694. }
  695. *EventLogPtr += *LogSize;
  696. *LogSize += NewLogSize;
  697. CopyMem (*EventLogPtr, NewEventHdr, NewEventHdrSize);
  698. CopyMem (
  699. *EventLogPtr + NewEventHdrSize,
  700. NewEventData,
  701. NewEventSize
  702. );
  703. return EFI_SUCCESS;
  704. }
  705. /**
  706. Add a new entry to the Event Log.
  707. @param[in] EventLogFormat The type of the event log for which the information is requested.
  708. @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
  709. @param[in] NewEventHdrSize New event header size.
  710. @param[in] NewEventData Pointer to the new event data.
  711. @param[in] NewEventSize New event data size.
  712. @retval EFI_SUCCESS The new event log entry was added.
  713. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
  714. **/
  715. EFI_STATUS
  716. TcgDxeLogEvent (
  717. IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
  718. IN VOID *NewEventHdr,
  719. IN UINT32 NewEventHdrSize,
  720. IN UINT8 *NewEventData,
  721. IN UINT32 NewEventSize
  722. )
  723. {
  724. EFI_STATUS Status;
  725. UINTN Index;
  726. TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;
  727. for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
  728. if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {
  729. break;
  730. }
  731. }
  732. if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) {
  733. return EFI_INVALID_PARAMETER;
  734. }
  735. //
  736. // Record to normal event log
  737. //
  738. EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];
  739. if (EventLogAreaStruct->EventLogTruncated) {
  740. return EFI_VOLUME_FULL;
  741. }
  742. EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;
  743. Status = TcgCommLogEvent (
  744. &EventLogAreaStruct->LastEvent,
  745. &EventLogAreaStruct->EventLogSize,
  746. (UINTN)EventLogAreaStruct->Laml,
  747. NewEventHdr,
  748. NewEventHdrSize,
  749. NewEventData,
  750. NewEventSize
  751. );
  752. if (Status == EFI_OUT_OF_RESOURCES) {
  753. EventLogAreaStruct->EventLogTruncated = TRUE;
  754. return EFI_VOLUME_FULL;
  755. } else if (Status == EFI_SUCCESS) {
  756. EventLogAreaStruct->EventLogStarted = TRUE;
  757. }
  758. //
  759. // If GetEventLog is called, record to FinalEventsTable, too.
  760. //
  761. if (mTcgDxeData.GetEventLogCalled[Index]) {
  762. if (mTcgDxeData.FinalEventsTable[Index] == NULL) {
  763. //
  764. // no need for FinalEventsTable
  765. //
  766. return EFI_SUCCESS;
  767. }
  768. EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];
  769. if (EventLogAreaStruct->EventLogTruncated) {
  770. return EFI_VOLUME_FULL;
  771. }
  772. EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;
  773. Status = TcgCommLogEvent (
  774. &EventLogAreaStruct->LastEvent,
  775. &EventLogAreaStruct->EventLogSize,
  776. (UINTN)EventLogAreaStruct->Laml,
  777. NewEventHdr,
  778. NewEventHdrSize,
  779. NewEventData,
  780. NewEventSize
  781. );
  782. if (Status == EFI_OUT_OF_RESOURCES) {
  783. EventLogAreaStruct->EventLogTruncated = TRUE;
  784. return EFI_VOLUME_FULL;
  785. } else if (Status == EFI_SUCCESS) {
  786. EventLogAreaStruct->EventLogStarted = TRUE;
  787. //
  788. // Increase the NumberOfEvents in FinalEventsTable
  789. //
  790. (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;
  791. DEBUG ((EFI_D_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents));
  792. DEBUG ((EFI_D_INFO, " Size - 0x%x\n", (UINTN)EventLogAreaStruct->EventLogSize));
  793. }
  794. }
  795. return Status;
  796. }
  797. /**
  798. Get TPML_DIGEST_VALUES compact binary buffer size.
  799. @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
  800. @return TPML_DIGEST_VALUES compact binary buffer size.
  801. **/
  802. UINT32
  803. GetDigestListBinSize (
  804. IN VOID *DigestListBin
  805. )
  806. {
  807. UINTN Index;
  808. UINT16 DigestSize;
  809. UINT32 TotalSize;
  810. UINT32 Count;
  811. TPMI_ALG_HASH HashAlg;
  812. Count = ReadUnaligned32 (DigestListBin);
  813. TotalSize = sizeof(Count);
  814. DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);
  815. for (Index = 0; Index < Count; Index++) {
  816. HashAlg = ReadUnaligned16 (DigestListBin);
  817. TotalSize += sizeof(HashAlg);
  818. DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);
  819. DigestSize = GetHashSizeFromAlgo (HashAlg);
  820. TotalSize += DigestSize;
  821. DigestListBin = (UINT8 *)DigestListBin + DigestSize;
  822. }
  823. return TotalSize;
  824. }
  825. /**
  826. Copy TPML_DIGEST_VALUES compact binary into a buffer
  827. @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
  828. @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
  829. @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
  830. @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.
  831. @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.
  832. **/
  833. VOID *
  834. CopyDigestListBinToBuffer (
  835. IN OUT VOID *Buffer,
  836. IN VOID *DigestListBin,
  837. IN UINT32 HashAlgorithmMask,
  838. OUT UINT32 *HashAlgorithmMaskCopied
  839. )
  840. {
  841. UINTN Index;
  842. UINT16 DigestSize;
  843. UINT32 Count;
  844. TPMI_ALG_HASH HashAlg;
  845. UINT32 DigestListCount;
  846. UINT32 *DigestListCountPtr;
  847. DigestListCountPtr = (UINT32 *) Buffer;
  848. DigestListCount = 0;
  849. (*HashAlgorithmMaskCopied) = 0;
  850. Count = ReadUnaligned32 (DigestListBin);
  851. Buffer = (UINT8 *)Buffer + sizeof(Count);
  852. DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);
  853. for (Index = 0; Index < Count; Index++) {
  854. HashAlg = ReadUnaligned16 (DigestListBin);
  855. DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);
  856. DigestSize = GetHashSizeFromAlgo (HashAlg);
  857. if (IsHashAlgSupportedInHashAlgorithmMask(HashAlg, HashAlgorithmMask)) {
  858. CopyMem (Buffer, &HashAlg, sizeof(HashAlg));
  859. Buffer = (UINT8 *)Buffer + sizeof(HashAlg);
  860. CopyMem (Buffer, DigestListBin, DigestSize);
  861. Buffer = (UINT8 *)Buffer + DigestSize;
  862. DigestListCount++;
  863. (*HashAlgorithmMaskCopied) |= GetHashMaskFromAlgo (HashAlg);
  864. } else {
  865. DEBUG ((DEBUG_ERROR, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg));
  866. }
  867. DigestListBin = (UINT8 *)DigestListBin + DigestSize;
  868. }
  869. WriteUnaligned32 (DigestListCountPtr, DigestListCount);
  870. return Buffer;
  871. }
  872. /**
  873. Add a new entry to the Event Log.
  874. @param[in] DigestList A list of digest.
  875. @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
  876. @param[in] NewEventData Pointer to the new event data.
  877. @retval EFI_SUCCESS The new event log entry was added.
  878. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
  879. **/
  880. EFI_STATUS
  881. TcgDxeLogHashEvent (
  882. IN TPML_DIGEST_VALUES *DigestList,
  883. IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
  884. IN UINT8 *NewEventData
  885. )
  886. {
  887. EFI_STATUS Status;
  888. EFI_TPL OldTpl;
  889. UINTN Index;
  890. EFI_STATUS RetStatus;
  891. TCG_PCR_EVENT2 TcgPcrEvent2;
  892. UINT8 *DigestBuffer;
  893. UINT32 *EventSizePtr;
  894. DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
  895. RetStatus = EFI_SUCCESS;
  896. for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
  897. if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
  898. DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));
  899. switch (mTcg2EventInfo[Index].LogFormat) {
  900. case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
  901. Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
  902. if (!EFI_ERROR (Status)) {
  903. //
  904. // Enter critical region
  905. //
  906. OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
  907. Status = TcgDxeLogEvent (
  908. mTcg2EventInfo[Index].LogFormat,
  909. NewEventHdr,
  910. sizeof(TCG_PCR_EVENT_HDR),
  911. NewEventData,
  912. NewEventHdr->EventSize
  913. );
  914. if (Status != EFI_SUCCESS) {
  915. RetStatus = Status;
  916. }
  917. gBS->RestoreTPL (OldTpl);
  918. //
  919. // Exit critical region
  920. //
  921. }
  922. break;
  923. case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
  924. ZeroMem (&TcgPcrEvent2, sizeof(TcgPcrEvent2));
  925. TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;
  926. TcgPcrEvent2.EventType = NewEventHdr->EventType;
  927. DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;
  928. EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, mTcgDxeData.BsCap.ActivePcrBanks);
  929. CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));
  930. //
  931. // Enter critical region
  932. //
  933. OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
  934. Status = TcgDxeLogEvent (
  935. mTcg2EventInfo[Index].LogFormat,
  936. &TcgPcrEvent2,
  937. sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof(TcgPcrEvent2.EventSize),
  938. NewEventData,
  939. NewEventHdr->EventSize
  940. );
  941. if (Status != EFI_SUCCESS) {
  942. RetStatus = Status;
  943. }
  944. gBS->RestoreTPL (OldTpl);
  945. //
  946. // Exit critical region
  947. //
  948. break;
  949. }
  950. }
  951. }
  952. return RetStatus;
  953. }
  954. /**
  955. Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
  956. and add an entry to the Event Log.
  957. @param[in] Flags Bitmap providing additional information.
  958. @param[in] HashData Physical address of the start of the data buffer
  959. to be hashed, extended, and logged.
  960. @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
  961. @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
  962. @param[in] NewEventData Pointer to the new event data.
  963. @retval EFI_SUCCESS Operation completed successfully.
  964. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
  965. @retval EFI_DEVICE_ERROR The command was unsuccessful.
  966. **/
  967. EFI_STATUS
  968. TcgDxeHashLogExtendEvent (
  969. IN UINT64 Flags,
  970. IN UINT8 *HashData,
  971. IN UINT64 HashDataLen,
  972. IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
  973. IN UINT8 *NewEventData
  974. )
  975. {
  976. EFI_STATUS Status;
  977. TPML_DIGEST_VALUES DigestList;
  978. if (!mTcgDxeData.BsCap.TPMPresentFlag) {
  979. return EFI_DEVICE_ERROR;
  980. }
  981. Status = HashAndExtend (
  982. NewEventHdr->PCRIndex,
  983. HashData,
  984. (UINTN)HashDataLen,
  985. &DigestList
  986. );
  987. if (!EFI_ERROR (Status)) {
  988. if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
  989. Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
  990. }
  991. }
  992. if (Status == EFI_DEVICE_ERROR) {
  993. DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));
  994. mTcgDxeData.BsCap.TPMPresentFlag = FALSE;
  995. REPORT_STATUS_CODE (
  996. EFI_ERROR_CODE | EFI_ERROR_MINOR,
  997. (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
  998. );
  999. }
  1000. return Status;
  1001. }
  1002. /**
  1003. The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with
  1004. an opportunity to extend and optionally log events without requiring
  1005. knowledge of actual TPM commands.
  1006. The extend operation will occur even if this function cannot create an event
  1007. log entry (e.g. due to the event log being full).
  1008. @param[in] This Indicates the calling context
  1009. @param[in] Flags Bitmap providing additional information.
  1010. @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
  1011. @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
  1012. @param[in] Event Pointer to data buffer containing information about the event.
  1013. @retval EFI_SUCCESS Operation completed successfully.
  1014. @retval EFI_DEVICE_ERROR The command was unsuccessful.
  1015. @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
  1016. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
  1017. @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
  1018. **/
  1019. EFI_STATUS
  1020. EFIAPI
  1021. Tcg2HashLogExtendEvent (
  1022. IN EFI_TCG2_PROTOCOL *This,
  1023. IN UINT64 Flags,
  1024. IN EFI_PHYSICAL_ADDRESS DataToHash,
  1025. IN UINT64 DataToHashLen,
  1026. IN EFI_TCG2_EVENT *Event
  1027. )
  1028. {
  1029. EFI_STATUS Status;
  1030. TCG_PCR_EVENT_HDR NewEventHdr;
  1031. TPML_DIGEST_VALUES DigestList;
  1032. DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));
  1033. if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {
  1034. return EFI_INVALID_PARAMETER;
  1035. }
  1036. if (!mTcgDxeData.BsCap.TPMPresentFlag) {
  1037. return EFI_DEVICE_ERROR;
  1038. }
  1039. if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) {
  1040. return EFI_INVALID_PARAMETER;
  1041. }
  1042. if (Event->Header.PCRIndex > MAX_PCR_INDEX) {
  1043. return EFI_INVALID_PARAMETER;
  1044. }
  1045. NewEventHdr.PCRIndex = Event->Header.PCRIndex;
  1046. NewEventHdr.EventType = Event->Header.EventType;
  1047. NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;
  1048. if ((Flags & PE_COFF_IMAGE) != 0) {
  1049. Status = MeasurePeImageAndExtend (
  1050. NewEventHdr.PCRIndex,
  1051. DataToHash,
  1052. (UINTN)DataToHashLen,
  1053. &DigestList
  1054. );
  1055. if (!EFI_ERROR (Status)) {
  1056. if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
  1057. Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);
  1058. }
  1059. }
  1060. if (Status == EFI_DEVICE_ERROR) {
  1061. DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));
  1062. mTcgDxeData.BsCap.TPMPresentFlag = FALSE;
  1063. REPORT_STATUS_CODE (
  1064. EFI_ERROR_CODE | EFI_ERROR_MINOR,
  1065. (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
  1066. );
  1067. }
  1068. } else {
  1069. Status = TcgDxeHashLogExtendEvent (
  1070. Flags,
  1071. (UINT8 *) (UINTN) DataToHash,
  1072. DataToHashLen,
  1073. &NewEventHdr,
  1074. Event->Event
  1075. );
  1076. }
  1077. DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent - %r\n", Status));
  1078. return Status;
  1079. }
  1080. /**
  1081. This service enables the sending of commands to the TPM.
  1082. @param[in] This Indicates the calling context
  1083. @param[in] InputParameterBlockSize Size of the TPM input parameter block.
  1084. @param[in] InputParameterBlock Pointer to the TPM input parameter block.
  1085. @param[in] OutputParameterBlockSize Size of the TPM output parameter block.
  1086. @param[in] OutputParameterBlock Pointer to the TPM output parameter block.
  1087. @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
  1088. @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
  1089. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
  1090. @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
  1091. **/
  1092. EFI_STATUS
  1093. EFIAPI
  1094. Tcg2SubmitCommand (
  1095. IN EFI_TCG2_PROTOCOL *This,
  1096. IN UINT32 InputParameterBlockSize,
  1097. IN UINT8 *InputParameterBlock,
  1098. IN UINT32 OutputParameterBlockSize,
  1099. IN UINT8 *OutputParameterBlock
  1100. )
  1101. {
  1102. EFI_STATUS Status;
  1103. DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand ...\n"));
  1104. if ((This == NULL) ||
  1105. (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||
  1106. (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) {
  1107. return EFI_INVALID_PARAMETER;
  1108. }
  1109. if (!mTcgDxeData.BsCap.TPMPresentFlag) {
  1110. return EFI_DEVICE_ERROR;
  1111. }
  1112. if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {
  1113. return EFI_INVALID_PARAMETER;
  1114. }
  1115. if (OutputParameterBlockSize > mTcgDxeData.BsCap.MaxResponseSize) {
  1116. return EFI_INVALID_PARAMETER;
  1117. }
  1118. Status = Tpm2SubmitCommand (
  1119. InputParameterBlockSize,
  1120. InputParameterBlock,
  1121. &OutputParameterBlockSize,
  1122. OutputParameterBlock
  1123. );
  1124. DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand - %r\n", Status));
  1125. return Status;
  1126. }
  1127. /**
  1128. This service returns the currently active PCR banks.
  1129. @param[in] This Indicates the calling context
  1130. @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.
  1131. @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.
  1132. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
  1133. **/
  1134. EFI_STATUS
  1135. EFIAPI
  1136. Tcg2GetActivePCRBanks (
  1137. IN EFI_TCG2_PROTOCOL *This,
  1138. OUT UINT32 *ActivePcrBanks
  1139. )
  1140. {
  1141. if (ActivePcrBanks == NULL) {
  1142. return EFI_INVALID_PARAMETER;
  1143. }
  1144. *ActivePcrBanks = mTcgDxeData.BsCap.ActivePcrBanks;
  1145. return EFI_SUCCESS;
  1146. }
  1147. /**
  1148. This service sets the currently active PCR banks.
  1149. @param[in] This Indicates the calling context
  1150. @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.
  1151. @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.
  1152. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
  1153. **/
  1154. EFI_STATUS
  1155. EFIAPI
  1156. Tcg2SetActivePCRBanks (
  1157. IN EFI_TCG2_PROTOCOL *This,
  1158. IN UINT32 ActivePcrBanks
  1159. )
  1160. {
  1161. EFI_STATUS Status;
  1162. UINT32 ReturnCode;
  1163. DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks));
  1164. if (ActivePcrBanks == 0) {
  1165. return EFI_INVALID_PARAMETER;
  1166. }
  1167. if ((ActivePcrBanks & (~mTcgDxeData.BsCap.HashAlgorithmBitmap)) != 0) {
  1168. return EFI_INVALID_PARAMETER;
  1169. }
  1170. if (ActivePcrBanks == mTcgDxeData.BsCap.ActivePcrBanks) {
  1171. //
  1172. // Need clear previous SET_PCR_BANKS setting
  1173. //
  1174. ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION, 0);
  1175. } else {
  1176. ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, ActivePcrBanks);
  1177. }
  1178. if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
  1179. Status = EFI_SUCCESS;
  1180. } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
  1181. Status = EFI_OUT_OF_RESOURCES;
  1182. } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
  1183. Status = EFI_UNSUPPORTED;
  1184. } else {
  1185. Status = EFI_DEVICE_ERROR;
  1186. }
  1187. DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks - %r\n", Status));
  1188. return Status;
  1189. }
  1190. /**
  1191. This service retrieves the result of a previous invocation of SetActivePcrBanks.
  1192. @param[in] This Indicates the calling context
  1193. @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.
  1194. @param[out] Response The response from the SetActivePcrBank request.
  1195. @retval EFI_SUCCESS The result value could be returned.
  1196. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
  1197. **/
  1198. EFI_STATUS
  1199. EFIAPI
  1200. Tcg2GetResultOfSetActivePcrBanks (
  1201. IN EFI_TCG2_PROTOCOL *This,
  1202. OUT UINT32 *OperationPresent,
  1203. OUT UINT32 *Response
  1204. )
  1205. {
  1206. UINT32 ReturnCode;
  1207. if ((OperationPresent == NULL) || (Response == NULL)) {
  1208. return EFI_INVALID_PARAMETER;
  1209. }
  1210. ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);
  1211. if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {
  1212. return EFI_SUCCESS;
  1213. } else {
  1214. return EFI_UNSUPPORTED;
  1215. }
  1216. }
  1217. EFI_TCG2_PROTOCOL mTcg2Protocol = {
  1218. Tcg2GetCapability,
  1219. Tcg2GetEventLog,
  1220. Tcg2HashLogExtendEvent,
  1221. Tcg2SubmitCommand,
  1222. Tcg2GetActivePCRBanks,
  1223. Tcg2SetActivePCRBanks,
  1224. Tcg2GetResultOfSetActivePcrBanks,
  1225. };
  1226. /**
  1227. Initialize the Event Log and log events passed from the PEI phase.
  1228. @retval EFI_SUCCESS Operation completed successfully.
  1229. @retval EFI_OUT_OF_RESOURCES Out of memory.
  1230. **/
  1231. EFI_STATUS
  1232. SetupEventLog (
  1233. VOID
  1234. )
  1235. {
  1236. EFI_STATUS Status;
  1237. VOID *TcgEvent;
  1238. EFI_PEI_HOB_POINTERS GuidHob;
  1239. EFI_PHYSICAL_ADDRESS Lasa;
  1240. UINTN Index;
  1241. VOID *DigestListBin;
  1242. TPML_DIGEST_VALUES TempDigestListBin;
  1243. UINT32 DigestListBinSize;
  1244. UINT8 *Event;
  1245. UINT32 EventSize;
  1246. UINT32 *EventSizePtr;
  1247. UINT32 HashAlgorithmMaskCopied;
  1248. TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
  1249. UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];
  1250. TCG_PCR_EVENT_HDR SpecIdEvent;
  1251. TCG_PCR_EVENT2_HDR NoActionEvent;
  1252. TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
  1253. TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;
  1254. UINT8 *VendorInfoSize;
  1255. UINT32 NumberOfAlgorithms;
  1256. TCG_EfiStartupLocalityEvent StartupLocalityEvent;
  1257. DEBUG ((EFI_D_INFO, "SetupEventLog\n"));
  1258. //
  1259. // 1. Create Log Area
  1260. //
  1261. for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
  1262. if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
  1263. mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
  1264. if (PcdGet8(PcdTpm2AcpiTableRev) >= 4) {
  1265. Status = gBS->AllocatePages (
  1266. AllocateAnyPages,
  1267. EfiACPIMemoryNVS,
  1268. EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
  1269. &Lasa
  1270. );
  1271. } else {
  1272. Status = gBS->AllocatePages (
  1273. AllocateAnyPages,
  1274. EfiBootServicesData,
  1275. EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
  1276. &Lasa
  1277. );
  1278. }
  1279. if (EFI_ERROR (Status)) {
  1280. return Status;
  1281. }
  1282. mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;
  1283. mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);
  1284. if ((PcdGet8(PcdTpm2AcpiTableRev) >= 4) ||
  1285. (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)) {
  1286. //
  1287. // Report TCG2 event log address and length, so that they can be reported in TPM2 ACPI table.
  1288. // Ignore the return status, because those fields are optional.
  1289. //
  1290. PcdSet32S(PcdTpm2AcpiTableLaml, (UINT32)mTcgDxeData.EventLogAreaStruct[Index].Laml);
  1291. PcdSet64S(PcdTpm2AcpiTableLasa, mTcgDxeData.EventLogAreaStruct[Index].Lasa);
  1292. }
  1293. //
  1294. // To initialize them as 0xFF is recommended
  1295. // because the OS can know the last entry for that.
  1296. //
  1297. SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
  1298. //
  1299. // Create first entry for Log Header Entry Data
  1300. //
  1301. if (mTcg2EventInfo[Index].LogFormat != EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {
  1302. //
  1303. // TcgEfiSpecIdEventStruct
  1304. //
  1305. TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;
  1306. CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof(TcgEfiSpecIdEventStruct->signature));
  1307. TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);
  1308. TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;
  1309. TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;
  1310. TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;
  1311. TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);
  1312. NumberOfAlgorithms = 0;
  1313. DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));
  1314. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
  1315. TempDigestSize = DigestSize;
  1316. TempDigestSize += NumberOfAlgorithms;
  1317. TempDigestSize->algorithmId = TPM_ALG_SHA1;
  1318. TempDigestSize->digestSize = SHA1_DIGEST_SIZE;
  1319. NumberOfAlgorithms++;
  1320. }
  1321. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
  1322. TempDigestSize = DigestSize;
  1323. TempDigestSize += NumberOfAlgorithms;
  1324. TempDigestSize->algorithmId = TPM_ALG_SHA256;
  1325. TempDigestSize->digestSize = SHA256_DIGEST_SIZE;
  1326. NumberOfAlgorithms++;
  1327. }
  1328. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
  1329. TempDigestSize = DigestSize;
  1330. TempDigestSize += NumberOfAlgorithms;
  1331. TempDigestSize->algorithmId = TPM_ALG_SHA384;
  1332. TempDigestSize->digestSize = SHA384_DIGEST_SIZE;
  1333. NumberOfAlgorithms++;
  1334. }
  1335. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
  1336. TempDigestSize = DigestSize;
  1337. TempDigestSize += NumberOfAlgorithms;
  1338. TempDigestSize->algorithmId = TPM_ALG_SHA512;
  1339. TempDigestSize->digestSize = SHA512_DIGEST_SIZE;
  1340. NumberOfAlgorithms++;
  1341. }
  1342. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
  1343. TempDigestSize = DigestSize;
  1344. TempDigestSize += NumberOfAlgorithms;
  1345. TempDigestSize->algorithmId = TPM_ALG_SM3_256;
  1346. TempDigestSize->digestSize = SM3_256_DIGEST_SIZE;
  1347. NumberOfAlgorithms++;
  1348. }
  1349. CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof(NumberOfAlgorithms));
  1350. TempDigestSize = DigestSize;
  1351. TempDigestSize += NumberOfAlgorithms;
  1352. VendorInfoSize = (UINT8 *)TempDigestSize;
  1353. *VendorInfoSize = 0;
  1354. SpecIdEvent.PCRIndex = 0;
  1355. SpecIdEvent.EventType = EV_NO_ACTION;
  1356. ZeroMem (&SpecIdEvent.Digest, sizeof(SpecIdEvent.Digest));
  1357. SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);
  1358. //
  1359. // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.
  1360. // TCG EFI Protocol Spec. Section 5.3 Event Log Header
  1361. // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log
  1362. //
  1363. Status = TcgDxeLogEvent (
  1364. mTcg2EventInfo[Index].LogFormat,
  1365. &SpecIdEvent,
  1366. sizeof(SpecIdEvent),
  1367. (UINT8 *)TcgEfiSpecIdEventStruct,
  1368. SpecIdEvent.EventSize
  1369. );
  1370. //
  1371. // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2
  1372. //
  1373. GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);
  1374. if (GuidHob.Guid != NULL) {
  1375. //
  1376. // Get Locality Indicator from StartupLocality HOB
  1377. //
  1378. StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));
  1379. CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));
  1380. DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));
  1381. //
  1382. // Initialize StartupLocalityEvent
  1383. //
  1384. InitNoActionEvent(&NoActionEvent, sizeof(StartupLocalityEvent));
  1385. //
  1386. // Log EfiStartupLocalityEvent as the second Event
  1387. // TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event
  1388. //
  1389. Status = TcgDxeLogEvent (
  1390. mTcg2EventInfo[Index].LogFormat,
  1391. &NoActionEvent,
  1392. sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),
  1393. (UINT8 *)&StartupLocalityEvent,
  1394. sizeof(StartupLocalityEvent)
  1395. );
  1396. }
  1397. }
  1398. }
  1399. }
  1400. //
  1401. // 2. Create Final Log Area
  1402. //
  1403. for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
  1404. if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
  1405. if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
  1406. Status = gBS->AllocatePages (
  1407. AllocateAnyPages,
  1408. EfiACPIMemoryNVS,
  1409. EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),
  1410. &Lasa
  1411. );
  1412. if (EFI_ERROR (Status)) {
  1413. return Status;
  1414. }
  1415. SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);
  1416. //
  1417. // Initialize
  1418. //
  1419. mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;
  1420. (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
  1421. (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;
  1422. mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
  1423. mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
  1424. mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
  1425. mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
  1426. mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;
  1427. mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
  1428. mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
  1429. //
  1430. // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
  1431. //
  1432. Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);
  1433. if (EFI_ERROR (Status)) {
  1434. return Status;
  1435. }
  1436. } else {
  1437. //
  1438. // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
  1439. //
  1440. mTcgDxeData.FinalEventsTable[Index] = NULL;
  1441. mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
  1442. mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;
  1443. mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;
  1444. mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
  1445. mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;
  1446. mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
  1447. mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
  1448. }
  1449. }
  1450. }
  1451. //
  1452. // 3. Sync data from PEI to DXE
  1453. //
  1454. Status = EFI_SUCCESS;
  1455. for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
  1456. if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
  1457. GuidHob.Raw = GetHobList ();
  1458. Status = EFI_SUCCESS;
  1459. while (!EFI_ERROR (Status) &&
  1460. (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {
  1461. TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));
  1462. ASSERT (TcgEvent != NULL);
  1463. GuidHob.Raw = GET_NEXT_HOB (GuidHob);
  1464. switch (mTcg2EventInfo[Index].LogFormat) {
  1465. case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
  1466. Status = TcgDxeLogEvent (
  1467. mTcg2EventInfo[Index].LogFormat,
  1468. TcgEvent,
  1469. sizeof(TCG_PCR_EVENT_HDR),
  1470. ((TCG_PCR_EVENT*)TcgEvent)->Event,
  1471. ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize
  1472. );
  1473. break;
  1474. case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
  1475. DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE);
  1476. DigestListBinSize = GetDigestListBinSize (DigestListBin);
  1477. //
  1478. // Save event size.
  1479. //
  1480. CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof(UINT32));
  1481. Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32);
  1482. //
  1483. // Filter inactive digest in the event2 log from PEI HOB.
  1484. //
  1485. CopyMem (&TempDigestListBin, DigestListBin, GetDigestListBinSize (DigestListBin));
  1486. EventSizePtr = CopyDigestListBinToBuffer (
  1487. DigestListBin,
  1488. &TempDigestListBin,
  1489. mTcgDxeData.BsCap.ActivePcrBanks,
  1490. &HashAlgorithmMaskCopied
  1491. );
  1492. if (HashAlgorithmMaskCopied != mTcgDxeData.BsCap.ActivePcrBanks) {
  1493. DEBUG ((
  1494. DEBUG_ERROR,
  1495. "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",
  1496. HashAlgorithmMaskCopied,
  1497. mTcgDxeData.BsCap.ActivePcrBanks
  1498. ));
  1499. }
  1500. //
  1501. // Restore event size.
  1502. //
  1503. CopyMem (EventSizePtr, &EventSize, sizeof(UINT32));
  1504. DigestListBinSize = GetDigestListBinSize (DigestListBin);
  1505. Status = TcgDxeLogEvent (
  1506. mTcg2EventInfo[Index].LogFormat,
  1507. TcgEvent,
  1508. sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),
  1509. Event,
  1510. EventSize
  1511. );
  1512. break;
  1513. }
  1514. FreePool (TcgEvent);
  1515. }
  1516. }
  1517. }
  1518. return Status;
  1519. }
  1520. /**
  1521. Measure and log an action string, and extend the measurement result into PCR[PCRIndex].
  1522. @param[in] PCRIndex PCRIndex to extend
  1523. @param[in] String A specific string that indicates an Action event.
  1524. @retval EFI_SUCCESS Operation completed successfully.
  1525. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1526. **/
  1527. EFI_STATUS
  1528. TcgMeasureAction (
  1529. IN TPM_PCRINDEX PCRIndex,
  1530. IN CHAR8 *String
  1531. )
  1532. {
  1533. TCG_PCR_EVENT_HDR TcgEvent;
  1534. TcgEvent.PCRIndex = PCRIndex;
  1535. TcgEvent.EventType = EV_EFI_ACTION;
  1536. TcgEvent.EventSize = (UINT32)AsciiStrLen (String);
  1537. return TcgDxeHashLogExtendEvent (
  1538. 0,
  1539. (UINT8*)String,
  1540. TcgEvent.EventSize,
  1541. &TcgEvent,
  1542. (UINT8 *) String
  1543. );
  1544. }
  1545. /**
  1546. Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
  1547. @retval EFI_SUCCESS Operation completed successfully.
  1548. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1549. **/
  1550. EFI_STATUS
  1551. MeasureHandoffTables (
  1552. VOID
  1553. )
  1554. {
  1555. EFI_STATUS Status;
  1556. TCG_PCR_EVENT_HDR TcgEvent;
  1557. EFI_HANDOFF_TABLE_POINTERS HandoffTables;
  1558. UINTN ProcessorNum;
  1559. EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
  1560. ProcessorLocBuf = NULL;
  1561. Status = EFI_SUCCESS;
  1562. if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
  1563. //
  1564. // Tcg Server spec.
  1565. // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
  1566. //
  1567. Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);
  1568. if (!EFI_ERROR(Status)){
  1569. TcgEvent.PCRIndex = 1;
  1570. TcgEvent.EventType = EV_TABLE_OF_DEVICES;
  1571. TcgEvent.EventSize = sizeof (HandoffTables);
  1572. HandoffTables.NumberOfTables = 1;
  1573. HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
  1574. HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
  1575. Status = TcgDxeHashLogExtendEvent (
  1576. 0,
  1577. (UINT8*)(UINTN)ProcessorLocBuf,
  1578. sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
  1579. &TcgEvent,
  1580. (UINT8*)&HandoffTables
  1581. );
  1582. FreePool(ProcessorLocBuf);
  1583. }
  1584. }
  1585. return Status;
  1586. }
  1587. /**
  1588. Measure and log Separator event, and extend the measurement result into a specific PCR.
  1589. @param[in] PCRIndex PCR index.
  1590. @retval EFI_SUCCESS Operation completed successfully.
  1591. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1592. **/
  1593. EFI_STATUS
  1594. MeasureSeparatorEvent (
  1595. IN TPM_PCRINDEX PCRIndex
  1596. )
  1597. {
  1598. TCG_PCR_EVENT_HDR TcgEvent;
  1599. UINT32 EventData;
  1600. DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));
  1601. EventData = 0;
  1602. TcgEvent.PCRIndex = PCRIndex;
  1603. TcgEvent.EventType = EV_SEPARATOR;
  1604. TcgEvent.EventSize = (UINT32)sizeof (EventData);
  1605. return TcgDxeHashLogExtendEvent (
  1606. 0,
  1607. (UINT8 *)&EventData,
  1608. sizeof (EventData),
  1609. &TcgEvent,
  1610. (UINT8 *)&EventData
  1611. );
  1612. }
  1613. /**
  1614. Measure and log an EFI variable, and extend the measurement result into a specific PCR.
  1615. @param[in] PCRIndex PCR Index.
  1616. @param[in] EventType Event type.
  1617. @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
  1618. @param[in] VendorGuid A unique identifier for the vendor.
  1619. @param[in] VarData The content of the variable data.
  1620. @param[in] VarSize The size of the variable data.
  1621. @retval EFI_SUCCESS Operation completed successfully.
  1622. @retval EFI_OUT_OF_RESOURCES Out of memory.
  1623. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1624. **/
  1625. EFI_STATUS
  1626. MeasureVariable (
  1627. IN TPM_PCRINDEX PCRIndex,
  1628. IN TCG_EVENTTYPE EventType,
  1629. IN CHAR16 *VarName,
  1630. IN EFI_GUID *VendorGuid,
  1631. IN VOID *VarData,
  1632. IN UINTN VarSize
  1633. )
  1634. {
  1635. EFI_STATUS Status;
  1636. TCG_PCR_EVENT_HDR TcgEvent;
  1637. UINTN VarNameLength;
  1638. UEFI_VARIABLE_DATA *VarLog;
  1639. DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));
  1640. DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
  1641. VarNameLength = StrLen (VarName);
  1642. TcgEvent.PCRIndex = PCRIndex;
  1643. TcgEvent.EventType = EventType;
  1644. TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
  1645. - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
  1646. VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (TcgEvent.EventSize);
  1647. if (VarLog == NULL) {
  1648. return EFI_OUT_OF_RESOURCES;
  1649. }
  1650. VarLog->VariableName = *VendorGuid;
  1651. VarLog->UnicodeNameLength = VarNameLength;
  1652. VarLog->VariableDataLength = VarSize;
  1653. CopyMem (
  1654. VarLog->UnicodeName,
  1655. VarName,
  1656. VarNameLength * sizeof (*VarName)
  1657. );
  1658. if (VarSize != 0 && VarData != NULL) {
  1659. CopyMem (
  1660. (CHAR16 *)VarLog->UnicodeName + VarNameLength,
  1661. VarData,
  1662. VarSize
  1663. );
  1664. }
  1665. if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
  1666. //
  1667. // Digest is the event data (UEFI_VARIABLE_DATA)
  1668. //
  1669. Status = TcgDxeHashLogExtendEvent (
  1670. 0,
  1671. (UINT8*)VarLog,
  1672. TcgEvent.EventSize,
  1673. &TcgEvent,
  1674. (UINT8*)VarLog
  1675. );
  1676. } else {
  1677. ASSERT (VarData != NULL);
  1678. Status = TcgDxeHashLogExtendEvent (
  1679. 0,
  1680. (UINT8*)VarData,
  1681. VarSize,
  1682. &TcgEvent,
  1683. (UINT8*)VarLog
  1684. );
  1685. }
  1686. FreePool (VarLog);
  1687. return Status;
  1688. }
  1689. /**
  1690. Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
  1691. @param[in] PCRIndex PCR Index.
  1692. @param[in] EventType Event type.
  1693. @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
  1694. @param[in] VendorGuid A unique identifier for the vendor.
  1695. @param[out] VarSize The size of the variable data.
  1696. @param[out] VarData Pointer to the content of the variable.
  1697. @retval EFI_SUCCESS Operation completed successfully.
  1698. @retval EFI_OUT_OF_RESOURCES Out of memory.
  1699. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1700. **/
  1701. EFI_STATUS
  1702. ReadAndMeasureVariable (
  1703. IN TPM_PCRINDEX PCRIndex,
  1704. IN TCG_EVENTTYPE EventType,
  1705. IN CHAR16 *VarName,
  1706. IN EFI_GUID *VendorGuid,
  1707. OUT UINTN *VarSize,
  1708. OUT VOID **VarData
  1709. )
  1710. {
  1711. EFI_STATUS Status;
  1712. Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);
  1713. if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
  1714. if (EFI_ERROR (Status)) {
  1715. //
  1716. // It is valid case, so we need handle it.
  1717. //
  1718. *VarData = NULL;
  1719. *VarSize = 0;
  1720. }
  1721. } else {
  1722. //
  1723. // if status error, VarData is freed and set NULL by GetVariable2
  1724. //
  1725. if (EFI_ERROR (Status)) {
  1726. return EFI_NOT_FOUND;
  1727. }
  1728. }
  1729. Status = MeasureVariable (
  1730. PCRIndex,
  1731. EventType,
  1732. VarName,
  1733. VendorGuid,
  1734. *VarData,
  1735. *VarSize
  1736. );
  1737. return Status;
  1738. }
  1739. /**
  1740. Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].
  1741. according to TCG PC Client PFP spec 0021 Section 2.4.4.2
  1742. @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
  1743. @param[in] VendorGuid A unique identifier for the vendor.
  1744. @param[out] VarSize The size of the variable data.
  1745. @param[out] VarData Pointer to the content of the variable.
  1746. @retval EFI_SUCCESS Operation completed successfully.
  1747. @retval EFI_OUT_OF_RESOURCES Out of memory.
  1748. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1749. **/
  1750. EFI_STATUS
  1751. ReadAndMeasureBootVariable (
  1752. IN CHAR16 *VarName,
  1753. IN EFI_GUID *VendorGuid,
  1754. OUT UINTN *VarSize,
  1755. OUT VOID **VarData
  1756. )
  1757. {
  1758. return ReadAndMeasureVariable (
  1759. 1,
  1760. EV_EFI_VARIABLE_BOOT,
  1761. VarName,
  1762. VendorGuid,
  1763. VarSize,
  1764. VarData
  1765. );
  1766. }
  1767. /**
  1768. Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
  1769. @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
  1770. @param[in] VendorGuid A unique identifier for the vendor.
  1771. @param[out] VarSize The size of the variable data.
  1772. @param[out] VarData Pointer to the content of the variable.
  1773. @retval EFI_SUCCESS Operation completed successfully.
  1774. @retval EFI_OUT_OF_RESOURCES Out of memory.
  1775. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1776. **/
  1777. EFI_STATUS
  1778. ReadAndMeasureSecureVariable (
  1779. IN CHAR16 *VarName,
  1780. IN EFI_GUID *VendorGuid,
  1781. OUT UINTN *VarSize,
  1782. OUT VOID **VarData
  1783. )
  1784. {
  1785. return ReadAndMeasureVariable (
  1786. 7,
  1787. EV_EFI_VARIABLE_DRIVER_CONFIG,
  1788. VarName,
  1789. VendorGuid,
  1790. VarSize,
  1791. VarData
  1792. );
  1793. }
  1794. /**
  1795. Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
  1796. The EFI boot variables are BootOrder and Boot#### variables.
  1797. @retval EFI_SUCCESS Operation completed successfully.
  1798. @retval EFI_OUT_OF_RESOURCES Out of memory.
  1799. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1800. **/
  1801. EFI_STATUS
  1802. MeasureAllBootVariables (
  1803. VOID
  1804. )
  1805. {
  1806. EFI_STATUS Status;
  1807. UINT16 *BootOrder;
  1808. UINTN BootCount;
  1809. UINTN Index;
  1810. VOID *BootVarData;
  1811. UINTN Size;
  1812. Status = ReadAndMeasureBootVariable (
  1813. mBootVarName,
  1814. &gEfiGlobalVariableGuid,
  1815. &BootCount,
  1816. (VOID **) &BootOrder
  1817. );
  1818. if (Status == EFI_NOT_FOUND || BootOrder == NULL) {
  1819. return EFI_SUCCESS;
  1820. }
  1821. if (EFI_ERROR (Status)) {
  1822. //
  1823. // BootOrder can't be NULL if status is not EFI_NOT_FOUND
  1824. //
  1825. FreePool (BootOrder);
  1826. return Status;
  1827. }
  1828. BootCount /= sizeof (*BootOrder);
  1829. for (Index = 0; Index < BootCount; Index++) {
  1830. UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
  1831. Status = ReadAndMeasureBootVariable (
  1832. mBootVarName,
  1833. &gEfiGlobalVariableGuid,
  1834. &Size,
  1835. &BootVarData
  1836. );
  1837. if (!EFI_ERROR (Status)) {
  1838. FreePool (BootVarData);
  1839. }
  1840. }
  1841. FreePool (BootOrder);
  1842. return EFI_SUCCESS;
  1843. }
  1844. /**
  1845. Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
  1846. The EFI boot variables are BootOrder and Boot#### variables.
  1847. @retval EFI_SUCCESS Operation completed successfully.
  1848. @retval EFI_OUT_OF_RESOURCES Out of memory.
  1849. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1850. **/
  1851. EFI_STATUS
  1852. MeasureAllSecureVariables (
  1853. VOID
  1854. )
  1855. {
  1856. EFI_STATUS Status;
  1857. VOID *Data;
  1858. UINTN DataSize;
  1859. UINTN Index;
  1860. Status = EFI_NOT_FOUND;
  1861. for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
  1862. Status = ReadAndMeasureSecureVariable (
  1863. mVariableType[Index].VariableName,
  1864. mVariableType[Index].VendorGuid,
  1865. &DataSize,
  1866. &Data
  1867. );
  1868. if (!EFI_ERROR (Status)) {
  1869. if (Data != NULL) {
  1870. FreePool (Data);
  1871. }
  1872. }
  1873. }
  1874. //
  1875. // Measure DBT if present and not empty
  1876. //
  1877. Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);
  1878. if (!EFI_ERROR(Status)) {
  1879. Status = MeasureVariable (
  1880. 7,
  1881. EV_EFI_VARIABLE_DRIVER_CONFIG,
  1882. EFI_IMAGE_SECURITY_DATABASE2,
  1883. &gEfiImageSecurityDatabaseGuid,
  1884. Data,
  1885. DataSize
  1886. );
  1887. FreePool(Data);
  1888. } else {
  1889. DEBUG((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));
  1890. }
  1891. return EFI_SUCCESS;
  1892. }
  1893. /**
  1894. Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
  1895. @retval EFI_SUCCESS Operation completed successfully.
  1896. @retval EFI_OUT_OF_RESOURCES Out of memory.
  1897. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  1898. **/
  1899. EFI_STATUS
  1900. MeasureLaunchOfFirmwareDebugger (
  1901. VOID
  1902. )
  1903. {
  1904. TCG_PCR_EVENT_HDR TcgEvent;
  1905. TcgEvent.PCRIndex = 7;
  1906. TcgEvent.EventType = EV_EFI_ACTION;
  1907. TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;
  1908. return TcgDxeHashLogExtendEvent (
  1909. 0,
  1910. (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,
  1911. sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,
  1912. &TcgEvent,
  1913. (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING
  1914. );
  1915. }
  1916. /**
  1917. Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
  1918. Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
  1919. - The contents of the SecureBoot variable
  1920. - The contents of the PK variable
  1921. - The contents of the KEK variable
  1922. - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
  1923. - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
  1924. - Separator
  1925. - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
  1926. NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
  1927. EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
  1928. @param[in] Event Event whose notification function is being invoked
  1929. @param[in] Context Pointer to the notification function's context
  1930. **/
  1931. VOID
  1932. EFIAPI
  1933. MeasureSecureBootPolicy (
  1934. IN EFI_EVENT Event,
  1935. IN VOID *Context
  1936. )
  1937. {
  1938. EFI_STATUS Status;
  1939. VOID *Protocol;
  1940. Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
  1941. if (EFI_ERROR (Status)) {
  1942. return;
  1943. }
  1944. if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {
  1945. Status = MeasureLaunchOfFirmwareDebugger ();
  1946. DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));
  1947. }
  1948. Status = MeasureAllSecureVariables ();
  1949. DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));
  1950. //
  1951. // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
  1952. // and ImageVerification (Authority)
  1953. // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
  1954. // the Authority measurement happen before ReadToBoot event.
  1955. //
  1956. Status = MeasureSeparatorEvent (7);
  1957. DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));
  1958. return ;
  1959. }
  1960. /**
  1961. Ready to Boot Event notification handler.
  1962. Sequence of OS boot events is measured in this event notification handler.
  1963. @param[in] Event Event whose notification function is being invoked
  1964. @param[in] Context Pointer to the notification function's context
  1965. **/
  1966. VOID
  1967. EFIAPI
  1968. OnReadyToBoot (
  1969. IN EFI_EVENT Event,
  1970. IN VOID *Context
  1971. )
  1972. {
  1973. EFI_STATUS Status;
  1974. TPM_PCRINDEX PcrIndex;
  1975. PERF_START_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE);
  1976. if (mBootAttempts == 0) {
  1977. //
  1978. // Measure handoff tables.
  1979. //
  1980. Status = MeasureHandoffTables ();
  1981. if (EFI_ERROR (Status)) {
  1982. DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));
  1983. }
  1984. //
  1985. // Measure BootOrder & Boot#### variables.
  1986. //
  1987. Status = MeasureAllBootVariables ();
  1988. if (EFI_ERROR (Status)) {
  1989. DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));
  1990. }
  1991. //
  1992. // 1. This is the first boot attempt.
  1993. //
  1994. Status = TcgMeasureAction (
  1995. 4,
  1996. EFI_CALLING_EFI_APPLICATION
  1997. );
  1998. if (EFI_ERROR (Status)) {
  1999. DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
  2000. }
  2001. //
  2002. // 2. Draw a line between pre-boot env and entering post-boot env.
  2003. // PCR[7] is already done.
  2004. //
  2005. for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {
  2006. Status = MeasureSeparatorEvent (PcrIndex);
  2007. if (EFI_ERROR (Status)) {
  2008. DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));
  2009. }
  2010. }
  2011. //
  2012. // 3. Measure GPT. It would be done in SAP driver.
  2013. //
  2014. //
  2015. // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
  2016. //
  2017. //
  2018. // 5. Read & Measure variable. BootOrder already measured.
  2019. //
  2020. } else {
  2021. //
  2022. // 6. Not first attempt, meaning a return from last attempt
  2023. //
  2024. Status = TcgMeasureAction (
  2025. 4,
  2026. EFI_RETURNING_FROM_EFI_APPLICATION
  2027. );
  2028. if (EFI_ERROR (Status)) {
  2029. DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));
  2030. }
  2031. //
  2032. // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again
  2033. // TCG PC Client PFP spec Section 2.4.4.5 Step 4
  2034. //
  2035. Status = TcgMeasureAction (
  2036. 4,
  2037. EFI_CALLING_EFI_APPLICATION
  2038. );
  2039. if (EFI_ERROR (Status)) {
  2040. DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
  2041. }
  2042. }
  2043. DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));
  2044. //
  2045. // Increase boot attempt counter.
  2046. //
  2047. mBootAttempts++;
  2048. PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE + 1);
  2049. }
  2050. /**
  2051. Exit Boot Services Event notification handler.
  2052. Measure invocation and success of ExitBootServices.
  2053. @param[in] Event Event whose notification function is being invoked
  2054. @param[in] Context Pointer to the notification function's context
  2055. **/
  2056. VOID
  2057. EFIAPI
  2058. OnExitBootServices (
  2059. IN EFI_EVENT Event,
  2060. IN VOID *Context
  2061. )
  2062. {
  2063. EFI_STATUS Status;
  2064. //
  2065. // Measure invocation of ExitBootServices,
  2066. //
  2067. Status = TcgMeasureAction (
  2068. 5,
  2069. EFI_EXIT_BOOT_SERVICES_INVOCATION
  2070. );
  2071. if (EFI_ERROR (Status)) {
  2072. DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
  2073. }
  2074. //
  2075. // Measure success of ExitBootServices
  2076. //
  2077. Status = TcgMeasureAction (
  2078. 5,
  2079. EFI_EXIT_BOOT_SERVICES_SUCCEEDED
  2080. );
  2081. if (EFI_ERROR (Status)) {
  2082. DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));
  2083. }
  2084. }
  2085. /**
  2086. Exit Boot Services Failed Event notification handler.
  2087. Measure Failure of ExitBootServices.
  2088. @param[in] Event Event whose notification function is being invoked
  2089. @param[in] Context Pointer to the notification function's context
  2090. **/
  2091. VOID
  2092. EFIAPI
  2093. OnExitBootServicesFailed (
  2094. IN EFI_EVENT Event,
  2095. IN VOID *Context
  2096. )
  2097. {
  2098. EFI_STATUS Status;
  2099. //
  2100. // Measure Failure of ExitBootServices,
  2101. //
  2102. Status = TcgMeasureAction (
  2103. 5,
  2104. EFI_EXIT_BOOT_SERVICES_FAILED
  2105. );
  2106. if (EFI_ERROR (Status)) {
  2107. DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));
  2108. }
  2109. }
  2110. /**
  2111. This routine is called to properly shutdown the TPM before system reset.
  2112. It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
  2113. Part 1: Architecture, Revision 01.16.
  2114. @param[in] ResetType The type of reset to perform.
  2115. @param[in] ResetStatus The status code for the reset.
  2116. @param[in] DataSize The size, in bytes, of ResetData.
  2117. @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
  2118. EfiResetShutdown the data buffer starts with a Null-terminated
  2119. string, optionally followed by additional binary data.
  2120. The string is a description that the caller may use to further
  2121. indicate the reason for the system reset.
  2122. For a ResetType of EfiResetPlatformSpecific the data buffer
  2123. also starts with a Null-terminated string that is followed
  2124. by an EFI_GUID that describes the specific type of reset to perform.
  2125. **/
  2126. VOID
  2127. EFIAPI
  2128. ShutdownTpmOnReset (
  2129. IN EFI_RESET_TYPE ResetType,
  2130. IN EFI_STATUS ResetStatus,
  2131. IN UINTN DataSize,
  2132. IN VOID *ResetData OPTIONAL
  2133. )
  2134. {
  2135. EFI_STATUS Status;
  2136. Status = Tpm2Shutdown (TPM_SU_CLEAR);
  2137. DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));
  2138. }
  2139. /**
  2140. Hook the system reset to properly shutdown TPM.
  2141. It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
  2142. Part 1: Architecture, Revision 01.16.
  2143. @param[in] Event Event whose notification function is being invoked
  2144. @param[in] Context Pointer to the notification function's context
  2145. **/
  2146. VOID
  2147. EFIAPI
  2148. OnResetNotificationInstall (
  2149. IN EFI_EVENT Event,
  2150. IN VOID *Context
  2151. )
  2152. {
  2153. EFI_STATUS Status;
  2154. EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify;
  2155. Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);
  2156. if (!EFI_ERROR (Status)) {
  2157. Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);
  2158. ASSERT_EFI_ERROR (Status);
  2159. DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));
  2160. gBS->CloseEvent (Event);
  2161. }
  2162. }
  2163. /**
  2164. The function install Tcg2 protocol.
  2165. @retval EFI_SUCCESS Tcg2 protocol is installed.
  2166. @retval other Some error occurs.
  2167. **/
  2168. EFI_STATUS
  2169. InstallTcg2 (
  2170. VOID
  2171. )
  2172. {
  2173. EFI_STATUS Status;
  2174. EFI_HANDLE Handle;
  2175. Handle = NULL;
  2176. Status = gBS->InstallMultipleProtocolInterfaces (
  2177. &Handle,
  2178. &gEfiTcg2ProtocolGuid,
  2179. &mTcg2Protocol,
  2180. NULL
  2181. );
  2182. return Status;
  2183. }
  2184. /**
  2185. The driver's entry point. It publishes EFI Tcg2 Protocol.
  2186. @param[in] ImageHandle The firmware allocated handle for the EFI image.
  2187. @param[in] SystemTable A pointer to the EFI System Table.
  2188. @retval EFI_SUCCESS The entry point is executed successfully.
  2189. @retval other Some error occurs when executing this entry point.
  2190. **/
  2191. EFI_STATUS
  2192. EFIAPI
  2193. DriverEntry (
  2194. IN EFI_HANDLE ImageHandle,
  2195. IN EFI_SYSTEM_TABLE *SystemTable
  2196. )
  2197. {
  2198. EFI_STATUS Status;
  2199. EFI_EVENT Event;
  2200. VOID *Registration;
  2201. UINT32 MaxCommandSize;
  2202. UINT32 MaxResponseSize;
  2203. UINTN Index;
  2204. EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;
  2205. UINT32 ActivePCRBanks;
  2206. UINT32 NumberOfPCRBanks;
  2207. mImageHandle = ImageHandle;
  2208. if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
  2209. CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
  2210. DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));
  2211. return EFI_UNSUPPORTED;
  2212. }
  2213. if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
  2214. DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
  2215. return EFI_DEVICE_ERROR;
  2216. }
  2217. Status = Tpm2RequestUseTpm ();
  2218. if (EFI_ERROR (Status)) {
  2219. DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));
  2220. return Status;
  2221. }
  2222. //
  2223. // Fill information
  2224. //
  2225. ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));
  2226. mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);
  2227. mTcgDxeData.BsCap.ProtocolVersion.Major = 1;
  2228. mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;
  2229. mTcgDxeData.BsCap.StructureVersion.Major = 1;
  2230. mTcgDxeData.BsCap.StructureVersion.Minor = 1;
  2231. DEBUG ((EFI_D_INFO, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));
  2232. DEBUG ((EFI_D_INFO, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));
  2233. Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);
  2234. if (EFI_ERROR (Status)) {
  2235. DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));
  2236. } else {
  2237. DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));
  2238. }
  2239. DEBUG_CODE (
  2240. UINT32 FirmwareVersion1;
  2241. UINT32 FirmwareVersion2;
  2242. Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);
  2243. if (EFI_ERROR (Status)) {
  2244. DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
  2245. } else {
  2246. DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));
  2247. }
  2248. );
  2249. Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);
  2250. if (EFI_ERROR (Status)) {
  2251. DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
  2252. } else {
  2253. mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;
  2254. mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;
  2255. DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));
  2256. }
  2257. //
  2258. // Get supported PCR and current Active PCRs
  2259. //
  2260. Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePCRBanks);
  2261. ASSERT_EFI_ERROR (Status);
  2262. mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);
  2263. mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);
  2264. //
  2265. // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.
  2266. //
  2267. NumberOfPCRBanks = 0;
  2268. for (Index = 0; Index < 32; Index++) {
  2269. if ((mTcgDxeData.BsCap.HashAlgorithmBitmap & (1u << Index)) != 0) {
  2270. NumberOfPCRBanks++;
  2271. }
  2272. }
  2273. if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {
  2274. mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;
  2275. } else {
  2276. mTcgDxeData.BsCap.NumberOfPCRBanks = PcdGet32 (PcdTcg2NumberOfPCRBanks);
  2277. if (PcdGet32 (PcdTcg2NumberOfPCRBanks) > NumberOfPCRBanks) {
  2278. DEBUG ((EFI_D_ERROR, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks), NumberOfPCRBanks));
  2279. mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;
  2280. }
  2281. }
  2282. mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
  2283. if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) == 0) {
  2284. //
  2285. // No need to expose TCG1.2 event log if SHA1 bank does not exist.
  2286. //
  2287. mTcgDxeData.BsCap.SupportedEventLogs &= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
  2288. }
  2289. DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
  2290. DEBUG ((EFI_D_INFO, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));
  2291. DEBUG ((EFI_D_INFO, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData.BsCap.NumberOfPCRBanks));
  2292. DEBUG ((EFI_D_INFO, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData.BsCap.ActivePcrBanks));
  2293. if (mTcgDxeData.BsCap.TPMPresentFlag) {
  2294. //
  2295. // Setup the log area and copy event log from hob list to it
  2296. //
  2297. Status = SetupEventLog ();
  2298. ASSERT_EFI_ERROR (Status);
  2299. //
  2300. // Measure handoff tables, Boot#### variables etc.
  2301. //
  2302. Status = EfiCreateEventReadyToBootEx (
  2303. TPL_CALLBACK,
  2304. OnReadyToBoot,
  2305. NULL,
  2306. &Event
  2307. );
  2308. Status = gBS->CreateEventEx (
  2309. EVT_NOTIFY_SIGNAL,
  2310. TPL_NOTIFY,
  2311. OnExitBootServices,
  2312. NULL,
  2313. &gEfiEventExitBootServicesGuid,
  2314. &Event
  2315. );
  2316. //
  2317. // Measure Exit Boot Service failed
  2318. //
  2319. Status = gBS->CreateEventEx (
  2320. EVT_NOTIFY_SIGNAL,
  2321. TPL_NOTIFY,
  2322. OnExitBootServicesFailed,
  2323. NULL,
  2324. &gEventExitBootServicesFailedGuid,
  2325. &Event
  2326. );
  2327. //
  2328. // Create event callback, because we need access variable on SecureBootPolicyVariable
  2329. // We should use VariableWriteArch instead of VariableArch, because Variable driver
  2330. // may update SecureBoot value based on last setting.
  2331. //
  2332. EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);
  2333. //
  2334. // Hook the system reset to properly shutdown TPM.
  2335. //
  2336. EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);
  2337. }
  2338. //
  2339. // Install Tcg2Protocol
  2340. //
  2341. Status = InstallTcg2 ();
  2342. DEBUG ((EFI_D_INFO, "InstallTcg2 - %r\n", Status));
  2343. return Status;
  2344. }