|
@@ -8,10 +8,13 @@
|
|
|
Copyright (c) 2021, Semihalf All rights reserved.<BR>
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
**/
|
|
|
+#include <Uefi.h>
|
|
|
+#include <UefiSecureBoot.h>
|
|
|
#include <Guid/GlobalVariable.h>
|
|
|
#include <Guid/AuthenticatedVariableFormat.h>
|
|
|
#include <Guid/ImageAuthentication.h>
|
|
|
#include <Library/BaseLib.h>
|
|
|
+#include <Library/BaseCryptLib.h>
|
|
|
#include <Library/BaseMemoryLib.h>
|
|
|
#include <Library/DebugLib.h>
|
|
|
#include <Library/UefiLib.h>
|
|
@@ -19,6 +22,117 @@
|
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
|
#include <Library/SecureBootVariableLib.h>
|
|
|
#include <Library/SecureBootVariableProvisionLib.h>
|
|
|
+#include <Library/DxeServicesLib.h>
|
|
|
+
|
|
|
+/**
|
|
|
+ Create a EFI Signature List with data fetched from section specified as a argument.
|
|
|
+ Found keys are verified using RsaGetPublicKeyFromX509().
|
|
|
+
|
|
|
+ @param[in] KeyFileGuid A pointer to to the FFS filename GUID
|
|
|
+ @param[out] SigListsSize A pointer to size of signature list
|
|
|
+ @param[out] SigListOut a pointer to a callee-allocated buffer with signature lists
|
|
|
+
|
|
|
+ @retval EFI_SUCCESS Create time based payload successfully.
|
|
|
+ @retval EFI_NOT_FOUND Section with key has not been found.
|
|
|
+ @retval EFI_INVALID_PARAMETER Embedded key has a wrong format.
|
|
|
+ @retval Others Unexpected error happens.
|
|
|
+
|
|
|
+**/
|
|
|
+STATIC
|
|
|
+EFI_STATUS
|
|
|
+SecureBootFetchData (
|
|
|
+ IN EFI_GUID *KeyFileGuid,
|
|
|
+ OUT UINTN *SigListsSize,
|
|
|
+ OUT EFI_SIGNATURE_LIST **SigListOut
|
|
|
+ )
|
|
|
+{
|
|
|
+ EFI_SIGNATURE_LIST *EfiSig;
|
|
|
+ EFI_STATUS Status;
|
|
|
+ VOID *Buffer;
|
|
|
+ VOID *RsaPubKey;
|
|
|
+ UINTN Size;
|
|
|
+ UINTN KeyIndex;
|
|
|
+ UINTN Index;
|
|
|
+ SECURE_BOOT_CERTIFICATE_INFO *CertInfo;
|
|
|
+ SECURE_BOOT_CERTIFICATE_INFO *NewCertInfo;
|
|
|
+
|
|
|
+ KeyIndex = 0;
|
|
|
+ EfiSig = NULL;
|
|
|
+ *SigListOut = NULL;
|
|
|
+ *SigListsSize = 0;
|
|
|
+ CertInfo = AllocatePool (sizeof (SECURE_BOOT_CERTIFICATE_INFO));
|
|
|
+ NewCertInfo = CertInfo;
|
|
|
+ while (1) {
|
|
|
+ if (NewCertInfo == NULL) {
|
|
|
+ Status = EFI_OUT_OF_RESOURCES;
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ CertInfo = NewCertInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ Status = GetSectionFromAnyFv (
|
|
|
+ KeyFileGuid,
|
|
|
+ EFI_SECTION_RAW,
|
|
|
+ KeyIndex,
|
|
|
+ &Buffer,
|
|
|
+ &Size
|
|
|
+ );
|
|
|
+
|
|
|
+ if (Status == EFI_SUCCESS) {
|
|
|
+ RsaPubKey = NULL;
|
|
|
+ if (RsaGetPublicKeyFromX509 (Buffer, Size, &RsaPubKey) == FALSE) {
|
|
|
+ DEBUG ((DEBUG_ERROR, "%a: Invalid key format: %d\n", __FUNCTION__, KeyIndex));
|
|
|
+ if (EfiSig != NULL) {
|
|
|
+ FreePool (EfiSig);
|
|
|
+ }
|
|
|
+
|
|
|
+ FreePool (Buffer);
|
|
|
+ Status = EFI_INVALID_PARAMETER;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ CertInfo[KeyIndex].Data = Buffer;
|
|
|
+ CertInfo[KeyIndex].DataSize = Size;
|
|
|
+ KeyIndex++;
|
|
|
+ NewCertInfo = ReallocatePool (
|
|
|
+ sizeof (SECURE_BOOT_CERTIFICATE_INFO) * KeyIndex,
|
|
|
+ sizeof (SECURE_BOOT_CERTIFICATE_INFO) * (KeyIndex + 1),
|
|
|
+ CertInfo
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Status == EFI_NOT_FOUND) {
|
|
|
+ Status = EFI_SUCCESS;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (EFI_ERROR (Status)) {
|
|
|
+ goto Cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (KeyIndex == 0) {
|
|
|
+ Status = EFI_NOT_FOUND;
|
|
|
+ goto Cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Now that we collected all certs from FV, convert it into sig list
|
|
|
+ Status = SecureBootCreateDataFromInput (SigListsSize, SigListOut, KeyIndex, CertInfo);
|
|
|
+ if (EFI_ERROR (Status)) {
|
|
|
+ goto Cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+Cleanup:
|
|
|
+ if (CertInfo) {
|
|
|
+ for (Index = 0; Index < KeyIndex; Index++) {
|
|
|
+ FreePool ((VOID *)CertInfo[Index].Data);
|
|
|
+ }
|
|
|
+
|
|
|
+ FreePool (CertInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ return Status;
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
Enroll a key/certificate based on a default variable.
|
|
@@ -52,36 +166,7 @@ EnrollFromDefault (
|
|
|
return Status;
|
|
|
}
|
|
|
|
|
|
- CreateTimeBasedPayload (&DataSize, (UINT8 **)&Data);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Allocate memory for auth variable
|
|
|
- //
|
|
|
- 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
|
|
|
- );
|
|
|
-
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- DEBUG ((
|
|
|
- DEBUG_ERROR,
|
|
|
- "error: %a (\"%s\", %g): %r\n",
|
|
|
- __FUNCTION__,
|
|
|
- VariableName,
|
|
|
- VendorGuid,
|
|
|
- Status
|
|
|
- ));
|
|
|
- }
|
|
|
+ Status = EnrollFromInput (VariableName, VendorGuid, DataSize, Data);
|
|
|
|
|
|
if (Data != NULL) {
|
|
|
FreePool (Data);
|