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 } 282