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