Enable/Disable Secured Boot by 'Secure Boot Configuration' Page which is under Setup...
[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
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
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
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
43 { \r
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
65 \r
66 Status = gRT->SetVariable (\r
67 EFI_SECURE_BOOT_ENABLE_NAME, \r
68 &gEfiSecureBootEnableDisableGuid,\r
69 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, \r
70 sizeof (UINT8), \r
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
117 SECUREBOOT_CONFIGURATION Configuration;\r
118 \r
119 EFI_STRING ConfigRequest;\r
120 UINT8 *SecureBootEnable;\r
121 \r
122 if (Progress == NULL || Results == NULL) {\r
123 return EFI_INVALID_PARAMETER;\r
124 }\r
125\r
126 *Progress = Request;\r
127 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {\r
128 return EFI_NOT_FOUND;\r
129 }\r
130\r
131 //\r
132 // Get the SecureBoot Variable\r
133 //\r
134 SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid); \r
135 \r
136 //\r
137 // If the SecureBoot Variable doesn't exist, hide the SecureBoot Enable/Disable\r
138 // Checkbox.\r
139 //\r
140 if (SecureBootEnable == NULL) {\r
141 Configuration.HideSecureBoot = TRUE;\r
142 } else {\r
143 Configuration.HideSecureBoot = FALSE;\r
144 Configuration.SecureBootState = *SecureBootEnable;\r
145 }\r
146 \r
147 BufferSize = sizeof (Configuration);\r
148 ConfigRequest = Request;\r
149\r
150 Status = gHiiConfigRouting->BlockToConfig (\r
151 gHiiConfigRouting,\r
152 ConfigRequest,\r
153 (UINT8 *) &Configuration,\r
154 BufferSize,\r
155 Results,\r
156 Progress\r
157 );\r
158 \r
159 //\r
160 // Set Progress string to the original request string.\r
161 //\r
162 if (Request == NULL) {\r
163 *Progress = NULL;\r
164 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
165 *Progress = Request + StrLen (Request);\r
166 }\r
167\r
168 return Status;\r
169}\r
170\r
171/**\r
172 This function processes the results of changes in configuration.\r
173\r
174 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
175 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
176 format.\r
177 @param[out] Progress A pointer to a string filled in with the offset of\r
178 the most recent '&' before the first failing\r
179 name/value pair (or the beginning of the string if\r
180 the failure is in the first name/value pair) or\r
181 the terminating NULL if all was successful.\r
182\r
183 @retval EFI_SUCCESS The Results is processed successfully.\r
184 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
185 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
186 driver.\r
187\r
188**/\r
189EFI_STATUS\r
190EFIAPI\r
191SecureBootRouteConfig (\r
192 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
193 IN CONST EFI_STRING Configuration,\r
194 OUT EFI_STRING *Progress\r
195 )\r
196{\r
197 EFI_STATUS Status;\r
198 UINTN BufferSize;\r
199 SECUREBOOT_CONFIGURATION SecureBootConfiguration;\r
200 UINT8 *SecureBootEnable;\r
201 \r
202\r
203 if (Configuration == NULL || Progress == NULL) {\r
204 return EFI_INVALID_PARAMETER;\r
205 }\r
206\r
207 *Progress = Configuration;\r
208 if (!HiiIsConfigHdrMatch (Configuration, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {\r
209 return EFI_NOT_FOUND;\r
210 }\r
211\r
212 //\r
213 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
214 //\r
215 BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
216 Status = gHiiConfigRouting->ConfigToBlock (\r
217 gHiiConfigRouting,\r
218 Configuration,\r
219 (UINT8 *) &SecureBootConfiguration,\r
220 &BufferSize,\r
221 Progress\r
222 );\r
223 if (EFI_ERROR (Status)) {\r
224 return Status;\r
225 }\r
226\r
227 SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid); \r
228 if (SecureBootEnable == NULL) {\r
229 return EFI_SUCCESS;\r
230 } \r
231 \r
232 if ((*SecureBootEnable) != SecureBootConfiguration.SecureBootState) {\r
233 //\r
234 // If the configure is changed, update the SecureBoot Variable.\r
235 //\r
236 SaveSecureBootVariable (SecureBootConfiguration.SecureBootState); \r
237 } \r
238 return EFI_SUCCESS;\r
239}\r
240\r
241/**\r
242 This function processes the results of changes in configuration.\r
243\r
244 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
245 @param[in] Action Specifies the type of action taken by the browser.\r
246 @param[in] QuestionId A unique value which is sent to the original\r
247 exporting driver so that it can identify the type\r
248 of data to expect.\r
249 @param[in] Type The type of value for the question.\r
250 @param[in] Value A pointer to the data being sent to the original\r
251 exporting driver.\r
252 @param[out] ActionRequest On return, points to the action requested by the\r
253 callback function.\r
254\r
255 @retval EFI_SUCCESS The callback successfully handled the action.\r
256 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
257 variable and its data.\r
258 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
259 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
260 callback.\r
261\r
262**/\r
263EFI_STATUS\r
264EFIAPI\r
265SecureBootCallback (\r
266 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
267 IN EFI_BROWSER_ACTION Action,\r
268 IN EFI_QUESTION_ID QuestionId,\r
269 IN UINT8 Type,\r
270 IN EFI_IFR_TYPE_VALUE *Value,\r
271 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
272 )\r
273{\r
274 BOOLEAN SecureBootEnable;\r
275 \r
276 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
277 return EFI_INVALID_PARAMETER;\r
278 }\r
279\r
280 if ((Action != EFI_BROWSER_ACTION_CHANGING) || (QuestionId != KEY_SECURE_BOOT_ENABLE)) {\r
281 return EFI_UNSUPPORTED;\r
282 }\r
283 \r
284 if (NULL == GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid)) {\r
285 return EFI_SUCCESS;\r
286 }\r
287 \r
288 SecureBootEnable = Value->u8;\r
289 SaveSecureBootVariable (Value->u8); \r
290 return EFI_SUCCESS;\r
291\r
292}\r
293\r
294/**\r
295 This function publish the SecureBoot configuration Form.\r
296\r
297 @param[in, out] PrivateData Points to SecureBoot configuration private data.\r
298\r
299 @retval EFI_SUCCESS HII Form is installed for this network device.\r
300 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
301 @retval Others Other errors as indicated.\r
302\r
303**/\r
304EFI_STATUS\r
305InstallSecureBootConfigForm (\r
306 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData\r
307 )\r
308{\r
309 EFI_STATUS Status;\r
310 EFI_HII_HANDLE HiiHandle;\r
311 EFI_HANDLE DriverHandle;\r
312\r
313 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
314\r
315 DriverHandle = NULL;\r
316 ConfigAccess = &PrivateData->ConfigAccess;\r
317 Status = gBS->InstallMultipleProtocolInterfaces (\r
318 &DriverHandle,\r
319 &gEfiDevicePathProtocolGuid,\r
320 &mSecureBootHiiVendorDevicePath,\r
321 &gEfiHiiConfigAccessProtocolGuid,\r
322 ConfigAccess,\r
323 NULL\r
324 );\r
325 if (EFI_ERROR (Status)) {\r
326 return Status;\r
327 }\r
328\r
329 PrivateData->DriverHandle = DriverHandle;\r
330\r
331 //\r
332 // Publish the HII package list\r
333 //\r
334 HiiHandle = HiiAddPackages (\r
335 &gSecureBootConfigFormSetGuid,\r
336 DriverHandle,\r
337 SecureBootConfigDxeStrings,\r
338 SecureBootConfigBin,\r
339 NULL\r
340 );\r
341 if (HiiHandle == NULL) {\r
342 gBS->UninstallMultipleProtocolInterfaces (\r
343 DriverHandle,\r
344 &gEfiDevicePathProtocolGuid,\r
345 &mSecureBootHiiVendorDevicePath,\r
346 &gEfiHiiConfigAccessProtocolGuid,\r
347 ConfigAccess,\r
348 NULL\r
349 ); \r
350\r
351 return EFI_OUT_OF_RESOURCES;\r
352 }\r
353 \r
354 PrivateData->HiiHandle = HiiHandle;\r
355 return EFI_SUCCESS; \r
356}\r
357\r
358/**\r
359 This function removes SecureBoot configuration Form.\r
360\r
361 @param[in, out] PrivateData Points to SecureBoot configuration private data.\r
362\r
363**/\r
364VOID\r
365UninstallSecureBootConfigForm (\r
366 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData\r
367 )\r
368{\r
369 //\r
370 // Uninstall HII package list\r
371 //\r
372 if (PrivateData->HiiHandle != NULL) {\r
373 HiiRemovePackages (PrivateData->HiiHandle);\r
374 PrivateData->HiiHandle = NULL;\r
375 }\r
376\r
377 //\r
378 // Uninstall HII Config Access Protocol\r
379 //\r
380 if (PrivateData->DriverHandle != NULL) {\r
381 gBS->UninstallMultipleProtocolInterfaces (\r
382 PrivateData->DriverHandle,\r
383 &gEfiDevicePathProtocolGuid,\r
384 &mSecureBootHiiVendorDevicePath,\r
385 &gEfiHiiConfigAccessProtocolGuid,\r
386 &PrivateData->ConfigAccess,\r
387 NULL\r
388 );\r
389 PrivateData->DriverHandle = NULL;\r
390 }\r
391 \r
392 FreePool (PrivateData);\r
393}\r