MmTcg2PhysicalPresenceLibCommon.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /** @file
  2. Handle TPM 2.0 physical presence requests from OS.
  3. This library will handle TPM 2.0 physical presence request from OS.
  4. Caution: This module requires additional review when modified.
  5. This driver will have external input - variable.
  6. This external input must be validated carefully to avoid security issue.
  7. Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction()
  8. will receive untrusted input and do validation.
  9. Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
  10. SPDX-License-Identifier: BSD-2-Clause-Patent
  11. **/
  12. #include <PiMm.h>
  13. #include <Guid/Tcg2PhysicalPresenceData.h>
  14. #include <Protocol/SmmVariable.h>
  15. #include <Library/BaseLib.h>
  16. #include <Library/DebugLib.h>
  17. #include <Library/BaseMemoryLib.h>
  18. #include <Library/Tcg2PpVendorLib.h>
  19. #include <Library/MmServicesTableLib.h>
  20. #define PP_INF_VERSION_1_2 "1.2"
  21. EFI_SMM_VARIABLE_PROTOCOL *mTcg2PpSmmVariable;
  22. BOOLEAN mIsTcg2PPVerLowerThan_1_3 = FALSE;
  23. UINT32 mTcg2PhysicalPresenceFlags;
  24. /**
  25. The handler for TPM physical presence function:
  26. Return TPM Operation Response to OS Environment.
  27. This API should be invoked in OS runtime phase to interface with ACPI method.
  28. @param[out] MostRecentRequest Most recent operation request.
  29. @param[out] Response Response to the most recent operation request.
  30. @return Return Code for Return TPM Operation Response to OS Environment.
  31. **/
  32. UINT32
  33. EFIAPI
  34. Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
  35. OUT UINT32 *MostRecentRequest,
  36. OUT UINT32 *Response
  37. )
  38. {
  39. EFI_STATUS Status;
  40. UINTN DataSize;
  41. EFI_TCG2_PHYSICAL_PRESENCE PpData;
  42. DEBUG ((DEBUG_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));
  43. //
  44. // Get the Physical Presence variable
  45. //
  46. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  47. Status = mTcg2PpSmmVariable->SmmGetVariable (
  48. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  49. &gEfiTcg2PhysicalPresenceGuid,
  50. NULL,
  51. &DataSize,
  52. &PpData
  53. );
  54. if (EFI_ERROR (Status)) {
  55. *MostRecentRequest = 0;
  56. *Response = 0;
  57. DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
  58. return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;
  59. }
  60. *MostRecentRequest = PpData.LastPPRequest;
  61. *Response = PpData.PPResponse;
  62. return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;
  63. }
  64. /**
  65. The handler for TPM physical presence function:
  66. Submit TPM Operation Request to Pre-OS Environment and
  67. Submit TPM Operation Request to Pre-OS Environment 2.
  68. This API should be invoked in OS runtime phase to interface with ACPI method.
  69. Caution: This function may receive untrusted input.
  70. @param[in, out] Pointer to OperationRequest TPM physical presence operation request.
  71. @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.
  72. @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
  73. Submit TPM Operation Request to Pre-OS Environment 2.
  74. **/
  75. UINT32
  76. Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
  77. IN OUT UINT32 *OperationRequest,
  78. IN OUT UINT32 *RequestParameter
  79. )
  80. {
  81. EFI_STATUS Status;
  82. UINT32 ReturnCode;
  83. UINTN DataSize;
  84. EFI_TCG2_PHYSICAL_PRESENCE PpData;
  85. EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
  86. DEBUG ((DEBUG_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest, *RequestParameter));
  87. ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
  88. //
  89. // Get the Physical Presence variable
  90. //
  91. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  92. Status = mTcg2PpSmmVariable->SmmGetVariable (
  93. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  94. &gEfiTcg2PhysicalPresenceGuid,
  95. NULL,
  96. &DataSize,
  97. &PpData
  98. );
  99. if (EFI_ERROR (Status)) {
  100. DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
  101. ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
  102. goto EXIT;
  103. }
  104. if ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
  105. (*OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN))
  106. {
  107. ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
  108. goto EXIT;
  109. }
  110. if ((PpData.PPRequest != *OperationRequest) ||
  111. (PpData.PPRequestParameter != *RequestParameter))
  112. {
  113. PpData.PPRequest = (UINT8)*OperationRequest;
  114. PpData.PPRequestParameter = *RequestParameter;
  115. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  116. Status = mTcg2PpSmmVariable->SmmSetVariable (
  117. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  118. &gEfiTcg2PhysicalPresenceGuid,
  119. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
  120. DataSize,
  121. &PpData
  122. );
  123. if (EFI_ERROR (Status)) {
  124. DEBUG ((DEBUG_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
  125. ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
  126. goto EXIT;
  127. }
  128. }
  129. if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
  130. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
  131. Status = mTcg2PpSmmVariable->SmmGetVariable (
  132. TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
  133. &gEfiTcg2PhysicalPresenceGuid,
  134. NULL,
  135. &DataSize,
  136. &Flags
  137. );
  138. if (EFI_ERROR (Status)) {
  139. Flags.PPFlags = mTcg2PhysicalPresenceFlags;
  140. }
  141. ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);
  142. }
  143. EXIT:
  144. //
  145. // Sync PPRQ/PPRM from PP Variable if PP submission fails
  146. //
  147. if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
  148. DEBUG ((DEBUG_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status));
  149. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  150. ZeroMem (&PpData, DataSize);
  151. Status = mTcg2PpSmmVariable->SmmGetVariable (
  152. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  153. &gEfiTcg2PhysicalPresenceGuid,
  154. NULL,
  155. &DataSize,
  156. &PpData
  157. );
  158. *OperationRequest = (UINT32)PpData.PPRequest;
  159. *RequestParameter = PpData.PPRequestParameter;
  160. }
  161. return ReturnCode;
  162. }
  163. /**
  164. The handler for TPM physical presence function:
  165. Submit TPM Operation Request to Pre-OS Environment and
  166. Submit TPM Operation Request to Pre-OS Environment 2.
  167. This API should be invoked in OS runtime phase to interface with ACPI method.
  168. Caution: This function may receive untrusted input.
  169. @param[in] OperationRequest TPM physical presence operation request.
  170. @param[in] RequestParameter TPM physical presence operation request parameter.
  171. @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
  172. Submit TPM Operation Request to Pre-OS Environment 2.
  173. **/
  174. UINT32
  175. EFIAPI
  176. Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
  177. IN UINT32 OperationRequest,
  178. IN UINT32 RequestParameter
  179. )
  180. {
  181. UINT32 TempOperationRequest;
  182. UINT32 TempRequestParameter;
  183. TempOperationRequest = OperationRequest;
  184. TempRequestParameter = RequestParameter;
  185. return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (&TempOperationRequest, &TempRequestParameter);
  186. }
  187. /**
  188. The handler for TPM physical presence function:
  189. Get User Confirmation Status for Operation.
  190. This API should be invoked in OS runtime phase to interface with ACPI method.
  191. Caution: This function may receive untrusted input.
  192. @param[in] OperationRequest TPM physical presence operation request.
  193. @return Return Code for Get User Confirmation Status for Operation.
  194. **/
  195. UINT32
  196. EFIAPI
  197. Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
  198. IN UINT32 OperationRequest
  199. )
  200. {
  201. EFI_STATUS Status;
  202. UINTN DataSize;
  203. EFI_TCG2_PHYSICAL_PRESENCE PpData;
  204. EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
  205. BOOLEAN RequestConfirmed;
  206. DEBUG ((DEBUG_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));
  207. //
  208. // Get the Physical Presence variable
  209. //
  210. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  211. Status = mTcg2PpSmmVariable->SmmGetVariable (
  212. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  213. &gEfiTcg2PhysicalPresenceGuid,
  214. NULL,
  215. &DataSize,
  216. &PpData
  217. );
  218. if (EFI_ERROR (Status)) {
  219. DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
  220. return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
  221. }
  222. //
  223. // Get the Physical Presence flags
  224. //
  225. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
  226. Status = mTcg2PpSmmVariable->SmmGetVariable (
  227. TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
  228. &gEfiTcg2PhysicalPresenceGuid,
  229. NULL,
  230. &DataSize,
  231. &Flags
  232. );
  233. if (EFI_ERROR (Status)) {
  234. DEBUG ((DEBUG_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));
  235. return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
  236. }
  237. RequestConfirmed = FALSE;
  238. switch (OperationRequest) {
  239. case TCG2_PHYSICAL_PRESENCE_CLEAR:
  240. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
  241. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
  242. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
  243. if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {
  244. RequestConfirmed = TRUE;
  245. }
  246. break;
  247. case TCG2_PHYSICAL_PRESENCE_NO_ACTION:
  248. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
  249. RequestConfirmed = TRUE;
  250. break;
  251. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
  252. break;
  253. case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
  254. if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {
  255. RequestConfirmed = TRUE;
  256. }
  257. break;
  258. case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
  259. if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {
  260. RequestConfirmed = TRUE;
  261. }
  262. break;
  263. case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
  264. RequestConfirmed = TRUE;
  265. break;
  266. case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
  267. if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {
  268. RequestConfirmed = TRUE;
  269. }
  270. break;
  271. case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
  272. if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {
  273. RequestConfirmed = TRUE;
  274. }
  275. break;
  276. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
  277. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
  278. RequestConfirmed = TRUE;
  279. break;
  280. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
  281. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
  282. break;
  283. default:
  284. if (!mIsTcg2PPVerLowerThan_1_3) {
  285. if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
  286. //
  287. // TCG2 PP1.3 spec defined operations that are reserved or un-implemented
  288. //
  289. return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
  290. }
  291. } else {
  292. //
  293. // TCG PP lower than 1.3. (1.0, 1.1, 1.2)
  294. //
  295. if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
  296. RequestConfirmed = TRUE;
  297. } else if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
  298. return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
  299. }
  300. }
  301. break;
  302. }
  303. if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
  304. return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);
  305. }
  306. if (RequestConfirmed) {
  307. return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;
  308. } else {
  309. return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;
  310. }
  311. }
  312. /**
  313. The constructor function locates SmmVariable protocol.
  314. It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
  315. @retval EFI_SUCCESS The constructor successfully added string package.
  316. @retval Other value The constructor can't add string package.
  317. **/
  318. EFI_STATUS
  319. Tcg2PhysicalPresenceLibCommonConstructor (
  320. VOID
  321. )
  322. {
  323. EFI_STATUS Status;
  324. if (AsciiStrnCmp (PP_INF_VERSION_1_2, (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer), sizeof (PP_INF_VERSION_1_2) - 1) >= 0) {
  325. mIsTcg2PPVerLowerThan_1_3 = TRUE;
  326. }
  327. //
  328. // Locate SmmVariableProtocol.
  329. //
  330. Status = gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mTcg2PpSmmVariable);
  331. ASSERT_EFI_ERROR (Status);
  332. mTcg2PhysicalPresenceFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);
  333. return EFI_SUCCESS;
  334. }