[edk2-devel] [PATCH v3 06/11] SecurityPkg: SecureBootVariableProvisionLib: Updated implementation

Kun Qin kuqin12 at gmail.com
Thu Jun 30 23:53:36 UTC 2022


From: Kun Qin <kuqin at microsoft.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3910

This change is in pair with the previous SecureBootVariableLib, which
removes the explicit invocation of `CreateTimeBasedPayload` and used new
interface `EnrollFromInput` instead.

The original `SecureBootFetchData` is also moved to this library and
incorporated with the newly defined `SecureBootCreateDataFromInput` to
keep the original code flow.

Cc: Jiewen Yao <jiewen.yao at intel.com>
Cc: Jian J Wang <jian.j.wang at intel.com>
Cc: Min Xu <min.m.xu at intel.com>

Signed-off-by: Kun Qin <kun.qin at microsoft.com>
Reviewed-by: Jiewen Yao <Jiewen.yao at intel.com>
Acked-by: Michael Kubacki <michael.kubacki at microsoft.com>
---

Notes:
    v3:
    - Added reviewed-by tag [Jiewen]
    - Added acked-by tag [Michael Kubacki]

 SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c | 145 ++++++++++++++++----
 1 file changed, 115 insertions(+), 30 deletions(-)

diff --git a/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c b/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
index 536b0f369907..bed1fe86205d 100644
--- a/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
+++ b/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
@@ -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);
-- 
2.36.0.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#90954): https://edk2.groups.io/g/devel/message/90954
Mute This Topic: https://groups.io/mt/92098743/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list