]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
Change IPF version AuthVariable driver to support multiple-platform feature.
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / SecureBootConfigDxe / SecureBootConfigImpl.c
CommitLineData
beda2356 1/** @file\r
2 HII Config Access protocol implementation of SecureBoot configuration module.\r
3\r
4Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
bc0c99b3 5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
beda2356 8http://opensource.org/licenses/bsd-license.php\r
9\r
bc0c99b3 10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
beda2356 11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "SecureBootConfigImpl.h"\r
16\r
17CHAR16 mSecureBootStorageName[] = L"SECUREBOOT_CONFIGURATION";\r
18\r
19SECUREBOOT_CONFIG_PRIVATE_DATA mSecureBootConfigPrivateDateTemplate = {\r
20 SECUREBOOT_CONFIG_PRIVATE_DATA_SIGNATURE,\r
21 {\r
22 SecureBootExtractConfig,\r
23 SecureBootRouteConfig,\r
24 SecureBootCallback\r
25 }\r
26};\r
27\r
28HII_VENDOR_DEVICE_PATH mSecureBootHiiVendorDevicePath = {\r
29 {\r
30 {\r
31 HARDWARE_DEVICE_PATH,\r
32 HW_VENDOR_DP,\r
33 {\r
34 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
35 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
36 }\r
37 },\r
38 SECUREBOOT_CONFIG_FORM_SET_GUID\r
39 },\r
40 {\r
41 END_DEVICE_PATH_TYPE,\r
42 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
bc0c99b3 43 {\r
beda2356 44 (UINT8) (END_DEVICE_PATH_LENGTH),\r
45 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
46 }\r
47 }\r
48};\r
49\r
50/**\r
51 Save Secure Boot option to variable space.\r
52\r
53 @param[in] VarValue The option of Secure Boot.\r
54\r
55 @retval EFI_SUCCESS The operation is finished successfully.\r
56 @retval Others Other errors as indicated.\r
57\r
58**/\r
59EFI_STATUS\r
60SaveSecureBootVariable (\r
61 IN UINT8 VarValue\r
62 )\r
63{\r
64 EFI_STATUS Status;\r
bc0c99b3 65\r
beda2356 66 Status = gRT->SetVariable (\r
bc0c99b3 67 EFI_SECURE_BOOT_ENABLE_NAME,\r
beda2356 68 &gEfiSecureBootEnableDisableGuid,\r
bc0c99b3 69 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
70 sizeof (UINT8),\r
beda2356 71 &VarValue\r
72 );\r
73 if (EFI_ERROR (Status)) {\r
74 return Status;\r
75 }\r
76 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
77 return EFI_SUCCESS;\r
78}\r
79\r
80/**\r
81 This function allows a caller to extract the current configuration for one\r
82 or more named elements from the target driver.\r
83\r
84 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
85 @param[in] Request A null-terminated Unicode string in\r
86 <ConfigRequest> format.\r
87 @param[out] Progress On return, points to a character in the Request\r
88 string. Points to the string's null terminator if\r
89 request was successful. Points to the most recent\r
90 '&' before the first failing name/value pair (or\r
91 the beginning of the string if the failure is in\r
92 the first name/value pair) if the request was not\r
93 successful.\r
94 @param[out] Results A null-terminated Unicode string in\r
95 <ConfigAltResp> format which has all values filled\r
96 in for the names in the Request string. String to\r
97 be allocated by the called function.\r
98\r
99 @retval EFI_SUCCESS The Results is filled with the requested values.\r
100 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
101 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
102 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
103 driver.\r
104\r
105**/\r
106EFI_STATUS\r
107EFIAPI\r
108SecureBootExtractConfig (\r
109 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
110 IN CONST EFI_STRING Request,\r
111 OUT EFI_STRING *Progress,\r
112 OUT EFI_STRING *Results\r
113 )\r
114{\r
115 EFI_STATUS Status;\r
116 UINTN BufferSize;\r
bc0c99b3 117 UINTN Size;\r
beda2356 118 SECUREBOOT_CONFIGURATION Configuration;\r
bc0c99b3 119\r
beda2356 120 EFI_STRING ConfigRequest;\r
bc0c99b3 121 EFI_STRING ConfigRequestHdr;\r
beda2356 122 UINT8 *SecureBootEnable;\r
bc0c99b3 123 SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData;\r
124 BOOLEAN AllocatedRequest;\r
125\r
beda2356 126 if (Progress == NULL || Results == NULL) {\r
127 return EFI_INVALID_PARAMETER;\r
128 }\r
bc0c99b3 129 AllocatedRequest = FALSE;\r
130 ConfigRequestHdr = NULL;\r
131 ConfigRequest = NULL;\r
132 Size = 0;\r
133 \r
134 PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);\r
135 *Progress = Request;\r
136 \r
beda2356 137 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {\r
138 return EFI_NOT_FOUND;\r
139 }\r
140\r
bc0c99b3 141 \r
beda2356 142 //\r
143 // Get the SecureBoot Variable\r
144 //\r
bc0c99b3 145 SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid);\r
146\r
beda2356 147 //\r
148 // If the SecureBoot Variable doesn't exist, hide the SecureBoot Enable/Disable\r
149 // Checkbox.\r
150 //\r
151 if (SecureBootEnable == NULL) {\r
152 Configuration.HideSecureBoot = TRUE;\r
153 } else {\r
154 Configuration.HideSecureBoot = FALSE;\r
155 Configuration.SecureBootState = *SecureBootEnable;\r
156 }\r
157 \r
bc0c99b3 158 BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
beda2356 159 ConfigRequest = Request;\r
bc0c99b3 160 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
161 //\r
162 // Request is set to NULL or OFFSET is NULL, construct full request string.\r
163 //\r
164\r
165 //\r
166 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
167 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
168 //\r
169 ConfigRequestHdr = HiiConstructConfigHdr (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, PrivateData->DriverHandle);\r
170 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
171 ConfigRequest = AllocateZeroPool (Size);\r
172 ASSERT (ConfigRequest != NULL);\r
173 AllocatedRequest = TRUE;\r
174 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
175 FreePool (ConfigRequestHdr);\r
176 ConfigRequestHdr = NULL;\r
177 }\r
beda2356 178\r
179 Status = gHiiConfigRouting->BlockToConfig (\r
180 gHiiConfigRouting,\r
181 ConfigRequest,\r
182 (UINT8 *) &Configuration,\r
183 BufferSize,\r
184 Results,\r
185 Progress\r
186 );\r
bc0c99b3 187\r
188 //\r
189 // Free the allocated config request string.\r
190 //\r
191 if (AllocatedRequest) {\r
192 FreePool (ConfigRequest);\r
193 }\r
194\r
beda2356 195 //\r
196 // Set Progress string to the original request string.\r
197 //\r
198 if (Request == NULL) {\r
199 *Progress = NULL;\r
200 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
201 *Progress = Request + StrLen (Request);\r
202 }\r
203\r
204 return Status;\r
205}\r
206\r
207/**\r
208 This function processes the results of changes in configuration.\r
209\r
210 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
211 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
212 format.\r
213 @param[out] Progress A pointer to a string filled in with the offset of\r
214 the most recent '&' before the first failing\r
215 name/value pair (or the beginning of the string if\r
216 the failure is in the first name/value pair) or\r
217 the terminating NULL if all was successful.\r
218\r
219 @retval EFI_SUCCESS The Results is processed successfully.\r
220 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
221 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
222 driver.\r
223\r
224**/\r
225EFI_STATUS\r
226EFIAPI\r
227SecureBootRouteConfig (\r
228 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
229 IN CONST EFI_STRING Configuration,\r
230 OUT EFI_STRING *Progress\r
231 )\r
232{\r
233 EFI_STATUS Status;\r
234 UINTN BufferSize;\r
235 SECUREBOOT_CONFIGURATION SecureBootConfiguration;\r
236 UINT8 *SecureBootEnable;\r
bc0c99b3 237\r
beda2356 238\r
239 if (Configuration == NULL || Progress == NULL) {\r
240 return EFI_INVALID_PARAMETER;\r
241 }\r
242\r
243 *Progress = Configuration;\r
244 if (!HiiIsConfigHdrMatch (Configuration, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {\r
245 return EFI_NOT_FOUND;\r
246 }\r
247\r
248 //\r
249 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
250 //\r
251 BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
252 Status = gHiiConfigRouting->ConfigToBlock (\r
253 gHiiConfigRouting,\r
254 Configuration,\r
255 (UINT8 *) &SecureBootConfiguration,\r
256 &BufferSize,\r
257 Progress\r
258 );\r
259 if (EFI_ERROR (Status)) {\r
260 return Status;\r
261 }\r
262\r
bc0c99b3 263 SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid);\r
beda2356 264 if (SecureBootEnable == NULL) {\r
265 return EFI_SUCCESS;\r
bc0c99b3 266 }\r
267\r
beda2356 268 if ((*SecureBootEnable) != SecureBootConfiguration.SecureBootState) {\r
269 //\r
270 // If the configure is changed, update the SecureBoot Variable.\r
271 //\r
bc0c99b3 272 SaveSecureBootVariable (SecureBootConfiguration.SecureBootState);\r
273 }\r
beda2356 274 return EFI_SUCCESS;\r
275}\r
276\r
277/**\r
278 This function processes the results of changes in configuration.\r
279\r
280 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
281 @param[in] Action Specifies the type of action taken by the browser.\r
282 @param[in] QuestionId A unique value which is sent to the original\r
283 exporting driver so that it can identify the type\r
284 of data to expect.\r
285 @param[in] Type The type of value for the question.\r
286 @param[in] Value A pointer to the data being sent to the original\r
287 exporting driver.\r
288 @param[out] ActionRequest On return, points to the action requested by the\r
289 callback function.\r
290\r
291 @retval EFI_SUCCESS The callback successfully handled the action.\r
292 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
293 variable and its data.\r
294 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
295 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
296 callback.\r
297\r
298**/\r
299EFI_STATUS\r
300EFIAPI\r
301SecureBootCallback (\r
302 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
303 IN EFI_BROWSER_ACTION Action,\r
304 IN EFI_QUESTION_ID QuestionId,\r
305 IN UINT8 Type,\r
306 IN EFI_IFR_TYPE_VALUE *Value,\r
307 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
308 )\r
309{\r
310 BOOLEAN SecureBootEnable;\r
bc0c99b3 311\r
beda2356 312 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
313 return EFI_INVALID_PARAMETER;\r
314 }\r
315\r
316 if ((Action != EFI_BROWSER_ACTION_CHANGING) || (QuestionId != KEY_SECURE_BOOT_ENABLE)) {\r
317 return EFI_UNSUPPORTED;\r
318 }\r
bc0c99b3 319\r
beda2356 320 if (NULL == GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid)) {\r
321 return EFI_SUCCESS;\r
322 }\r
bc0c99b3 323\r
beda2356 324 SecureBootEnable = Value->u8;\r
bc0c99b3 325 SaveSecureBootVariable (Value->u8);\r
beda2356 326 return EFI_SUCCESS;\r
327\r
328}\r
329\r
330/**\r
331 This function publish the SecureBoot configuration Form.\r
332\r
333 @param[in, out] PrivateData Points to SecureBoot configuration private data.\r
334\r
335 @retval EFI_SUCCESS HII Form is installed for this network device.\r
336 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
337 @retval Others Other errors as indicated.\r
338\r
339**/\r
340EFI_STATUS\r
341InstallSecureBootConfigForm (\r
342 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData\r
343 )\r
344{\r
345 EFI_STATUS Status;\r
346 EFI_HII_HANDLE HiiHandle;\r
347 EFI_HANDLE DriverHandle;\r
348\r
349 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
350\r
351 DriverHandle = NULL;\r
352 ConfigAccess = &PrivateData->ConfigAccess;\r
353 Status = gBS->InstallMultipleProtocolInterfaces (\r
354 &DriverHandle,\r
355 &gEfiDevicePathProtocolGuid,\r
356 &mSecureBootHiiVendorDevicePath,\r
357 &gEfiHiiConfigAccessProtocolGuid,\r
358 ConfigAccess,\r
359 NULL\r
360 );\r
361 if (EFI_ERROR (Status)) {\r
362 return Status;\r
363 }\r
364\r
365 PrivateData->DriverHandle = DriverHandle;\r
366\r
367 //\r
368 // Publish the HII package list\r
369 //\r
370 HiiHandle = HiiAddPackages (\r
371 &gSecureBootConfigFormSetGuid,\r
372 DriverHandle,\r
373 SecureBootConfigDxeStrings,\r
374 SecureBootConfigBin,\r
375 NULL\r
376 );\r
377 if (HiiHandle == NULL) {\r
378 gBS->UninstallMultipleProtocolInterfaces (\r
379 DriverHandle,\r
380 &gEfiDevicePathProtocolGuid,\r
381 &mSecureBootHiiVendorDevicePath,\r
382 &gEfiHiiConfigAccessProtocolGuid,\r
383 ConfigAccess,\r
384 NULL\r
bc0c99b3 385 );\r
beda2356 386\r
387 return EFI_OUT_OF_RESOURCES;\r
388 }\r
bc0c99b3 389\r
beda2356 390 PrivateData->HiiHandle = HiiHandle;\r
bc0c99b3 391 return EFI_SUCCESS;\r
beda2356 392}\r
393\r
394/**\r
395 This function removes SecureBoot configuration Form.\r
396\r
397 @param[in, out] PrivateData Points to SecureBoot configuration private data.\r
398\r
399**/\r
400VOID\r
401UninstallSecureBootConfigForm (\r
402 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData\r
403 )\r
404{\r
405 //\r
406 // Uninstall HII package list\r
407 //\r
408 if (PrivateData->HiiHandle != NULL) {\r
409 HiiRemovePackages (PrivateData->HiiHandle);\r
410 PrivateData->HiiHandle = NULL;\r
411 }\r
412\r
413 //\r
414 // Uninstall HII Config Access Protocol\r
415 //\r
416 if (PrivateData->DriverHandle != NULL) {\r
417 gBS->UninstallMultipleProtocolInterfaces (\r
418 PrivateData->DriverHandle,\r
419 &gEfiDevicePathProtocolGuid,\r
420 &mSecureBootHiiVendorDevicePath,\r
421 &gEfiHiiConfigAccessProtocolGuid,\r
422 &PrivateData->ConfigAccess,\r
423 NULL\r
424 );\r
425 PrivateData->DriverHandle = NULL;\r
426 }\r
bc0c99b3 427\r
beda2356 428 FreePool (PrivateData);\r
429}\r