Measurement.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  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. return TRUE;
  141. }
  142. }
  143. return FALSE;
  144. }
  145. /**
  146. This function will return if this variable is SecureAuthority Variable.
  147. @param[in] VariableName A Null-terminated string that is the name of the vendor's variable.
  148. @param[in] VendorGuid A unique identifier for the vendor.
  149. @retval TRUE This is SecureAuthority Variable
  150. @retval FALSE This is not SecureAuthority Variable
  151. **/
  152. BOOLEAN
  153. IsSecureAuthorityVariable (
  154. IN CHAR16 *VariableName,
  155. IN EFI_GUID *VendorGuid
  156. )
  157. {
  158. UINTN Index;
  159. for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
  160. if ((StrCmp (VariableName, mVariableType[Index].VariableName) == 0) &&
  161. (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid))) {
  162. return TRUE;
  163. }
  164. }
  165. return FALSE;
  166. }
  167. /**
  168. Measure and log an EFI variable, and extend the measurement result into a specific PCR.
  169. @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
  170. @param[in] VendorGuid A unique identifier for the vendor.
  171. @param[in] VarData The content of the variable data.
  172. @param[in] VarSize The size of the variable data.
  173. @retval EFI_SUCCESS Operation completed successfully.
  174. @retval EFI_OUT_OF_RESOURCES Out of memory.
  175. @retval EFI_DEVICE_ERROR The operation was unsuccessful.
  176. **/
  177. EFI_STATUS
  178. EFIAPI
  179. MeasureVariable (
  180. IN CHAR16 *VarName,
  181. IN EFI_GUID *VendorGuid,
  182. IN VOID *VarData,
  183. IN UINTN VarSize
  184. )
  185. {
  186. EFI_STATUS Status;
  187. UINTN VarNameLength;
  188. UEFI_VARIABLE_DATA *VarLog;
  189. UINT32 VarLogSize;
  190. //
  191. // The UEFI_VARIABLE_DATA.VariableData value shall be the EFI_SIGNATURE_DATA value
  192. // from the EFI_SIGNATURE_LIST that contained the authority that was used to validate the image
  193. //
  194. VarNameLength = StrLen (VarName);
  195. VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
  196. - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
  197. VarLog = (UEFI_VARIABLE_DATA *) AllocateZeroPool (VarLogSize);
  198. if (VarLog == NULL) {
  199. return EFI_OUT_OF_RESOURCES;
  200. }
  201. CopyMem (&VarLog->VariableName, VendorGuid, sizeof(VarLog->VariableName));
  202. VarLog->UnicodeNameLength = VarNameLength;
  203. VarLog->VariableDataLength = VarSize;
  204. CopyMem (
  205. VarLog->UnicodeName,
  206. VarName,
  207. VarNameLength * sizeof (*VarName)
  208. );
  209. CopyMem (
  210. (CHAR16 *)VarLog->UnicodeName + VarNameLength,
  211. VarData,
  212. VarSize
  213. );
  214. DEBUG ((EFI_D_INFO, "DxeImageVerification: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY));
  215. DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
  216. Status = TpmMeasureAndLogData (
  217. 7,
  218. EV_EFI_VARIABLE_AUTHORITY,
  219. VarLog,
  220. VarLogSize,
  221. VarLog,
  222. VarLogSize
  223. );
  224. FreePool (VarLog);
  225. return Status;
  226. }
  227. /**
  228. SecureBoot Hook for processing image verification.
  229. @param[in] VariableName Name of Variable to be found.
  230. @param[in] VendorGuid Variable vendor GUID.
  231. @param[in] DataSize Size of Data found. If size is less than the
  232. data, this value contains the required size.
  233. @param[in] Data Data pointer.
  234. **/
  235. VOID
  236. EFIAPI
  237. SecureBootHook (
  238. IN CHAR16 *VariableName,
  239. IN EFI_GUID *VendorGuid,
  240. IN UINTN DataSize,
  241. IN VOID *Data
  242. )
  243. {
  244. EFI_STATUS Status;
  245. if (!IsSecureAuthorityVariable (VariableName, VendorGuid)) {
  246. return ;
  247. }
  248. if (IsDataMeasured (VariableName, VendorGuid, Data, DataSize)) {
  249. DEBUG ((EFI_D_ERROR, "MeasureSecureAuthorityVariable - IsDataMeasured\n"));
  250. return ;
  251. }
  252. Status = MeasureVariable (
  253. VariableName,
  254. VendorGuid,
  255. Data,
  256. DataSize
  257. );
  258. DEBUG ((EFI_D_INFO, "MeasureBootPolicyVariable - %r\n", Status));
  259. if (!EFI_ERROR (Status)) {
  260. AddDataMeasured (VariableName, VendorGuid, Data, DataSize);
  261. }
  262. return ;
  263. }