From: Jiewen Yao <jiewen.yao@intel.com>
To: edk2-devel@lists.01.org
Cc: Feng Tian <feng.tian@intel.com>, Star Zeng <star.zeng@intel.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Liming Gao <liming.gao@intel.com>,
Chao Zhang <chao.b.zhang@intel.com>
Subject: [PATCH V5 13/15] SecurityPkg/FmpAuthenticationLibPkcs7: Add PKCS7 instance for FMP.
Date: Thu, 27 Oct 2016 21:36:20 +0800 [thread overview]
Message-ID: <1477575382-20992-14-git-send-email-jiewen.yao@intel.com> (raw)
In-Reply-To: <1477575382-20992-1-git-send-email-jiewen.yao@intel.com>
It provides PKCS7 based FMP authentication.
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Chao Zhang <chao.b.zhang@intel.com>
---
SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.c | 222 ++++++++++++++++++++
SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf | 49 +++++
SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.uni | 26 +++
3 files changed, 297 insertions(+)
diff --git a/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.c b/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.c
new file mode 100644
index 0000000..d79f270
--- /dev/null
+++ b/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.c
@@ -0,0 +1,222 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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 (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/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf b/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
new file mode 100644
index 0000000..ac263bf
--- /dev/null
+++ b/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
@@ -0,0 +1,49 @@
+## @file
+# FMP Authentication PKCS7 handler.
+#
+# Instance of FmpAuthentication Library for DXE/PEI post memory phase.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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 IPF 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
diff --git a/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.uni b/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.uni
new file mode 100644
index 0000000..d327e53
--- /dev/null
+++ b/SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.uni
@@ -0,0 +1,26 @@
+// /** @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>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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."
+
--
2.7.4.windows.1
next prev parent reply other threads:[~2016-10-27 13:37 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-27 13:36 [PATCH V5 00/15] Add capsule update and recovery sample Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 01/15] MdeModulePkg/Include: Add FmpAuthenticationLib header Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 02/15] MdeModulePkg/CapsuleLib: Add ProcessCapsules() API Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 03/15] MdeModulePkg/MdeModulePkg.dec: Add capsule related definition Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 04/15] MdeModulePkg/FmpAuthenticationLibNull: Add NULL instance FMP Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 05/15] MdeModulePkg/DxeCapsuleLibNull: Add ProcessCapsules() interface Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 06/15] MdeModulePkg/DxeCapsuleLibFmp: Add DxeCapsuleLibFmp instance Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 07/15] MdeModulePkg/Esrt: Add ESRT_FW_TYPE_SYSTEMFIRMWARE check Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 08/15] MdeModulePkg/CapsuleApp: Add CapsuleApp application Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 09/15] MdeModulePkg/UiApp: Show test key warning info in FrontPage Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 10/15] MdeModulePkg/MdeModulePkg.dsc: Add FMP related component Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 11/15] IntelFrameworkModulePkg/DxeCapsuleLib: Add ProcessCapsules() interface Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 12/15] SecurityPkg/SecurityPkg.dec: Add PcdPkcs7CertBuffer PCD Jiewen Yao
2016-10-27 13:36 ` Jiewen Yao [this message]
2016-10-27 13:36 ` [PATCH V5 14/15] SecurityPkg/FmpAuthenticationLibRsa2048Sha256: Add RSA2048 instance Jiewen Yao
2016-10-27 13:36 ` [PATCH V5 15/15] SecurityPkg/SecurityPkg.dsc: Add FmpAuthenticationLib* Jiewen Yao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1477575382-20992-14-git-send-email-jiewen.yao@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox