123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852 |
- /** @file
- Enroll default PK, KEK, db, dbx.
- Copyright (C) 2014-2019, Red Hat, Inc.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Guid/AuthenticatedVariableFormat.h> // gEfiCustomModeEnableGuid
- #include <Guid/GlobalVariable.h> // EFI_SETUP_MODE_NAME
- #include <Guid/ImageAuthentication.h> // EFI_IMAGE_SECURITY_DATABASE
- #include <Guid/MicrosoftVendor.h> // gMicrosoftVendorGuid
- #include <Guid/OvmfPkKek1AppPrefix.h> // gOvmfPkKek1AppPrefixGuid
- #include <IndustryStandard/SmBios.h> // SMBIOS_HANDLE_PI_RESERVED
- #include <Library/BaseLib.h> // GUID_STRING_LENGTH
- #include <Library/BaseMemoryLib.h> // CopyGuid()
- #include <Library/DebugLib.h> // ASSERT()
- #include <Library/MemoryAllocationLib.h> // FreePool()
- #include <Library/PrintLib.h> // AsciiSPrint()
- #include <Library/ShellCEntryLib.h> // ShellAppMain()
- #include <Library/UefiBootServicesTableLib.h> // gBS
- #include <Library/UefiLib.h> // AsciiPrint()
- #include <Library/UefiRuntimeServicesTableLib.h> // gRT
- #include <Protocol/Smbios.h> // EFI_SMBIOS_PROTOCOL
- #include "EnrollDefaultKeys.h"
- /**
- Fetch the X509 certificate (to be used as Platform Key and first Key Exchange
- Key) from SMBIOS.
- @param[out] PkKek1 The X509 certificate in DER encoding from the
- hypervisor, to be enrolled as PK and first KEK
- entry. On success, the caller is responsible for
- releasing PkKek1 with FreePool().
- @param[out] SizeOfPkKek1 The size of PkKek1 in bytes.
- @retval EFI_SUCCESS PkKek1 and SizeOfPkKek1 have been set
- successfully.
- @retval EFI_NOT_FOUND An OEM String matching
- OVMF_PK_KEK1_APP_PREFIX_GUID has not been
- found.
- @retval EFI_PROTOCOL_ERROR In the OEM String matching
- OVMF_PK_KEK1_APP_PREFIX_GUID, the certificate
- is empty, or it has invalid base64 encoding.
- @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
- @return Error codes from gBS->LocateProtocol().
- **/
- STATIC
- EFI_STATUS
- GetPkKek1 (
- OUT UINT8 **PkKek1,
- OUT UINTN *SizeOfPkKek1
- )
- {
- CONST CHAR8 *Base64Cert;
- CHAR8 OvmfPkKek1AppPrefix[GUID_STRING_LENGTH + 1 + 1];
- EFI_STATUS Status;
- EFI_SMBIOS_PROTOCOL *Smbios;
- EFI_SMBIOS_HANDLE Handle;
- EFI_SMBIOS_TYPE Type;
- EFI_SMBIOS_TABLE_HEADER *Header;
- SMBIOS_TABLE_TYPE11 *OemStringsTable;
- UINTN Base64CertLen;
- UINTN DecodedCertSize;
- UINT8 *DecodedCert;
- Base64Cert = NULL;
- //
- // Format the application prefix, for OEM String matching.
- //
- AsciiSPrint (
- OvmfPkKek1AppPrefix,
- sizeof OvmfPkKek1AppPrefix,
- "%g:",
- &gOvmfPkKek1AppPrefixGuid
- );
- //
- // Scan all "OEM Strings" tables.
- //
- Status = gBS->LocateProtocol (
- &gEfiSmbiosProtocolGuid,
- NULL,
- (VOID **)&Smbios
- );
- if (EFI_ERROR (Status)) {
- AsciiPrint ("error: failed to locate EFI_SMBIOS_PROTOCOL: %r\n", Status);
- return Status;
- }
- Handle = SMBIOS_HANDLE_PI_RESERVED;
- Type = SMBIOS_TYPE_OEM_STRINGS;
- for (Status = Smbios->GetNext (Smbios, &Handle, &Type, &Header, NULL);
- !EFI_ERROR (Status);
- Status = Smbios->GetNext (Smbios, &Handle, &Type, &Header, NULL))
- {
- CONST CHAR8 *OemString;
- UINTN Idx;
- if (Header->Length < sizeof *OemStringsTable) {
- //
- // Malformed table header, skip to next.
- //
- continue;
- }
- OemStringsTable = (SMBIOS_TABLE_TYPE11 *)Header;
- //
- // Scan all strings in the unformatted area of the current "OEM Strings"
- // table.
- //
- OemString = (CONST CHAR8 *)(OemStringsTable + 1);
- for (Idx = 0; Idx < OemStringsTable->StringCount; ++Idx) {
- CHAR8 CandidatePrefix[sizeof OvmfPkKek1AppPrefix];
- //
- // NUL-terminate the candidate prefix for case-insensitive comparison.
- //
- AsciiStrnCpyS (
- CandidatePrefix,
- sizeof CandidatePrefix,
- OemString,
- GUID_STRING_LENGTH + 1
- );
- if (AsciiStriCmp (OvmfPkKek1AppPrefix, CandidatePrefix) == 0) {
- //
- // The current string matches the prefix.
- //
- Base64Cert = OemString + GUID_STRING_LENGTH + 1;
- break;
- }
- OemString += AsciiStrSize (OemString);
- }
- if (Idx < OemStringsTable->StringCount) {
- //
- // The current table has a matching string.
- //
- break;
- }
- }
- if (EFI_ERROR (Status)) {
- //
- // No table with a matching string has been found.
- //
- AsciiPrint (
- "error: OEM String with app prefix %g not found: %r\n",
- &gOvmfPkKek1AppPrefixGuid,
- Status
- );
- return EFI_NOT_FOUND;
- }
- ASSERT (Base64Cert != NULL);
- Base64CertLen = AsciiStrLen (Base64Cert);
- //
- // Verify the base64 encoding, and determine the decoded size.
- //
- DecodedCertSize = 0;
- Status = Base64Decode (Base64Cert, Base64CertLen, NULL, &DecodedCertSize);
- switch (Status) {
- case EFI_BUFFER_TOO_SMALL:
- ASSERT (DecodedCertSize > 0);
- break;
- case EFI_SUCCESS:
- AsciiPrint (
- "error: empty certificate after app prefix %g\n",
- &gOvmfPkKek1AppPrefixGuid
- );
- return EFI_PROTOCOL_ERROR;
- default:
- AsciiPrint (
- "error: invalid base64 string after app prefix %g\n",
- &gOvmfPkKek1AppPrefixGuid
- );
- return EFI_PROTOCOL_ERROR;
- }
- //
- // Allocate the output buffer.
- //
- DecodedCert = AllocatePool (DecodedCertSize);
- if (DecodedCert == NULL) {
- AsciiPrint ("error: failed to allocate memory\n");
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Decoding will succeed at this point.
- //
- Status = Base64Decode (
- Base64Cert,
- Base64CertLen,
- DecodedCert,
- &DecodedCertSize
- );
- ASSERT_EFI_ERROR (Status);
- *PkKek1 = DecodedCert;
- *SizeOfPkKek1 = DecodedCertSize;
- return EFI_SUCCESS;
- }
- /**
- Enroll a set of certificates in a global variable, overwriting it.
- The variable will be rewritten with NV+BS+RT+AT attributes.
- @param[in] VariableName The name of the variable to overwrite.
- @param[in] VendorGuid The namespace (ie. vendor GUID) of the variable to
- overwrite.
- @param[in] CertType The GUID determining the type of all the
- certificates in the set that is passed in. For
- example, gEfiCertX509Guid stands for DER-encoded
- X.509 certificates, while gEfiCertSha256Guid stands
- for SHA256 image hashes.
- @param[in] ... A list of
- IN CONST UINT8 *Cert,
- IN UINTN CertSize,
- IN CONST EFI_GUID *OwnerGuid
- triplets. If the first component of a triplet is
- NULL, then the other two components are not
- accessed, and processing is terminated. The list of
- certificates is enrolled in the variable specified,
- overwriting it. The OwnerGuid component identifies
- the agent installing the certificate.
- @retval EFI_INVALID_PARAMETER The triplet list is empty (ie. the first Cert
- value is NULL), or one of the CertSize values
- is 0, or one of the CertSize values would
- overflow the accumulated UINT32 data size.
- @retval EFI_OUT_OF_RESOURCES Out of memory while formatting variable
- payload.
- @retval EFI_SUCCESS Enrollment successful; the variable has been
- overwritten (or created).
- @return Error codes from gRT->GetTime() and
- gRT->SetVariable().
- **/
- STATIC
- EFI_STATUS
- EFIAPI
- EnrollListOfCerts (
- IN CHAR16 *VariableName,
- IN EFI_GUID *VendorGuid,
- IN EFI_GUID *CertType,
- ...
- )
- {
- UINTN DataSize;
- SINGLE_HEADER *SingleHeader;
- REPEATING_HEADER *RepeatingHeader;
- VA_LIST Marker;
- CONST UINT8 *Cert;
- EFI_STATUS Status;
- UINT8 *Data;
- UINT8 *Position;
- Status = EFI_SUCCESS;
- //
- // compute total size first, for UINT32 range check, and allocation
- //
- DataSize = sizeof *SingleHeader;
- VA_START (Marker, CertType);
- for (Cert = VA_ARG (Marker, CONST UINT8 *);
- Cert != NULL;
- Cert = VA_ARG (Marker, CONST UINT8 *))
- {
- UINTN CertSize;
- CertSize = VA_ARG (Marker, UINTN);
- (VOID)VA_ARG (Marker, CONST EFI_GUID *);
- if ((CertSize == 0) ||
- (CertSize > MAX_UINT32 - sizeof *RepeatingHeader) ||
- (DataSize > MAX_UINT32 - sizeof *RepeatingHeader - CertSize))
- {
- Status = EFI_INVALID_PARAMETER;
- break;
- }
- DataSize += sizeof *RepeatingHeader + CertSize;
- }
- VA_END (Marker);
- if (DataSize == sizeof *SingleHeader) {
- Status = EFI_INVALID_PARAMETER;
- }
- if (EFI_ERROR (Status)) {
- goto Out;
- }
- Data = AllocatePool (DataSize);
- if (Data == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Out;
- }
- Position = Data;
- SingleHeader = (SINGLE_HEADER *)Position;
- Status = gRT->GetTime (&SingleHeader->TimeStamp, NULL);
- if (EFI_ERROR (Status)) {
- goto FreeData;
- }
- SingleHeader->TimeStamp.Pad1 = 0;
- SingleHeader->TimeStamp.Nanosecond = 0;
- SingleHeader->TimeStamp.TimeZone = 0;
- SingleHeader->TimeStamp.Daylight = 0;
- SingleHeader->TimeStamp.Pad2 = 0;
- #if 0
- SingleHeader->dwLength = DataSize - sizeof SingleHeader->TimeStamp;
- #else
- //
- // This looks like a bug in edk2. According to the UEFI specification,
- // dwLength is "The length of the entire certificate, including the length of
- // the header, in bytes". That shouldn't stop right after CertType -- it
- // should include everything below it.
- //
- SingleHeader->dwLength = sizeof *SingleHeader
- - sizeof SingleHeader->TimeStamp;
- #endif
- SingleHeader->wRevision = 0x0200;
- SingleHeader->wCertificateType = WIN_CERT_TYPE_EFI_GUID;
- CopyGuid (&SingleHeader->CertType, &gEfiCertPkcs7Guid);
- Position += sizeof *SingleHeader;
- VA_START (Marker, CertType);
- for (Cert = VA_ARG (Marker, CONST UINT8 *);
- Cert != NULL;
- Cert = VA_ARG (Marker, CONST UINT8 *))
- {
- UINTN CertSize;
- CONST EFI_GUID *OwnerGuid;
- CertSize = VA_ARG (Marker, UINTN);
- OwnerGuid = VA_ARG (Marker, CONST EFI_GUID *);
- RepeatingHeader = (REPEATING_HEADER *)Position;
- CopyGuid (&RepeatingHeader->SignatureType, CertType);
- RepeatingHeader->SignatureListSize =
- (UINT32)(sizeof *RepeatingHeader + CertSize);
- RepeatingHeader->SignatureHeaderSize = 0;
- RepeatingHeader->SignatureSize =
- (UINT32)(sizeof RepeatingHeader->SignatureOwner + CertSize);
- CopyGuid (&RepeatingHeader->SignatureOwner, OwnerGuid);
- Position += sizeof *RepeatingHeader;
- CopyMem (Position, Cert, CertSize);
- Position += CertSize;
- }
- VA_END (Marker);
- ASSERT (Data + DataSize == Position);
- Status = gRT->SetVariable (
- VariableName,
- VendorGuid,
- (EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
- EFI_VARIABLE_RUNTIME_ACCESS |
- EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS),
- DataSize,
- Data
- );
- FreeData:
- FreePool (Data);
- Out:
- if (EFI_ERROR (Status)) {
- AsciiPrint (
- "error: %a(\"%s\", %g): %r\n",
- __FUNCTION__,
- VariableName,
- VendorGuid,
- Status
- );
- }
- return Status;
- }
- /**
- Read a UEFI variable into a caller-allocated buffer, enforcing an exact size.
- @param[in] VariableName The name of the variable to read; passed to
- gRT->GetVariable().
- @param[in] VendorGuid The vendor (namespace) GUID of the variable to read;
- passed to gRT->GetVariable().
- @param[out] Data The caller-allocated buffer that is supposed to
- receive the variable's contents. On error, the
- contents of Data are indeterminate.
- @param[in] DataSize The size in bytes that the caller requires the UEFI
- variable to have. The caller is responsible for
- providing room for DataSize bytes in Data.
- @param[in] AllowMissing If FALSE, the variable is required to exist. If
- TRUE, the variable is permitted to be missing.
- @retval EFI_SUCCESS The UEFI variable exists, has the required size
- (DataSize), and has been read into Data.
- @retval EFI_SUCCESS The UEFI variable doesn't exist, and
- AllowMissing is TRUE. DataSize bytes in Data
- have been zeroed out.
- @retval EFI_NOT_FOUND The UEFI variable doesn't exist, and
- AllowMissing is FALSE.
- @retval EFI_BUFFER_TOO_SMALL The UEFI variable exists, but its size is
- greater than DataSize.
- @retval EFI_PROTOCOL_ERROR The UEFI variable exists, but its size is
- smaller than DataSize.
- @return Error codes propagated from gRT->GetVariable().
- **/
- STATIC
- EFI_STATUS
- GetExact (
- IN CHAR16 *VariableName,
- IN EFI_GUID *VendorGuid,
- OUT VOID *Data,
- IN UINTN DataSize,
- IN BOOLEAN AllowMissing
- )
- {
- UINTN Size;
- EFI_STATUS Status;
- Size = DataSize;
- Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &Size, Data);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_NOT_FOUND) && AllowMissing) {
- ZeroMem (Data, DataSize);
- return EFI_SUCCESS;
- }
- AsciiPrint (
- "error: GetVariable(\"%s\", %g): %r\n",
- VariableName,
- VendorGuid,
- Status
- );
- return Status;
- }
- if (Size != DataSize) {
- AsciiPrint (
- "error: GetVariable(\"%s\", %g): expected size 0x%Lx, "
- "got 0x%Lx\n",
- VariableName,
- VendorGuid,
- (UINT64)DataSize,
- (UINT64)Size
- );
- return EFI_PROTOCOL_ERROR;
- }
- return EFI_SUCCESS;
- }
- /**
- Populate a SETTINGS structure from the underlying UEFI variables.
- The following UEFI variables are standard variables:
- - L"SetupMode" (EFI_SETUP_MODE_NAME)
- - L"SecureBoot" (EFI_SECURE_BOOT_MODE_NAME)
- - L"VendorKeys" (EFI_VENDOR_KEYS_VARIABLE_NAME)
- The following UEFI variables are edk2 extensions:
- - L"SecureBootEnable" (EFI_SECURE_BOOT_ENABLE_NAME)
- - L"CustomMode" (EFI_CUSTOM_MODE_NAME)
- The L"SecureBootEnable" UEFI variable is permitted to be missing, in which
- case the corresponding field in the SETTINGS object will be zeroed out. The
- rest of the covered UEFI variables are required to exist; otherwise, the
- function will fail.
- @param[out] Settings The SETTINGS object to fill.
- @retval EFI_SUCCESS Settings has been populated.
- @return Error codes propagated from the GetExact() function. The
- contents of Settings are indeterminate.
- **/
- STATIC
- EFI_STATUS
- GetSettings (
- OUT SETTINGS *Settings
- )
- {
- EFI_STATUS Status;
- Status = GetExact (
- EFI_SETUP_MODE_NAME,
- &gEfiGlobalVariableGuid,
- &Settings->SetupMode,
- sizeof Settings->SetupMode,
- FALSE
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = GetExact (
- EFI_SECURE_BOOT_MODE_NAME,
- &gEfiGlobalVariableGuid,
- &Settings->SecureBoot,
- sizeof Settings->SecureBoot,
- FALSE
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = GetExact (
- EFI_SECURE_BOOT_ENABLE_NAME,
- &gEfiSecureBootEnableDisableGuid,
- &Settings->SecureBootEnable,
- sizeof Settings->SecureBootEnable,
- TRUE
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = GetExact (
- EFI_CUSTOM_MODE_NAME,
- &gEfiCustomModeEnableGuid,
- &Settings->CustomMode,
- sizeof Settings->CustomMode,
- FALSE
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = GetExact (
- EFI_VENDOR_KEYS_VARIABLE_NAME,
- &gEfiGlobalVariableGuid,
- &Settings->VendorKeys,
- sizeof Settings->VendorKeys,
- FALSE
- );
- return Status;
- }
- /**
- Print the contents of a SETTINGS structure to the UEFI console.
- @param[in] Settings The SETTINGS object to print the contents of.
- **/
- STATIC
- VOID
- PrintSettings (
- IN CONST SETTINGS *Settings
- )
- {
- AsciiPrint (
- "info: SetupMode=%d SecureBoot=%d SecureBootEnable=%d "
- "CustomMode=%d VendorKeys=%d\n",
- Settings->SetupMode,
- Settings->SecureBoot,
- Settings->SecureBootEnable,
- Settings->CustomMode,
- Settings->VendorKeys
- );
- }
- /**
- Entry point function of this shell application.
- **/
- INTN
- EFIAPI
- ShellAppMain (
- IN UINTN Argc,
- IN CHAR16 **Argv
- )
- {
- INTN RetVal;
- EFI_STATUS Status;
- SETTINGS Settings;
- UINT8 *PkKek1;
- UINTN SizeOfPkKek1;
- BOOLEAN NoDefault;
- if ((Argc == 2) && (StrCmp (Argv[1], L"--no-default") == 0)) {
- NoDefault = TRUE;
- } else {
- NoDefault = FALSE;
- }
- //
- // Prepare for failure.
- //
- RetVal = 1;
- //
- // If we're not in Setup Mode, we can't do anything.
- //
- Status = GetSettings (&Settings);
- if (EFI_ERROR (Status)) {
- return RetVal;
- }
- PrintSettings (&Settings);
- if (Settings.SetupMode != 1) {
- AsciiPrint ("error: already in User Mode\n");
- return RetVal;
- }
- //
- // Set PkKek1 and SizeOfPkKek1 to suppress incorrect compiler/analyzer
- // warnings.
- //
- PkKek1 = NULL;
- SizeOfPkKek1 = 0;
- //
- // Fetch the X509 certificate (to be used as Platform Key and first Key
- // Exchange Key) from SMBIOS.
- //
- Status = GetPkKek1 (&PkKek1, &SizeOfPkKek1);
- if (EFI_ERROR (Status)) {
- return RetVal;
- }
- //
- // Enter Custom Mode so we can enroll PK, KEK, db, and dbx without signature
- // checks on those variable writes.
- //
- if (Settings.CustomMode != CUSTOM_SECURE_BOOT_MODE) {
- Settings.CustomMode = CUSTOM_SECURE_BOOT_MODE;
- Status = gRT->SetVariable (
- EFI_CUSTOM_MODE_NAME,
- &gEfiCustomModeEnableGuid,
- (EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS),
- sizeof Settings.CustomMode,
- &Settings.CustomMode
- );
- if (EFI_ERROR (Status)) {
- AsciiPrint (
- "error: SetVariable(\"%s\", %g): %r\n",
- EFI_CUSTOM_MODE_NAME,
- &gEfiCustomModeEnableGuid,
- Status
- );
- goto FreePkKek1;
- }
- }
- //
- // Enroll db.
- //
- if (NoDefault) {
- Status = EnrollListOfCerts (
- EFI_IMAGE_SECURITY_DATABASE,
- &gEfiImageSecurityDatabaseGuid,
- &gEfiCertX509Guid,
- PkKek1,
- SizeOfPkKek1,
- &gEfiCallerIdGuid,
- NULL
- );
- } else {
- Status = EnrollListOfCerts (
- EFI_IMAGE_SECURITY_DATABASE,
- &gEfiImageSecurityDatabaseGuid,
- &gEfiCertX509Guid,
- mMicrosoftPca,
- mSizeOfMicrosoftPca,
- &gMicrosoftVendorGuid,
- mMicrosoftUefiCa,
- mSizeOfMicrosoftUefiCa,
- &gMicrosoftVendorGuid,
- NULL
- );
- }
- if (EFI_ERROR (Status)) {
- goto FreePkKek1;
- }
- //
- // Enroll dbx.
- //
- Status = EnrollListOfCerts (
- EFI_IMAGE_SECURITY_DATABASE1,
- &gEfiImageSecurityDatabaseGuid,
- &gEfiCertSha256Guid,
- mSha256OfDevNull,
- mSizeOfSha256OfDevNull,
- &gEfiCallerIdGuid,
- NULL
- );
- if (EFI_ERROR (Status)) {
- goto FreePkKek1;
- }
- //
- // Enroll KEK.
- //
- if (NoDefault) {
- Status = EnrollListOfCerts (
- EFI_KEY_EXCHANGE_KEY_NAME,
- &gEfiGlobalVariableGuid,
- &gEfiCertX509Guid,
- PkKek1,
- SizeOfPkKek1,
- &gEfiCallerIdGuid,
- NULL
- );
- } else {
- Status = EnrollListOfCerts (
- EFI_KEY_EXCHANGE_KEY_NAME,
- &gEfiGlobalVariableGuid,
- &gEfiCertX509Guid,
- PkKek1,
- SizeOfPkKek1,
- &gEfiCallerIdGuid,
- mMicrosoftKek,
- mSizeOfMicrosoftKek,
- &gMicrosoftVendorGuid,
- NULL
- );
- }
- if (EFI_ERROR (Status)) {
- goto FreePkKek1;
- }
- //
- // Enroll PK, leaving Setup Mode (entering User Mode) at once.
- //
- Status = EnrollListOfCerts (
- EFI_PLATFORM_KEY_NAME,
- &gEfiGlobalVariableGuid,
- &gEfiCertX509Guid,
- PkKek1,
- SizeOfPkKek1,
- &gEfiGlobalVariableGuid,
- NULL
- );
- if (EFI_ERROR (Status)) {
- goto FreePkKek1;
- }
- //
- // Leave Custom Mode, so that updates to PK, KEK, db, and dbx require valid
- // signatures.
- //
- Settings.CustomMode = STANDARD_SECURE_BOOT_MODE;
- Status = gRT->SetVariable (
- EFI_CUSTOM_MODE_NAME,
- &gEfiCustomModeEnableGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof Settings.CustomMode,
- &Settings.CustomMode
- );
- if (EFI_ERROR (Status)) {
- AsciiPrint (
- "error: SetVariable(\"%s\", %g): %r\n",
- EFI_CUSTOM_MODE_NAME,
- &gEfiCustomModeEnableGuid,
- Status
- );
- goto FreePkKek1;
- }
- //
- // Final sanity check:
- //
- // [SetupMode]
- // (read-only, standardized by UEFI)
- // / \_
- // 0 1, default
- // / \_
- // PK enrolled no PK enrolled yet,
- // (this is called "User Mode") PK enrollment possible
- // |
- // |
- // [SecureBootEnable]
- // (read-write, edk2-specific, boot service only)
- // / \_
- // 0 1, default
- // / \_
- // [SecureBoot]=0 [SecureBoot]=1
- // (read-only, standardized by UEFI) (read-only, standardized by UEFI)
- // images are not verified images are verified, platform is
- // operating in Secure Boot mode
- // |
- // |
- // [CustomMode]
- // (read-write, edk2-specific, boot service only)
- // / \_
- // 0, default 1
- // / \_
- // PK, KEK, db, dbx PK, KEK, db, dbx
- // updates are verified updates are not verified
- //
- Status = GetSettings (&Settings);
- if (EFI_ERROR (Status)) {
- goto FreePkKek1;
- }
- PrintSettings (&Settings);
- if ((Settings.SetupMode != 0) || (Settings.SecureBoot != 1) ||
- (Settings.SecureBootEnable != 1) || (Settings.CustomMode != 0) ||
- (Settings.VendorKeys != 0))
- {
- AsciiPrint ("error: unexpected\n");
- goto FreePkKek1;
- }
- AsciiPrint ("info: success\n");
- RetVal = 0;
- FreePkKek1:
- FreePool (PkKek1);
- return RetVal;
- }
|