summaryrefslogtreecommitdiff
path: root/Core/EM/CryptoPkg
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/CryptoPkg
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/EM/CryptoPkg')
-rw-r--r--Core/EM/CryptoPkg/CryptLib/Cryptlib.cif15
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlib.chmbin0 -> 82444 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlib.libbin0 -> 139706 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlib.sdl36
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlibX64.libbin0 -> 232926 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlibpei.libbin0 -> 92784 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptLib/license.txt102
-rw-r--r--Core/EM/CryptoPkg/CryptoAPI.chmbin0 -> 110686 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptoAPI.cif16
-rw-r--r--Core/EM/CryptoPkg/CryptoAPI.mak127
-rw-r--r--Core/EM/CryptoPkg/CryptoAPI.sdl95
-rw-r--r--Core/EM/CryptoPkg/CryptoDxe.c1108
-rw-r--r--Core/EM/CryptoPkg/CryptoDxe.dxs53
-rw-r--r--Core/EM/CryptoPkg/CryptoPei.c800
-rw-r--r--Core/EM/CryptoPkg/CryptoPei.dxs54
-rw-r--r--Core/EM/CryptoPkg/CryptoPkg.cif9
16 files changed, 2415 insertions, 0 deletions
diff --git a/Core/EM/CryptoPkg/CryptLib/Cryptlib.cif b/Core/EM/CryptoPkg/CryptLib/Cryptlib.cif
new file mode 100644
index 0000000..d3f341b
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/Cryptlib.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "Crypto LIB"
+ category = ModulePart
+ LocalRoot = "Core\EM\CryptoPkg\CryptLib\"
+ RefName = "CryptoLIB"
+[files]
+"cryptlib.chm"
+"cryptlib.sdl"
+"cryptlib.lib"
+"cryptlibX64.lib"
+"cryptlibpei.lib"
+"license.txt"
+[parts]
+"CryptoLibInc"
+<endComponent>
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlib.chm b/Core/EM/CryptoPkg/CryptLib/cryptlib.chm
new file mode 100644
index 0000000..9f80f28
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlib.chm
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlib.lib b/Core/EM/CryptoPkg/CryptLib/cryptlib.lib
new file mode 100644
index 0000000..53ce46a
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlib.lib
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlib.sdl b/Core/EM/CryptoPkg/CryptLib/cryptlib.sdl
new file mode 100644
index 0000000..8587961
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlib.sdl
@@ -0,0 +1,36 @@
+TOKEN
+ Name = "CryptLib_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "CRYPTO_trace_level"
+ Value = "0"
+ Help = "0-skip debug messages, 1- short trace, 2- full trace"
+ TokenType = Integer
+ TargetH = Yes
+ TargetMAK = Yes
+ Range = "0-1-2"
+End
+
+TOKEN
+ Name = "CRYPTOLIB"
+ Value = "$(Cryptlib_DIR)\CRYPTLIB$(ARCH).lib"
+ TokenType = "Expression"
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CRYPTOLIBPEI"
+ Value = "$(Cryptlib_DIR)\CRYPTLIBPEI.lib"
+ TokenType = "Expression"
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "Cryptlib_DIR"
+End
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlibX64.lib b/Core/EM/CryptoPkg/CryptLib/cryptlibX64.lib
new file mode 100644
index 0000000..be4663b
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlibX64.lib
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlibpei.lib b/Core/EM/CryptoPkg/CryptLib/cryptlibpei.lib
new file mode 100644
index 0000000..bfad267
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlibpei.lib
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptLib/license.txt b/Core/EM/CryptoPkg/CryptLib/license.txt
new file mode 100644
index 0000000..378df36
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/license.txt
@@ -0,0 +1,102 @@
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+// Name: License
+// Description: WPA Supplicant License
+======================================================================
+
+Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> and contributors
+All Rights Reserved.
+
+======================================================================
+License
+--------
+
+This software may be distributed, used, and modified
+under the terms of BSD license:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name(s) of the above-listed copyright holder(s) nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+==============
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+======================================================================
+
+Features
+--------
+
+Internal crypto implementation (optional):
+- X.509 certificate processing in PEM and DER formats
+- PKCS #1
+- ASN.1
+- RSA
+- bignum
+- minimal size (ca. 50 kB binary, parts of which are already needed for WPA;
+ TLSv1/X.509/ASN.1/RSA/bignum parts are about 25 kB on x86)
+
+
+Requirements
+------------
+
+wpa_supplicant was designed to be portable for different drivers and
+operating systems. Hopefully, support for more wlan cards and OSes will be
+added in the future. See developer's documentation
+(http://hostap.epitest.fi/wpa_supplicant/devel/) for more information about the
+design of wpa_supplicant and porting to other drivers. One main goal
+is to add full WPA/WPA2 support to Linux wireless extensions to allow
+new drivers to be supported without having to implement new
+driver-specific interface code in wpa_supplicant.
+
+
+WPA
+---
+
+The original security mechanism of IEEE 802.11 standard was not
+designed to be strong and has proven to be insufficient for most
+networks that require some kind of security. Task group I (Security)
+of IEEE 802.11 working group (http://www.ieee802.org/11/) has worked
+to address the flaws of the base standard and has in practice
+completed its work in May 2004. The IEEE 802.11i amendment to the IEEE
+802.11 standard was approved in June 2004 and published in July 2004.
+
+Wi-Fi Alliance (http://www.wi-fi.org/) used a draft version of the
+IEEE 802.11i work (draft 3.0) to define a subset of the security
+enhancements that can be implemented with existing wlan hardware. This
+is called Wi-Fi Protected Access<TM> (WPA). This has now become a
+mandatory component of interoperability testing and certification done
+by Wi-Fi Alliance. Wi-Fi provides information about WPA at its web
+site (http://www.wi-fi.org/OpenSection/protected_access.asp).
+
+IEEE 802.11 standard defined wired equivalent privacy (WEP) algorithm
+for protecting wireless networks. WEP uses RC4 with 40-bit keys,
+24-bit initialization vector (IV), and CRC32 to protect against packet
+forgery. All these choices have proven to be insufficient: key space is
+too small against current attacks, RC4 key scheduling is insufficient
+(beginning of the pseudorandom stream should be skipped), IV space is
+too small and IV reuse makes attacks easier, there is no replay
+protection, and non-keyed authentication does not protect against bit
+flipping packet data.
+
+//<AMI_FHDR_END>
diff --git a/Core/EM/CryptoPkg/CryptoAPI.chm b/Core/EM/CryptoPkg/CryptoAPI.chm
new file mode 100644
index 0000000..7c69ddc
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoAPI.chm
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptoAPI.cif b/Core/EM/CryptoPkg/CryptoAPI.cif
new file mode 100644
index 0000000..f572730
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoAPI.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "Crypto Protocol"
+ category = ModulePart
+ LocalRoot = "Core\EM\CryptoPkg"
+ RefName = "CryptoAPI"
+[files]
+"CryptoAPI.chm"
+"CryptoAPI.sdl"
+"CryptoAPI.mak"
+"CryptoPei.c"
+"CryptoDxe.c"
+"CryptoPei.dxs"
+"CryptoDxe.dxs"
+[parts]
+"CryptoIncludes"
+<endComponent>
diff --git a/Core/EM/CryptoPkg/CryptoAPI.mak b/Core/EM/CryptoPkg/CryptoAPI.mak
new file mode 100644
index 0000000..f83d42a
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoAPI.mak
@@ -0,0 +1,127 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoAPI.mak 1 6/13/11 5:19p Alexp $
+#
+# $Revision: 1 $
+#
+# $Date: 6/13/11 5:19p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoAPI.mak $
+#
+# 1 6/13/11 5:19p Alexp
+#
+# 2 5/11/11 12:59p Alexp
+# renamed cryptolib macro name
+#
+# 1 5/06/11 6:11p Alexp
+# initial module release
+#
+# 5 5/06/11 6:04p Alexp
+# link PEI Crypto Lib module
+#
+# 4 5/06/11 4:39p Alexp
+# add help header
+#
+# 3 4/07/11 12:22p Alexp
+#
+# 2 4/04/11 7:19p Alexp
+#
+# 1 3/10/11 4:52p Alexp
+#
+# 1 2/18/11 5:42p Alexp
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CryptoApi.mak
+#
+# Description: Build rules to build PEI, DXE and SMM Crypto drivers
+#
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : CryptoAPI
+
+BUILD_CryptoAPI_DIR = $(BUILD_DIR)\$(CryptoAPI_DIR)
+BUILD_CryptoAPIIA32_DIR = $(BUILD_DIR)\IA32\$(CryptoAPI_DIR)
+
+CryptoAPI : CryptLib $(BUILD_DIR)\CryptoAPI.mak CryptoAPIDxeBin \
+!IF "$(CryptoPPI_SUPPORT)" == "1"
+ CryptoAPIPeiBin
+!ENDIF
+
+#dummy target. Will be used to build Crypto Library if sources are present
+CryptLib:
+
+$(BUILD_DIR)\CryptoAPI.mak : $(CryptoAPI_DIR)\CryptoAPI.cif $(CryptoAPI_DIR)\CryptoAPI.mak $(BUILD_RULES)
+ $(CIF2MAK) $(CryptoAPI_DIR)\CryptoAPI.cif $(CIF2MAK_DEFAULTS)
+
+CryptoAPI_PEI_OBJECTS = \
+ $(BUILD_CryptoAPIIA32_DIR)\CryptoPei.obj
+
+CryptoAPI_DXE_OBJECTS = \
+ $(BUILD_CryptoAPI_DIR)\CryptoDxe.obj
+
+CryptoAPI_INCLUDES= \
+ /I $(CryptoAPI_DIR)\
+ /I $(Cryptlib_DIR)\
+ /I $(ReFlash_DIR)\
+ /I$(CORE_DIR)
+
+!IF "$(CryptoPPI_SUPPORT)" == "1"
+CryptoAPIPeiBin : $(AMIPEILIB) $(CRYPTOLIBPEI)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CryptoAPI.mak all\
+ NAME=CryptoPei\
+ MAKEFILE=$(BUILD_DIR)\CryptoAPI.mak \
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ GUID=D6D2FBA6-EF60-4C38-A83E-6769814D23B0 \
+ ENTRY_POINT=CryptoPei_Init \
+ "MY_INCLUDES=$(CryptoAPI_INCLUDES)"\
+ "CFLAGS=$(CFLAGS) /D PEI_BUILD" \
+ OBJECTS="$(CryptoAPI_PEI_OBJECTS)" \
+ DEPEX1=$(CryptoAPI_DIR)\CryptoPei.DXS DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ TYPE=PEIM COMPRESS=1
+!ENDIF
+
+CryptoAPIDxeBin : $(AMIDXELIB) $(CRYPTOLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CryptoAPI.mak all\
+ NAME=CryptoDxe\
+ MAKEFILE=$(BUILD_DIR)\CryptoAPI.mak \
+ GUID=20D8FFFE-15C3-4ea9-9D28-CFE2745D78F3 \
+ ENTRY_POINT=CryptoDxe_Init\
+ DEPEX1=$(CryptoAPI_DIR)\CryptoDxe.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ "MY_INCLUDES=$(CryptoAPI_INCLUDES) "\
+ OBJECTS="$(CryptoAPI_DXE_OBJECTS)" \
+ TYPE=RT_DRIVER COMPRESS=1
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoAPI.sdl b/Core/EM/CryptoPkg/CryptoAPI.sdl
new file mode 100644
index 0000000..5e6f9ee
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoAPI.sdl
@@ -0,0 +1,95 @@
+TOKEN
+ Name = "CryptoAPI_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CryptoAPI support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "CryptoPPI_SUPPORT"
+ Value = "1"
+ Help = "Includes the Crypto PPI module"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CR_PEI_MAX_HEAP_SIZE"
+ Value = "48*1024"
+ Help = "Crypt Optimized Mem manager. Min 15kb in rsa decrypt in Mode2,(?? if page alligned heap)"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CR_DXE_MAX_HEAP_SIZE"
+ Value = "48*1024"
+ Help = "Crypt Optimized Mem manager. Min 48kb if process PKCS7 Certs and Rsa decrypt in Mode2,(?? if page alligned heap)"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "E_CONST"
+ Value = "0x01, 0x00, 0x01"
+ Help = "RSA2048. Predefined value of Public Exponent:E = 0x10001"
+ TokenType = Expression
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "PSS_SIG_SALTLEN"
+ Value = "8"
+ Help = "PKCS_1 PSS Signature constant. Size of the Salt (random data) field in PSS signature."
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "CONFIG_PEI_PKCS7"
+ Value = "0"
+ Help = "Support x509 & Pkcs7 in PEI CryptoLib. Add ~8kb to CryptoPEI binary"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "0-1"
+End
+
+TOKEN
+ Name = "PKCS7_MUTEX_LOCK"
+ Value = "0"
+ Help = "Turn on mutex functionality for Pkcs7Verify back to back operations. Preserves internal context until mutext released/reset"
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "0-1"
+End
+
+PATH
+ Name = "CryptoAPI_DIR"
+ Help = "Path to CryptoAPI Module in Project"
+End
+
+MODULE
+ Help = "Includes CryptoAP.mak to Project"
+ File = "CryptoAPI.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CryptoPei.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+ Token = "CryptoPPI_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CryptoDxe.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/CryptoPkg/CryptoDxe.c b/Core/EM/CryptoPkg/CryptoDxe.c
new file mode 100644
index 0000000..8c40af1
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoDxe.c
@@ -0,0 +1,1108 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoDxe.c 31 8/15/13 9:43a Alexp $
+//
+// $Revision: 31 $
+//
+// $Date: 8/15/13 9:43a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoDxe.c $
+//
+// 31 8/15/13 9:43a Alexp
+// Pkcs7Verify() - add TimeStamp signature processing(UEFI ECR1009)
+// Pkcs7Verify() - enable code branch for PKCS7_MUTEX_LOCK
+//
+// 30 8/02/13 4:26p Alexp
+// Moved EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID under AmiDigSig
+// Protocol defining header file
+//
+// 29 8/02/13 4:00p Alexp
+// 1. Fix logic to get FwKey from a Hob.
+// Key is copied into pre-allocated buffer by driver entry point
+// 2. Optimized Pkcs7Verify.
+//
+// 27 6/20/13 1:55p Alexp
+// Impove FwKey handling. CryptoPEI pass FwKey location to Dxe via Hob
+// Add mor parameter checking including
+// check for FwKey location to be mapped to Flash FV_BB
+//
+// 26 1/11/13 10:07a Alexp
+// GetKey(): fix MemCpy() 2nd argument. Was not copying a key buffer.
+//
+// 25 12/28/12 2:50p Alexp
+// EIP#110823:The system cannot boot to UEFI(WIN8) OS if the Secure Flash
+// Pkg module is not supported
+// Update GetKey(); InSmmFunction() and NotInSmmFunction() routines
+// to handle cases when Fw Key FFS file not present
+//
+// 23 12/10/12 6:09p Alexp
+// Bug fix: InSmmFunction() the Key pointer gKeyBuf was to updated to Key
+// in SMM region
+//
+// 21 12/07/12 4:08p Alexp
+// disable debug crypto traces in SMM
+//
+// 20 11/29/12 3:10p Alexp
+// Pkcs7Verify()-
+// Fix error checking for input **Data parameter : Data == NULL
+//
+// 18 11/16/12 5:10p Alexp
+// EIP#105015: Add handling of x509 format for Platform FW Key in FFS
+// files
+//
+// 16 8/28/12 12:33p Alexp
+// UEFI 2.3.1. ErrataC.
+// Added support for new Hash types
+// defined by a GUID with 'NOPAD' keyword:
+// EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID
+// EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID
+//
+// 15 8/22/12 4:28p Alexp
+// Added support in Pkcs7Parse() for new operations:
+// Pkcs7CertValidateGetSignerKey - n-modulus of Signer key
+// Pkcs7CertGetMatchInCertChain - true if found leaf cert matching
+// to
+// trust cert
+// Pkcs7CertValidateGetCAKey, - n-modulus of CA key if detected
+// in
+// x509 chain
+// Pkcs7GetCAKey, Pkcs7GetSignerKey
+//
+// 12 7/23/12 4:12p Alexp
+// Pkcs7Verify:
+// Bug Fix. For condition:Pkcs7CertValidateGetMatchInCertChain return
+// success if leaf cert is found. Before code fell down testing
+// certificate and could return error potentially misleading Caller of this
+// function.
+//
+// 11 7/18/12 8:57p Alexp
+// Pkcs7Verify
+// fix bug - "reason" var was used uninitialized
+//
+// 10 5/04/12 9:49a Alexp
+// [TAG] EIP89280
+// [Category] Improvement
+// [Description] When secure boot enable with secure flash disable, in
+// Security page of setup menu same items will exist twice
+// Fix: Install Crypto Protocols even if Root FW Key not found (brought in
+// by Sec Flash module)
+// [Files] cryptoDxe.c
+//
+// 9 4/11/12 5:27p Alexp
+// Add new operand within Pkcs7Validate:
+// Pkcs7CertValidateGetMatchInCertChain
+//
+// 7 3/02/12 10:43a Alexp
+// Remove dependency on SDL Token FWKEY_FORMAT to determine format of PR
+// Key file
+// Try different Ffs GUIDs to select proper Key format: SHA or RSA
+//
+// 6 2/29/12 4:04p Alexp
+// 1. Add VerifyKey
+// 2. Fix GetKey (API call will be deprecated as not needed) to move PR
+// Key from file to local storage
+// 3. Use FWKEY_FORMAT to process VerifyKey according to file format. Hash
+// input RSA2048 key for comparison if PR Key stored as Hash
+//
+// 5 11/14/11 12:01p Alexp
+// InSmmFunction()->InstallMultipleProtocols() Change the HAndle argument
+// from ImageHandle to a DummyHandle=NULL
+//
+// 4 6/30/11 5:45p Alexp
+// GetRawImage: added freepool(HandleBuffer)
+//
+// 3 6/27/11 5:30p Alexp
+// removed commented out lines
+//
+// 2 6/22/11 5:46p Alexp
+// update deafult Crypto trace level
+//
+// 1 6/13/11 5:19p Alexp
+//
+// 7 6/10/11 6:21p Alexp
+// added new Pkcs7 parse Operation: Pkcs7CertValidateGetSignerKeyHash
+//
+// 6 6/09/11 9:57a Alexp
+// always parse PKCS7 cert
+//
+// 5 5/18/11 1:18p Alexp
+// edited text in func headers
+//
+// 4 5/17/11 12:53p Alexp
+// fix WDK Level4 compiler warnings
+//
+// 3 5/11/11 7:38p Alexp
+// remove set trace level call. If needed, modify Sdl token in Crypto Src
+//
+// 2 5/10/11 6:55p Alexp
+// use external Guid variable declarations
+//
+// 1 5/06/11 6:11p Alexp
+// initial module release
+//
+// 10 4/22/11 4:20p Alexp
+// cleaned up CryptoGetRawImage
+//
+// 9 4/18/11 7:09p Alexp
+//
+// 8 4/11/11 12:52p Alexp
+// remove ASN1 as possible Key buf format.
+//
+// 7 4/05/11 6:31p Alexp
+// remove content from GetKey. We may add get FwSig key in later
+// revisions
+//
+// 6 3/31/11 6:14p Alexp
+// hashing of SpcIndirect data is done inside Pkcs Validate
+//
+//
+//**********************************************************************
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include "Setup.h"
+#include "AmiCertificate.h"
+#include <Protocol\AmiDigitalSignature.h>
+#include <Protocol\Hash.h>
+
+#include <cryptlib.h>
+
+#include <Protocol\SmmBase.h> // used for SMM Malloc
+
+//
+// Global variables
+//
+extern EFI_BOOT_SERVICES *pBS;
+extern EFI_RUNTIME_SERVICES *pRS;
+
+static EFI_GUID gPRKeyGuid = PR_KEY_GUID;
+
+// The ptr to a buffer containing the Fw Platform Key
+// Key Image is copied from .ffs to a local buffer.
+// It is a safe location in case of AmiSig running in SMM
+static CRYPT_HANDLE gKey = {{0},0,NULL};
+
+// Second part of the Public key, public exponent (e),
+// must be hardwired in the FW elsewhere(recommended value of e=65537).
+//
+// SDL Hardwired value of publicExponent--e
+const UINT8 KeyE[] = {E_CONST}; // 0x10001
+const UINT32 LenE = sizeof(KeyE);
+const INT32 saltlen = PSS_SIG_SALTLEN; // 8
+static UINT8 Rsa2048Sig[DEFAULT_RSA_SIG_LEN];
+
+// Pkcs7 Certificate private var
+//struct pkcs7_signed_data_st* PKCS7cert = NULL;
+// Mutex to control Memory reset during atomic Pkcs7 operations
+static UINT8 MutexLock = RESET;
+
+//----------------------------------------------------------------------------
+// Crypto Function prototypes
+//----------------------------------------------------------------------------
+EFI_STATUS
+Pkcs1Verify (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CRYPT_HANDLE *PublicKey,
+ IN CRYPT_HANDLE *Hash,
+ IN VOID *Signature,
+ IN UINTN SignatureSize,
+ IN UINT32 Flags
+ );
+
+EFI_STATUS
+Pkcs7Verify (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Size,
+ IN CONST UINT8 *TrustedCert,
+ IN UINTN CertSize,
+ IN OUT UINT8 **Data,
+ IN OUT UINTN *DataSize,
+ IN UINT8 Operation,
+ IN UINT32 Flags
+ );
+
+EFI_STATUS
+Hash(
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN UINTN Num_elem,
+ IN CONST UINT8 *Addr[],
+ IN CONST UINTN *Len,
+ OUT UINT8 *Hash
+ );
+
+EFI_STATUS
+GetKey (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ OUT CRYPT_HANDLE *Key,
+ IN EFI_GUID *AlgId,
+ IN UINTN KeyLen,
+ IN UINT32 Flags
+ );
+
+EFI_STATUS
+VerifyKey (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN EFI_GUID *AlgId,
+ IN CRYPT_HANDLE *Key
+ );
+//----------------------------------------------------------------------------
+// Crypto Protocol Identifiers
+//----------------------------------------------------------------------------
+AMI_DIGITAL_SIGNATURE_PROTOCOL mAmiSig = {
+ Pkcs1Verify,
+ Pkcs7Verify,
+ Hash,
+ GetKey,
+ VerifyKey
+};
+
+//----------------------------------------------------------------------------
+// Crypto Function Implementation
+//----------------------------------------------------------------------------
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Hash
+//
+// Description: Allows creating a hash of an arbitrary message digest using one or more hash algorithms
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE_PROTOCOL instance.
+// HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+// num_elem Number of blocks to be passed via next argument:addr[]
+// addr[] Pointer to array of UINT8* addresses of data blocks to be hashed
+// len Pointer to array of integers containing length of each block listed by addr[]
+// Hash Holds the resulting hash computed from the message.
+//
+// Output:
+// EFI_SUCCESS Hash returned successfully.
+// EFI_INVALID_PARAMETER Message or Hash is NULL
+// EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this
+// driver.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+Hash(
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN UINTN num_elem,
+ IN CONST UINT8 *addr[],
+ IN CONST UINTN *len,
+ OUT UINT8 *Hash
+ )
+{
+ BOOLEAN bSha1 = FALSE, bSha256 = FALSE;
+ UINT32 HashLen=SHA256_DIGEST_SIZE;
+
+// Support only SHA1 & SHA256 hashes
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha1Guid) ||
+ !guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha1NoPadGuid))
+ {
+ bSha1 = TRUE;
+ HashLen = SHA1_DIGEST_SIZE;
+ }
+ else
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha256Guid) ||
+ !guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha256NoPadGuid))
+ {
+ bSha256 = TRUE;
+ HashLen = SHA256_DIGEST_SIZE;
+ }
+ else
+ return EFI_UNSUPPORTED;
+
+ MemSet(Hash, HashLen, 0);
+ if(bSha1)
+ sha1_vector(num_elem, addr, len, Hash);
+ else
+ sha256_vector(num_elem, addr, len, Hash);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Pkcs7Verify
+//
+// Description: Verifies the validity of a PKCS#7 signed data as described in "PKCS #7: Cryptographic
+// Message Syntax Standard".
+// Function perfors several operations on input Pkcs7 certificate
+// based on the input Operation argument
+// 1. Verifies validity of the signature contained inside the Certificate
+// This function decrypts the signature with the Public key from the Signer certificate
+// and then compares the decrypted value to the input Data
+// 2. Extracts the Signer certificate in format of x509
+// 3. Extracts Root CA certificate that used to sign the Signer certificate.
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE_PROTOCOL instance.
+// P7Data Pointer to the PKCS#7 DER encoded message to verify.
+// P7Size Size of the PKCS#7 message in bytes.
+// TrustedCert Pointer to a trusted/root X509 certificate encoded in DER, which
+// is used for certificate chain verification.
+// CertSize Size of the trusted certificate in bytes.
+// Data Pointer to the content to be verified/returned at
+// DataSize Size of Data in bytes
+// Operation Specifies different tasks to perform:
+// 0-Function presence check. Must return EFI_SUCCESS
+// 1-Validate Certificate
+// 2-Return Signer Certificate in *Data. Performs cert chaining and time based validity tests
+// 3-Return Root CA certificate referenced by Signer. Used to compare with Trusted Cert in FW
+// 4-Validate Root Certificate
+// 5-Validate Signer Certificate Chain
+// 6-Return Signature Digest Algorithm
+// 7-Validate Certificate, return Root CA Certificate
+// 8-Validate Certificate, return Signer Certificate
+// 9-Validate Certificate, return Signer Key Hash (SHA256)
+// 10-Validate Certificate and return Success if match is found between Trust and any leaf certificates in the Signer chain
+// 11-Validate Certificate, return ptr in *Data to n-modulus of a Signer Key
+// 12-Return Success if match is found between Trust and any leaf certificates in the Signer chain
+// 13-Validate Certificate, return ptr in *Data to n-modulus of a Root CA Key
+// 14-Return ptr in *Data to n-modulus of a Root CA Key
+// 15-Return ptr in *Data to n-modulus of a Signer Key
+// 16-Validate TimeStamp certificate chain in Pkcs7 Certificate
+// 17-255 reserved values
+// Flags Specifies additional flags to further customize the signing/verifying behavior.
+//
+// Output:
+// EFI_SUCCESS The specified PKCS#7 signed data is valid
+// EFI_SECURITY_VIOLATION Invalid PKCS#7 signed data.
+// EFI_ACCESS_DENIED The Trusted certificate does not have a match in SignedData.certificate store.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+Pkcs7Verify (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Size,
+ IN CONST UINT8 *TrustedCert,
+ IN UINTN CertSize,
+ IN OUT UINT8 **Data,
+ IN OUT UINTN *DataSize,
+ IN UINT8 Operation,
+ IN UINT32 Flags
+ )
+{
+ EFI_STATUS Status;
+ INTN err, reason;
+ static struct pkcs7_signed_data_st* PKCS7cert;
+ struct x509_certificate *x509SignCert;
+ struct x509_certificate *x509TrustCert;
+ UINT8 *x509SignCertPtr, *x509RootCertPtr;
+ UINTN SignCert_len, CARootCert_len;
+ struct pkcs7_cert_revoke_info revokeInfo;
+ EFI_CERT_X509_SHA256 *revokeCert;
+
+// Mutex functionality:
+/*
+Structure mutex
+Mutual exclusion (mutex) semaphore locking mechanism used to serialise interthread intraprocess activities.
+*/
+#if PKCS7_MUTEX_LOCK == 1
+ switch(Flags & 0x3) {
+ case RESET:
+ ResetCRmm(); // first time needs mem clean
+ MutexLock = RESET;
+ PKCS7cert = NULL;
+ break;
+
+ case LOCK:
+ ResetCRmm(); // first time needs mem clean
+ MutexLock = LOCK;
+ PKCS7cert = NULL;
+ break;
+
+ case RELEASE: // clear memory after execute routines
+ if(MutexLock == RESET)
+ ResetCRmm();
+ MutexLock = RESET;
+ break;
+
+ case KEEP:
+ if(MutexLock == RESET)
+ ResetCRmm();
+ break;
+
+ default:
+ ResetCRmm();
+ }
+#else
+ PKCS7cert = NULL;
+ ResetCRmm();
+#endif
+/*
+ Notes of implementation:
+
+ IN order to allocate the Pool for returned Cert (Signer or CA)
+ -run getCert with Size 0 -> it will return real cert size
+ -allocate buffer of Size and re-run with new size
+ OR caller is responsible for freeng the Data buffer
+ OR caller always allocates sufficient size == Trusted Cert + 1k
+
+ GetSignerCert
+ parse Pkcs7 to *Pkcs7cert
+ get SignerName from SignerInfo.serialName
+ find x509 cert matching Signer name
+ GetCACert
+ run GetSignerCert
+ run cert chain valid for that cert
+
+ ValidateSignCert - internal Cert validation, returns Root CA Cert ptr
+ ValidateTrustCert - external Trust Cert validation, returns Sign Cert ptr
+
+*/
+ err = -1;
+ reason=0;
+
+ switch(Operation){
+ case Pkcs7Arg0:
+ Status = EFI_SUCCESS;
+ err = 0;
+ break;
+// Validate Digest and returns Root CA cert or Signer Cert
+ case Pkcs7CertGetMatchInCertChain:
+ case Pkcs7CertValidateGetMatchInCertChain: // obsolete
+ reason = -1; // non-0 reason argument forces Pkcs7_Chain_Validate to scan for matching Cert in the Chain if other checks failed
+ case Pkcs7CertValidate:
+ case Pkcs7CertValidateGetCAKey:
+ case Pkcs7CertValidateGetCACert:
+ case Pkcs7CertValidateGetSignerKey:
+ case Pkcs7CertValidateGetSignerCert:
+ case Pkcs7CertValidateGetSignerKeyHash:
+ case Pkcs7TimeStampCertValidateGet:
+ if(Data == NULL || DataSize == NULL)
+ break;
+ case Pkcs7ValidateRootCert:
+ if (!PKCS7cert) PKCS7cert = Pkcs7_parse_Authenticode_certificate(P7Data, P7Size);
+ if (!PKCS7cert)
+ break;
+ // verify Pkcs7 Signing Cert chain up to the TrustCert...if provided
+ if(TrustedCert && CertSize) {
+ x509TrustCert = x509_certificate_parse(TrustedCert, CertSize);
+ if(x509TrustCert) {
+ err = Pkcs7_x509_certificate_chain_validate_with_timestamp(PKCS7cert, (Operation == Pkcs7TimeStampCertValidateGet), x509TrustCert, NULL, (int*)&reason);
+ } else {
+ // potentially a TimeStamped revocation cert
+ revokeCert = (EFI_CERT_X509_SHA256*)TrustedCert;
+ if(CertSize == sizeof(EFI_CERT_X509_SHA256))
+ revokeInfo.ToBeSignedHashLen = 32;
+ else
+ if(CertSize == sizeof(EFI_CERT_X509_SHA384))
+ revokeInfo.ToBeSignedHashLen = 48;
+ else
+ if(CertSize == sizeof(EFI_CERT_X509_SHA512))
+ revokeInfo.ToBeSignedHashLen = 64;
+ else { // unsupported Hash struct
+ err = -1;
+ break;
+ }
+ revokeInfo.ToBeSignedHash = (UINT8*)&revokeCert->ToBeSignedHash;
+ err = Pkcs7_x509_certificate_chain_validate_with_timestamp(PKCS7cert, FALSE, NULL, &revokeInfo, (int*)DataSize);
+ }
+
+ if(err == -1 ||
+ Operation==Pkcs7CertGetMatchInCertChain ||
+ Operation == Pkcs7ValidateRootCert
+ )
+ break; // break(err=0) if leaf found to match trust cert
+ }
+ // x509SignCert== NULL -> extract SignCert from Pkcs7 crt
+ err = Pkcs7_certificate_validate_digest(PKCS7cert, NULL, (UINT8*)*Data, (UINTN)*DataSize);
+ if(!err) {
+ switch(Operation){
+ //Returns CA Root cert after successfully validating Cert chain and signature digest
+ case Pkcs7CertValidateGetCACert:
+ err = Pkcs7_return_cerificate_ptr(PKCS7cert, Data, DataSize, &x509SignCertPtr, (size_t*)&SignCert_len);
+ break;
+ //Returns Signing Key from Cert after successfully validating Cert chain and signature digest
+ case Pkcs7CertValidateGetSignerCert:
+ err = Pkcs7_return_cerificate_ptr(PKCS7cert, &x509RootCertPtr, (size_t*)&CARootCert_len, Data, DataSize);
+ break;
+ case Pkcs7CertValidateGetSignerKeyHash:
+ err = Pkcs7_x509_return_signing_Key(PKCS7cert, &x509SignCertPtr, &SignCert_len);
+ if(!err) {
+ Hash(This, &gEfiHashAlgorithmSha256Guid, 1, &x509SignCertPtr, (const UINTN*)&SignCert_len, *Data);
+ *DataSize=SHA256_DIGEST_SIZE;
+ }
+ break;
+ case Pkcs7CertValidateGetSignerKey:
+ err = Pkcs7_x509_return_signing_Key(PKCS7cert, Data, DataSize);
+ break;
+ case Pkcs7CertValidateGetCAKey:
+ err = Pkcs7_return_cerificate_ptr(PKCS7cert, Data, DataSize, &x509SignCertPtr, (size_t*)&SignCert_len);
+ if(!err)
+ err = Pkcs7_x509_return_Cert_pubKey(*Data, *DataSize, Data, DataSize);
+ break;
+ case Pkcs7TimeStampCertValidateGet:
+ err = Pkcs7_certificate_validate_timestamp_digest(PKCS7cert, (long*)DataSize);
+ break;
+ }
+ }
+ break;
+
+// returns Ptr within input P7Data DER buffer to RootCA cert or Signing Cert
+ case Pkcs7GetSignerCert:
+ case Pkcs7GetCACert:
+ case Pkcs7GetSignerKey:
+ case Pkcs7GetCAKey:
+ if(Data == NULL || DataSize == NULL) {
+ break;
+ }
+ if (!PKCS7cert) PKCS7cert = Pkcs7_parse_Authenticode_certificate(P7Data, P7Size);
+ if (PKCS7cert) {
+ err = Pkcs7_return_cerificate_ptr(PKCS7cert, &x509RootCertPtr, (size_t*)&CARootCert_len, &x509SignCertPtr, (size_t*)&SignCert_len);
+ if(!err) {
+ switch(Operation){
+ case Pkcs7GetSignerCert:
+ *DataSize = SignCert_len;
+ *Data = x509SignCertPtr;
+ break;
+ case Pkcs7GetCACert:
+ *DataSize = CARootCert_len;
+ *Data = x509RootCertPtr;
+ break;
+ case Pkcs7GetCAKey:
+ err = Pkcs7_x509_return_Cert_pubKey(x509RootCertPtr, CARootCert_len, Data, DataSize);
+ break;
+ case Pkcs7GetSignerKey:
+ err = Pkcs7_x509_return_Cert_pubKey(x509SignCertPtr, SignCert_len, Data, DataSize);
+ break;
+ }
+ }
+ }
+ break;
+
+ case x509ValidateCertChain:
+ //Validates Signer certificate's key against Trusted Cert
+ x509SignCert = x509_certificate_parse(P7Data, P7Size);
+ if(TrustedCert && CertSize)
+ x509TrustCert = x509_certificate_parse(TrustedCert, CertSize);
+ if (x509TrustCert && x509SignCert)
+ err = x509_certificate_chain_validate(x509TrustCert, x509SignCert, (int*)&reason);
+ break;
+
+ case Pkcs7GetDigestAlgorithm:
+ // validate input params.
+ if(Data == NULL || DataSize == NULL) {
+ break;
+ }
+ if (!PKCS7cert) PKCS7cert = Pkcs7_parse_Authenticode_certificate(P7Data, P7Size);
+ if (PKCS7cert) {
+ err = Pkcs7_return_digestAlgorithm(PKCS7cert, (UINT8*)*Data);
+ if(!err)
+ *DataSize = sizeof(UINT8);
+ }
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ err = -1;
+ }
+
+// Security concern, memory heap is being cleared on exit
+ if(err)
+ MutexLock = RESET;
+
+#if PKCS7_MUTEX_LOCK == 1
+ if(MutexLock == RESET)
+#endif
+ {
+ ResetCRmm();
+ PKCS7cert = NULL;
+ }
+
+// failed to process
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Pkcs1Verify
+//
+// Description: Function verifies that the specified signature matches the specified hash.
+// Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in
+// RSA PKCS#1.
+// This function decrypts the signature with the provided key and then compares
+// the decrypted value to the specified hash value
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE_PROTOCOL instance.
+// PublicKey Handle to a key used for verifying signatures. This handle must be identifying a public key.
+// Hash Handle of the hash object to verify.
+// Signature Pointer to the signature data to be verified.
+// SignatureSize The size, in bytes, of the signature data.
+// Flags Specifies additional flags to further customize the signing/verifying behavior.
+//
+// Output:
+// EFI_SUCCESS The signature is successfully verified.
+// EFI_SECURITY_VIOLATION The signature does not match the given message.
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+Pkcs1Verify (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CRYPT_HANDLE *PublicKey,
+ IN CRYPT_HANDLE *Hash,
+ IN VOID *Signature,
+ IN UINTN SignatureSize,
+ IN UINT32 Flags
+ )
+{
+ EFI_STATUS Status;
+ INTN err;
+ struct crypto_rsa_key *key = NULL;
+ UINT16 Size = (UINT16)(PublicKey->BlobSize);
+ size_t *sig_len=(size_t*)&SignatureSize;
+ INT32 modulus_bitlen = DEFAULT_RSA_SIG_LEN << 3;
+ UINT32 HashLen;
+
+// Only supporting RSASSA_PKCS1V15 & PSS signature types
+ if(!((Flags & EFI_CRYPT_RSASSA_PKCS1V15) ||
+ (Flags & EFI_CRYPT_RSASSA_PSS)) )
+ return EFI_INVALID_PARAMETER;
+
+ if(!PublicKey || !Hash || !Signature)
+ return EFI_INVALID_PARAMETER;
+
+ ResetCRmm();
+ MutexLock = RESET;
+
+// For now Public Key is supported in 2 formats: RAW 256 bytes and ASN.1 Integer
+ if(!guidcmp(&PublicKey->AlgGuid, &gEfiCertRsa2048Guid))
+ key = crypto_import_rsa2048_public_key(PublicKey->Blob, Size, (UINT8*)&KeyE, LenE);
+ else
+ return EFI_INVALID_PARAMETER;
+
+// 2 hash types supporte: SHA1 & SHA256
+ if(!guidcmp(&Hash->AlgGuid, &gEfiHashAlgorithmSha256Guid))
+ HashLen = SHA256_DIGEST_SIZE;
+ else if(!guidcmp(&Hash->AlgGuid, &gEfiHashAlgorithmSha1Guid))
+ HashLen = SHA1_DIGEST_SIZE;
+ else
+ HashLen = SHA256_DIGEST_SIZE;
+
+ if(key == NULL )
+ err = -1;
+ else
+ err = crypto_rsa_exptmod((const UINT8*)Signature, (size_t)SignatureSize, (UINT8*)&Rsa2048Sig, sig_len, key, 0);
+
+// locate Hash inside the decrypted signature body and compare it with given Hash;
+ if(!err) {
+ if(Flags & EFI_CRYPT_RSASSA_PKCS1V15)
+ {
+ // Validate PKCS#1 Padding
+// err = pkcs_1_v1_5_decode((const UINT8 *)&Hash->Blob, HashLen, (const UINT8 *)&Rsa2048Sig, (unsigned long)*sig_len);
+ err = MemCmp((void*)(UINTN)Hash->Blob, (void*)(UINTN)((UINT32)(UINTN)Rsa2048Sig + (UINT32)(*sig_len - HashLen)), HashLen);
+ }
+ else //(Flags & EFI_CRYPT_RSASSA_PSS))
+ // Validate PKCS_1 PSS Signature: padding & hash
+ err = pkcs_1_pss_decode((UINT8*)Hash->Blob, HashLen,(const unsigned char *)&Rsa2048Sig, (unsigned long)*sig_len,
+ saltlen, modulus_bitlen);
+ }
+
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+// Security concern, memory heap is being cleared on exit
+ ResetCRmm();
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: CryptoGetFwKey
+//
+// Description: Passes FwKey info from a Hob to an external Key handler structure
+//
+// Input: Key - ptr to the buffer to hold the target key parameters
+//
+// Output: Status
+//
+// EFI_NOT_FOUND - Can't find the Key Hob
+// EFI_INVALID_PARAMETER - Wrong KeyID
+// EFI_LOAD_ERROR - Load fail.
+// EFI_SUCCESS - Load success.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CryptoGetFwKey (
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN CRYPT_HANDLE *Key
+)
+{
+ EFI_STATUS Status=EFI_NOT_FOUND;
+ FW_KEY_HOB *pFwKeyHob;
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+
+ if(!Key) return EFI_INVALID_PARAMETER;
+
+ pFwKeyHob = GetEfiConfigurationTable(SystemTable, &HobListGuid);
+ if (pFwKeyHob!=NULL) {
+ Status = FindNextHobByGuid(&gPRKeyGuid, &pFwKeyHob);
+ if(!EFI_ERROR(Status)) {
+// make sure the Key buffer is mapped to FV_BB address space
+/*
+ if(!((UINT32)pFwKeyHob->KeyAddress > FV_BB_BASE &&
+ (UINT64)((UINT32)pFwKeyHob->KeyAddress+pFwKeyHob->KeySize) <
+ (UINT64)(FV_BB_BASE+(UINT64)FV_BB_BLOCKS*FLASH_BLOCK_SIZE))) {
+ return EFI_NOT_FOUND;
+*/
+ Key->Blob = (UINT8*)(UINT32)pFwKeyHob->KeyAddress;
+ Key->BlobSize = pFwKeyHob->KeySize;
+ Key->AlgGuid = pFwKeyHob->KeyGuid;
+ }
+ }
+
+ TRACE(((UINTN) -1,"Get Key File %g: %r\n(%lx, %dbytes)=%X,%X\n", Key->AlgGuid, Status, Key->Blob, Key->BlobSize, Key->Blob[0], Key->Blob[1]));
+
+ return Status;
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetKey
+//
+// Description: Return Firmware Signing Key from a local storage
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE_PROTOCOL instance.
+// Key ptr to the buffer to hold the target key
+// AlgId Key GUID
+// KeyLen Length of the target Key buffer
+// Flags Specifies additional flags to further customize the GetKey behavior.
+// Output:
+// EFI_SUCCESS
+// EFI_ACCESS_DENIED The key could not be located
+// EFI_INVALID_PARAMETER Wrong KeyID
+// BUFFER_TOO_SMALL The Key->BlobSize will contain the size of the buffer to be prepared
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+GetKey (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ OUT CRYPT_HANDLE *Key,
+ IN EFI_GUID *AlgId,
+ IN UINTN KeyLen,
+ IN UINT32 Flags
+ )
+{
+ if(!AlgId || !Key)
+ return EFI_INVALID_PARAMETER;
+
+// Guid must match one of the valid keys we can use in Sig verification.
+ if(guidcmp(AlgId, &gPRKeyGuid))
+ return EFI_UNSUPPORTED;
+
+ if(gKey.Blob && gKey.BlobSize){
+
+// make sure the Key buffer is mapped to FV_BB address space
+/* if(!((UINT32)gKey.Blob > FV_BB_BASE &&
+ (UINT64)((UINT32)gKey.Blob+gKey.BlobSize) <
+ (UINT64)(FV_BB_BASE+(UINT64)FV_BB_BLOCKS*FLASH_BLOCK_SIZE)))
+ return EFI_NOT_FOUND;
+*/
+ Key->BlobSize = gKey.BlobSize;
+ Key->AlgGuid = gKey.AlgGuid;
+ if(Key->Blob) {
+ if(KeyLen < gKey.BlobSize)
+ return EFI_BUFFER_TOO_SMALL;
+ else
+ MemCpy(Key->Blob, gKey.Blob, gKey.BlobSize);
+ } else
+ Key->Blob = gKey.Blob;// upd address to int buffer
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: VerifyKey
+//
+// Description: Function compares the input PublicKey against
+// Platform Signing Key (PK) image in the flash.
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE protocol instance.
+// KeyAlgorithm Points to the EFI_GUID which identifies the PKpub algorithm to use.
+// PublicKey Handle to a key used for verifying signatures. This handle must be identifying a public key.
+//
+// Output:
+// EFI_SUCCESS The Key is successfully verified.
+// EFI_SECURITY_VIOLATION The Key does not match current FW key.
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+VerifyKey (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN EFI_GUID *AlgId,
+ IN CRYPT_HANDLE *Key
+ )
+{
+ EFI_STATUS Status;
+ CRYPT_HANDLE PubKeyHndl;
+ UINT8 Hash[SHA256_DIGEST_SIZE]={0};
+ UINT8 *KeyFfs, *KeyCmp;
+ UINTN KeyLen;
+ UINT32 Flags=0;
+ INTN err;
+
+ if(!AlgId || !Key || !Key->Blob)
+ return EFI_INVALID_PARAMETER;
+
+// Guid must match one of the valid keys we can use in Sig verification.
+ if(guidcmp(AlgId, &gPRKeyGuid))
+ return EFI_UNSUPPORTED;
+
+// Get PRKey
+ PubKeyHndl.Blob = NULL;
+ PubKeyHndl.BlobSize = 0;
+ Status = GetKey(NULL, &PubKeyHndl, AlgId, 0, Flags);
+ if(!EFI_ERROR(Status))
+ {
+ KeyFfs = PubKeyHndl.Blob;
+ KeyLen = PubKeyHndl.BlobSize;
+ KeyCmp = Key->Blob;
+
+ // If FwKey is Hash of Rsa2048 Key and Key->Algo is Rsa2048 -
+ // prepare Key for SHA256 Hash compare
+ if(!guidcmp(&Key->AlgGuid, &gEfiCertRsa2048Guid))
+ {
+ if(!guidcmp(&PubKeyHndl.AlgGuid, &gEfiCertSha256Guid))
+ {
+ KeyCmp = Hash;
+ KeyLen = SHA256_DIGEST_SIZE;
+ sha256_vector(1, (const UINT8**)&Key->Blob, (const UINTN*)&Key->BlobSize, Hash);
+ } else
+ // if FwKey is x509 and Key->Algo - gEfiCertRsa2048Guid:
+ // derive nModulus from x509 Key Cert for comparison
+ if(!guidcmp(&PubKeyHndl.AlgGuid, &gEfiCertX509Guid))
+ {
+ KeyFfs = &Rsa2048Sig[0];
+ KeyLen = DEFAULT_RSA_KEY_MODULUS_LEN;
+ ResetCRmm();
+ err = Pkcs7_x509_return_Cert_pubKey((UINT8*)PubKeyHndl.Blob, (UINTN)PubKeyHndl.BlobSize, &KeyFfs,&KeyLen);
+ ResetCRmm();
+ if(err) return EFI_SECURITY_VIOLATION;
+ }
+ }
+ err = MemCmp(KeyFfs, KeyCmp, KeyLen);
+
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+ }
+ return Status;
+}
+//----------------------------------------------------------------------------
+// END of Crypto DXE Function definitions
+//----------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DummyHandle = NULL;
+ UINT8 *pKey;
+
+ TRACE(((UINTN) -1,"Init Crypto API in SMM\n"));
+ //
+ // Init Crypto lib internal state
+ //
+ RuntimeCryptLibConstructorInSmm(ImageHandle, SystemTable);
+ //
+ // Update Crypto debug traces level
+ //
+#ifdef EFI_DEBUG
+// wpa_set_trace_level(CRYPTO_trace_level);
+#endif
+ //
+ // Get location of PRKey from .ffs
+ // ReadFfs/FindHob are preboot services whereas Key needs to be available during EFI runtime
+ //
+ gKey.Blob = NULL;
+ Status = CryptoGetFwKey(SystemTable, &gKey);
+ if(!EFI_ERROR(Status) && gKey.Blob) {
+ // re-allocate buffer in runtime mem
+ pKey = gKey.Blob; // preserve the pointer
+ Status = pSmmBase->SmmAllocatePool(pSmmBase, EfiRuntimeServicesData, gKey.BlobSize, (void**)&pKey);
+ ASSERT_EFI_ERROR (Status);
+ if(!EFI_ERROR(Status)) {
+ MemCpy(pKey, gKey.Blob, gKey.BlobSize);
+ gKey.Blob = pKey;
+ }
+ }
+ if(EFI_ERROR(Status))
+ gKey.Blob = NULL;
+
+ TRACE((TRACE_ALWAYS,"Init: GetKey %r (addr %x(%X, %X), %d bytes)\n", Status, gKey.Blob, gKey.Blob[0], gKey.Blob[1], gKey.BlobSize));
+
+///////////////////////////////////////////////////////////////////////////////////
+// Install the SMM clone of Crypto protocols
+///////////////////////////////////////////////////////////////////////////////////
+ return pBS->InstallMultipleProtocolInterfaces (
+ &DummyHandle,
+ &gAmiSmmDigitalSignatureProtocolGuid, &mAmiSig,
+ NULL
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NotInSmmFunction
+//
+// Description: This function is called from outside of SMM during SMM registration.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NotInSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ UINT8 *pKey;
+
+ TRACE(((UINTN) -1,"Init Crypto API NOT in SMM\n"));
+ //
+ // Init Crypto lib internal state
+ //
+ RuntimeCryptLibConstructor(ImageHandle, SystemTable);
+ //
+ // Update Crypto debug traces level
+ //
+#ifdef EFI_DEBUG
+ wpa_set_trace_level(CRYPTO_trace_level);
+#else
+ wpa_set_trace_level(0);
+#endif
+ //
+ // Get location of PRKey from .ffs
+ // ReadFfs/FindHob are preboot services whereas Key needs to be available during EFI runtime
+ //
+ gKey.Blob = NULL;
+ Status = CryptoGetFwKey(SystemTable, &gKey);
+ if(!EFI_ERROR(Status) && gKey.Blob) {
+ // re-allocate buffer in runtime mem
+ pKey = gKey.Blob; // preserve the pointer
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, gKey.BlobSize, (void**)&pKey);
+ ASSERT_EFI_ERROR (Status);
+ if(!EFI_ERROR(Status)) {
+ MemCpy(pKey, gKey.Blob, gKey.BlobSize);
+ gKey.Blob = pKey;
+ }
+ }
+ if(EFI_ERROR(Status))
+ gKey.Blob = NULL;
+
+ TRACE((TRACE_ALWAYS,"Init: GetKey %r (addr %x(%X, %X), %d bytes)\n", Status, gKey.Blob, gKey.Blob[0], gKey.Blob[1], gKey.BlobSize));
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Install the DXE Crypto protocols
+//
+///////////////////////////////////////////////////////////////////////////////
+ return pBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gAmiDigitalSignatureProtocolGuid, &mAmiSig,
+ NULL
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CryptoDxe_Init
+//
+// Description: Entry point of Crypto DXE driver
+//
+// Input: EFI_HANDLE ImageHandle,
+// EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CryptoDxe_Init (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle, SystemTable);
+ //
+ // Install DXE & SMM Crypto Services
+ //
+
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NotInSmmFunction);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoDxe.dxs b/Core/EM/CryptoPkg/CryptoDxe.dxs
new file mode 100644
index 0000000..ba16a62
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoDxe.dxs
@@ -0,0 +1,53 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoDxe.dxs 1 6/13/11 5:19p Alexp $
+//
+// $Revision: 1 $
+//
+// $Date: 6/13/11 5:19p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoDxe.dxs $
+//
+// 1 6/13/11 5:19p Alexp
+//
+// 1 5/06/11 6:11p Alexp
+// initial module release
+//
+// 1 3/10/11 4:52p Alexp
+//
+// 1 2/18/11 5:42p Alexp
+//
+//**********************************************************************
+#include <Protocol/SmmBase.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoPei.c b/Core/EM/CryptoPkg/CryptoPei.c
new file mode 100644
index 0000000..1945986
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoPei.c
@@ -0,0 +1,800 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoPei.c 15 8/01/13 6:27p Alexp $
+//
+// $Revision: 15 $
+//
+// $Date: 8/01/13 6:27p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoPei.c $
+//
+// 15 8/01/13 6:27p Alexp
+// Comment out a check for FwKey location to be mapped to Flash FV_BB
+// In some cases FindFFS for FwKey may return a location outside of Flash
+// space.
+// Will have the logic fixed in the next label.
+//
+// 14 7/01/13 5:24p Alexp
+// CryptoPei_Init(): fix addr typecasting for pFwKeyHob->KeyAddress
+//
+// 13 6/20/13 1:55p Alexp
+// Impove FwKey handling. CryptoPEI pass FwKey location to Dxe via Hob
+// Add mor parameter checking including
+// check for FwKey location to be mapped to Flash FV_BB
+//
+// 12 5/23/13 12:04p Alexp
+// Add dependency on PKCS7_PEI_Support switch to turn off Pkcs7 support in
+// CryptoPEI. Saves ~8kb of space
+//
+// 11 12/28/12 3:05p Alexp
+// CryptoGetRawImage(): calculate raw Key size inside FwKey ffs file
+//
+// 10 12/19/12 10:31a Alexp
+// code modify to meet "cppcheck" style & performance suggestions
+//
+// 8 11/15/12 9:28a Alexp
+// update Pkcs7Verify help header
+//
+// 7 11/14/12 6:28p Alexp
+// rename ppPS to gPeiServices in order to keep backward compatibility for
+// older Secure Flash eModules
+//
+// 6 11/13/12 11:50a Alexp
+// EIP#105015: Add Pkcs#7 Cert Verification function in Crypto PPI
+// Add handling of x509 formatted FW Key in FFS files
+//
+// 5 7/25/12 10:00a Alexp
+// cleaned comments in Hash Hdr
+//
+// 4 3/12/12 4:11p Alexp
+// do not install Crypto PPI on S3 resume.
+//
+// 3 3/02/12 10:43a Alexp
+// Remove dependency on SDL Token FWKEY_FORMAT to determine format of PR
+// Key file
+// Try different Ffs GUIDs to select proper Key format: SHA or RSA
+//
+// 2 2/29/12 4:01p Alexp
+// 1. Use SDL Token FWKEY_FORMAT to define format of PR Key file: Hash or
+// RSA2048
+// 2. Modify VerifyKey to account for PR Key in SHA256 format
+//
+// 1 6/13/11 5:19p Alexp
+//
+// 1 5/06/11 6:11p Alexp
+// initial module release
+//
+// 10 4/22/11 4:19p Alexp
+// fix GetRaw file
+//
+// 9 4/18/11 7:09p Alexp
+//
+// 8 4/11/11 12:53p Alexp
+// remove Verify Capsule from Crypto PPI. Function moved to SecRecovery.c
+//
+// 7 4/08/11 1:33p Alexp
+// This revision Supports single PK(FwSign) Ffs file with SigDb with
+// multiple Keys
+//
+// 6 4/05/11 6:31p Alexp
+//
+// 5 3/21/11 6:58p Alexp
+//
+// 4 3/15/11 12:48p Alexp
+//
+// 3 3/14/11 3:26p Alexp
+// add provision to handle multiple Platform Signing keys.
+// rom may containg multiple Keys as FFS files with same Guid
+//
+// 2 3/11/11 6:51p Alexp
+//
+// 1 3/10/11 4:52p Alexp
+//
+// 2 2/28/11 6:46p Alexp
+//
+// 1 2/18/11 5:42p Alexp
+//
+//**********************************************************************
+#include <Token.h>
+#include <AmiPeiLib.h>
+#include "PPI\LoadFile.h"
+#include <Protocol\Hash.h>
+#include <PPI\CryptoPPI.h>
+#include "AmiCertificate.h"
+
+#include <cryptlib.h>
+
+//
+// Global variables
+//
+
+// Although ShaXXXGuid global variables are defined in EDK's EdkProtocol Lib, but linking it adds additional 20k in debug mode.
+static EFI_GUID gEfiHashAlgorithmSha1Guid = EFI_HASH_ALGORITHM_SHA1_GUID;
+static EFI_GUID gEfiHashAlgorithmSha256Guid = EFI_HASH_ALGORITHM_SHA256_GUID;
+static EFI_GUID gPKeyGuid = PR_KEY_GUID;
+
+// Hardwired at Build time. Supported formats: RSA2048, HASH256 Key Certs
+static EFI_GUID gPKeyFileRsa2048Guid = PR_KEY_FFS_FILE_RAW_GUID;
+static EFI_GUID gPKeyFileSha256Guid = PR_KEY_FFS_FILE_SHA256_GUID;
+static EFI_GUID gPKeyFileX509Guid = PR_KEY_FFS_FILE_X509_GUID;
+
+static EFI_GUID gEfiCertSha256Guid = EFI_CERT_SHA256_GUID;
+static EFI_GUID gEfiCertRsa2048Guid = EFI_CERT_RSA2048_GUID;
+static EFI_GUID gEfiCertX509Guid = EFI_CERT_X509;
+
+static EFI_GUID *gKeyFileGuid [] = {
+ &gPKeyFileX509Guid,
+ &gPKeyFileRsa2048Guid,
+ &gPKeyFileSha256Guid,
+ NULL
+};
+static EFI_GUID *gKeyTypeGuid [] = {
+ &gEfiCertX509Guid,
+ &gEfiCertRsa2048Guid,
+ &gEfiCertSha256Guid,
+ NULL
+};
+
+EFI_PEI_SERVICES **gPeiServices;
+FW_KEY_HOB *pFwKeyHob = NULL;
+//
+// SDL defined Public Exponent E of RSA Key.
+//
+const UINT8 KeyE[] = {E_CONST}; // 0x10001
+const UINT32 LenE = sizeof(KeyE);
+// PKCS_1 PSS Signature constatnt. Size of the Salt (random data) field in PSS signature.
+const INT32 saltlen = PSS_SIG_SALTLEN; // 8
+static UINT8 DecriptedSig[DEFAULT_RSA_SIG_LEN];
+//----------------------------------------------------------------------------
+// Crypto Function prototypes
+//----------------------------------------------------------------------------
+EFI_STATUS
+PeiHash (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN UINTN num_elem,
+ IN CONST UINT8 *addr[],
+ IN CONST UINTN *len,
+ OUT UINT8 *Hash
+ );
+
+EFI_STATUS
+PeiPkcs7Verify (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Size,
+ IN CONST UINT8 *TrustedCert,
+ IN UINTN CertSize,
+ IN OUT UINT8 **Data,
+ IN OUT UINTN *DataSize
+ );
+
+EFI_STATUS
+PeiVerifySig
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN PEI_CRYPT_HANDLE *PublicKey,
+ IN PEI_CRYPT_HANDLE *Hash,
+ IN VOID *Signature,
+ IN UINTN SignatureSize,
+ IN UINT32 Flags
+);
+
+EFI_STATUS
+PeiGetKey
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *KeyAlgorithm, // reserved to PKPUB_KEY_GUID
+ IN PEI_CRYPT_HANDLE *PublicKey
+ );
+
+EFI_STATUS
+PeiVerifyKey
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *KeyAlgorithm, // reserved to PKPUB_KEY_GUID
+ IN PEI_CRYPT_HANDLE *PublicKey
+ );
+
+//----------------------------------------------------------------------------
+// Crypto Protocol Identifiers
+//----------------------------------------------------------------------------
+static EFI_GUID gAmiDigitalSignaturePPIGuid = AMI_DIGITAL_SIGNATURE_PPI_GUID;
+
+AMI_CRYPT_DIGITAL_SIGNATURE_PPI mSigPeiInitPpi = {
+ PeiHash,
+ PeiVerifyKey,
+ PeiVerifySig,
+ PeiGetKey,
+ PeiPkcs7Verify
+};
+
+//static
+EFI_PEI_PPI_DESCRIPTOR mPpiSigListVariable = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gAmiDigitalSignaturePPIGuid,
+ &mSigPeiInitPpi
+};
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CryptoGetRawImage
+//
+// Description: Loads binary from RAW section of X firwmare volume
+//
+//
+// Output: Buffer - returns a pointer to allocated memory. Caller
+// must free it when done.
+// Size - returns the size of the binary loaded into the
+// buffer.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+CryptoGetRawImage (IN EFI_GUID *FileGuid, IN OUT VOID **Buffer, IN OUT UINTN *Size)
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_HEADER *pFV;
+ UINTN FvNum=0;
+ EFI_FFS_FILE_HEADER *ppFile=NULL;
+
+ if (!Buffer || !Size)
+ return EFI_INVALID_PARAMETER;
+
+ Status = (*gPeiServices)->FfsFindNextVolume (gPeiServices, FvNum, &pFV);
+
+ while(TRUE)
+ {
+ Status = (*gPeiServices)->FfsFindNextFile(gPeiServices, EFI_FV_FILETYPE_ALL, pFV, &ppFile);
+ if(Status == EFI_NOT_FOUND)
+ {
+// FvNum++;
+// Status = (*gPeiServices)->FfsFindNextVolume (gPeiServices, FvNum, &pFV);
+// if(EFI_ERROR(Status)) return Status;
+// continue;
+// !!! the PK Key may only be in FV_BB volume. FvNum=0!!!!
+ return Status;
+ }
+
+ if(guidcmp(&ppFile->Name, FileGuid)==0) break;
+ }
+
+ // hopefully we found the file...now try to read raw data
+ // !!! Keys are uncompressed. There is no much reason to run compression on prime numbers anyway
+ Status = (*gPeiServices)->FfsFindSectionData(gPeiServices, EFI_SECTION_RAW, ppFile, Buffer);
+ if(!EFI_ERROR(Status)) {
+ // Size may need to subtract Section hdr size = 28 bytes sizeof(EFI_FFS_FILE_HEADER + EFI_COMMON_SECTION_HEADER)
+ *Size = FVFILE_SIZE(ppFile)-sizeof(EFI_FFS_FILE_HEADER)-sizeof(EFI_COMMON_SECTION_HEADER);
+ }
+PEI_TRACE(((UINTN)TRACE_ALWAYS, gPeiServices, "Find Key Ffs %r addr=%X (%X,%X), size=%d\n", Status, (UINT32)*Buffer, ((UINT8*)*Buffer)[0], ((UINT8*)*Buffer)[1], *Size));
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiHash
+//
+// Description: Allows creating a hash of an arbitrary message digest using one or more hash algorithms
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+// num_elem Number of blocks to be passed via next argument:addr[]
+// addr[] Pointer to array of UINT8* addresses of data blocks to be hashed
+// len Pointer to array of integers containing length of each block listed by addr[]
+// Hash Holds the resulting hash computed from the message.
+//
+// Output:
+// EFI_SUCCESS Hash returned successfully.
+// EFI_INVALID_PARAMETER Message or Hash is NULL
+// EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this
+// driver.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiHash (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN UINTN num_elem,
+ IN CONST UINT8 *addr[],
+ IN CONST UINTN *len,
+ OUT UINT8 *Hash
+ )
+{
+ BOOLEAN bSha1 = FALSE, bSha256 = FALSE;
+ UINT32 HashLen=SHA256_DIGEST_SIZE;
+
+// Support only SHA1 & SHA256 hashes
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha1Guid))
+ {
+ bSha1 = TRUE;
+ HashLen = SHA1_DIGEST_SIZE;
+ }
+ else
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha256Guid))
+ {
+ bSha256 = TRUE;
+ HashLen = SHA256_DIGEST_SIZE;
+ }
+ else
+ return EFI_UNSUPPORTED;
+
+ MemSet(Hash, HashLen, 0);
+ if(bSha1)
+ sha1_vector(num_elem, addr, len, Hash);
+ else
+ sha256_vector(num_elem, addr, len, Hash);
+
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiVerifySig
+//
+// Description: Function verifies that the specified signature matches the specified hash.
+// This function decrypts the signature with the provided key and then compares
+// the decrypted value to the specified hash value
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// PublicKey Handle to a key used for verifying signatures. This handle must be identifying a public key.
+// Hash Handle of the hash object to verify.
+// Signature Pointer to the signature data to be verified.
+// SignatureSize The size, in bytes, of the signature data.
+// Flags Specifies additional flags to further customize the signing/verifying behavior.
+//
+// Output:
+// EFI_SUCCESS The signature is successfully verified.
+// EFI_SECURITY_VIOLATION The signature does not match the given message.
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiVerifySig
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN PEI_CRYPT_HANDLE *PublicKey,
+ IN PEI_CRYPT_HANDLE *Hash,
+ IN VOID *Signature,
+ IN UINTN SignatureSize,
+ IN UINT32 Flags
+ )
+{
+ EFI_STATUS Status;
+ INTN err;
+ struct crypto_rsa_key *key = NULL;
+ UINT16 Size = (UINT16)(PublicKey->BlobSize);
+ size_t *sig_len=(size_t*)&SignatureSize;
+ INT32 modulus_bitlen = DEFAULT_RSA_SIG_LEN << 3;
+ UINT32 HashLen;
+
+// Only supporting RSASSA_PKCS1V15 signature types
+ if(!((Flags & EFI_CRYPT_RSASSA_PKCS1V15) ||
+ (Flags & EFI_CRYPT_RSASSA_PSS)) )
+ return EFI_INVALID_PARAMETER;
+
+ ResetCRmm();
+
+// check Key handle if requested PubKey is a Platform FW Key
+// In this case use the FW key from ffs image
+// validity of the Key must be verified prior to calling VerifySig
+// Guid must match one of the valid keys we can use in PEI Sig verification.
+// For now Public Key is supported in 2 formats: RAW 256 bytes and ASN.1 Integer
+// shall be extended to gPBkey_x509_Guid
+ if(!guidcmp(&PublicKey->AlgGuid, &gEfiCertRsa2048Guid))
+ key = crypto_import_rsa2048_public_key(PublicKey->Blob, Size, (UINT8*)&KeyE, LenE);
+ else
+ return EFI_INVALID_PARAMETER;
+
+ if(!guidcmp(&Hash->AlgGuid, &gEfiHashAlgorithmSha256Guid))
+ HashLen = SHA256_DIGEST_SIZE;
+ else if(!guidcmp(&Hash->AlgGuid, &gEfiHashAlgorithmSha1Guid))
+ HashLen = SHA1_DIGEST_SIZE;
+ else
+ HashLen = SHA256_DIGEST_SIZE;
+
+ if(key == NULL )
+ err = -1;
+ else
+ err = crypto_rsa_exptmod((const UINT8*)Signature, (size_t)SignatureSize, (UINT8*)&DecriptedSig, sig_len, key, 0);
+// locate Hash inside the decrypted signature body and compare it with given Hash;
+// Should be extended to handle sha1, sha256 hashes. use Hash->AlgGuid to determine the Hash type
+ if(!err)
+ {
+ if(Flags & EFI_CRYPT_RSASSA_PKCS1V15)
+ {
+ // Validate PKCS#1v1.5 Padding
+// err = pkcs_1_v1_5_decode(Hash->Blob, HashLen, (const UINT8 *)&DecriptedSig, (unsigned long)*sig_len);
+// just compare the hash at the end of the sig blob
+ err = MemCmp(Hash->Blob, (void*)((UINT32)DecriptedSig + (UINT32)(*sig_len - HashLen)), HashLen);
+ } else //(Flags & EFI_CRYPT_RSASSA_PSS))
+ // Validate PKCS#1 PSS Signature: padding & hash
+ err = pkcs_1_pss_decode(
+ Hash->Blob, HashLen,
+ (const unsigned char *)&DecriptedSig, (unsigned long)*sig_len,
+ saltlen, modulus_bitlen);
+ }
+
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+// Security concern, memory heap is being cleared on exit
+ ResetCRmm();
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiPkcs7Verify
+//
+// Description: Verifies the validity of a PKCS#7 signed data as described in "PKCS #7: Cryptographic
+// Message Syntax Standard".
+// Function verifies validity of the signature contained inside the Certificate
+// This function decrypts the signature with the Public key from the Signer certificate
+// and then compares the decrypted value to the input Data
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// P7Data Pointer to the PKCS#7 DER encoded message to verify.
+// P7Size Size of the PKCS#7 message in bytes.
+// TrustedCert Pointer to a trusted/root X509 certificate encoded in DER, which
+// is used for certificate chain verification.
+// CertSize Size of the trusted certificate in bytes.
+// Data Pointer to the content to be verified/returned at
+// DataSize Size of Data in bytes
+//
+// Output:
+// EFI_SUCCESS The specified PKCS#7 signed data is valid
+// EFI_SECURITY_VIOLATION Invalid PKCS#7 signed data.
+// EFI_ACCESS_DENIED The Trusted certificate does not have a match in SignedData.certificate store.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiPkcs7Verify (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Size,
+ IN CONST UINT8 *TrustedCert,
+ IN UINTN CertSize,
+ IN OUT UINT8 **Data,
+ IN OUT UINTN *DataSize
+ )
+{
+#if CONFIG_PEI_PKCS7 == 1
+
+ EFI_STATUS Status;
+ INTN err, reason;
+ struct pkcs7_signed_data_st* PKCS7cert;
+ struct x509_certificate *x509TrustCert;
+ struct x509_certificate *x509SignCert;
+
+ err = -1;
+ reason = 0;
+ x509SignCert = NULL;
+
+ if((*Data == NULL || DataSize == NULL) ||
+ (!P7Data || P7Size== 0) ||
+ (!TrustedCert || CertSize== 0)
+ )
+ return EFI_INVALID_PARAMETER;
+
+ ResetCRmm();
+
+ PKCS7cert = Pkcs7_parse_Authenticode_certificate(P7Data, P7Size);
+ if (PKCS7cert) {
+ // verify Pkcs7 Signing Cert chain up to the TrustCert...
+ x509TrustCert = x509_certificate_parse(TrustedCert, CertSize);
+ if(x509TrustCert) {
+ err = Pkcs7_x509_certificate_chain_validate(PKCS7cert, x509TrustCert, (int*)&reason);
+ if(!err)
+ err = Pkcs7_certificate_validate_digest(PKCS7cert, x509SignCert, *Data, *DataSize);
+ }
+ }
+
+ // Security concern, memory heap is being cleared on exit
+ ResetCRmm();
+
+ // failed to process
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+ return Status;
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiGetKey
+//
+// Description: Function returns Ptr to a Platform Signing Key (PK) Ffs
+// inside Recovery FV (FV_BB or similar)
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// KeyAlgorithm Points to the EFI_GUID which identifies the PKpub algorithm to use.
+// PublicKey Handle to a key used to return a ptr to a Key. This handle must be identifying a public key.
+//
+// Output:
+// EFI_SUCCESS The Key is successfully returned.
+// EFI_NOT_FOUND The Key not found
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiGetKey (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *KeyAlgorithm, // reserved to PKPUB_KEY_GUID
+ IN PEI_CRYPT_HANDLE *PublicKey
+ )
+{
+ if(!PublicKey || !KeyAlgorithm)
+ return EFI_INVALID_PARAMETER;
+
+ // now only supporting PKpub key comparison
+ if(guidcmp((EFI_GUID*)KeyAlgorithm, &gPKeyGuid))
+ return EFI_INVALID_PARAMETER;
+
+ if(pFwKeyHob) {
+ PublicKey->AlgGuid = pFwKeyHob->KeyGuid;
+ PublicKey->Blob = (UINT8*)pFwKeyHob->KeyAddress;
+ PublicKey->BlobSize = pFwKeyHob->KeySize;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiVerifyKey
+//
+// Description: Function compares the input PublicKey against
+// Platform Signing Key (PK) image in the flash.
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// KeyAlgorithm Points to the EFI_GUID which identifies the PKpub algorithm to use.
+// PublicKey Handle to a key used for verifying signatures. This handle must be identifying a public key.
+//
+// Output:
+// EFI_SUCCESS The Key is successfully verified.
+// EFI_SECURITY_VIOLATION The Key does not match current FW key.
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiVerifyKey
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *KeyAlgorithm, // reserved to PKPUB_KEY_GUID
+ IN PEI_CRYPT_HANDLE *PublicKey
+ )
+{
+ EFI_STATUS Status;
+ int err;
+ PEI_CRYPT_HANDLE KeyHndl;
+ UINT8 Hash[SHA256_DIGEST_SIZE] = {0};
+ UINT8 *KeyBuf, *PKpubBuffer=NULL;
+ UINT32 KeyLen;
+
+ if(!PublicKey || !KeyAlgorithm || !PublicKey->Blob)
+ return EFI_INVALID_PARAMETER;
+// check Key handle if requested PubKey is a Platform Key PKpub.
+// In this case use PKpub key from ffs image
+ if(guidcmp((EFI_GUID*)KeyAlgorithm, &gPKeyGuid))
+ return EFI_INVALID_PARAMETER;
+
+ Status = PeiGetKey(This, KeyAlgorithm, &KeyHndl);
+ if(!EFI_ERROR(Status)) {
+// only store Sha256 or n-modulus of RSA2048. For x509 cert - compare hash of an entire cert
+// FFS - Sha256 Hash ->
+// Input =Sha258 -> cmp
+// Input =RSA2048 -> Hash n-modulus
+// Input =x509 -> Hash x509 cert
+// FFS - RSA2048 ->
+// Input =RSA2048 -> cmp
+// Input =x509 -> extract n-modulus
+// FFS - x5098 ->
+// Input =x509 -> cmp
+/*
+ PKpubBuffer = KeyHndl.Blob;
+ KeyLen = KeyHndl.BlobSize; // always 256
+ KeyBuf = PublicKey->Blob;
+
+ if(!guidcmp(&KeyHndl.AlgGuid, &gEfiCertSha256Guid)) {
+ KeyBuf = Hash;
+ KeyLen = SHA256_DIGEST_SIZE;
+ if(!guidcmp(&PublicKey->AlgGuid, &gEfiCertRsa2048Guid) ||
+ !guidcmp(&PublicKey->AlgGuid, &gEfiCertX509Guid) ) {
+ // SHA256 Hash of RSA Key/x509 cert
+ sha256_vector(1, (const UINT8**)&PublicKey->Blob, (const UINTN*)&PublicKey->BlobSize, Hash);
+ }
+ } else
+ // if FwKey is x509 and Key->Algo - gEfiCertRsa2048Guid:
+ // derive nModulus from x509 Key Cert for comparison
+ if(!guidcmp(&KeyHndl.AlgGuid, &gEfiCertRsa2048Guid) &&
+ !guidcmp(&PublicKey->AlgGuid, &gEfiCertX509Guid) ) {
+ PKpubBuffer = &Hash[0];
+ KeyLen = DEFAULT_RSA_KEY_MODULUS_LEN;
+ ResetCRmm();
+ err = Pkcs7_x509_return_Cert_pubKey((UINT8*)PublicKey->Blob, (UINTN)PublicKey->BlobSize, &PKpubBuffer, &KeyLen);
+ ResetCRmm();
+ if(err) return EFI_SECURITY_VIOLATION;
+ }
+*/
+ PKpubBuffer = KeyHndl.Blob;
+ KeyLen = KeyHndl.BlobSize; // always 256
+ KeyBuf = PublicKey->Blob;
+ if(!guidcmp(&KeyHndl.AlgGuid, &gEfiCertSha256Guid) &&
+ !guidcmp(&PublicKey->AlgGuid, &gEfiCertRsa2048Guid)
+ ) {
+ // SHA256 Hash of RSA Key
+ KeyLen = SHA256_DIGEST_SIZE;
+ KeyBuf = Hash;
+ sha256_vector(1, (const UINT8**)&PublicKey->Blob, (const UINTN*)&PublicKey->BlobSize, KeyBuf);
+#if CONFIG_PEI_PKCS7 == 1
+ } else {
+ // if FwKey is x509 and Key->Algo - gEfiCertRsa2048Guid:
+ // derive nModulus from x509 Key Cert for comparison
+ if(!guidcmp(&KeyHndl.AlgGuid, &gEfiCertRsa2048Guid) &&
+ !guidcmp(&PublicKey->AlgGuid, &gEfiCertX509Guid)
+ ) {
+ PKpubBuffer = &Hash[0];
+ KeyLen = DEFAULT_RSA_KEY_MODULUS_LEN;
+ ResetCRmm();
+ err = Pkcs7_x509_return_Cert_pubKey((UINT8*)PublicKey->Blob, (UINTN)PublicKey->BlobSize, &PKpubBuffer, &KeyLen);
+ ResetCRmm();
+ if(err) return EFI_SECURITY_VIOLATION;
+ }
+#endif
+ }
+
+ err = MemCmp(PKpubBuffer, KeyBuf, KeyLen);
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CryptoPei_Init
+//
+// Description: This function is the entry point for this PEI.
+//
+//
+// Input: FfsHeader Pointer to the FFS file header
+// PeiServices Pointer to the PEI services table
+//
+// Output: Return Status based on errors that occurred while waiting for
+// time to expire.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CryptoPei_Init (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINTN Npages;
+ EFI_PHYSICAL_ADDRESS DstAddress;
+ EFI_BOOT_MODE BootMode;
+ UINT8 Index;
+ UINT8 *pBuf;
+
+ gPeiServices = PeiServices;
+
+ Status = (*gPeiServices)->GetBootMode( PeiServices, &BootMode );
+ if(EFI_ERROR(Status) || BootMode == BOOT_ON_S3_RESUME) {
+ return Status; // skip Crypto PPI install on S3 resume
+ }
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// Create FwKey Hob
+//
+////////////////////////////////////////////////////////////////////////////////////
+ Index = 0;
+ while(gKeyFileGuid[Index] != NULL)
+ {
+// Available Key Cert GUIDs: RSA2048, SHA256 and x509
+ Status = CryptoGetRawImage(gKeyFileGuid[Index], (VOID**)&pBuf, (UINTN*)&Size);
+ if(!EFI_ERROR(Status)) {
+ // make sure the Key buffer is mapped to FV_BB address space
+/*
+ if(!((UINT32)pBuf > FV_BB_BASE &&
+ (UINT64)((UINT32)pBuf+Size) <
+ (UINT64)(FV_BB_BASE+(UINT64)FV_BB_BLOCKS*FLASH_BLOCK_SIZE)))
+ break;
+*/
+ Status = (*PeiServices)->CreateHob(
+ PeiServices, EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(FW_KEY_HOB), &pFwKeyHob);
+ if (!EFI_ERROR(Status) && pFwKeyHob) {
+ pFwKeyHob->Header.Name = gPKeyGuid;
+ pFwKeyHob->KeyGuid = *gKeyTypeGuid[Index];
+ pFwKeyHob->KeyAddress = (EFI_PHYSICAL_ADDRESS)(UINT32)pBuf;
+ pFwKeyHob->KeySize = Size;
+ }
+ break;
+ }
+ Index++;
+ }
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// Init Aux Memory Manager
+//
+////////////////////////////////////////////////////////////////////////////////////
+// convert the Heap Size in bytes to the number of pages and allocate appropriate number of pages
+
+ Size = CR_PEI_MAX_HEAP_SIZE;
+ Npages = EFI_SIZE_TO_PAGES(Size);
+ Status = (*gPeiServices)->AllocatePages(gPeiServices, EfiBootServicesData, Npages, &DstAddress);
+ PEI_TRACE(((UINTN)TRACE_ALWAYS, gPeiServices, "Heap alloc %r (addr=%X, size=%d)\n", Status, (UINT32)DstAddress, Size));
+ if(EFI_ERROR(Status))
+ {
+ return Status;
+ }
+ InitCRmm((void*)DstAddress, Size);
+ //
+ // Update Crypto debug traces level
+ //
+ wpa_set_trace_level(CRYPTO_trace_level);
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// Install VerifySig PPI
+//
+////////////////////////////////////////////////////////////////////////////////////
+ return (**gPeiServices).InstallPpi (gPeiServices, &mPpiSigListVariable);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoPei.dxs b/Core/EM/CryptoPkg/CryptoPei.dxs
new file mode 100644
index 0000000..86c2008
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoPei.dxs
@@ -0,0 +1,54 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoPei.dxs 1 6/13/11 5:19p Alexp $
+//
+// $Revision: 1 $
+//
+// $Date: 6/13/11 5:19p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoPei.dxs $
+//
+// 1 6/13/11 5:19p Alexp
+//
+// 1 5/06/11 6:11p Alexp
+// initial module release
+//
+// 1 3/10/11 4:52p Alexp
+//
+// 1 2/18/11 5:42p Alexp
+//
+//**********************************************************************
+#include <pei.h>
+//#include <Ppi\ReadOnlyVariable.h>
+#include <token.h>
+
+DEPENDENCY_START
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+DEPENDENCY_END
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoPkg.cif b/Core/EM/CryptoPkg/CryptoPkg.cif
new file mode 100644
index 0000000..9a35890
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoPkg.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "CryptoPkg"
+ category = eModule
+ LocalRoot = "Core\EM\CryptoPkg\"
+ RefName = "CryptoPkg"
+[parts]
+"CryptoAPI"
+"CryptoLIB"
+<endComponent>