]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
SecurityPkg: Create library for enrolling Secure Boot variables.
[mirror_edk2.git] / SecurityPkg / Library / SecureBootVariableProvisionLib / SecureBootVariableProvisionLib.c
1 /** @file
2 This library provides functions to set/clear Secure Boot
3 keys and databases.
4
5 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
6 (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
7 Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
8 Copyright (c) 2021, Semihalf All rights reserved.<BR>
9 SPDX-License-Identifier: BSD-2-Clause-Patent
10 **/
11 #include <Guid/GlobalVariable.h>
12 #include <Guid/AuthenticatedVariableFormat.h>
13 #include <Guid/ImageAuthentication.h>
14 #include <Library/BaseLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/UefiLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/UefiRuntimeServicesTableLib.h>
20 #include <Library/SecureBootVariableLib.h>
21 #include <Library/SecureBootVariableProvisionLib.h>
22
23 /**
24 Enroll a key/certificate based on a default variable.
25
26 @param[in] VariableName The name of the key/database.
27 @param[in] DefaultName The name of the default variable.
28 @param[in] VendorGuid The namespace (ie. vendor GUID) of the variable
29
30 @retval EFI_OUT_OF_RESOURCES Out of memory while allocating AuthHeader.
31 @retval EFI_SUCCESS Successful enrollment.
32 @return Error codes from GetTime () and SetVariable ().
33 **/
34 STATIC
35 EFI_STATUS
36 EnrollFromDefault (
37 IN CHAR16 *VariableName,
38 IN CHAR16 *DefaultName,
39 IN EFI_GUID *VendorGuid
40 )
41 {
42 VOID *Data;
43 UINTN DataSize;
44 EFI_STATUS Status;
45
46 Status = EFI_SUCCESS;
47
48 DataSize = 0;
49 Status = GetVariable2 (DefaultName, &gEfiGlobalVariableGuid, &Data, &DataSize);
50 if (EFI_ERROR (Status)) {
51 DEBUG ((DEBUG_ERROR, "error: GetVariable (\"%s): %r\n", DefaultName, Status));
52 return Status;
53 }
54
55 CreateTimeBasedPayload (&DataSize, (UINT8 **)&Data);
56 if (EFI_ERROR (Status)) {
57 DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
58 return Status;
59 }
60
61 //
62 // Allocate memory for auth variable
63 //
64 Status = gRT->SetVariable (
65 VariableName,
66 VendorGuid,
67 (EFI_VARIABLE_NON_VOLATILE |
68 EFI_VARIABLE_BOOTSERVICE_ACCESS |
69 EFI_VARIABLE_RUNTIME_ACCESS |
70 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS),
71 DataSize,
72 Data
73 );
74
75 if (EFI_ERROR (Status)) {
76 DEBUG ((DEBUG_ERROR, "error: %a (\"%s\", %g): %r\n", __FUNCTION__, VariableName,
77 VendorGuid, Status));
78 }
79
80 if (Data != NULL) {
81 FreePool (Data);
82 }
83
84 return Status;
85 }
86
87 /** Initializes PKDefault variable with data from FFS section.
88
89 @retval EFI_SUCCESS Variable was initialized successfully.
90 @retval EFI_UNSUPPORTED Variable already exists.
91 **/
92 EFI_STATUS
93 SecureBootInitPKDefault (
94 IN VOID
95 )
96 {
97 EFI_SIGNATURE_LIST *EfiSig;
98 UINTN SigListsSize;
99 EFI_STATUS Status;
100 UINT8 *Data;
101 UINTN DataSize;
102
103 //
104 // Check if variable exists, if so do not change it
105 //
106 Status = GetVariable2 (EFI_PK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
107 if (Status == EFI_SUCCESS) {
108 DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_PK_DEFAULT_VARIABLE_NAME));
109 FreePool (Data);
110 return EFI_UNSUPPORTED;
111 }
112
113 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
114 return Status;
115 }
116
117 //
118 // Variable does not exist, can be initialized
119 //
120 DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_PK_DEFAULT_VARIABLE_NAME));
121
122 Status = SecureBootFetchData (&gDefaultPKFileGuid, &SigListsSize, &EfiSig);
123 if (EFI_ERROR (Status)) {
124 DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_PK_DEFAULT_VARIABLE_NAME));
125 return Status;
126 }
127
128 Status = gRT->SetVariable (
129 EFI_PK_DEFAULT_VARIABLE_NAME,
130 &gEfiGlobalVariableGuid,
131 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
132 SigListsSize,
133 (VOID *)EfiSig
134 );
135 if (EFI_ERROR (Status)) {
136 DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_PK_DEFAULT_VARIABLE_NAME));
137 }
138
139 FreePool (EfiSig);
140
141 return Status;
142 }
143
144 /** Initializes KEKDefault variable with data from FFS section.
145
146 @retval EFI_SUCCESS Variable was initialized successfully.
147 @retval EFI_UNSUPPORTED Variable already exists.
148 **/
149 EFI_STATUS
150 SecureBootInitKEKDefault (
151 IN VOID
152 )
153 {
154 EFI_SIGNATURE_LIST *EfiSig;
155 UINTN SigListsSize;
156 EFI_STATUS Status;
157 UINT8 *Data;
158 UINTN DataSize;
159
160 //
161 // Check if variable exists, if so do not change it
162 //
163 Status = GetVariable2 (EFI_KEK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
164 if (Status == EFI_SUCCESS) {
165 DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
166 FreePool (Data);
167 return EFI_UNSUPPORTED;
168 }
169
170 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
171 return Status;
172 }
173
174 //
175 // Variable does not exist, can be initialized
176 //
177 DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
178
179 Status = SecureBootFetchData (&gDefaultKEKFileGuid, &SigListsSize, &EfiSig);
180 if (EFI_ERROR (Status)) {
181 DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
182 return Status;
183 }
184
185
186 Status = gRT->SetVariable (
187 EFI_KEK_DEFAULT_VARIABLE_NAME,
188 &gEfiGlobalVariableGuid,
189 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
190 SigListsSize,
191 (VOID *)EfiSig
192 );
193 if (EFI_ERROR (Status)) {
194 DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
195 }
196
197 FreePool (EfiSig);
198
199 return Status;
200 }
201
202 /** Initializes dbDefault variable with data from FFS section.
203
204 @retval EFI_SUCCESS Variable was initialized successfully.
205 @retval EFI_UNSUPPORTED Variable already exists.
206 **/
207 EFI_STATUS
208 SecureBootInitDbDefault (
209 IN VOID
210 )
211 {
212 EFI_SIGNATURE_LIST *EfiSig;
213 UINTN SigListsSize;
214 EFI_STATUS Status;
215 UINT8 *Data;
216 UINTN DataSize;
217
218 Status = GetVariable2 (EFI_DB_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
219 if (Status == EFI_SUCCESS) {
220 DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DB_DEFAULT_VARIABLE_NAME));
221 FreePool (Data);
222 return EFI_UNSUPPORTED;
223 }
224
225 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
226 return Status;
227 }
228
229 DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DB_DEFAULT_VARIABLE_NAME));
230
231 Status = SecureBootFetchData (&gDefaultdbFileGuid, &SigListsSize, &EfiSig);
232 if (EFI_ERROR (Status)) {
233 return Status;
234 }
235
236 Status = gRT->SetVariable (
237 EFI_DB_DEFAULT_VARIABLE_NAME,
238 &gEfiGlobalVariableGuid,
239 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
240 SigListsSize,
241 (VOID *)EfiSig
242 );
243 if (EFI_ERROR (Status)) {
244 DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DB_DEFAULT_VARIABLE_NAME));
245 }
246
247 FreePool (EfiSig);
248
249 return Status;
250 }
251
252 /** Initializes dbxDefault variable with data from FFS section.
253
254 @retval EFI_SUCCESS Variable was initialized successfully.
255 @retval EFI_UNSUPPORTED Variable already exists.
256 **/
257 EFI_STATUS
258 SecureBootInitDbxDefault (
259 IN VOID
260 )
261 {
262 EFI_SIGNATURE_LIST *EfiSig;
263 UINTN SigListsSize;
264 EFI_STATUS Status;
265 UINT8 *Data;
266 UINTN DataSize;
267
268 //
269 // Check if variable exists, if so do not change it
270 //
271 Status = GetVariable2 (EFI_DBX_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
272 if (Status == EFI_SUCCESS) {
273 DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
274 FreePool (Data);
275 return EFI_UNSUPPORTED;
276 }
277
278 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
279 return Status;
280 }
281
282 //
283 // Variable does not exist, can be initialized
284 //
285 DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
286
287 Status = SecureBootFetchData (&gDefaultdbxFileGuid, &SigListsSize, &EfiSig);
288 if (EFI_ERROR (Status)) {
289 DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
290 return Status;
291 }
292
293 Status = gRT->SetVariable (
294 EFI_DBX_DEFAULT_VARIABLE_NAME,
295 &gEfiGlobalVariableGuid,
296 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
297 SigListsSize,
298 (VOID *)EfiSig
299 );
300 if (EFI_ERROR (Status)) {
301 DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
302 }
303
304 FreePool (EfiSig);
305
306 return Status;
307 }
308
309 /** Initializes dbtDefault variable with data from FFS section.
310
311 @retval EFI_SUCCESS Variable was initialized successfully.
312 @retval EFI_UNSUPPORTED Variable already exists.
313 **/
314 EFI_STATUS
315 SecureBootInitDbtDefault (
316 IN VOID
317 )
318 {
319 EFI_SIGNATURE_LIST *EfiSig;
320 UINTN SigListsSize;
321 EFI_STATUS Status;
322 UINT8 *Data;
323 UINTN DataSize;
324
325 //
326 // Check if variable exists, if so do not change it
327 //
328 Status = GetVariable2 (EFI_DBT_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
329 if (Status == EFI_SUCCESS) {
330 DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DBT_DEFAULT_VARIABLE_NAME));
331 FreePool (Data);
332 return EFI_UNSUPPORTED;
333 }
334
335 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
336 return Status;
337 }
338
339 //
340 // Variable does not exist, can be initialized
341 //
342 DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DBT_DEFAULT_VARIABLE_NAME));
343
344 Status = SecureBootFetchData (&gDefaultdbtFileGuid, &SigListsSize, &EfiSig);
345 if (EFI_ERROR (Status)) {
346 return Status;
347 }
348
349 Status = gRT->SetVariable (
350 EFI_DBT_DEFAULT_VARIABLE_NAME,
351 &gEfiGlobalVariableGuid,
352 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
353 SigListsSize,
354 (VOID *)EfiSig
355 );
356 if (EFI_ERROR (Status)) {
357 DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DBT_DEFAULT_VARIABLE_NAME));
358 }
359
360 FreePool (EfiSig);
361
362 return EFI_SUCCESS;
363 }
364
365 /**
366 Sets the content of the 'db' variable based on 'dbDefault' variable content.
367
368 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
369 while VendorGuid is NULL.
370 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
371 **/
372 EFI_STATUS
373 EFIAPI
374 EnrollDbFromDefault (
375 VOID
376 )
377 {
378 EFI_STATUS Status;
379
380 Status = EnrollFromDefault (
381 EFI_IMAGE_SECURITY_DATABASE,
382 EFI_DB_DEFAULT_VARIABLE_NAME,
383 &gEfiImageSecurityDatabaseGuid
384 );
385
386 return Status;
387 }
388
389 /**
390 Sets the content of the 'dbx' variable based on 'dbxDefault' variable content.
391
392 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
393 while VendorGuid is NULL.
394 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
395 **/
396 EFI_STATUS
397 EFIAPI
398 EnrollDbxFromDefault (
399 VOID
400 )
401 {
402 EFI_STATUS Status;
403
404 Status = EnrollFromDefault (
405 EFI_IMAGE_SECURITY_DATABASE1,
406 EFI_DBX_DEFAULT_VARIABLE_NAME,
407 &gEfiImageSecurityDatabaseGuid
408 );
409
410 return Status;
411 }
412
413 /**
414 Sets the content of the 'dbt' variable based on 'dbtDefault' variable content.
415
416 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
417 while VendorGuid is NULL.
418 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
419 **/
420 EFI_STATUS
421 EFIAPI
422 EnrollDbtFromDefault (
423 VOID
424 )
425 {
426 EFI_STATUS Status;
427
428 Status = EnrollFromDefault (
429 EFI_IMAGE_SECURITY_DATABASE2,
430 EFI_DBT_DEFAULT_VARIABLE_NAME,
431 &gEfiImageSecurityDatabaseGuid);
432
433 return Status;
434 }
435
436 /**
437 Sets the content of the 'KEK' variable based on 'KEKDefault' variable content.
438
439 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
440 while VendorGuid is NULL.
441 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
442 **/
443 EFI_STATUS
444 EFIAPI
445 EnrollKEKFromDefault (
446 VOID
447 )
448 {
449 EFI_STATUS Status;
450
451 Status = EnrollFromDefault (
452 EFI_KEY_EXCHANGE_KEY_NAME,
453 EFI_KEK_DEFAULT_VARIABLE_NAME,
454 &gEfiGlobalVariableGuid
455 );
456
457 return Status;
458 }
459
460 /**
461 Sets the content of the 'KEK' variable based on 'KEKDefault' variable content.
462
463 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
464 while VendorGuid is NULL.
465 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
466 **/
467 EFI_STATUS
468 EFIAPI
469 EnrollPKFromDefault (
470 VOID
471 )
472 {
473 EFI_STATUS Status;
474
475 Status = EnrollFromDefault (
476 EFI_PLATFORM_KEY_NAME,
477 EFI_PK_DEFAULT_VARIABLE_NAME,
478 &gEfiGlobalVariableGuid
479 );
480
481 return Status;
482 }