diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7')
3 files changed, 280 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.c new file mode 100644 index 00000000..71775bab --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.c @@ -0,0 +1,216 @@ +/** @file + FMP Authentication PKCS7 handler. + Provide generic FMP authentication functions for DXE/PEI post memory phase. + + Caution: This module requires additional review when modified. + This module will have external input - capsule image. + This external input must be validated carefully to avoid security issue like + buffer overflow, integer overflow. + + FmpAuthenticatedHandlerPkcs7(), AuthenticateFmpImage() will receive + untrusted input and do basic validation. + + Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Uefi.h> + +#include <Guid/SystemResourceTable.h> +#include <Guid/FirmwareContentsSigned.h> +#include <Guid/WinCertificate.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/BaseCryptLib.h> +#include <Library/FmpAuthenticationLib.h> +#include <Library/PcdLib.h> +#include <Protocol/FirmwareManagement.h> +#include <Guid/SystemResourceTable.h> + +/** + The handler is used to do the authentication for FMP capsule based upon + EFI_FIRMWARE_IMAGE_AUTHENTICATION. + + Caution: This function may receive untrusted input. + + This function assumes the caller AuthenticateFmpImage() + already did basic validation for EFI_FIRMWARE_IMAGE_AUTHENTICATION. + + @param[in] Image Points to an FMP authentication image, started from EFI_FIRMWARE_IMAGE_AUTHENTICATION. + @param[in] ImageSize Size of the authentication image in bytes. + @param[in] PublicKeyData The public key data used to validate the signature. + @param[in] PublicKeyDataLength The length of the public key data. + + @retval RETURN_SUCCESS Authentication pass. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_SUCCESS. + @retval RETURN_SECURITY_VIOLATION Authentication fail. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR. + @retval RETURN_INVALID_PARAMETER The image is in an invalid format. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT. + @retval RETURN_OUT_OF_RESOURCES No Authentication handler associated with CertType. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES. +**/ +RETURN_STATUS +FmpAuthenticatedHandlerPkcs7 ( + IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image, + IN UINTN ImageSize, + IN CONST UINT8 *PublicKeyData, + IN UINTN PublicKeyDataLength + ) +{ + RETURN_STATUS Status; + BOOLEAN CryptoStatus; + VOID *P7Data; + UINTN P7Length; + VOID *TempBuffer; + + DEBUG((DEBUG_INFO, "FmpAuthenticatedHandlerPkcs7 - Image: 0x%08x - 0x%08x\n", (UINTN)Image, (UINTN)ImageSize)); + + P7Length = Image->AuthInfo.Hdr.dwLength - (OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData)); + P7Data = Image->AuthInfo.CertData; + + // It is a signature across the variable data and the Monotonic Count value. + TempBuffer = AllocatePool(ImageSize - Image->AuthInfo.Hdr.dwLength); + if (TempBuffer == NULL) { + DEBUG((DEBUG_ERROR, "FmpAuthenticatedHandlerPkcs7: TempBuffer == NULL\n")); + Status = RETURN_OUT_OF_RESOURCES; + goto Done; + } + + CopyMem( + TempBuffer, + (UINT8 *)Image + sizeof(Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength, + ImageSize - sizeof(Image->MonotonicCount) - Image->AuthInfo.Hdr.dwLength + ); + CopyMem( + (UINT8 *)TempBuffer + ImageSize - sizeof(Image->MonotonicCount) - Image->AuthInfo.Hdr.dwLength, + &Image->MonotonicCount, + sizeof(Image->MonotonicCount) + ); + CryptoStatus = Pkcs7Verify( + P7Data, + P7Length, + PublicKeyData, + PublicKeyDataLength, + (UINT8 *)TempBuffer, + ImageSize - Image->AuthInfo.Hdr.dwLength + ); + FreePool(TempBuffer); + if (!CryptoStatus) { + // + // If PKCS7 signature verification fails, AUTH tested failed bit is set. + // + DEBUG((DEBUG_ERROR, "FmpAuthenticatedHandlerPkcs7: Pkcs7Verify() failed\n")); + Status = RETURN_SECURITY_VIOLATION; + goto Done; + } + DEBUG((DEBUG_INFO, "FmpAuthenticatedHandlerPkcs7: PASS verification\n")); + + Status = RETURN_SUCCESS; + +Done: + return Status; +} + +/** + The function is used to do the authentication for FMP capsule based upon + EFI_FIRMWARE_IMAGE_AUTHENTICATION. + + The FMP capsule image should start with EFI_FIRMWARE_IMAGE_AUTHENTICATION, + followed by the payload. + + If the return status is RETURN_SUCCESS, the caller may continue the rest + FMP update process. + If the return status is NOT RETURN_SUCCESS, the caller should stop the FMP + update process and convert the return status to LastAttemptStatus + to indicate that FMP update fails. + The LastAttemptStatus can be got from ESRT table or via + EFI_FIRMWARE_MANAGEMENT_PROTOCOL.GetImageInfo(). + + Caution: This function may receive untrusted input. + + @param[in] Image Points to an FMP authentication image, started from EFI_FIRMWARE_IMAGE_AUTHENTICATION. + @param[in] ImageSize Size of the authentication image in bytes. + @param[in] PublicKeyData The public key data used to validate the signature. + @param[in] PublicKeyDataLength The length of the public key data. + + @retval RETURN_SUCCESS Authentication pass. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_SUCCESS. + @retval RETURN_SECURITY_VIOLATION Authentication fail. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR. + @retval RETURN_INVALID_PARAMETER The image is in an invalid format. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT. + @retval RETURN_UNSUPPORTED No Authentication handler associated with CertType. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT. + @retval RETURN_UNSUPPORTED Image or ImageSize is invalid. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT. + @retval RETURN_OUT_OF_RESOURCES No Authentication handler associated with CertType. + The LastAttemptStatus should be LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES. +**/ +RETURN_STATUS +EFIAPI +AuthenticateFmpImage ( + IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image, + IN UINTN ImageSize, + IN CONST UINT8 *PublicKeyData, + IN UINTN PublicKeyDataLength + ) +{ + GUID *CertType; + EFI_STATUS Status; + + if ((Image == NULL) || (ImageSize == 0)) { + return RETURN_UNSUPPORTED; + } + + if (ImageSize < sizeof(EFI_FIRMWARE_IMAGE_AUTHENTICATION)) { + DEBUG((DEBUG_ERROR, "AuthenticateFmpImage - ImageSize too small\n")); + return RETURN_INVALID_PARAMETER; + } + if (Image->AuthInfo.Hdr.dwLength <= OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData)) { + DEBUG((DEBUG_ERROR, "AuthenticateFmpImage - dwLength too small\n")); + return RETURN_INVALID_PARAMETER; + } + if ((UINTN) Image->AuthInfo.Hdr.dwLength > MAX_UINTN - sizeof(UINT64)) { + DEBUG((DEBUG_ERROR, "AuthenticateFmpImage - dwLength too big\n")); + return RETURN_INVALID_PARAMETER; + } + if (ImageSize <= sizeof(Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) { + DEBUG((DEBUG_ERROR, "AuthenticateFmpImage - ImageSize too small\n")); + return RETURN_INVALID_PARAMETER; + } + if (Image->AuthInfo.Hdr.wRevision != 0x0200) { + DEBUG((DEBUG_ERROR, "AuthenticateFmpImage - wRevision: 0x%02x, expect - 0x%02x\n", (UINTN)Image->AuthInfo.Hdr.wRevision, (UINTN)0x0200)); + return RETURN_INVALID_PARAMETER; + } + if (Image->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) { + DEBUG((DEBUG_ERROR, "AuthenticateFmpImage - wCertificateType: 0x%02x, expect - 0x%02x\n", (UINTN)Image->AuthInfo.Hdr.wCertificateType, (UINTN)WIN_CERT_TYPE_EFI_GUID)); + return RETURN_INVALID_PARAMETER; + } + + CertType = &Image->AuthInfo.CertType; + DEBUG((DEBUG_INFO, "AuthenticateFmpImage - CertType: %g\n", CertType)); + + if (CompareGuid (&gEfiCertPkcs7Guid, CertType)) { + // + // Call the match handler to extract raw data for the input section data. + // + Status = FmpAuthenticatedHandlerPkcs7 ( + Image, + ImageSize, + PublicKeyData, + PublicKeyDataLength + ); + return Status; + } + + // + // Not found, the input guided section is not supported. + // + return RETURN_UNSUPPORTED; +} + diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf new file mode 100644 index 00000000..65e5648a --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf @@ -0,0 +1,43 @@ +## @file +# FMP Authentication PKCS7 handler. +# +# Instance of FmpAuthentication Library for DXE/PEI post memory phase. +# +# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FmpAuthenticationLibPkcs7 + MODULE_UNI_FILE = FmpAuthenticationLibPkcs7.uni + FILE_GUID = F4EA205B-7345-452C-9D62-53BA6F3B8910 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FmpAuthenticationLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + FmpAuthenticationLibPkcs7.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + CryptoPkg/CryptoPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + BaseCryptLib + +[Guids] + gEfiCertPkcs7Guid ## CONSUMES ## GUID diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.uni b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.uni new file mode 100644 index 00000000..e499b6d4 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.uni @@ -0,0 +1,21 @@ +// /** @file
+// FMP Authentication PKCS7 handler.
+//
+// This library provide FMP Authentication PKCS7 handler to verify EFI_FIRMWARE_IMAGE_AUTHENTICATION.
+//
+// Caution: This module requires additional review when modified.
+// This library will have external input - capsule image.
+// This external input must be validated carefully to avoid security issues such as
+// buffer overflow or integer overflow.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "FMP Authentication PKCS7 handler."
+
+#string STR_MODULE_DESCRIPTION #language en-US "This library provide FMP Authentication PKCS7 handler to verify EFI_FIRMWARE_IMAGE_AUTHENTICATION."
+
|