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
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