2 Enroll default PK, KEK, db, dbx.
4 Copyright (C) 2014-2019, Red Hat, Inc.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
8 #include <Guid/AuthenticatedVariableFormat.h> // gEfiCustomModeEnableGuid
9 #include <Guid/GlobalVariable.h> // EFI_SETUP_MODE_NAME
10 #include <Guid/ImageAuthentication.h> // EFI_IMAGE_SECURITY_DATABASE
11 #include <Library/BaseMemoryLib.h> // CopyGuid()
12 #include <Library/DebugLib.h> // ASSERT()
13 #include <Library/MemoryAllocationLib.h> // FreePool()
14 #include <Library/ShellCEntryLib.h> // ShellAppMain()
15 #include <Library/UefiLib.h> // AsciiPrint()
16 #include <Library/UefiRuntimeServicesTableLib.h> // gRT
18 #include "EnrollDefaultKeys.h"
21 Enroll a set of certificates in a global variable, overwriting it.
23 The variable will be rewritten with NV+BS+RT+AT attributes.
25 @param[in] VariableName The name of the variable to overwrite.
27 @param[in] VendorGuid The namespace (ie. vendor GUID) of the variable to
30 @param[in] CertType The GUID determining the type of all the
31 certificates in the set that is passed in. For
32 example, gEfiCertX509Guid stands for DER-encoded
33 X.509 certificates, while gEfiCertSha256Guid stands
34 for SHA256 image hashes.
36 @param[in] ... A list of
40 IN CONST EFI_GUID *OwnerGuid
42 triplets. If the first component of a triplet is
43 NULL, then the other two components are not
44 accessed, and processing is terminated. The list of
45 certificates is enrolled in the variable specified,
46 overwriting it. The OwnerGuid component identifies
47 the agent installing the certificate.
49 @retval EFI_INVALID_PARAMETER The triplet list is empty (ie. the first Cert
50 value is NULL), or one of the CertSize values
51 is 0, or one of the CertSize values would
52 overflow the accumulated UINT32 data size.
54 @retval EFI_OUT_OF_RESOURCES Out of memory while formatting variable
57 @retval EFI_SUCCESS Enrollment successful; the variable has been
58 overwritten (or created).
60 @return Error codes from gRT->GetTime() and
67 IN CHAR16
*VariableName
,
68 IN EFI_GUID
*VendorGuid
,
69 IN EFI_GUID
*CertType
,
74 SINGLE_HEADER
*SingleHeader
;
75 REPEATING_HEADER
*RepeatingHeader
;
85 // compute total size first, for UINT32 range check, and allocation
87 DataSize
= sizeof *SingleHeader
;
88 VA_START (Marker
, CertType
);
89 for (Cert
= VA_ARG (Marker
, CONST UINT8
*);
91 Cert
= VA_ARG (Marker
, CONST UINT8
*)) {
94 CertSize
= VA_ARG (Marker
, UINTN
);
95 (VOID
)VA_ARG (Marker
, CONST EFI_GUID
*);
98 CertSize
> MAX_UINT32
- sizeof *RepeatingHeader
||
99 DataSize
> MAX_UINT32
- sizeof *RepeatingHeader
- CertSize
) {
100 Status
= EFI_INVALID_PARAMETER
;
103 DataSize
+= sizeof *RepeatingHeader
+ CertSize
;
107 if (DataSize
== sizeof *SingleHeader
) {
108 Status
= EFI_INVALID_PARAMETER
;
110 if (EFI_ERROR (Status
)) {
114 Data
= AllocatePool (DataSize
);
116 Status
= EFI_OUT_OF_RESOURCES
;
122 SingleHeader
= (SINGLE_HEADER
*)Position
;
123 Status
= gRT
->GetTime (&SingleHeader
->TimeStamp
, NULL
);
124 if (EFI_ERROR (Status
)) {
127 SingleHeader
->TimeStamp
.Pad1
= 0;
128 SingleHeader
->TimeStamp
.Nanosecond
= 0;
129 SingleHeader
->TimeStamp
.TimeZone
= 0;
130 SingleHeader
->TimeStamp
.Daylight
= 0;
131 SingleHeader
->TimeStamp
.Pad2
= 0;
133 SingleHeader
->dwLength
= DataSize
- sizeof SingleHeader
->TimeStamp
;
136 // This looks like a bug in edk2. According to the UEFI specification,
137 // dwLength is "The length of the entire certificate, including the length of
138 // the header, in bytes". That shouldn't stop right after CertType -- it
139 // should include everything below it.
141 SingleHeader
->dwLength
= sizeof *SingleHeader
142 - sizeof SingleHeader
->TimeStamp
;
144 SingleHeader
->wRevision
= 0x0200;
145 SingleHeader
->wCertificateType
= WIN_CERT_TYPE_EFI_GUID
;
146 CopyGuid (&SingleHeader
->CertType
, &gEfiCertPkcs7Guid
);
147 Position
+= sizeof *SingleHeader
;
149 VA_START (Marker
, CertType
);
150 for (Cert
= VA_ARG (Marker
, CONST UINT8
*);
152 Cert
= VA_ARG (Marker
, CONST UINT8
*)) {
154 CONST EFI_GUID
*OwnerGuid
;
156 CertSize
= VA_ARG (Marker
, UINTN
);
157 OwnerGuid
= VA_ARG (Marker
, CONST EFI_GUID
*);
159 RepeatingHeader
= (REPEATING_HEADER
*)Position
;
160 CopyGuid (&RepeatingHeader
->SignatureType
, CertType
);
161 RepeatingHeader
->SignatureListSize
=
162 (UINT32
)(sizeof *RepeatingHeader
+ CertSize
);
163 RepeatingHeader
->SignatureHeaderSize
= 0;
164 RepeatingHeader
->SignatureSize
=
165 (UINT32
)(sizeof RepeatingHeader
->SignatureOwner
+ CertSize
);
166 CopyGuid (&RepeatingHeader
->SignatureOwner
, OwnerGuid
);
167 Position
+= sizeof *RepeatingHeader
;
169 CopyMem (Position
, Cert
, CertSize
);
170 Position
+= CertSize
;
174 ASSERT (Data
+ DataSize
== Position
);
176 Status
= gRT
->SetVariable (VariableName
, VendorGuid
,
177 (EFI_VARIABLE_NON_VOLATILE
|
178 EFI_VARIABLE_BOOTSERVICE_ACCESS
|
179 EFI_VARIABLE_RUNTIME_ACCESS
|
180 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
),
187 if (EFI_ERROR (Status
)) {
188 AsciiPrint ("error: %a(\"%s\", %g): %r\n", __FUNCTION__
, VariableName
,
198 IN CHAR16
*VariableName
,
199 IN EFI_GUID
*VendorGuid
,
202 IN BOOLEAN AllowMissing
209 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &Size
, Data
);
210 if (EFI_ERROR (Status
)) {
211 if (Status
== EFI_NOT_FOUND
&& AllowMissing
) {
212 ZeroMem (Data
, DataSize
);
216 AsciiPrint ("error: GetVariable(\"%s\", %g): %r\n", VariableName
,
221 if (Size
!= DataSize
) {
222 AsciiPrint ("error: GetVariable(\"%s\", %g): expected size 0x%Lx, "
223 "got 0x%Lx\n", VariableName
, VendorGuid
, (UINT64
)DataSize
, (UINT64
)Size
);
224 return EFI_PROTOCOL_ERROR
;
233 OUT SETTINGS
*Settings
238 Status
= GetExact (EFI_SETUP_MODE_NAME
, &gEfiGlobalVariableGuid
,
239 &Settings
->SetupMode
, sizeof Settings
->SetupMode
, FALSE
);
240 if (EFI_ERROR (Status
)) {
244 Status
= GetExact (EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
,
245 &Settings
->SecureBoot
, sizeof Settings
->SecureBoot
, FALSE
);
246 if (EFI_ERROR (Status
)) {
250 Status
= GetExact (EFI_SECURE_BOOT_ENABLE_NAME
,
251 &gEfiSecureBootEnableDisableGuid
, &Settings
->SecureBootEnable
,
252 sizeof Settings
->SecureBootEnable
, TRUE
);
253 if (EFI_ERROR (Status
)) {
257 Status
= GetExact (EFI_CUSTOM_MODE_NAME
, &gEfiCustomModeEnableGuid
,
258 &Settings
->CustomMode
, sizeof Settings
->CustomMode
, FALSE
);
259 if (EFI_ERROR (Status
)) {
263 Status
= GetExact (EFI_VENDOR_KEYS_VARIABLE_NAME
, &gEfiGlobalVariableGuid
,
264 &Settings
->VendorKeys
, sizeof Settings
->VendorKeys
, FALSE
);
271 IN CONST SETTINGS
*Settings
274 AsciiPrint ("info: SetupMode=%d SecureBoot=%d SecureBootEnable=%d "
275 "CustomMode=%d VendorKeys=%d\n", Settings
->SetupMode
, Settings
->SecureBoot
,
276 Settings
->SecureBootEnable
, Settings
->CustomMode
, Settings
->VendorKeys
);
290 Status
= GetSettings (&Settings
);
291 if (EFI_ERROR (Status
)) {
294 PrintSettings (&Settings
);
296 if (Settings
.SetupMode
!= 1) {
297 AsciiPrint ("error: already in User Mode\n");
301 if (Settings
.CustomMode
!= CUSTOM_SECURE_BOOT_MODE
) {
302 Settings
.CustomMode
= CUSTOM_SECURE_BOOT_MODE
;
303 Status
= gRT
->SetVariable (EFI_CUSTOM_MODE_NAME
, &gEfiCustomModeEnableGuid
,
304 (EFI_VARIABLE_NON_VOLATILE
|
305 EFI_VARIABLE_BOOTSERVICE_ACCESS
),
306 sizeof Settings
.CustomMode
, &Settings
.CustomMode
);
307 if (EFI_ERROR (Status
)) {
308 AsciiPrint ("error: SetVariable(\"%s\", %g): %r\n", EFI_CUSTOM_MODE_NAME
,
309 &gEfiCustomModeEnableGuid
, Status
);
314 Status
= EnrollListOfCerts (
315 EFI_IMAGE_SECURITY_DATABASE
,
316 &gEfiImageSecurityDatabaseGuid
,
318 mMicrosoftPca
, mSizeOfMicrosoftPca
, &mMicrosoftOwnerGuid
,
319 mMicrosoftUefiCa
, mSizeOfMicrosoftUefiCa
, &mMicrosoftOwnerGuid
,
321 if (EFI_ERROR (Status
)) {
325 Status
= EnrollListOfCerts (
326 EFI_IMAGE_SECURITY_DATABASE1
,
327 &gEfiImageSecurityDatabaseGuid
,
329 mSha256OfDevNull
, mSizeOfSha256OfDevNull
, &gEfiCallerIdGuid
,
331 if (EFI_ERROR (Status
)) {
335 Status
= EnrollListOfCerts (
336 EFI_KEY_EXCHANGE_KEY_NAME
,
337 &gEfiGlobalVariableGuid
,
339 mRedHatPkKek1
, mSizeOfRedHatPkKek1
, &gEfiCallerIdGuid
,
340 mMicrosoftKek
, mSizeOfMicrosoftKek
, &mMicrosoftOwnerGuid
,
342 if (EFI_ERROR (Status
)) {
346 Status
= EnrollListOfCerts (
347 EFI_PLATFORM_KEY_NAME
,
348 &gEfiGlobalVariableGuid
,
350 mRedHatPkKek1
, mSizeOfRedHatPkKek1
, &gEfiGlobalVariableGuid
,
352 if (EFI_ERROR (Status
)) {
356 Settings
.CustomMode
= STANDARD_SECURE_BOOT_MODE
;
357 Status
= gRT
->SetVariable (EFI_CUSTOM_MODE_NAME
, &gEfiCustomModeEnableGuid
,
358 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
359 sizeof Settings
.CustomMode
, &Settings
.CustomMode
);
360 if (EFI_ERROR (Status
)) {
361 AsciiPrint ("error: SetVariable(\"%s\", %g): %r\n", EFI_CUSTOM_MODE_NAME
,
362 &gEfiCustomModeEnableGuid
, Status
);
366 Status
= GetSettings (&Settings
);
367 if (EFI_ERROR (Status
)) {
370 PrintSettings (&Settings
);
372 if (Settings
.SetupMode
!= 0 || Settings
.SecureBoot
!= 1 ||
373 Settings
.SecureBootEnable
!= 1 || Settings
.CustomMode
!= 0 ||
374 Settings
.VendorKeys
!= 0) {
375 AsciiPrint ("error: unexpected\n");
379 AsciiPrint ("info: success\n");