]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.c
Security: Add SecTpmMeasurementLibTdx
[mirror_edk2.git] / SecurityPkg / Library / SecTpmMeasurementLib / SecTpmMeasurementLibTdx.c
CommitLineData
2818fda9
MX
1/** @file\r
2 This library is used by other modules to measure data to TPM.\r
3\r
4Copyright (c) 2020, Intel Corporation. All rights reserved. <BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include <PiPei.h>\r
10#include <Guid/CcEventHob.h>\r
11#include <Library/BaseLib.h>\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/HashLib.h>\r
15#include <Library/HobLib.h>\r
16#include <Library/PrintLib.h>\r
17#include <IndustryStandard/Tpm20.h>\r
18#include <Protocol/CcMeasurement.h>\r
19#include <Library/TpmMeasurementLib.h>\r
20\r
21#pragma pack(1)\r
22\r
23typedef struct {\r
24 UINT32 Count;\r
25 TPMI_ALG_HASH HashAlg;\r
26 BYTE Sha384[SHA384_DIGEST_SIZE];\r
27} TDX_DIGEST_VALUE;\r
28\r
29#pragma pack()\r
30\r
31#define INVALID_PCR2MR_INDEX 0xFF\r
32\r
33/**\r
34 Get the mapped RTMR index based on the input PCRIndex.\r
35 RTMR[0] => PCR[1,7]\r
36 RTMR[1] => PCR[2,3,4,5]\r
37 RTMR[2] => PCR[8~15]\r
38 RTMR[3] => NA\r
39 Note:\r
40 PCR[0] is mapped to MRTD and should not appear here.\r
41 PCR[6] is reserved for OEM. It is not used.\r
42\r
43 @param[in] PCRIndex The input PCR index\r
44\r
45 @retval UINT8 The mapped RTMR index.\r
46**/\r
47UINT8\r
48GetMappedRtmrIndex (\r
49 IN UINT32 PCRIndex\r
50 )\r
51{\r
52 UINT8 RtmrIndex;\r
53\r
54 if ((PCRIndex == 6) || (PCRIndex == 0) || (PCRIndex > 15)) {\r
55 DEBUG ((DEBUG_ERROR, "Invalid PCRIndex(%d) map to MR Index.\n", PCRIndex));\r
56 ASSERT (FALSE);\r
57 return INVALID_PCR2MR_INDEX;\r
58 }\r
59\r
60 RtmrIndex = 0;\r
61 if ((PCRIndex == 1) || (PCRIndex == 7)) {\r
62 RtmrIndex = 0;\r
63 } else if ((PCRIndex >= 2) && (PCRIndex < 6)) {\r
64 RtmrIndex = 1;\r
65 } else if ((PCRIndex >= 8) && (PCRIndex <= 15)) {\r
66 RtmrIndex = 2;\r
67 }\r
68\r
69 return RtmrIndex;\r
70}\r
71\r
72/**\r
73 Tpm measure and log data, and extend the measurement result into a specific PCR.\r
74\r
75 @param[in] PcrIndex PCR Index.\r
76 @param[in] EventType Event type.\r
77 @param[in] EventLog Measurement event log.\r
78 @param[in] LogLen Event log length in bytes.\r
79 @param[in] HashData The start of the data buffer to be hashed, extended.\r
80 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData\r
81\r
82 @retval EFI_SUCCESS Operation completed successfully.\r
83 @retval EFI_UNSUPPORTED TPM device not available.\r
84 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
85 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
86**/\r
87EFI_STATUS\r
88EFIAPI\r
89TpmMeasureAndLogData (\r
90 IN UINT32 PcrIndex,\r
91 IN UINT32 EventType,\r
92 IN VOID *EventLog,\r
93 IN UINT32 LogLen,\r
94 IN VOID *HashData,\r
95 IN UINT64 HashDataLen\r
96 )\r
97{\r
98 EFI_STATUS Status;\r
99 UINT32 RtmrIndex;\r
100 VOID *EventHobData;\r
101 TCG_PCR_EVENT2 *TcgPcrEvent2;\r
102 UINT8 *DigestBuffer;\r
103 TDX_DIGEST_VALUE *TdxDigest;\r
104 TPML_DIGEST_VALUES DigestList;\r
105 UINT8 *Ptr;\r
106\r
107 if (!TdIsEnabled ()) {\r
108 return EFI_UNSUPPORTED;\r
109 }\r
110\r
111 RtmrIndex = GetMappedRtmrIndex (PcrIndex);\r
112 if (RtmrIndex == INVALID_PCR2MR_INDEX) {\r
113 return EFI_INVALID_PARAMETER;\r
114 }\r
115\r
116 DEBUG ((DEBUG_INFO, "Creating TdTcg2PcrEvent PCR[%d]/RTMR[%d] EventType 0x%x\n", PcrIndex, RtmrIndex, EventType));\r
117\r
118 Status = HashAndExtend (\r
119 RtmrIndex,\r
120 (VOID *)HashData,\r
121 HashDataLen,\r
122 &DigestList\r
123 );\r
124\r
125 if (EFI_ERROR (Status)) {\r
126 DEBUG ((DEBUG_INFO, "Failed to HashAndExtend. %r\n", Status));\r
127 return Status;\r
128 }\r
129\r
130 //\r
131 // Use TDX_DIGEST_VALUE in the GUID HOB DataLength calculation\r
132 // to reserve enough buffer to hold TPML_DIGEST_VALUES compact binary\r
133 // which is limited to a SHA384 digest list\r
134 //\r
135 EventHobData = BuildGuidHob (\r
136 &gCcEventEntryHobGuid,\r
137 sizeof (TcgPcrEvent2->PCRIndex) + sizeof (TcgPcrEvent2->EventType) +\r
138 sizeof (TDX_DIGEST_VALUE) +\r
139 sizeof (TcgPcrEvent2->EventSize) + LogLen\r
140 );\r
141\r
142 if (EventHobData == NULL) {\r
143 return EFI_OUT_OF_RESOURCES;\r
144 }\r
145\r
146 Ptr = (UINT8 *)EventHobData;\r
147 //\r
148 // Initialize PcrEvent data now\r
149 //\r
150 RtmrIndex++;\r
151 CopyMem (Ptr, &RtmrIndex, sizeof (UINT32));\r
152 Ptr += sizeof (UINT32);\r
153 CopyMem (Ptr, &EventType, sizeof (TCG_EVENTTYPE));\r
154 Ptr += sizeof (TCG_EVENTTYPE);\r
155\r
156 DigestBuffer = Ptr;\r
157\r
158 TdxDigest = (TDX_DIGEST_VALUE *)DigestBuffer;\r
159 TdxDigest->Count = 1;\r
160 TdxDigest->HashAlg = TPM_ALG_SHA384;\r
161 CopyMem (\r
162 TdxDigest->Sha384,\r
163 DigestList.digests[0].digest.sha384,\r
164 SHA384_DIGEST_SIZE\r
165 );\r
166\r
167 Ptr += sizeof (TDX_DIGEST_VALUE);\r
168\r
169 CopyMem (Ptr, &LogLen, sizeof (UINT32));\r
170 Ptr += sizeof (UINT32);\r
171 CopyMem (Ptr, EventLog, LogLen);\r
172 Ptr += LogLen;\r
173\r
174 Status = EFI_SUCCESS;\r
175 return Status;\r
176}\r