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