]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c
SecurityPkg: Add TPM PTP support in TCG2 Config.
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Config / Tcg2ConfigDriver.c
1 /** @file
2 The module entry point for Tcg2 configuration module.
3
4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "Tcg2ConfigImpl.h"
16
17 extern TPM_INSTANCE_ID mTpmInstanceId[TPM_DEVICE_MAX + 1];
18
19 /**
20 Update default PCR banks data.
21
22 @param[in] HiiPackage HII Package.
23 @param[in] HiiPackageSize HII Package size.
24 @param[in] PCRBanks PCR Banks data.
25
26 **/
27 VOID
28 UpdateDefaultPCRBanks (
29 IN VOID *HiiPackage,
30 IN UINTN HiiPackageSize,
31 IN UINT32 PCRBanks
32 )
33 {
34 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
35 EFI_IFR_OP_HEADER *IfrOpCodeHeader;
36 EFI_IFR_CHECKBOX *IfrCheckBox;
37 EFI_IFR_DEFAULT *IfrDefault;
38
39 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage;
40
41 switch (HiiPackageHeader->Type) {
42 case EFI_HII_PACKAGE_FORMS:
43 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1);
44 while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) {
45 switch (IfrOpCodeHeader->OpCode) {
46 case EFI_IFR_CHECKBOX_OP:
47 IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader;
48 if ((IfrCheckBox->Question.QuestionId >= KEY_TPM2_PCR_BANKS_REQUEST_0) && (IfrCheckBox->Question.QuestionId <= KEY_TPM2_PCR_BANKS_REQUEST_4)) {
49 IfrDefault = (EFI_IFR_DEFAULT *)(IfrCheckBox + 1);
50 ASSERT (IfrDefault->Header.OpCode == EFI_IFR_DEFAULT_OP);
51 ASSERT (IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN);
52 IfrDefault->Value.b = (BOOLEAN)((PCRBanks >> (IfrCheckBox->Question.QuestionId - KEY_TPM2_PCR_BANKS_REQUEST_0)) & 0x1);
53 }
54 break;
55 }
56 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
57 }
58 break;
59 }
60 return ;
61 }
62
63 /**
64 The entry point for Tcg2 configuration driver.
65
66 @param[in] ImageHandle The image handle of the driver.
67 @param[in] SystemTable The system table.
68
69 @retval EFI_ALREADY_STARTED The driver already exists in system.
70 @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of resources.
71 @retval EFI_SUCCES All the related protocols are installed on the driver.
72 @retval Others Fail to install protocols as indicated.
73
74 **/
75 EFI_STATUS
76 EFIAPI
77 Tcg2ConfigDriverEntryPoint (
78 IN EFI_HANDLE ImageHandle,
79 IN EFI_SYSTEM_TABLE *SystemTable
80 )
81 {
82 EFI_STATUS Status;
83 TCG2_CONFIG_PRIVATE_DATA *PrivateData;
84 TCG2_CONFIGURATION Tcg2Configuration;
85 TCG2_DEVICE_DETECTION Tcg2DeviceDetection;
86 UINTN Index;
87 UINTN DataSize;
88 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
89 UINT32 CurrentActivePCRBanks;
90
91 Status = gBS->OpenProtocol (
92 ImageHandle,
93 &gEfiCallerIdGuid,
94 NULL,
95 ImageHandle,
96 ImageHandle,
97 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
98 );
99 if (!EFI_ERROR (Status)) {
100 return EFI_ALREADY_STARTED;
101 }
102
103 //
104 // Create a private data structure.
105 //
106 PrivateData = AllocateCopyPool (sizeof (TCG2_CONFIG_PRIVATE_DATA), &mTcg2ConfigPrivateDateTemplate);
107 ASSERT (PrivateData != NULL);
108 mTcg2ConfigPrivateDate = PrivateData;
109 //
110 // Install private GUID.
111 //
112 Status = gBS->InstallMultipleProtocolInterfaces (
113 &ImageHandle,
114 &gEfiCallerIdGuid,
115 PrivateData,
116 NULL
117 );
118 ASSERT_EFI_ERROR (Status);
119
120 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &PrivateData->Tcg2Protocol);
121 ASSERT_EFI_ERROR (Status);
122
123 PrivateData->ProtocolCapability.Size = sizeof(PrivateData->ProtocolCapability);
124 Status = PrivateData->Tcg2Protocol->GetCapability (
125 PrivateData->Tcg2Protocol,
126 &PrivateData->ProtocolCapability
127 );
128 ASSERT_EFI_ERROR (Status);
129
130 DataSize = sizeof(Tcg2Configuration);
131 Status = gRT->GetVariable (
132 TCG2_STORAGE_NAME,
133 &gTcg2ConfigFormSetGuid,
134 NULL,
135 &DataSize,
136 &Tcg2Configuration
137 );
138 if (EFI_ERROR (Status)) {
139 //
140 // Variable not ready, set default value
141 //
142 Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;
143 }
144
145 //
146 // Validation
147 //
148 if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) {
149 Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;
150 }
151
152 //
153 // Set value for Tcg2CurrentActivePCRBanks
154 // Search Tcg2ConfigBin[] and update default value there
155 //
156 Status = PrivateData->Tcg2Protocol->GetActivePcrBanks (PrivateData->Tcg2Protocol, &CurrentActivePCRBanks);
157 ASSERT_EFI_ERROR (Status);
158 PrivateData->PCRBanksDesired = CurrentActivePCRBanks;
159 UpdateDefaultPCRBanks (Tcg2ConfigBin + sizeof(UINT32), ReadUnaligned32((UINT32 *)Tcg2ConfigBin) - sizeof(UINT32), CurrentActivePCRBanks);
160
161 //
162 // Sync data from PCD to variable, so that we do not need detect again in S3 phase.
163 //
164 Tcg2DeviceDetection.TpmDeviceDetected = TPM_DEVICE_NULL;
165 for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
166 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {
167 Tcg2DeviceDetection.TpmDeviceDetected = mTpmInstanceId[Index].TpmDevice;
168 break;
169 }
170 }
171
172 PrivateData->TpmDeviceDetected = Tcg2DeviceDetection.TpmDeviceDetected;
173 Tcg2Configuration.TpmDevice = Tcg2DeviceDetection.TpmDeviceDetected;
174
175 //
176 // Save to variable so platform driver can get it.
177 //
178 Status = gRT->SetVariable (
179 TCG2_DEVICE_DETECTION_NAME,
180 &gTcg2ConfigFormSetGuid,
181 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
182 sizeof(Tcg2DeviceDetection),
183 &Tcg2DeviceDetection
184 );
185 if (EFI_ERROR (Status)) {
186 DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_DEVICE_DETECTION_NAME\n"));
187 Status = gRT->SetVariable (
188 TCG2_DEVICE_DETECTION_NAME,
189 &gTcg2ConfigFormSetGuid,
190 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
191 0,
192 NULL
193 );
194 ASSERT_EFI_ERROR (Status);
195 }
196
197 //
198 // Save to variable so platform driver can get it.
199 //
200 Status = gRT->SetVariable (
201 TCG2_STORAGE_NAME,
202 &gTcg2ConfigFormSetGuid,
203 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
204 sizeof(Tcg2Configuration),
205 &Tcg2Configuration
206 );
207 if (EFI_ERROR (Status)) {
208 DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_STORAGE_NAME\n"));
209 }
210
211 //
212 // We should lock Tcg2DeviceDetection, because it contains information needed at S3.
213 //
214 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
215 if (!EFI_ERROR (Status)) {
216 Status = VariableLockProtocol->RequestToLock (
217 VariableLockProtocol,
218 TCG2_DEVICE_DETECTION_NAME,
219 &gTcg2ConfigFormSetGuid
220 );
221 ASSERT_EFI_ERROR (Status);
222 }
223
224 //
225 // Install Tcg2 configuration form
226 //
227 Status = InstallTcg2ConfigForm (PrivateData);
228 if (EFI_ERROR (Status)) {
229 goto ErrorExit;
230 }
231
232 return EFI_SUCCESS;
233
234 ErrorExit:
235 if (PrivateData != NULL) {
236 UninstallTcg2ConfigForm (PrivateData);
237 }
238
239 return Status;
240 }
241
242 /**
243 Unload the Tcg2 configuration form.
244
245 @param[in] ImageHandle The driver's image handle.
246
247 @retval EFI_SUCCESS The Tcg2 configuration form is unloaded.
248 @retval Others Failed to unload the form.
249
250 **/
251 EFI_STATUS
252 EFIAPI
253 Tcg2ConfigDriverUnload (
254 IN EFI_HANDLE ImageHandle
255 )
256 {
257 EFI_STATUS Status;
258 TCG2_CONFIG_PRIVATE_DATA *PrivateData;
259
260 Status = gBS->HandleProtocol (
261 ImageHandle,
262 &gEfiCallerIdGuid,
263 (VOID **) &PrivateData
264 );
265 if (EFI_ERROR (Status)) {
266 return Status;
267 }
268
269 ASSERT (PrivateData->Signature == TCG2_CONFIG_PRIVATE_DATA_SIGNATURE);
270
271 gBS->UninstallMultipleProtocolInterfaces (
272 &ImageHandle,
273 &gEfiCallerIdGuid,
274 PrivateData,
275 NULL
276 );
277
278 UninstallTcg2ConfigForm (PrivateData);
279
280 return EFI_SUCCESS;
281 }