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


Kun Qin
 

From: Kun Qin <kuqin@...>

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

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@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Min Xu <min.m.xu@...>

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

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

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

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