Update for SecurityPkg.
[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
ea71453f 134 ZeroMem (&Configuration, sizeof (Configuration));\r
bc0c99b3 135 PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);\r
136 *Progress = Request;\r
137 \r
beda2356 138 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {\r
139 return EFI_NOT_FOUND;\r
140 }\r
141\r
bc0c99b3 142 \r
beda2356 143 //\r
144 // Get the SecureBoot Variable\r
145 //\r
bc0c99b3 146 SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid);\r
147\r
beda2356 148 //\r
149 // If the SecureBoot Variable doesn't exist, hide the SecureBoot Enable/Disable\r
150 // Checkbox.\r
151 //\r
152 if (SecureBootEnable == NULL) {\r
153 Configuration.HideSecureBoot = TRUE;\r
154 } else {\r
155 Configuration.HideSecureBoot = FALSE;\r
156 Configuration.SecureBootState = *SecureBootEnable;\r
157 }\r
158 \r
bc0c99b3 159 BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
beda2356 160 ConfigRequest = Request;\r
bc0c99b3 161 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
162 //\r
163 // Request is set to NULL or OFFSET is NULL, construct full request string.\r
164 //\r
165\r
166 //\r
167 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
168 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
169 //\r
170 ConfigRequestHdr = HiiConstructConfigHdr (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, PrivateData->DriverHandle);\r
171 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
172 ConfigRequest = AllocateZeroPool (Size);\r
173 ASSERT (ConfigRequest != NULL);\r
174 AllocatedRequest = TRUE;\r
175 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
176 FreePool (ConfigRequestHdr);\r
177 ConfigRequestHdr = NULL;\r
178 }\r
beda2356 179\r
180 Status = gHiiConfigRouting->BlockToConfig (\r
181 gHiiConfigRouting,\r
182 ConfigRequest,\r
183 (UINT8 *) &Configuration,\r
184 BufferSize,\r
185 Results,\r
186 Progress\r
187 );\r
bc0c99b3 188\r
189 //\r
190 // Free the allocated config request string.\r
191 //\r
192 if (AllocatedRequest) {\r
193 FreePool (ConfigRequest);\r
194 }\r
195\r
beda2356 196 //\r
197 // Set Progress string to the original request string.\r
198 //\r
199 if (Request == NULL) {\r
200 *Progress = NULL;\r
201 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
202 *Progress = Request + StrLen (Request);\r
203 }\r
204\r
205 return Status;\r
206}\r
207\r
208/**\r
209 This function processes the results of changes in configuration.\r
210\r
211 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
212 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
213 format.\r
214 @param[out] Progress A pointer to a string filled in with the offset of\r
215 the most recent '&' before the first failing\r
216 name/value pair (or the beginning of the string if\r
217 the failure is in the first name/value pair) or\r
218 the terminating NULL if all was successful.\r
219\r
220 @retval EFI_SUCCESS The Results is processed successfully.\r
221 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
222 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
223 driver.\r
224\r
225**/\r
226EFI_STATUS\r
227EFIAPI\r
228SecureBootRouteConfig (\r
229 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
230 IN CONST EFI_STRING Configuration,\r
231 OUT EFI_STRING *Progress\r
232 )\r
233{\r
234 EFI_STATUS Status;\r
235 UINTN BufferSize;\r
236 SECUREBOOT_CONFIGURATION SecureBootConfiguration;\r
237 UINT8 *SecureBootEnable;\r
bc0c99b3 238\r
beda2356 239\r
240 if (Configuration == NULL || Progress == NULL) {\r
241 return EFI_INVALID_PARAMETER;\r
242 }\r
243\r
244 *Progress = Configuration;\r
245 if (!HiiIsConfigHdrMatch (Configuration, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {\r
246 return EFI_NOT_FOUND;\r
247 }\r
248\r
249 //\r
250 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
251 //\r
252 BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
253 Status = gHiiConfigRouting->ConfigToBlock (\r
254 gHiiConfigRouting,\r
255 Configuration,\r
256 (UINT8 *) &SecureBootConfiguration,\r
257 &BufferSize,\r
258 Progress\r
259 );\r
260 if (EFI_ERROR (Status)) {\r
261 return Status;\r
262 }\r
263\r
bc0c99b3 264 SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid);\r
beda2356 265 if (SecureBootEnable == NULL) {\r
266 return EFI_SUCCESS;\r
bc0c99b3 267 }\r
268\r
beda2356 269 if ((*SecureBootEnable) != SecureBootConfiguration.SecureBootState) {\r
270 //\r
271 // If the configure is changed, update the SecureBoot Variable.\r
272 //\r
bc0c99b3 273 SaveSecureBootVariable (SecureBootConfiguration.SecureBootState);\r
274 }\r
beda2356 275 return EFI_SUCCESS;\r
276}\r
277\r
278/**\r
279 This function processes the results of changes in configuration.\r
280\r
281 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
282 @param[in] Action Specifies the type of action taken by the browser.\r
283 @param[in] QuestionId A unique value which is sent to the original\r
284 exporting driver so that it can identify the type\r
285 of data to expect.\r
286 @param[in] Type The type of value for the question.\r
287 @param[in] Value A pointer to the data being sent to the original\r
288 exporting driver.\r
289 @param[out] ActionRequest On return, points to the action requested by the\r
290 callback function.\r
291\r
292 @retval EFI_SUCCESS The callback successfully handled the action.\r
293 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
294 variable and its data.\r
295 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
296 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
297 callback.\r
298\r
299**/\r
300EFI_STATUS\r
301EFIAPI\r
302SecureBootCallback (\r
303 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
304 IN EFI_BROWSER_ACTION Action,\r
305 IN EFI_QUESTION_ID QuestionId,\r
306 IN UINT8 Type,\r
307 IN EFI_IFR_TYPE_VALUE *Value,\r
308 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
309 )\r
310{\r
311 BOOLEAN SecureBootEnable;\r
bc0c99b3 312\r
beda2356 313 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
314 return EFI_INVALID_PARAMETER;\r
315 }\r
316\r
fab10465 317 if ((Action != EFI_BROWSER_ACTION_CHANGED) || (QuestionId != KEY_SECURE_BOOT_ENABLE)) {\r
beda2356 318 return EFI_UNSUPPORTED;\r
319 }\r
bc0c99b3 320\r
beda2356 321 if (NULL == GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid)) {\r
322 return EFI_SUCCESS;\r
323 }\r
bc0c99b3 324\r
beda2356 325 SecureBootEnable = Value->u8;\r
bc0c99b3 326 SaveSecureBootVariable (Value->u8);\r
beda2356 327 return EFI_SUCCESS;\r
328\r
329}\r
330\r
331/**\r
332 This function publish the SecureBoot configuration Form.\r
333\r
334 @param[in, out] PrivateData Points to SecureBoot configuration private data.\r
335\r
336 @retval EFI_SUCCESS HII Form is installed for this network device.\r
337 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
338 @retval Others Other errors as indicated.\r
339\r
340**/\r
341EFI_STATUS\r
342InstallSecureBootConfigForm (\r
343 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData\r
344 )\r
345{\r
346 EFI_STATUS Status;\r
347 EFI_HII_HANDLE HiiHandle;\r
348 EFI_HANDLE DriverHandle;\r
349\r
350 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
351\r
352 DriverHandle = NULL;\r
353 ConfigAccess = &PrivateData->ConfigAccess;\r
354 Status = gBS->InstallMultipleProtocolInterfaces (\r
355 &DriverHandle,\r
356 &gEfiDevicePathProtocolGuid,\r
357 &mSecureBootHiiVendorDevicePath,\r
358 &gEfiHiiConfigAccessProtocolGuid,\r
359 ConfigAccess,\r
360 NULL\r
361 );\r
362 if (EFI_ERROR (Status)) {\r
363 return Status;\r
364 }\r
365\r
366 PrivateData->DriverHandle = DriverHandle;\r
367\r
368 //\r
369 // Publish the HII package list\r
370 //\r
371 HiiHandle = HiiAddPackages (\r
372 &gSecureBootConfigFormSetGuid,\r
373 DriverHandle,\r
374 SecureBootConfigDxeStrings,\r
375 SecureBootConfigBin,\r
376 NULL\r
377 );\r
378 if (HiiHandle == NULL) {\r
379 gBS->UninstallMultipleProtocolInterfaces (\r
380 DriverHandle,\r
381 &gEfiDevicePathProtocolGuid,\r
382 &mSecureBootHiiVendorDevicePath,\r
383 &gEfiHiiConfigAccessProtocolGuid,\r
384 ConfigAccess,\r
385 NULL\r
bc0c99b3 386 );\r
beda2356 387\r
388 return EFI_OUT_OF_RESOURCES;\r
389 }\r
bc0c99b3 390\r
beda2356 391 PrivateData->HiiHandle = HiiHandle;\r
bc0c99b3 392 return EFI_SUCCESS;\r
beda2356 393}\r
394\r
395/**\r
396 This function removes SecureBoot configuration Form.\r
397\r
398 @param[in, out] PrivateData Points to SecureBoot configuration private data.\r
399\r
400**/\r
401VOID\r
402UninstallSecureBootConfigForm (\r
403 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData\r
404 )\r
405{\r
406 //\r
407 // Uninstall HII package list\r
408 //\r
409 if (PrivateData->HiiHandle != NULL) {\r
410 HiiRemovePackages (PrivateData->HiiHandle);\r
411 PrivateData->HiiHandle = NULL;\r
412 }\r
413\r
414 //\r
415 // Uninstall HII Config Access Protocol\r
416 //\r
417 if (PrivateData->DriverHandle != NULL) {\r
418 gBS->UninstallMultipleProtocolInterfaces (\r
419 PrivateData->DriverHandle,\r
420 &gEfiDevicePathProtocolGuid,\r
421 &mSecureBootHiiVendorDevicePath,\r
422 &gEfiHiiConfigAccessProtocolGuid,\r
423 &PrivateData->ConfigAccess,\r
424 NULL\r
425 );\r
426 PrivateData->DriverHandle = NULL;\r
427 }\r
bc0c99b3 428\r
beda2356 429 FreePool (PrivateData);\r
430}\r