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