Measurement.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /** @file
  2. Measure TCG required variable.
  3. Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <PiDxe.h>
  7. #include <Guid/ImageAuthentication.h>
  8. #include <IndustryStandard/UefiTcgPlatform.h>
  9. #include <Library/UefiBootServicesTableLib.h>
  10. #include <Library/UefiRuntimeServicesTableLib.h>
  11. #include <Library/MemoryAllocationLib.h>
  12. #include <Library/BaseMemoryLib.h>
  13. #include <Library/DebugLib.h>
  14. #include <Library/BaseLib.h>
  15. #include <Library/TpmMeasurementLib.h>
  16. typedef struct {
  17. CHAR16 *VariableName;
  18. EFI_GUID *VendorGuid;
  19. } VARIABLE_TYPE;
  20. typedef struct {
  21. CHAR16 *VariableName;
  22. EFI_GUID *VendorGuid;
  23. VOID *Data;
  24. UINTN Size;
  25. } VARIABLE_RECORD;
  26. #define MEASURED_AUTHORITY_COUNT_MAX 0x100
  27. UINTN mMeasuredAuthorityCount = 0;
  28. UINTN mMeasuredAuthorityCountMax = 0;
  29. VARIABLE_RECORD *mMeasuredAuthorityList = NULL;
  30. VARIABLE_TYPE mVariableType[] = {
  31. { EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid },
  32. };
  33. /**
  34. This function will check if VarName should be recorded and return the address of VarName if it is needed.
  35. @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
  36. @return the address of VarName.
  37. **/
  38. CHAR16 *
  39. AssignVarName (
  40. IN CHAR16 *VarName
  41. )
  42. {
  43. UINTN Index;
  44. for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {
  45. if (StrCmp (VarName, mVariableType[Index].VariableName) == 0) {
  46. return mVariableType[Index].VariableName;
  47. }
  48. }
  49. return NULL;
  50. }
  51. /**
  52. This function will check if VendorGuid should be recorded and return the address of VendorGuid if it is needed.
  53. @param[in] VendorGuid A unique identifier for the vendor.
  54. @return the address of VendorGuid.
  55. **/
  56. EFI_GUID *
  57. AssignVendorGuid (
  58. IN EFI_GUID *VendorGuid
  59. )
  60. {
  61. UINTN Index;
  62. for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {
  63. if (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid)) {
  64. return mVariableType[Index].VendorGuid;
  65. }
  66. }
  67. return NULL;
  68. }
  69. /**
  70. This function will add variable information to MeasuredAuthorityList.
  71. @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
  72. @param[in] VendorGuid A unique identifier for the vendor.
  73. @param[in] VarData The content of the variable data.
  74. @param[in] VarSize The size of the variable data.
  75. @retval EFI_SUCCESS Operation completed successfully.
  76. @retval EFI_OUT_OF_RESOURCES Out of memory.
  77. **/
  78. EFI_STATUS
  79. AddDataMeasured (
  80. IN CHAR16 *VarName,
  81. IN EFI_GUID *VendorGuid,
  82. IN VOID *Data,
  83. IN UINTN Size
  84. )
  85. {
  86. VARIABLE_RECORD *NewMeasuredAuthorityList;
  87. ASSERT (mMeasuredAuthorityCount <= mMeasuredAuthorityCountMax);
  88. if (mMeasuredAuthorityCount == mMeasuredAuthorityCountMax) {
  89. //
  90. // Need enlarge
  91. //
  92. NewMeasuredAuthorityList = AllocateZeroPool (sizeof (VARIABLE_RECORD) * (mMeasuredAuthorityCountMax + MEASURED_AUTHORITY_COUNT_MAX));
  93. if (NewMeasuredAuthorityList == NULL) {
  94. return EFI_OUT_OF_RESOURCES;
  95. }
  96. if (mMeasuredAuthorityList != NULL) {
  97. CopyMem (NewMeasuredAuthorityList, mMeasuredAuthorityList, sizeof (VARIABLE_RECORD) * mMeasuredAuthorityCount);
  98. FreePool (mMeasuredAuthorityList);
  99. }
  100. mMeasuredAuthorityList = NewMeasuredAuthorityList;
  101. mMeasuredAuthorityCountMax += MEASURED_AUTHORITY_COUNT_MAX;
  102. }
  103. //
  104. // Add new entry
  105. //
  106. mMeasuredAuthorityList[mMeasuredAuthorityCount].VariableName = AssignVarName (VarName);
  107. mMeasuredAuthorityList[mMeasuredAuthorityCount].VendorGuid = AssignVendorGuid (VendorGuid);
  108. mMeasuredAuthorityList[mMeasuredAuthorityCount].Size = Size;
  109. mMeasuredAuthorityList[mMeasuredAuthorityCount].Data = AllocatePool (Size);
  110. if (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data == NULL) {
  111. return EFI_OUT_OF_RESOURCES;
  112. }
  113. CopyMem (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data, Data, Size);
  114. mMeasuredAuthorityCount++;
  115. return EFI_SUCCESS;
  116. }
  117. /**
  118. This function will return if this variable is already measured.
  119. @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
  120. @param[in] VendorGuid A unique identifier for the vendor.
  121. @param[in] VarData The content of the variable data.
  122. @param[in] VarSize The size of the variable data.
  123. @retval TRUE The data is already measured.
  124. @retval FALSE The data is not measured yet.
  125. **/
  126. BOOLEAN
  127. IsDataMeasured (
  128. IN CHAR16 *VarName,
  129. IN EFI_GUID *VendorGuid,
  130. IN VOID *Data,
  131. IN UINTN Size
  132. )
  133. {
  134. UINTN Index;
  135. for (Index = 0; Index < mMeasuredAuthorityCount; Index++) {
  136. if ((StrCmp (VarName, mMeasuredAuthorityList[Index].VariableName) == 0) &&
  137. (CompareGuid (VendorGuid, mMeasuredAuthorityList[Index].VendorGuid)) &&
  138. (CompareMem (Data, mMeasuredAuthorityList[Index].Data, Size) == 0) &&
  139. (Size == mMeasuredAuthorityList[Index].Size))
  140. {
  141. return TRUE;
  142. }
  143. }
  144. return FALSE;
  145. }
  146. /**
  147. This function will return if this variable is SecureAuthority Variable.
  148. @param[in] VariableName A Null-terminated string that is the name of the vendor's variable.
  149. @param[in] VendorGuid A unique identifier for the vendor.
  150. @retval TRUE This is SecureAuthority Variable
  151. @retval FALSE This is not SecureAuthority Variable
  152. **/
  153. BOOLEAN
  154. IsSecureAuthorityVariable (
  155. IN CHAR16 *VariableName,
  156. IN EFI_GUID *VendorGuid
  157. )
  158. {
  159. UINTN Index;
  160. for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {
  161. if ((StrCmp (VariableName, mVariableType[Index].VariableName) == 0) &&
  162. (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid)))
  163. {
  164. return TRUE;
  165. }
  166. }
  167. return FALSE;
  168. }
  169. /**
  170. Measure and log an EFI variable, and extend the measurement result into a specific PCR.
  171. @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
  172. @param[in] VendorGuid A unique identifier for the vendor.
  173. @param[in] VarData The content of the variable data.
  174. @param[in] VarSize The size of the variable data.
  175. @retval EFI_SUCCESS Operation completed successfully.
  176. @retval EFI_OUT_OF_RESOURCES Out of memory.
  177. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  178. **/
  179. EFI_STATUS
  180. EFIAPI
  181. MeasureVariable (
  182. IN CHAR16 *VarName,
  183. IN EFI_GUID *VendorGuid,
  184. IN VOID *VarData,
  185. IN UINTN VarSize
  186. )
  187. {
  188. EFI_STATUS Status;
  189. UINTN VarNameLength;
  190. UEFI_VARIABLE_DATA *VarLog;
  191. UINT32 VarLogSize;
  192. //
  193. // The UEFI_VARIABLE_DATA.VariableData value shall be the EFI_SIGNATURE_DATA value
  194. // from the EFI_SIGNATURE_LIST that contained the authority that was used to validate the image
  195. //
  196. VarNameLength = StrLen (VarName);
  197. VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
  198. - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
  199. VarLog = (UEFI_VARIABLE_DATA *)AllocateZeroPool (VarLogSize);
  200. if (VarLog == NULL) {
  201. return EFI_OUT_OF_RESOURCES;
  202. }
  203. CopyMem (&VarLog->VariableName, VendorGuid, sizeof (VarLog->VariableName));
  204. VarLog->UnicodeNameLength = VarNameLength;
  205. VarLog->VariableDataLength = VarSize;
  206. CopyMem (
  207. VarLog->UnicodeName,
  208. VarName,
  209. VarNameLength * sizeof (*VarName)
  210. );
  211. CopyMem (
  212. (CHAR16 *)VarLog->UnicodeName + VarNameLength,
  213. VarData,
  214. VarSize
  215. );
  216. DEBUG ((DEBUG_INFO, "DxeImageVerification: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY));
  217. DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
  218. Status = TpmMeasureAndLogData (
  219. 7,
  220. EV_EFI_VARIABLE_AUTHORITY,
  221. VarLog,
  222. VarLogSize,
  223. VarLog,
  224. VarLogSize
  225. );
  226. FreePool (VarLog);
  227. return Status;
  228. }
  229. /**
  230. SecureBoot Hook for processing image verification.
  231. @param[in] VariableName Name of Variable to be found.
  232. @param[in] VendorGuid Variable vendor GUID.
  233. @param[in] DataSize Size of Data found. If size is less than the
  234. data, this value contains the required size.
  235. @param[in] Data Data pointer.
  236. **/
  237. VOID
  238. EFIAPI
  239. SecureBootHook (
  240. IN CHAR16 *VariableName,
  241. IN EFI_GUID *VendorGuid,
  242. IN UINTN DataSize,
  243. IN VOID *Data
  244. )
  245. {
  246. EFI_STATUS Status;
  247. if (!IsSecureAuthorityVariable (VariableName, VendorGuid)) {
  248. return;
  249. }
  250. if (IsDataMeasured (VariableName, VendorGuid, Data, DataSize)) {
  251. DEBUG ((DEBUG_ERROR, "MeasureSecureAuthorityVariable - IsDataMeasured\n"));
  252. return;
  253. }
  254. Status = MeasureVariable (
  255. VariableName,
  256. VendorGuid,
  257. Data,
  258. DataSize
  259. );
  260. DEBUG ((DEBUG_INFO, "MeasureBootPolicyVariable - %r\n", Status));
  261. if (!EFI_ERROR (Status)) {
  262. AddDataMeasured (VariableName, VendorGuid, Data, DataSize);
  263. }
  264. return;
  265. }