Date   

Re: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

Agrawal, Sachin
 

Hi Jiewen,

I reviewed RFC 8017 and I could not find any specific 'recommendations' on salt length to be used during signing with PSS encoding scheme.
However, in Section D.5.2.2.1(Notes 2) of IEEE 1363a-2004, it is recommended to use salt length atleast equal to the hash digest length.

We can modify the current API to take a additional parameter as salt length and ONLY pursue verification operation if Salt length is atleast equal to digest length.
This will act as a hardening mechanism for Edk2 as it will accept signatures only with 'appropriate' salt lengths.

Let me know if this is fine and I will push a corresponding patch.

Thx
Sachin

-----Original Message-----
From: Yao, Jiewen <jiewen.yao@intel.com>
Sent: Tuesday, April 20, 2021 2:12 AM
To: Agrawal, Sachin <sachin.agrawal@intel.com>; devel@edk2.groups.io
Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>
Subject: RE: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

Right. That has PROs and CONs.

On one hand, that allows maximum compatibility, salt could be HASH_SIZE or MAX, or even 0 ?

On the other hand, what if the consumer only wants to accept a specific length? E.g. TPM in FIPS mode and TLS requires SaltLength==HashLength.

Thank you
Yao Jiewen


-----Original Message-----
From: Agrawal, Sachin <sachin.agrawal@intel.com>
Sent: Tuesday, April 20, 2021 3:19 PM
To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, XiaoyuX
<xiaoyux.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>
Subject: RE: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS
verify support

Hi Jiewen,

From Section 9.1 in RFC 8017:
" Note that the verification operation follows reverse steps to recover
salt and then forward steps to recompute and compare H."

Therefore, salt length can be inferred from the PSS block structure
during verification operation.

I opted for 'RSA_PSS_SALTLEN_AUTO' as it will allow Edk2 to verify PSS
signatures of any salt lengths.

Thanks
Sachin

-----Original Message-----
From: Yao, Jiewen <jiewen.yao@intel.com>
Sent: Monday, April 19, 2021 7:30 PM
To: Agrawal, Sachin <sachin.agrawal@intel.com>; devel@edk2.groups.io
Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, XiaoyuX
<xiaoyux.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>
Subject: RE: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS
verify support

Hi Sachin
May I know why you hardcode PSS salt length to be RSA_PSS_SALTLEN_AUTO ?

Thank you
Yao Jiewen


-----Original Message-----
From: Agrawal, Sachin <sachin.agrawal@intel.com>
Sent: Tuesday, April 20, 2021 10:02 AM
To: devel@edk2.groups.io
Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
<jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>; Jiang,
Guomin <guomin.jiang@intel.com>; Agrawal, Sachin
<sachin.agrawal@intel.com>
Subject: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify
support

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

This patch uses Openssl's EVP API's to perform RSASSA-PSS
verification of a binary blob.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>

Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
---
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 139
++++++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 43 ++++++
CryptoPkg/Include/Library/BaseCryptLib.h | 27 ++++
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
7 files changed, 213 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
new file mode 100644
index 000000000000..acf5eb689cd8
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
@@ -0,0 +1,139 @@
+/** @file
+ RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file implements following APIs which provide basic capabilities for RSA:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+
+/**
+ Retrieve a pointer to EVP message digest object.
+
+ @param[in] DigestLen Length of the message digest.
+
+**/
+static
+EVP_MD*
+GetEvpMD (
+ IN UINT16 DigestLen
+ )
+{
+ switch (DigestLen){
+ case SHA256_DIGEST_SIZE:
+ return EVP_sha256();
+ break;
+ case SHA384_DIGEST_SIZE:
+ return EVP_sha384();
+ break;
+ case SHA512_DIGEST_SIZE:
+ return EVP_sha512();
+ break;
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme
+defined in RFC
8017.
+ Implementation determines salt length automatically from the
+ signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ BOOLEAN Result;
+ EVP_PKEY *pEvpRsaKey = NULL;
+ EVP_MD_CTX *pEvpVerifyCtx = NULL;
+ EVP_PKEY_CTX *pKeyCtx = NULL;
+ CONST EVP_MD *HashAlg = NULL;
+
+ if (RsaContext == NULL) {
+ return FALSE;
+ }
+ if (Message == NULL || MsgSize == 0 || MsgSize > INT_MAX) {
+ return FALSE;
+ }
+ if (Signature == NULL || SigSize == 0 || SigSize > INT_MAX) {
+ return FALSE;
+ }
+
+ HashAlg = GetEvpMD(DigestLen);
+
+ if (HashAlg == NULL) {
+ return FALSE;
+ }
+
+ pEvpRsaKey = EVP_PKEY_new();
+ if (pEvpRsaKey == NULL) {
+ goto _Exit;
+ }
+
+ EVP_PKEY_set1_RSA(pEvpRsaKey, RsaContext);
+
+ pEvpVerifyCtx = EVP_MD_CTX_create(); if (pEvpVerifyCtx == NULL) {
+ goto _Exit;
+ }
+
+ Result = EVP_DigestVerifyInit(pEvpVerifyCtx, &pKeyCtx, HashAlg,
+ NULL,
pEvpRsaKey) > 0;
+ if (pKeyCtx == NULL) {
+ goto _Exit;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_padding(pKeyCtx,
RSA_PKCS1_PSS_PADDING) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx,
RSA_PSS_SALTLEN_AUTO) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0; }
+ if (Result) {
+ Result = EVP_DigestVerifyUpdate(pEvpVerifyCtx, Message,
(UINT32)MsgSize) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestVerifyFinal(pEvpVerifyCtx, Signature,
+ (UINT32)SigSize) > 0; }
+
+_Exit :
+ if (pEvpRsaKey) {
+ EVP_PKEY_free(pEvpRsaKey);
+ }
+ if (pEvpVerifyCtx) {
+ EVP_MD_CTX_destroy(pEvpVerifyCtx);
+ }
+
+ return Result;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
new file mode 100644
index 000000000000..8d84b4c1426c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
@@ -0,0 +1,43 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme
+defined in RFC
8017.
+ Implementation determines salt length automatically from the
+ signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
b/CryptoPkg/Include/Library/BaseCryptLib.h
index 496121e6a4ed..36d560b8d691 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1363,6 +1363,33 @@ RsaPkcs1Verify (
IN UINTN SigSize
);

+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme
+defined in RFC
8017.
+ Implementation determines salt length automatically from the
+ signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ );
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.


Re: [PATCH 1/1] BaseTools: Add double quote around CLANG_BIN path string

Bob Feng
 

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bob Feng
Sent: Monday, April 19, 2021 5:13 PM
To: Shi, Steven <steven.shi@intel.com>; devel@edk2.groups.io
Cc: gaoliming@byosoft.com.cn
Subject: Re: [edk2-devel] [PATCH 1/1] BaseTools: Add double quote around CLANG_BIN path string

OK.

I also find a similar case in toolsetup.bat line 411 set "PATH=%BASE_TOOLS_PATH%\BinWrappers\WindowsLike;%PATH%"

Reviewed-by: Bob Feng <bob.c.feng@intel.com>

Thanks,
Bob
-----Original Message-----
From: Shi, Steven <steven.shi@intel.com>
Sent: Monday, April 19, 2021 4:47 PM
To: Feng, Bob C <bob.c.feng@intel.com>; devel@edk2.groups.io
Cc: gaoliming@byosoft.com.cn
Subject: RE: [PATCH 1/1] BaseTools: Add double quote around CLANG_BIN path string

Hi Bob,
I tried @set CLANG_BIN="c:\Program Files\LLVM\bin\", but it cannot work with my CI build service. Only the @set "CLANG_BIN=C:\Program Files\LLVM\bin\" can works. So, it is necessary to use double quote around the whole setting string, which includes both "=" left name and right value parts.


Thanks

Steven Shi
Intel\IAGS\SFP\FIA (Firmware Infrastructure Automation)


-----Original Message-----
From: Feng, Bob C <bob.c.feng@intel.com>
Sent: Monday, April 19, 2021 4:34 PM
To: Shi, Steven <steven.shi@intel.com>; devel@edk2.groups.io
Cc: gaoliming@byosoft.com.cn
Subject: RE: [PATCH 1/1] BaseTools: Add double quote around CLANG_BIN
path string

Steven,

Would you do a little change as

@set CLANG_BIN="c:\Program Files\LLVM\bin\"

I think the double quote should be only round the path.

Thanks,
Bob

-----Original Message-----
From: Shi, Steven <steven.shi@intel.com>
Sent: Saturday, April 17, 2021 8:22 PM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@intel.com>; gaoliming@byosoft.com.cn; Shi,
Steven <steven.shi@intel.com>
Subject: [PATCH 1/1] BaseTools: Add double quote around CLANG_BIN path
string

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

Current CLANG_BIN env variable is set without double quote around the
LLVM default installation path string in windows, which causes some CI
build service cannot find the LLVM path in windows.
This patch enhance it to add double quote around it.

Signed-off-by: Steven Shi <steven.shi@intel.com>
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
---
edksetup.bat | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/edksetup.bat b/edksetup.bat index
7b9377aaa5c2..7ad137bb3e9b
100755
--- a/edksetup.bat
+++ b/edksetup.bat
@@ -120,7 +120,7 @@ if not defined CLANG_BIN (
@echo. @echo !!! WARNING !!! CLANG_BIN environment variable is not
set @if exist "C:\Program Files\LLVM\bin\clang.exe" (- @set
CLANG_BIN=C:\Program Files\LLVM\bin\+ @set
"CLANG_BIN=C:\Program Files\LLVM\bin\" @echo Found LLVM, setting
CLANG_BIN environment variable to C:\Program Files\LLVM\bin\ ) )--
2.28.0.windows.1


Re: [PATCH] BaseTools: GenerateCapsule.py: Add support for version 3 of FMP Image Header structure

Bob Feng
 

Reviewed-by: Bob Feng <bob.c.feng@intel.com>

-----Original Message-----
From: Sughosh Ganu <sughosh.ganu@linaro.org>
Sent: Monday, April 19, 2021 7:40 PM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>; Chen, Christine <yuwei.chen@intel.com>; Sughosh Ganu <sughosh.ganu@linaro.org>
Subject: [PATCH] BaseTools: GenerateCapsule.py: Add support for version 3 of FMP Image Header structure

Add support for the ImageCapsuleSupport field, introduced in version 3 of the EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER structure. This structure member is used to indicate if the corresponding payload has support for authentication and dependency.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
---
.../Source/Python/Capsule/GenerateCapsule.py | 5 +++-
.../Common/Uefi/Capsule/FmpCapsuleHeader.py | 26 +++++++++++++------
2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index a8de988253..6419a2ac6f 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -561,6 +561,7 @@ if __name__ == '__main__':
print ('GenerateCapsule: error:' + str(Msg))
sys.exit (1)
for SinglePayloadDescriptor in PayloadDescriptorList:
+ ImageCapsuleSupport = 0x0000000000000000
Result = SinglePayloadDescriptor.Payload
try:
FmpPayloadHeader.FwVersion = SinglePayloadDescriptor.FwVersion
@@ -575,6 +576,7 @@ if __name__ == '__main__':
if SinglePayloadDescriptor.UseDependency:
CapsuleDependency.Payload = Result
CapsuleDependency.DepexExp = SinglePayloadDescriptor.DepexExp
+ ImageCapsuleSupport |= 0x0000000000000002
Result = CapsuleDependency.Encode ()
if args.Verbose:
CapsuleDependency.DumpInfo () @@ -607,13 +609,14 @@ if __name__ == '__main__':
FmpAuthHeader.MonotonicCount = SinglePayloadDescriptor.MonotonicCount
FmpAuthHeader.CertData = CertData
FmpAuthHeader.Payload = Result
+ ImageCapsuleSupport |= 0x0000000000000001
Result = FmpAuthHeader.Encode ()
if args.Verbose:
FmpAuthHeader.DumpInfo ()
except:
print ('GenerateCapsule: error: can not encode FMP Auth Header')
sys.exit (1)
- FmpCapsuleHeader.AddPayload (SinglePayloadDescriptor.Guid, Result, HardwareInstance = SinglePayloadDescriptor.HardwareInstance, UpdateImageIndex = SinglePayloadDescriptor.UpdateImageIndex)
+ FmpCapsuleHeader.AddPayload (SinglePayloadDescriptor.Guid,
+ Result, ImageCapsuleSupport, HardwareInstance =
+ SinglePayloadDescriptor.HardwareInstance, UpdateImageIndex =
+ SinglePayloadDescriptor.UpdateImageIndex)
try:
for EmbeddedDriver in EmbeddedDriverDescriptorList:
FmpCapsuleHeader.AddEmbeddedDriver(EmbeddedDriver)
diff --git a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
index 91d24919c4..a2a5cf0db8 100644
--- a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
+++ b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
@@ -47,14 +47,19 @@ class FmpCapsuleImageHeaderClass (object):
# /// therefore can be modified without changing the Auth data.
# ///
# UINT64 UpdateHardwareInstance;
+ #
+ # ///
+ # /// Bits which indicate authentication and depex information for the image that follows this structure
+ # ///
+ # UINT64 ImageCapsuleSupport
# } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;
#
- # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000002
+ # #define
+ EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000003

- _StructFormat = '<I16sB3BIIQ'
+ _StructFormat = '<I16sB3BIIQQ'
_StructSize = struct.calcsize (_StructFormat)

- EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION = 0x00000002
+ EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION =
+ 0x00000003

def __init__ (self):
self._Valid = False
@@ -64,6 +69,7 @@ class FmpCapsuleImageHeaderClass (object):
self.UpdateImageSize = 0
self.UpdateVendorCodeSize = 0
self.UpdateHardwareInstance = 0x0000000000000000
+ self.ImageCapsuleSupport = 0x0000000000000000
self.Payload = b''
self.VendorCodeBytes = b''

@@ -78,7 +84,8 @@ class FmpCapsuleImageHeaderClass (object):
0,0,0,
self.UpdateImageSize,
self.UpdateVendorCodeSize,
- self.UpdateHardwareInstance
+ self.UpdateHardwareInstance,
+ self.ImageCapsuleSupport
)
self._Valid = True
return FmpCapsuleImageHeader + self.Payload + self.VendorCodeBytes @@ -86,7 +93,7 @@ class FmpCapsuleImageHeaderClass (object):
def Decode (self, Buffer):
if len (Buffer) < self._StructSize:
raise ValueError
- (Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2, UpdateImageSize, UpdateVendorCodeSize, UpdateHardwareInstance) = \
+ (Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2,
+ UpdateImageSize, UpdateVendorCodeSize, UpdateHardwareInstance,
+ ImageCapsuleSupport) = \
struct.unpack (
self._StructFormat,
Buffer[0:self._StructSize] @@ -105,6 +112,7 @@ class FmpCapsuleImageHeaderClass (object):
self.UpdateImageSize = UpdateImageSize
self.UpdateVendorCodeSize = UpdateVendorCodeSize
self.UpdateHardwareInstance = UpdateHardwareInstance
+ self.ImageCapsuleSupport = ImageCapsuleSupport
self.Payload = Buffer[self._StructSize:self._StructSize + UpdateImageSize]
self.VendorCodeBytes = Buffer[self._StructSize + UpdateImageSize:]
self._Valid = True
@@ -119,6 +127,7 @@ class FmpCapsuleImageHeaderClass (object):
print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}'.format (UpdateImageSize = self.UpdateImageSize))
print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}'.format (UpdateVendorCodeSize = self.UpdateVendorCodeSize))
print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}'.format (UpdateHardwareInstance = self.UpdateHardwareInstance))
+ print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.ImageCapsuleSupport = {ImageCapsuleSupport:016X}'.format (ImageCapsuleSupport = self.ImageCapsuleSupport))
print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))
print ('sizeof (VendorCodeBytes) = {Size:08X}'.format (Size = len (self.VendorCodeBytes)))

@@ -172,8 +181,8 @@ class FmpCapsuleHeaderClass (object):
raise ValueError
return self._EmbeddedDriverList[Index]

- def AddPayload (self, UpdateImageTypeId, Payload = b'', VendorCodeBytes = b'', HardwareInstance = 0, UpdateImageIndex = 1):
- self._PayloadList.append ((UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance, UpdateImageIndex))
+ def AddPayload (self, UpdateImageTypeId, Payload = b'', ImageCapsuleSupport = 0, VendorCodeBytes = b'', HardwareInstance = 0, UpdateImageIndex = 1):
+ self._PayloadList.append ((UpdateImageTypeId, Payload,
+ ImageCapsuleSupport, VendorCodeBytes, HardwareInstance,
+ UpdateImageIndex))

def GetFmpCapsuleImageHeader (self, Index):
if Index >= len (self._FmpCapsuleImageHeaderList):
@@ -198,13 +207,14 @@ class FmpCapsuleHeaderClass (object):
self._ItemOffsetList.append (Offset)
Offset = Offset + len (EmbeddedDriver)
Index = 1
- for (UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance, UpdateImageIndex) in self._PayloadList:
+ for (UpdateImageTypeId, Payload, ImageCapsuleSupport, VendorCodeBytes, HardwareInstance, UpdateImageIndex) in self._PayloadList:
FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass ()
FmpCapsuleImageHeader.UpdateImageTypeId = UpdateImageTypeId
FmpCapsuleImageHeader.UpdateImageIndex = UpdateImageIndex
FmpCapsuleImageHeader.Payload = Payload
FmpCapsuleImageHeader.VendorCodeBytes = VendorCodeBytes
FmpCapsuleImageHeader.UpdateHardwareInstance = HardwareInstance
+ FmpCapsuleImageHeader.ImageCapsuleSupport = ImageCapsuleSupport
FmpCapsuleImage = FmpCapsuleImageHeader.Encode ()
FmpCapsuleData = FmpCapsuleData + FmpCapsuleImage

--
2.17.1


Re: [PATCH] [INTEL][TOOLS][FITGEN] Modify Fitgen tool to support new ACM header

Bob Feng
 

Reviewed-by: Bob Feng <bob.c.feng@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Mohammad Miazi
Sent: Thursday, April 15, 2021 2:31 PM
To: devel@edk2.groups.io
Cc: Miazi, Mohammad M <mohammad.m.miazi@intel.com>
Subject: [edk2-devel] [PATCH] [INTEL][TOOLS][FITGEN] Modify Fitgen tool to support new ACM header

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

Currently Fitgen tools verifies every detail of ACM header, so any ACM header change breaks the tool.
As ACM header is verified by microcode and ACM itself, Fitgen tool does not need to verify every fieldof ACM header except some important fields like ACM_TYPE/SUB_TYPE etc.The changes will remove the dependency between future ACM header changeand FitGen tool.

Signed-off-by: Mohammad Miazi <mohammad.m.miazi@intel.com>
---
Silicon/Intel/Tools/FitGen/FitGen.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/Silicon/Intel/Tools/FitGen/FitGen.c b/Silicon/Intel/Tools/FitGen/FitGen.c
index 36e6e3c905..290e688f6e 100644
--- a/Silicon/Intel/Tools/FitGen/FitGen.c
+++ b/Silicon/Intel/Tools/FitGen/FitGen.c
@@ -2,7 +2,7 @@
This utility is part of build process for IA32/X64 FD.
It generates FIT table.

-Copyright (c) 2010-2020, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010-2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
@@ -48,6 +48,7 @@ typedef struct {
#define ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE 384

#define ACM_HEADER_VERSION_3 (3 << 16)
+#define ACM_HEADER_VERSION_0 (0)
#define ACM_MODULE_TYPE_CHIPSET_ACM 2
#define ACM_MODULE_SUBTYPE_CAPABLE_OF_EXECUTE_AT_RESET 0x1
#define ACM_MODULE_SUBTYPE_ANC_MODULE 0x2
@@ -2456,7 +2457,16 @@ Returns:
DumpHex (Buffer, Acm->KeySize * 4);
printf ("\n");
Buffer += Acm->KeySize * 4;
-
+ //
+ // To simplify the tool and making it independent of ACM header
+ change, // the rest of ACM parsing will be skipped starting
+ ACM_HEADER_VERSION4 // if((Acm->HeaderVersion !=
+ ACM_HEADER_VERSION_3) && (Acm->HeaderVersion != ACM_HEADER_VERSION_0)){
+ printf (
+ "*****************************************************************************\n\n"
+ );
+ return;
+ }
if (Acm->HeaderVersion == ACM_HEADER_VERSION_3) {
printf (" RSASig - \n");
DumpHex (Buffer, ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE); // PKCS #1.5 RSA Signature @@ -2580,6 +2590,14 @@ Returns:
return FALSE;
}

+ //
+ // To simplify the tool and making it independent of ACM header
+ change, // the following check will be skipped starting
+ ACM_HEADER_VERSION3 // if((Acm->HeaderVersion !=
+ ACM_HEADER_VERSION_3) && (Acm->HeaderVersion != ACM_HEADER_VERSION_0)){
+ printf ("ACM header Version 4 or higher, bypassing other checks!\n");
+ return TRUE;
+ }
Buffer = (UINT8 *)(Acm + 1);
Buffer += Acm->KeySize * 4;
if (Acm->HeaderVersion == ACM_HEADER_VERSION_3) {
--
2.16.2.windows.1


Re: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

Yao, Jiewen
 

Right. That has PROs and CONs.

On one hand, that allows maximum compatibility, salt could be HASH_SIZE or MAX, or even 0 ?

On the other hand, what if the consumer only wants to accept a specific length? E.g. TPM in FIPS mode and TLS requires SaltLength==HashLength.

Thank you
Yao Jiewen

-----Original Message-----
From: Agrawal, Sachin <sachin.agrawal@intel.com>
Sent: Tuesday, April 20, 2021 3:19 PM
To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>;
Jiang, Guomin <guomin.jiang@intel.com>
Subject: RE: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

Hi Jiewen,

From Section 9.1 in RFC 8017:
" Note that the verification operation follows reverse steps to recover
salt and then forward steps to recompute and compare H."

Therefore, salt length can be inferred from the PSS block structure during
verification operation.

I opted for 'RSA_PSS_SALTLEN_AUTO' as it will allow Edk2 to verify PSS
signatures of any salt lengths.

Thanks
Sachin

-----Original Message-----
From: Yao, Jiewen <jiewen.yao@intel.com>
Sent: Monday, April 19, 2021 7:30 PM
To: Agrawal, Sachin <sachin.agrawal@intel.com>; devel@edk2.groups.io
Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>;
Jiang, Guomin <guomin.jiang@intel.com>
Subject: RE: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

Hi Sachin
May I know why you hardcode PSS salt length to be RSA_PSS_SALTLEN_AUTO ?

Thank you
Yao Jiewen


-----Original Message-----
From: Agrawal, Sachin <sachin.agrawal@intel.com>
Sent: Tuesday, April 20, 2021 10:02 AM
To: devel@edk2.groups.io
Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
<jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>; Jiang,
Guomin <guomin.jiang@intel.com>; Agrawal, Sachin
<sachin.agrawal@intel.com>
Subject: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify
support

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

This patch uses Openssl's EVP API's to perform RSASSA-PSS verification
of a binary blob.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>

Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
---
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 139
++++++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 43 ++++++
CryptoPkg/Include/Library/BaseCryptLib.h | 27 ++++
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
7 files changed, 213 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
new file mode 100644
index 000000000000..acf5eb689cd8
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
@@ -0,0 +1,139 @@
+/** @file
+ RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file implements following APIs which provide basic capabilities for RSA:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+
+/**
+ Retrieve a pointer to EVP message digest object.
+
+ @param[in] DigestLen Length of the message digest.
+
+**/
+static
+EVP_MD*
+GetEvpMD (
+ IN UINT16 DigestLen
+ )
+{
+ switch (DigestLen){
+ case SHA256_DIGEST_SIZE:
+ return EVP_sha256();
+ break;
+ case SHA384_DIGEST_SIZE:
+ return EVP_sha384();
+ break;
+ case SHA512_DIGEST_SIZE:
+ return EVP_sha512();
+ break;
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined
+in RFC
8017.
+ Implementation determines salt length automatically from the
+ signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ BOOLEAN Result;
+ EVP_PKEY *pEvpRsaKey = NULL;
+ EVP_MD_CTX *pEvpVerifyCtx = NULL;
+ EVP_PKEY_CTX *pKeyCtx = NULL;
+ CONST EVP_MD *HashAlg = NULL;
+
+ if (RsaContext == NULL) {
+ return FALSE;
+ }
+ if (Message == NULL || MsgSize == 0 || MsgSize > INT_MAX) {
+ return FALSE;
+ }
+ if (Signature == NULL || SigSize == 0 || SigSize > INT_MAX) {
+ return FALSE;
+ }
+
+ HashAlg = GetEvpMD(DigestLen);
+
+ if (HashAlg == NULL) {
+ return FALSE;
+ }
+
+ pEvpRsaKey = EVP_PKEY_new();
+ if (pEvpRsaKey == NULL) {
+ goto _Exit;
+ }
+
+ EVP_PKEY_set1_RSA(pEvpRsaKey, RsaContext);
+
+ pEvpVerifyCtx = EVP_MD_CTX_create(); if (pEvpVerifyCtx == NULL) {
+ goto _Exit;
+ }
+
+ Result = EVP_DigestVerifyInit(pEvpVerifyCtx, &pKeyCtx, HashAlg,
+ NULL,
pEvpRsaKey) > 0;
+ if (pKeyCtx == NULL) {
+ goto _Exit;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_padding(pKeyCtx,
RSA_PKCS1_PSS_PADDING) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx,
RSA_PSS_SALTLEN_AUTO) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0; }
+ if (Result) {
+ Result = EVP_DigestVerifyUpdate(pEvpVerifyCtx, Message,
(UINT32)MsgSize) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestVerifyFinal(pEvpVerifyCtx, Signature,
+ (UINT32)SigSize) > 0; }
+
+_Exit :
+ if (pEvpRsaKey) {
+ EVP_PKEY_free(pEvpRsaKey);
+ }
+ if (pEvpVerifyCtx) {
+ EVP_MD_CTX_destroy(pEvpVerifyCtx);
+ }
+
+ return Result;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
new file mode 100644
index 000000000000..8d84b4c1426c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
@@ -0,0 +1,43 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined
+in RFC
8017.
+ Implementation determines salt length automatically from the
+ signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
b/CryptoPkg/Include/Library/BaseCryptLib.h
index 496121e6a4ed..36d560b8d691 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1363,6 +1363,33 @@ RsaPkcs1Verify (
IN UINTN SigSize
);

+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined
+in RFC
8017.
+ Implementation determines salt length automatically from the
+ signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ );
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.


Re: [RFC PATCH 01/19] OvmfPkg: Reserve the Secrets and Cpuid page for the SEV-SNP guest

Laszlo Ersek
 

On 04/19/21 23:42, Brijesh Singh wrote:

On 4/13/21 4:49 AM, Laszlo Ersek wrote:
On 04/12/21 16:52, Brijesh Singh wrote:
Hi James and Laszlo,

I was planning to work to add the support to reserve the Secrets and
CPUID page in E820 map and then create the EFI configuration table entry
for it so that guest OS can reach to it. We have two packages
"SecretDxe" and "SecretPei" in OvmfPkg/AmdSev. Any issues if I use them
in the OvmfPkg.dsc ? Here is what I was thinking:

1) Rename the PcdSevLaunchSecretBase -> PcdSevSecretsBase

2) When SNP is enabled then VMM use this page as secrets page for the SNP

3) When SEV or SEV-ES is enabled then VMM uses this page as a launch
secret page

This will allow me to drop PcdOvmfSnpSecretsBase. This will not just
save 4-bytes but also minimize the code duplication.
I'm pretty unhappy about needing a separate page for each such purpose.
We're wasting room in MEMFD. The GUIDed structs that we expose to QEMU
seem to be flexible enough to describe non-page-aligned addresses,
right? Can we pack larger amounts of cruft into MEMFD pages?

I'm not looking forward to the day when we run out of slack in MEMFD and
we get to shift PEIFV / DXEFV. (Every time we need to increase the DXEFV
size, the same risk exists -- which is why I've been thinking for a
while now that OVMF includes too many features already.) This can
introduce obscure changes to the UEFI memory map, which has caused
compat problems in the past, for example with the "crash" utility.

What's your take to move all SEV-specific reserved pages at the end of
PcdOvmfDecompressionScratchEnd ? I have not tried yet, but I can give
try to make sure the ES works after such moves.
I don't recommend that, without a serious audit anyway. While we use
PCDs in the source code rather than open-coded constants, and so it's
relatively easy to change the value of a PCD, the source code may very
well rely on the *relations* between PCDs. If you change PCDs such that
their relations change (by moving around areas), things can break.

If you absolutely need more room, I'd prefer enlarging the currently
available gap in-place (pushing up everything that's currently above it).

What is a general rule of thump to what goes in MEMFD ? Is this all the
data pages accessed during the SEC phase ?
More or less; it lets us lay out ranges, with symbolic names, that are
needed very early (reset vector, SEC), during normal boot or ACPI S3
resume. If something can be allocated manually during PEI or later,
yielding a variable address, then it arguably doesn't beling on MEMFD.

If so, then we probably can't
do everything after the PcdOvmfDecompressionScratchEnd. The only thing
which we can quickly move out is a secret page.
IIRC, PcdOvmfDecompressionScratchEnd stands for the highest RAM address
overwritten during ACPI S3 resume. I wouldn't like to put anything above
it through MEMFD.

Thanks
Laszlo



The feature creep in OVMF has gone off the rails in the last few years,
really. (Not that I'm not guilty myself.)

Thanks,
Laszlo


Re: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

Agrawal, Sachin
 

Hi Jiewen,

From Section 9.1 in RFC 8017:
" Note that the verification operation follows reverse steps to recover
salt and then forward steps to recompute and compare H."

Therefore, salt length can be inferred from the PSS block structure during verification operation.

I opted for 'RSA_PSS_SALTLEN_AUTO' as it will allow Edk2 to verify PSS signatures of any salt lengths.

Thanks
Sachin

-----Original Message-----
From: Yao, Jiewen <jiewen.yao@intel.com>
Sent: Monday, April 19, 2021 7:30 PM
To: Agrawal, Sachin <sachin.agrawal@intel.com>; devel@edk2.groups.io
Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>
Subject: RE: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

Hi Sachin
May I know why you hardcode PSS salt length to be RSA_PSS_SALTLEN_AUTO ?

Thank you
Yao Jiewen


-----Original Message-----
From: Agrawal, Sachin <sachin.agrawal@intel.com>
Sent: Tuesday, April 20, 2021 10:02 AM
To: devel@edk2.groups.io
Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
<jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>; Jiang,
Guomin <guomin.jiang@intel.com>; Agrawal, Sachin
<sachin.agrawal@intel.com>
Subject: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify
support

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

This patch uses Openssl's EVP API's to perform RSASSA-PSS verification
of a binary blob.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>

Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
---
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 139
++++++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 43 ++++++
CryptoPkg/Include/Library/BaseCryptLib.h | 27 ++++
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
7 files changed, 213 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
new file mode 100644
index 000000000000..acf5eb689cd8
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
@@ -0,0 +1,139 @@
+/** @file
+ RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file implements following APIs which provide basic capabilities for RSA:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+
+/**
+ Retrieve a pointer to EVP message digest object.
+
+ @param[in] DigestLen Length of the message digest.
+
+**/
+static
+EVP_MD*
+GetEvpMD (
+ IN UINT16 DigestLen
+ )
+{
+ switch (DigestLen){
+ case SHA256_DIGEST_SIZE:
+ return EVP_sha256();
+ break;
+ case SHA384_DIGEST_SIZE:
+ return EVP_sha384();
+ break;
+ case SHA512_DIGEST_SIZE:
+ return EVP_sha512();
+ break;
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined
+in RFC
8017.
+ Implementation determines salt length automatically from the
+ signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ BOOLEAN Result;
+ EVP_PKEY *pEvpRsaKey = NULL;
+ EVP_MD_CTX *pEvpVerifyCtx = NULL;
+ EVP_PKEY_CTX *pKeyCtx = NULL;
+ CONST EVP_MD *HashAlg = NULL;
+
+ if (RsaContext == NULL) {
+ return FALSE;
+ }
+ if (Message == NULL || MsgSize == 0 || MsgSize > INT_MAX) {
+ return FALSE;
+ }
+ if (Signature == NULL || SigSize == 0 || SigSize > INT_MAX) {
+ return FALSE;
+ }
+
+ HashAlg = GetEvpMD(DigestLen);
+
+ if (HashAlg == NULL) {
+ return FALSE;
+ }
+
+ pEvpRsaKey = EVP_PKEY_new();
+ if (pEvpRsaKey == NULL) {
+ goto _Exit;
+ }
+
+ EVP_PKEY_set1_RSA(pEvpRsaKey, RsaContext);
+
+ pEvpVerifyCtx = EVP_MD_CTX_create(); if (pEvpVerifyCtx == NULL) {
+ goto _Exit;
+ }
+
+ Result = EVP_DigestVerifyInit(pEvpVerifyCtx, &pKeyCtx, HashAlg,
+ NULL,
pEvpRsaKey) > 0;
+ if (pKeyCtx == NULL) {
+ goto _Exit;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_padding(pKeyCtx,
RSA_PKCS1_PSS_PADDING) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx,
RSA_PSS_SALTLEN_AUTO) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0; }
+ if (Result) {
+ Result = EVP_DigestVerifyUpdate(pEvpVerifyCtx, Message,
(UINT32)MsgSize) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestVerifyFinal(pEvpVerifyCtx, Signature,
+ (UINT32)SigSize) > 0; }
+
+_Exit :
+ if (pEvpRsaKey) {
+ EVP_PKEY_free(pEvpRsaKey);
+ }
+ if (pEvpVerifyCtx) {
+ EVP_MD_CTX_destroy(pEvpVerifyCtx);
+ }
+
+ return Result;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
new file mode 100644
index 000000000000..8d84b4c1426c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
@@ -0,0 +1,43 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined
+in RFC
8017.
+ Implementation determines salt length automatically from the
+ signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
b/CryptoPkg/Include/Library/BaseCryptLib.h
index 496121e6a4ed..36d560b8d691 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1363,6 +1363,33 @@ RsaPkcs1Verify (
IN UINTN SigSize
);

+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined
+in RFC
8017.
+ Implementation determines salt length automatically from the
+ signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ );
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.


Re: [edk2-platforms][PATCH V1 5/8] Platform/Sgi: ACPI PPTT table for RD-E1-Edge platform

Pranav Madhu
 

Hi Pierre,

Thanks for reviewing this patch.


Hi Pranav,
+� }
+
+#define PPTT_CORE_INIT(pid, cid,
coreId)���������������������
����������������� \
+ { \
+��� /* Parameters for CPU Core
*/����������������������ï¿
½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ \
+��� EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR_INIT
(�����������������������
������� \
+����� __builtin_offsetof (RDE1EDGE_PPTT_CORE, DCache), /*
+Length
*/���������� \
+�����
+PPTT_PROCESSOR_CORE_THREADED_FLAGS,��������
/* Flag
*/������������������ \
+����� __builtin_offsetof
(EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE,��� \
+�������
+Package.Cluster[cid]),���������������ï¿
+½ï¿½ï¿½ï¿½ /* Parent
*/���������������� \
+�����
+0,����������������������ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* ACPI Id
*/��������������� \
+�����
+2����������������������ï¿
+½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* Num
of
+private
resource */\
+ ), \
+ \
+��� /* Offsets of the private resources
*/����������������������ï¿
½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ \
+ { \
+����� __builtin_offsetof
(EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE,��� \
+ Package.Cluster[cid].Core[coreId].DCache), \ �����
+__builtin_offsetof
(EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE,��� \
+ Package.Cluster[cid].Core[coreId].ICache) \ }, \
Would it be possible to use the edk2/MdePkg/Include/Base.h:OFFSET_OF()
macro to handle the different compilers ?
Yes, will update


This modification could be applied to all the other PPTT tables in the set.

+ \
+��� /* L1 Data cache parameters
*/����������������������ï¿
½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ \
+��� EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE_INIT
(�����������������������
����������� \
+�����
+PPTT_CACHE_STRUCTURE_FLAGS,���������� /*
Flag
*/����������������������ï¿
½ï¿½ \
+����� __builtin_offsetof
(EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE,��� \
+ Package.Cluster[cid].Core[coreId].L2Cache), \
+�����������������������
+�������������������� /* Next
+level of cache
*/��������� \
+�����
+SIZE_32KB,�������������������ï¿
+½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* Size
*/����������������������ï¿
½ï¿½ \
+�����
+128,���������������������ï¿
+½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* Num of sets
*/����������������� \
+�����
+4,����������������������ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* Associativity
*/��������������� \
+�����
+PPTT_DATA_CACHE_ATTR,��������������ï¿
½ï¿½
+/* Attributes
*/������������������ \
+�����
+64����������������������ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* Line size
*/������������������� \
+ ), \
+ \
[...]
+
+#pragma pack(1)
+typedef struct {
+� EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR Thread; }
+RDE1EDGE_PPTT_THREAD;
+
+typedef struct {
+� EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR� Core; �
+UINT32��������������������ï¿
½
+����������� Offset[2];
Similarly to the the first patch, I think there should be 3 elements (and if
possible renamed to 'PrivateResources').
+� EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE����� DCache; �
+EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE����� ICache; �
+EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE����� L2Cache; �
+RDE1EDGE_PPTT_THREAD Thread[THREAD_PER_CORE]; }
RDE1EDGE_PPTT_CORE;
+
+typedef struct {
+� EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR� Cluster; �
+UINT32��������������������ï¿
½
+����������� Offset; �
+EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE����� L3Cache; �
+RDE1EDGE_PPTT_CORE���������������ï¿
½ï¿½
+��� Core[CORE_COUNT /
THREAD_PER_CORE];
+} RDE1EDGE_PPTT_CLUSTER;
+
Regards,

Pierre
Regards,
Pranav


Cancelled Event: TianoCore Bug Triage - APAC / NAMO - Tuesday, 20 April 2021 #cal-cancelled

devel@edk2.groups.io Calendar <noreply@...>
 

Cancelled: TianoCore Bug Triage - APAC / NAMO

This event has been cancelled.

When:
Tuesday, 20 April 2021
6:30pm to 7:30pm
(UTC-07:00) America/Los Angeles

Where:
https://meetingsamer34.webex.com/meetingsamer34/j.php?MTID=mb96c5bd411bd010e1e6d43a6f6c65f45

Organizer: Liming Gao gaoliming@...

Description:

TianoCore Bug Triage - APAC / NAMO

Hosted by Liming Gao

 

https://meetingsamer34.webex.com/meetingsamer34/j.php?MTID=mb96c5bd411bd010e1e6d43a6f6c65f45

Wednesday, Jan 20, 2021 10:30 am | 50 minutes | (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi

Occurs every Wednesday effective 1/20/2021 from 10:30 AM to 11:20 AM, (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi

Meeting number: 126 867 1239

Password: ZhqYQunw246 (94797869 from video systems)

d8edc6c9604344b08f727b4bf054eaac_20210120T023000Z

 

Join by video system

Dial 1268671239@...

You can also dial 173.243.2.68 and enter your meeting number.

 

Join by phone

Use VoIP only


回复: [edk2-devel] TianoCore Bug Triage - APAC / NAMO - Tue, 04/20/2021 6:30pm-7:30pm #cal-reminder

gaoliming
 

Hi, all

 Few new issues are reported this week. Let’s cancel this week meeting.

 

3342

EDK2

Code

unassigned@...

UNCO

FmpDeviceLib interface for Driver Unload is missing.

16:22:05

jrahn@...

3339

EDK2 Cod

Specific

unassigned@...

UNCO

ACPI Code First - RASF Gen2

Thu 18:53

samer.el-haj-mahmoud@...

3338

EDK2 Cod

Specific

unassigned@...

UNCO

Clarify NVMe and Infiniband device path EUI-64 byte order

Thu 05:56

samer.el-haj-mahmoud@...

3311

EDK2

Code

unassigned@...

UNCO

SetupBrowserDxe does not handle two formsets using the same VarStoreID

Wed 21:01

Allen_Wynn@...

3292

EDK2

Code

unassigned@...

UNCO

MdePkg: IEEE Extended Unique Identifiers (EUI64) are big endian

Wed 18:34

xypron.glpk@...

3291

EDK2 Tes

UEFI-SCT

unassigned@...

UNCO

uefi-sct/SctPkg: IEEE Extended Unique Identifiers (EUI64) are big endian

Wed 18:34

xypron.glpk@...

 

Thanks

Liming

发件人: devel@edk2.groups.io <devel@edk2.groups.io>
发送时间: 2021420 9:30
收件人: devel@edk2.groups.io
主题: [edk2-devel] TianoCore Bug Triage - APAC / NAMO - Tue, 04/20/2021 6:30pm-7:30pm #cal-reminder

 

Reminder: TianoCore Bug Triage - APAC / NAMO

When: Tuesday, 20 April 2021, 6:30pm to 7:30pm, (GMT-07:00) America/Los Angeles

Where:https://meetingsamer34.webex.com/meetingsamer34/j.php?MTID=mb96c5bd411bd010e1e6d43a6f6c65f45

View Event

Organizer: Liming Gao gaoliming@...

Description:

TianoCore Bug Triage - APAC / NAMO

Hosted by Liming Gao

 

https://meetingsamer34.webex.com/meetingsamer34/j.php?MTID=mb96c5bd411bd010e1e6d43a6f6c65f45

Wednesday, Jan 20, 2021 10:30 am | 50 minutes | (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi

Occurs every Wednesday effective 1/20/2021 from 10:30 AM to 11:20 AM, (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi

Meeting number: 126 867 1239

Password: ZhqYQunw246 (94797869 from video systems)

d8edc6c9604344b08f727b4bf054eaac_20210120T023000Z

 

Join by video system

Dial 1268671239@...

You can also dial 173.243.2.68 and enter your meeting number.

 

Join by phone

Use VoIP only


Re: [edk2-platforms][PATCH V1 1/8] Platform/Sgi: Helper macros for PPTT Table

Pranav Madhu
 

Hi Pierre,

Thanks for reviewing this patch. Please find my response inline.

-----Original Message-----
From: Pierre Gondois <pierre.gondois@arm.com>
Sent: Tuesday, April 13, 2021 2:48 PM
To: devel@edk2.groups.io; Pranav Madhu <Pranav.Madhu@arm.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Leif Lindholm
<leif@nuviainc.com>; Sami Mujawar <Sami.Mujawar@arm.com>
Subject: Re: [edk2-devel] [edk2-platforms][PATCH V1 1/8] Platform/Sgi:
Helper macros for PPTT Table

Hi Pranav,

diff --git a/Platform/ARM/SgiPkg/Include/SgiAcpiHeader.h
b/Platform/ARM/SgiPkg/Include/SgiAcpiHeader.h
index 8d715de173c9..7ceb090a78e9 100644
--- a/Platform/ARM/SgiPkg/Include/SgiAcpiHeader.h
+++ b/Platform/ARM/SgiPkg/Include/SgiAcpiHeader.h
@@ -1,6 +1,6 @@
�/** @file
�*
-*� Copyright (c) 2018-2020, ARM Limited. All rights reserved.
+*� Copyright (c) 2018-2021, ARM Limited. All rights reserved.
�*
�*� SPDX-License-Identifier: BSD-2-Clause-Patent
�*
@@ -20,6 +20,132 @@
�#define EFI_ACPI_ARM_CREATOR_ID SIGNATURE_32('A','R','M',' ')
�#define EFI_ACPI_ARM_CREATOR_REVISION 0x00000099

+#define CORE_COUNT����� FixedPcdGet32 (PcdCoreCount)
+#define CLUSTER_COUNT�� FixedPcdGet32 (PcdClusterCount)
+
+#pragma pack(1)
+// PPTT processor core structure
+typedef struct {
+� EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR� Core; �
+UINT32��������������������ï¿
½
+����������� Offset[2];
I think there should be 3 entries (DCache, ICache, L2Cache). Updating this will
require updating the other PPTT tables written.
As per ACPI spec 6.4, chapter '5.2.29.2 Cache Type Structure - Type 1', " Only
the head of the list needs to be listed as a resource by a processor node (and
counted toward Number of Private Resources), as the cache node itself
contains a link to the next level of cache."
Here L2 cache is represented as next level of L1, so no need to count it.


Would it be also possible to rename the field 'PrivateResources' as in the
spec ?
Yes, but in actual, it is not the private resource count.

Another question: what does 'RD_' stands for ?
RD Stands for Reference Design, it is the convention we follow.


+� EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE����� DCache; �
+EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE����� ICache; �
+EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE����� L2Cache; }
+RD_PPTT_CORE;
+
+// PPTT processor cluster structure
+typedef struct {
+� EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR� Cluster; �
+UINT32��������������������ï¿
½
+����������� Offset; �
+EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE����� L3Cache; �
+RD_PPTT_CORE Core[CORE_COUNT]; } RD_PPTT_CLUSTER;
+
+// PPTT processor cluster structure without cache typedef struct {
+� EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR� Cluster; �
+UINT32��������������������ï¿
½
+����������� Offset;
I think there is no need for an offset here. Updating this will require updating
the other PPTT tables written.
Right. Will update.

+� RD_PPTT_CORE Core[CORE_COUNT];
+} RD_PPTT_MINIMAL_CLUSTER;
+
+// PPTT processor package structure
+typedef struct {
+� EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR� Package; �
+UINT32��������������������ï¿
½
+����������� Offset; �
+EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE����� Slc; �
+RD_PPTT_MINIMAL_CLUSTER Cluster[CLUSTER_COUNT]; }
+RD_PPTT_SLC_PACKAGE; #pragma pack ()
+
+//
+// PPTT processor structure flags for different SoC components as
defined in
+// ACPI 6.3 specification
+//
+
[...]

+// EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR
+#define EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR_INIT(Length, Flag,
Parent,������ \
+� ACPIProcessorID, NumberOfPrivateResource) \
I think it should be possible to remove the 'Length' parameter and compute it
as:
sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) +
NumberOfPrivateResource * sizeof
(EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE) + NumberOfPrivateResource *
sizeof (UINT32)
As per 6.4 specification, table 5.138, the Length is "Length of the local processor
structure in bytes" It is just the length of local processor, not the entire structure.

+ { \
+���
+EFI_ACPI_6_3_PPTT_TYPE_PROCESSOR,����������ï¿
½ï¿½
+���� /* Type 0
*/������������ \
+���
+Length,��������������������ï¿
+½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /*
+Length
*/������������ \
+ { \
+ EFI_ACPI_RESERVED_BYTE, \
+ EFI_ACPI_RESERVED_BYTE, \
+ }, \
+���
+Flag,���������������������ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½
+/* Processor
flags */��� \
+���
+Parent,��������������������ï¿
+½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /*
+Ref to
parent node */ \
+���
+ACPIProcessorID,�����������������ï¿
+½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* UID, as per
MADT */�� \
+���
+NumberOfPrivateResource��������������ï¿
½ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* Resource
count */���� \
+� }
+
+// EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE
+#define EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE_INIT(Flag,
NextLevelCache,
Size,���� \
+� NoOfSets, Associativity, Attributes,
LineSize)��������������������ï
¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ \
+ { \
+���
+EFI_ACPI_6_3_PPTT_TYPE_CACHE,������������ï
¿½ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* Type 1
*/������������ \
+��� sizeof
+(EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE),������ /* Length
*/������������ \
+ { \
+ EFI_ACPI_RESERVED_BYTE, \
+ EFI_ACPI_RESERVED_BYTE, \
+ }, \
+���
+Flag,���������������������ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½
+/* Cache flags
*/������� \
+���
+NextLevelCache,�����������������ï¿
½
+���������������� /* Ref to next
level */� \
+���
+Size,���������������������ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½
+/* Size in
bytes */����� \
+���
+NoOfSets,�������������������ï¿
½
+�������������������� /* Num
+of sets
*/������� \
+���
+Associativity,������������������ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* Num of ways
*/������� \
+���
+Attributes,�������������������ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /* Cache
attributes */�� \
+���
+LineSize��������������������ï
+¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ /*
+Line size in
bytes */ \
+� }
+
�#endif /* __SGI_ACPI_HEADER__ */
--
2.17.1
Regards,

Pierre
Regards,
Pranav.


Re: [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI FVB services

Guo Dong
 

Hi Ray,

This patch is about FVB module change. It is not related with SPI since it depends on SPI library.
The SPI hardware sequence could be used in SPI library.
I reviewed this patch, I think it is OK to replace the one used in existing platform FVB driver.

Thanks,
Guo

-----Original Message-----
From: Ni, Ray <ray.ni@intel.com>
Sent: Friday, April 16, 2021 4:18 AM
To: mikuback@linux.microsoft.com; devel@edk2.groups.io; Dong, Guo
<guo.dong@intel.com>
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>
Subject: RE: [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI
FVB services

Guo,
I remember you mentioned to me there is a standard way to manipulate the
flash storage because there is a HW between the SW and the real flash that
does the command translation.
Is this change related to the standard way what you mentioned to me?
If yes, can you please help to review and provide comments?

Michael,
Having a universal implementation for SPI access is wonderful! Can you
please share the documentation that explain the Intel Serial Flash Interface
Compatibility spec?

-----Original Message-----
From: mikuback@linux.microsoft.com <mikuback@linux.microsoft.com>
Sent: Friday, April 16, 2021 10:31 AM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
<rangasai.v.chaganty@intel.com>
Subject: [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI
FVB services

From: Michael Kubacki <michael.kubacki@microsoft.com>

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

Adds a Traditional MM and Standalone MM SPI FVB Service driver to
IntelSiliconPkg. These drivers produce the firmware volume block
protocol for SPI flash devices compliant with the Intel Serial
Flash Interface Compatibility Specification.

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c
| 94 ++
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCom
mon.c | 903 ++++++++++++++++++++
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm.
c | 271 ++++++
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceStan
daloneMm.c | 32 +
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceTradi
tionalMm.c | 32 +
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCom
mon.h | 158 ++++
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm.
h | 22 +
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm
.inf | 68 ++
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceStan
daloneMm.inf | 67 ++
Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc | 11 +
10 files changed, 1658 insertions(+)

diff --git
a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c
new file mode 100644
index 000000000000..7f2678fa9e5a
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c
@@ -0,0 +1,94 @@
+/**@file
+ Defines data structure that is the volume header found.
+ These data is intent to decouple FVB driver with FV header.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SpiFvbServiceCommon.h"
+
+#define FIRMWARE_BLOCK_SIZE 0x10000
+#define FVB_MEDIA_BLOCK_SIZE FIRMWARE_BLOCK_SIZE
+
+#define NV_STORAGE_BASE_ADDRESS
FixedPcdGet32(PcdFlashNvStorageVariableBase)
+#define SYSTEM_NV_BLOCK_NUM
((FixedPcdGet32(PcdFlashNvStorageVariableSize)+
FixedPcdGet32(PcdFlashNvStorageFtwWorkingSize) +
FixedPcdGet32(PcdFlashNvStorageFtwSpareSize))/
FVB_MEDIA_BLOCK_SIZE)
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ EFI_FIRMWARE_VOLUME_HEADER FvbInfo;
+ EFI_FV_BLOCK_MAP_ENTRY End[1];
+} EFI_FVB2_MEDIA_INFO;
+
+//
+// This data structure contains a template of all correct FV headers, which
is used to restore
+// Fv header if it's corrupted.
+//
+EFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] = {
+ //
+ // Systen NvStorage FVB
+ //
+ {
+ NV_STORAGE_BASE_ADDRESS,
+ {
+ {0,}, //ZeroVector[16]
+ EFI_SYSTEM_NV_DATA_FV_GUID,
+ FVB_MEDIA_BLOCK_SIZE * SYSTEM_NV_BLOCK_NUM,
+ EFI_FVH_SIGNATURE,
+ 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for
details on EFI_FVB_ATTRIBUTES_2
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof
(EFI_FV_BLOCK_MAP_ENTRY),
+ 0, //CheckSum which will be calucated dynamically.
+ 0, //ExtHeaderOffset
+ {0,}, //Reserved[1]
+ 2, //Revision
+ {
+ {
+ SYSTEM_NV_BLOCK_NUM,
+ FVB_MEDIA_BLOCK_SIZE,
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+ }
+};
+
+EFI_STATUS
+GetFvbInfo (
+ IN EFI_PHYSICAL_ADDRESS FvBaseAddress,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
+ )
+{
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+
+ for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof
(EFI_FVB2_MEDIA_INFO); Index++) {
+ if (mPlatformFvbMediaInfo[Index].BaseAddress == FvBaseAddress) {
+ FvHeader = &mPlatformFvbMediaInfo[Index].FvbInfo;
+
+ //
+ // Update the checksum value of FV header.
+ //
+ FvHeader->Checksum = CalculateCheckSum16 ( (UINT16 *) FvHeader,
FvHeader->HeaderLength);
+
+ *FvbInfo = FvHeader;
+
+ DEBUG ((DEBUG_INFO, "BaseAddr: 0x%lx \n", FvBaseAddress));
+ DEBUG ((DEBUG_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength));
+ DEBUG ((DEBUG_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)-
HeaderLength));
+ DEBUG ((DEBUG_INFO, "Header Checksum: 0x%X\n", (*FvbInfo)-
Checksum));
+ DEBUG ((DEBUG_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n",
(*FvbInfo)->BlockMap[0].NumBlocks));
+ DEBUG ((DEBUG_INFO, "FvBlockMap[0].BlockLength: 0x%x \n",
(*FvbInfo)->BlockMap[0].Length));
+ DEBUG ((DEBUG_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n",
(*FvbInfo)->BlockMap[1].NumBlocks));
+ DEBUG ((DEBUG_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n",
(*FvbInfo)->BlockMap[1].Length));
+
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
diff --git
a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
mmon.c
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
mmon.c
new file mode 100644
index 000000000000..dab818e98087
--- /dev/null
+++
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
mmon.c
@@ -0,0 +1,903 @@
+/** @file
+ Common driver source for several Serial Flash devices
+ which are compliant with the Intel(R) Serial Flash Interface Compatibility
Specification.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SpiFvbServiceCommon.h"
+
+//
+// Global variable for this FVB driver which contains
+// the private data of all firmware volume block instances
+//
+FVB_GLOBAL mFvbModuleGlobal;
+
+//
+// This platform driver knows there are multiple FVs on FD.
+// Now we only provide FVs on Variable region and MicorCode region for
performance issue.
+//
+FV_INFO mPlatformFvBaseAddress[] = {
+ {0, 0}, // {FixedPcdGet32(PcdFlashNvStorageVariableBase),
FixedPcdGet32(PcdFlashNvStorageVariableSize)},
+ {0, 0}, // {FixedPcdGet32(PcdFlashMicrocodeFvBase),
FixedPcdGet32(PcdFlashMicrocodeFvSize)},
+ {0, 0}
+};
+
+FV_INFO mPlatformDefaultBaseAddress[] = {
+ {0, 0}, // {FixedPcdGet32(PcdFlashNvStorageVariableBase),
FixedPcdGet32(PcdFlashNvStorageVariableSize)},
+ {0, 0}, // {FixedPcdGet32(PcdFlashMicrocodeFvBase),
FixedPcdGet32(PcdFlashMicrocodeFvSize)},
+ {0, 0}
+};
+
+FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ {
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
+ }
+ },
+ EfiMemoryMappedIO,
+ (EFI_PHYSICAL_ADDRESS) 0,
+ (EFI_PHYSICAL_ADDRESS) 0,
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {
+ {
+ {
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_VOL_DP,
+ {
+ (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),
+ (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)
+ }
+ },
+ { 0 }
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+//
+// Template structure used when installing FVB protocol
+//
+EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL mFvbProtocolTemplate = {
+ FvbProtocolGetAttributes,
+ FvbProtocolSetAttributes,
+ FvbProtocolGetPhysicalAddress,
+ FvbProtocolGetBlockSize,
+ FvbProtocolRead,
+ FvbProtocolWrite,
+ FvbProtocolEraseBlocks,
+ NULL
+};
+
+/**
+ Get the EFI_FVB_ATTRIBUTES_2 of a FV.
+
+ @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE.
+
+ @return Attributes of the FV identified by FvbInstance.
+
+**/
+EFI_FVB_ATTRIBUTES_2
+FvbGetVolumeAttributes (
+ IN EFI_FVB_INSTANCE *FvbInstance
+ )
+{
+ return FvbInstance->FvHeader.Attributes;
+}
+
+/**
+ Retrieves the starting address of an LBA in an FV. It also
+ return a few other attribut of the FV.
+
+ @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE.
+ @param[in] Lba The logical block address
+ @param[out] LbaAddress On output, contains the physical starting
address
+ of the Lba
+ @param[out] LbaLength On output, contains the length of the block
+ @param[out] NumOfBlocks A pointer to a caller allocated UINTN in
which the
+ number of consecutive blocks starting with Lba is
+ returned. All blocks in this range have a size of
+ BlockSize
+
+ @retval EFI_SUCCESS Successfully returns
+ @retval EFI_INVALID_PARAMETER Instance not found
+
+**/
+EFI_STATUS
+FvbGetLbaAddress (
+ IN EFI_FVB_INSTANCE *FvbInstance,
+ IN EFI_LBA Lba,
+ OUT UINTN *LbaAddress,
+ OUT UINTN *LbaLength,
+ OUT UINTN *NumOfBlocks
+ )
+{
+ UINT32 NumBlocks;
+ UINT32 BlockLength;
+ UINTN Offset;
+ EFI_LBA StartLba;
+ EFI_LBA NextLba;
+ EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
+
+ StartLba = 0;
+ Offset = 0;
+ BlockMap = &(FvbInstance->FvHeader.BlockMap[0]);
+
+ //
+ // Parse the blockmap of the FV to find which map entry the Lba belongs
to
+ //
+ while (TRUE) {
+ NumBlocks = BlockMap->NumBlocks;
+ BlockLength = BlockMap->Length;
+
+ if ( NumBlocks == 0 || BlockLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NextLba = StartLba + NumBlocks;
+
+ //
+ // The map entry found
+ //
+ if (Lba >= StartLba && Lba < NextLba) {
+ Offset = Offset + (UINTN)MultU64x32((Lba - StartLba), BlockLength);
+ if (LbaAddress ) {
+ *LbaAddress = FvbInstance->FvBase + Offset;
+ }
+
+ if (LbaLength ) {
+ *LbaLength = BlockLength;
+ }
+
+ if (NumOfBlocks ) {
+ *NumOfBlocks = (UINTN)(NextLba - Lba);
+ }
+ return EFI_SUCCESS;
+ }
+
+ StartLba = NextLba;
+ Offset = Offset + NumBlocks * BlockLength;
+ BlockMap++;
+ }
+}
+
+/**
+ Reads specified number of bytes into a buffer from the specified block.
+
+ @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE
+ @param[in] Lba The logical block address to be read from
+ @param[in] BlockOffset Offset into the block at which to begin
reading
+ @param[in] NumBytes Pointer that on input contains the total
size of
+ the buffer. On output, it contains the total number
+ of bytes read
+ @param[in] Buffer Pointer to a caller allocated buffer that will
be
+ used to hold the data read
+
+
+ @retval EFI_SUCCESS The firmware volume was read
successfully and
+ contents are in Buffer
+ @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA
boundary. On output,
+ NumBytes contains the total number of bytes
returned
+ in Buffer
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
ReadDisabled state
+ @retval EFI_DEVICE_ERROR The block device is not functioning
correctly and
+ could not be read
+ @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes,
Buffer are NULL
+
+**/
+EFI_STATUS
+FvbReadBlock (
+ IN EFI_FVB_INSTANCE *FvbInstance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN LbaAddress;
+ UINTN LbaLength;
+ EFI_STATUS Status;
+ BOOLEAN BadBufferSize = FALSE;
+
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (*NumBytes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FvbGetLbaAddress (FvbInstance, Lba, &LbaAddress,
&LbaLength, NULL);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Attributes = FvbGetVolumeAttributes (FvbInstance);
+
+ if ((Attributes & EFI_FVB2_READ_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ if (BlockOffset > LbaLength) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (LbaLength < (*NumBytes + BlockOffset)) {
+ DEBUG ((DEBUG_INFO,
+ "FvReadBlock: Reducing Numbytes from 0x%x to 0x%x\n",
+ *NumBytes,
+ (UINT32)(LbaLength - BlockOffset))
+ );
+ *NumBytes = (UINT32) (LbaLength - BlockOffset);
+ BadBufferSize = TRUE;
+ }
+
+ Status = SpiFlashRead (LbaAddress + BlockOffset, (UINT32 *)NumBytes,
Buffer);
+
+ if (!EFI_ERROR (Status) && BadBufferSize) {
+ return EFI_BAD_BUFFER_SIZE;
+ } else {
+ return Status;
+ }
+}
+
+/**
+ Writes specified number of bytes from the input buffer to the block.
+
+ @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE
+ @param[in] Lba The starting logical block index to write to
+ @param[in] BlockOffset Offset into the block at which to begin
writing
+ @param[in] NumBytes Pointer that on input contains the total
size of
+ the buffer. On output, it contains the total number
+ of bytes actually written
+ @param[in] Buffer Pointer to a caller allocated buffer that
contains
+ the source for the write
+ @retval EFI_SUCCESS The firmware volume was written
successfully
+ @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA
boundary. On output,
+ NumBytes contains the total number of bytes
+ actually written
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
WriteDisabled state
+ @retval EFI_DEVICE_ERROR The block device is not functioning
correctly and
+ could not be written
+ @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes,
Buffer are NULL
+
+**/
+EFI_STATUS
+FvbWriteBlock (
+ IN EFI_FVB_INSTANCE *FvbInstance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN LbaAddress;
+ UINTN LbaLength;
+ EFI_STATUS Status;
+ BOOLEAN BadBufferSize = FALSE;
+
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (*NumBytes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FvbGetLbaAddress (FvbInstance, Lba, &LbaAddress,
&LbaLength, NULL);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Check if the FV is write enabled
+ //
+ Attributes = FvbGetVolumeAttributes (FvbInstance);
+ if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // Perform boundary checks and adjust NumBytes
+ //
+ if (BlockOffset > LbaLength) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (LbaLength < (*NumBytes + BlockOffset)) {
+ DEBUG ((DEBUG_INFO,
+ "FvWriteBlock: Reducing Numbytes from 0x%x to 0x%x\n",
+ *NumBytes,
+ (UINT32)(LbaLength - BlockOffset))
+ );
+ *NumBytes = (UINT32) (LbaLength - BlockOffset);
+ BadBufferSize = TRUE;
+ }
+
+ Status = SpiFlashWrite (LbaAddress + BlockOffset, (UINT32 *)NumBytes,
Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = SpiFlashLock ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ WriteBackInvalidateDataCacheRange ((VOID *) (LbaAddress +
BlockOffset), *NumBytes);
+
+ if (!EFI_ERROR (Status) && BadBufferSize) {
+ return EFI_BAD_BUFFER_SIZE;
+ } else {
+ return Status;
+ }
+}
+
+
+
+/**
+ Erases and initializes a firmware volume block.
+
+ @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE
+ @param[in] Lba The logical block index to be erased
+
+ @retval EFI_SUCCESS The erase request was successfully
completed
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
WriteDisabled state
+ @retval EFI_DEVICE_ERROR The block device is not functioning
correctly and
+ could not be written. Firmware device may have been
+ partially erased
+ @retval EFI_INVALID_PARAMETER Instance not found
+
+**/
+EFI_STATUS
+FvbEraseBlock (
+ IN EFI_FVB_INSTANCE *FvbInstance,
+ IN EFI_LBA Lba
+ )
+{
+
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN LbaAddress;
+ UINTN LbaLength;
+ EFI_STATUS Status;
+
+ //
+ // Check if the FV is write enabled
+ //
+ Attributes = FvbGetVolumeAttributes (FvbInstance);
+
+ if( (Attributes & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // Get the starting address of the block for erase.
+ //
+ Status = FvbGetLbaAddress (FvbInstance, Lba, &LbaAddress,
&LbaLength, NULL);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = SpiFlashBlockErase (LbaAddress, &LbaLength);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = SpiFlashLock ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ WriteBackInvalidateDataCacheRange ((VOID *) LbaAddress, LbaLength);
+
+ return Status;
+}
+
+/**
+ Modifies the current settings of the firmware volume according to the
+ input parameter, and returns the new setting of the volume
+
+ @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE.
+ @param[in] Attributes On input, it is a pointer to
EFI_FVB_ATTRIBUTES_2
+ containing the desired firmware volume settings.
+ On successful return, it contains the new settings
+ of the firmware volume
+
+ @retval EFI_SUCCESS Successfully returns
+ @retval EFI_ACCESS_DENIED The volume setting is locked and
cannot be modified
+ @retval EFI_INVALID_PARAMETER Instance not found, or The
attributes requested are
+ in conflict with the capabilities as declared in the
+ firmware volume header
+
+**/
+EFI_STATUS
+FvbSetVolumeAttributes (
+ IN EFI_FVB_INSTANCE *FvbInstance,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+{
+ EFI_FVB_ATTRIBUTES_2 OldAttributes;
+ EFI_FVB_ATTRIBUTES_2 *AttribPtr;
+ EFI_FVB_ATTRIBUTES_2 UnchangedAttributes;
+ UINT32 Capabilities;
+ UINT32 OldStatus, NewStatus;
+
+ AttribPtr = (EFI_FVB_ATTRIBUTES_2 *) &(FvbInstance-
FvHeader.Attributes);
+ OldAttributes = *AttribPtr;
+ Capabilities = OldAttributes & EFI_FVB2_CAPABILITIES;
+ OldStatus = OldAttributes & EFI_FVB2_STATUS;
+ NewStatus = *Attributes & EFI_FVB2_STATUS;
+
+ UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP | \
+ EFI_FVB2_READ_ENABLED_CAP | \
+ EFI_FVB2_WRITE_DISABLED_CAP | \
+ EFI_FVB2_WRITE_ENABLED_CAP | \
+ EFI_FVB2_LOCK_CAP | \
+ EFI_FVB2_STICKY_WRITE | \
+ EFI_FVB2_MEMORY_MAPPED | \
+ EFI_FVB2_ERASE_POLARITY | \
+ EFI_FVB2_READ_LOCK_CAP | \
+ EFI_FVB2_WRITE_LOCK_CAP | \
+ EFI_FVB2_ALIGNMENT;
+
+ //
+ // Some attributes of FV is read only can *not* be set
+ //
+ if ((OldAttributes & UnchangedAttributes) ^ (*Attributes &
UnchangedAttributes)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If firmware volume is locked, no status bit can be updated
+ //
+ if ( OldAttributes & EFI_FVB2_LOCK_STATUS ) {
+ if ( OldStatus ^ NewStatus ) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+
+ //
+ // Test read disable
+ //
+ if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) {
+ if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Test read enable
+ //
+ if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_READ_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Test write disable
+ //
+ if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) {
+ if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Test write enable
+ //
+ if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_WRITE_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Test lock
+ //
+ if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_LOCK_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS));
+ *AttribPtr = (*AttribPtr) | NewStatus;
+ *Attributes = *AttribPtr;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Check the integrity of firmware volume header
+
+ @param[in] FvHeader A pointer to a firmware volume header
+
+ @retval TRUE The firmware volume is consistent
+ @retval FALSE The firmware volume has corrupted.
+
+**/
+BOOLEAN
+IsFvHeaderValid (
+ IN EFI_PHYSICAL_ADDRESS FvBase,
+ IN CONST EFI_FIRMWARE_VOLUME_HEADER *FvHeader
+ )
+{
+ if (FvBase == PcdGet32(PcdFlashNvStorageVariableBase)) {
+ if (CompareMem (&FvHeader->FileSystemGuid,
&gEfiSystemNvDataFvGuid, sizeof(EFI_GUID)) != 0 ) {
+ return FALSE;
+ }
+ } else {
+ if (CompareMem (&FvHeader->FileSystemGuid,
&gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
+ return FALSE;
+ }
+ }
+ if ( (FvHeader->Revision != EFI_FVH_REVISION) ||
+ (FvHeader->Signature != EFI_FVH_SIGNATURE) ||
+ (FvHeader->FvLength == ((UINTN) -1)) ||
+ ((FvHeader->HeaderLength & 0x01 ) !=0) ) {
+ return FALSE;
+ }
+
+ if (CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader-
HeaderLength) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//
+// FVB protocol APIs
+//
+
+/**
+ Retrieves the physical address of the device.
+
+ @param[in] This A pointer to
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL.
+ @param[out] Address Output buffer containing the address.
+
+ retval EFI_SUCCESS The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+{
+ EFI_FVB_INSTANCE *FvbInstance;
+
+ FvbInstance = FVB_INSTANCE_FROM_THIS (This);
+
+ *Address = FvbInstance->FvBase;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieve the size of a logical block
+
+ @param[in] This Calling context
+ @param[in] Lba Indicates which block to return the size for.
+ @param[out] BlockSize A pointer to a caller allocated UINTN in which
+ the size of the block is returned
+ @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which
the
+ number of consecutive blocks starting with Lba is
+ returned. All blocks in this range have a size of
+ BlockSize
+
+ @retval EFI_SUCCESS The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumOfBlocks
+ )
+{
+ EFI_FVB_INSTANCE *FvbInstance;
+
+ FvbInstance = FVB_INSTANCE_FROM_THIS (This);
+
+ DEBUG((DEBUG_INFO,
+ "FvbProtocolGetBlockSize: Lba: 0x%lx BlockSize: 0x%x NumOfBlocks:
0x%x\n",
+ Lba,
+ BlockSize,
+ NumOfBlocks)
+ );
+
+ return FvbGetLbaAddress (
+ FvbInstance,
+ Lba,
+ NULL,
+ BlockSize,
+ NumOfBlocks
+ );
+}
+
+/**
+ Retrieves Volume attributes. No polarity translations are done.
+
+ @param[in] This Calling context
+ @param[out] Attributes Output buffer which contains attributes
+
+ @retval EFI_SUCCESS The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+{
+ EFI_FVB_INSTANCE *FvbInstance;
+
+ FvbInstance = FVB_INSTANCE_FROM_THIS (This);
+
+ *Attributes = FvbGetVolumeAttributes (FvbInstance);
+
+ DEBUG ((DEBUG_INFO,
+ "FvbProtocolGetAttributes: This: 0x%x Attributes: 0x%x\n",
+ This,
+ *Attributes)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets Volume attributes. No polarity translations are done.
+
+ @param[in] This Calling context
+ @param[out] Attributes Output buffer which contains attributes
+
+ @retval EFI_SUCCESS The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+{
+ EFI_STATUS Status;
+ EFI_FVB_INSTANCE *FvbInstance;
+
+ DEBUG((DEBUG_INFO,
+ "FvbProtocolSetAttributes: Before SET - This: 0x%x Attributes: 0x%x\n",
+ This,
+ *Attributes)
+ );
+
+ FvbInstance = FVB_INSTANCE_FROM_THIS (This);
+
+ Status = FvbSetVolumeAttributes (FvbInstance, Attributes);
+
+ DEBUG((DEBUG_INFO,
+ "FvbProtocolSetAttributes: After SET - This: 0x%x Attributes: 0x%x\n",
+ This,
+ *Attributes)
+ );
+
+ return Status;
+}
+
+/**
+ The EraseBlock() function erases one or more blocks as denoted by the
+ variable argument list. The entire parameter list of blocks must be
verified
+ prior to erasing any blocks. If a block is requested that does not exist
+ within the associated firmware volume (it has a larger index than the last
+ block of the firmware volume), the EraseBlock() function must return
+ EFI_INVALID_PARAMETER without modifying the contents of the
firmware volume.
+
+ @param[in] This Calling context
+ @param[in] ... Starting LBA followed by Number of Lba to erase.
+ a -1 to terminate the list.
+
+ @retval EFI_SUCCESS The erase request was successfully completed
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
WriteDisabled state
+ @retval EFI_DEVICE_ERROR The block device is not functioning correctly
and
+ could not be written. Firmware device may have been
+ partially erased
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ )
+{
+ EFI_FVB_INSTANCE *FvbInstance;
+ UINTN NumOfBlocks;
+ VA_LIST Args;
+ EFI_LBA StartingLba;
+ UINTN NumOfLba;
+ EFI_STATUS Status;
+
+ DEBUG((DEBUG_INFO, "FvbProtocolEraseBlocks: \n"));
+
+ FvbInstance = FVB_INSTANCE_FROM_THIS (This);
+
+ NumOfBlocks = FvbInstance->NumOfBlocks;
+
+ VA_START (Args, This);
+
+ do {
+ StartingLba = VA_ARG (Args, EFI_LBA);
+ if ( StartingLba == EFI_LBA_LIST_TERMINATOR ) {
+ break;
+ }
+
+ NumOfLba = VA_ARG (Args, UINT32);
+
+ //
+ // Check input parameters
+ //
+ if (NumOfLba == 0) {
+ VA_END (Args);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( ( StartingLba + NumOfLba ) > NumOfBlocks ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } while ( 1 );
+
+ VA_END (Args);
+
+ VA_START (Args, This);
+ do {
+ StartingLba = VA_ARG (Args, EFI_LBA);
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+ break;
+ }
+
+ NumOfLba = VA_ARG (Args, UINT32);
+
+ while ( NumOfLba > 0 ) {
+ Status = FvbEraseBlock (FvbInstance, StartingLba);
+ if ( EFI_ERROR(Status)) {
+ VA_END (Args);
+ return Status;
+ }
+ StartingLba ++;
+ NumOfLba --;
+ }
+
+ } while ( 1 );
+
+ VA_END (Args);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Writes data beginning at Lba:Offset from FV. The write terminates either
+ when *NumBytes of data have been written, or when a block boundary
is
+ reached. *NumBytes is updated to reflect the actual number of bytes
+ written. The write opertion does not include erase. This routine will
+ attempt to write only the specified bytes. If the writes do not stick,
+ it will return an error.
+
+ @param[in] This Calling context
+ @param[in] Lba Block in which to begin write
+ @param[in] Offset Offset in the block at which to begin write
+ @param[in,out] NumBytes On input, indicates the requested write size.
On
+ output, indicates the actual number of bytes written
+ @param[in] Buffer Buffer containing source data for the write.
+
+ @retval EFI_SUCCESS The firmware volume was written successfully
+ @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary.
On output,
+ NumBytes contains the total number of bytes
+ actually written
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
WriteDisabled state
+ @retval EFI_DEVICE_ERROR The block device is not functioning
correctly and
+ could not be written
+ @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_FVB_INSTANCE *FvbInstance;
+
+ FvbInstance = FVB_INSTANCE_FROM_THIS (This);
+
+ DEBUG((DEBUG_INFO,
+ "FvbProtocolWrite: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer:
0x%x\n",
+ Lba,
+ Offset,
+ *NumBytes,
+ Buffer)
+ );
+
+ return FvbWriteBlock (FvbInstance, Lba, Offset, NumBytes, Buffer);
+}
+
+/**
+ Reads data beginning at Lba:Offset from FV. The Read terminates either
+ when *NumBytes of data have been read, or when a block boundary is
+ reached. *NumBytes is updated to reflect the actual number of bytes
+ written. The write opertion does not include erase. This routine will
+ attempt to write only the specified bytes. If the writes do not stick,
+ it will return an error.
+
+ @param[in] This Calling context
+ @param[in] Lba Block in which to begin write
+ @param[in] Offset Offset in the block at which to begin write
+ @param[in,out] NumBytes On input, indicates the requested write size.
On
+ output, indicates the actual number of bytes written
+ @param[in] Buffer Buffer containing source data for the write.
+
+ @retval EFI_SUCCESS The firmware volume was read successfully
and
+ contents are in Buffer
+ @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary.
On output,
+ NumBytes contains the total number of bytes returned
+ in Buffer
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
ReadDisabled state
+ @retval EFI_DEVICE_ERROR The block device is not functioning
correctly and
+ could not be read
+ @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ OUT UINT8 *Buffer
+ )
+{
+ EFI_FVB_INSTANCE *FvbInstance;
+ EFI_STATUS Status;
+
+ FvbInstance = FVB_INSTANCE_FROM_THIS (This);
+ Status = FvbReadBlock (FvbInstance, Lba, Offset, NumBytes, Buffer);
+ DEBUG((DEBUG_INFO,
+ "FvbProtocolRead: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer:
0x%x\n",
+ Lba,
+ Offset,
+ *NumBytes,
+ Buffer)
+ );
+
+ return Status;
+}
diff --git
a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
m.c
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
m.c
new file mode 100644
index 000000000000..42a0828c6fae
--- /dev/null
+++
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
m.c
@@ -0,0 +1,271 @@
+/** @file
+ MM driver source for several Serial Flash devices
+ which are compliant with the Intel(R) Serial Flash Interface Compatibility
Specification.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SpiFvbServiceCommon.h"
+#include <Library/MmServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Protocol/SmmFirmwareVolumeBlock.h>
+
+/**
+ The function installs EFI_FIRMWARE_VOLUME_BLOCK protocol
+ for each FV in the system.
+
+ @param[in] FvbInstance The pointer to a FW volume instance structure,
+ which contains the information about one FV.
+
+ @retval VOID
+
+**/
+VOID
+InstallFvbProtocol (
+ IN EFI_FVB_INSTANCE *FvbInstance
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_STATUS Status;
+ EFI_HANDLE FvbHandle;
+
+ ASSERT (FvbInstance != NULL);
+ if (FvbInstance == NULL) {
+ return;
+ }
+
+ CopyMem (&FvbInstance->FvbProtocol, &mFvbProtocolTemplate, sizeof
(EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL));
+
+ FvHeader = &FvbInstance->FvHeader;
+ if (FvHeader == NULL) {
+ return;
+ }
+
+ //
+ // Set up the devicepath
+ //
+ DEBUG ((DEBUG_INFO, "FwBlockService.c: Setting up DevicePath for
0x%lx:\n", FvbInstance->FvBase));
+ if (FvHeader->ExtHeaderOffset == 0) {
+ //
+ // FV does not contains extension header, then produce
MEMMAP_DEVICE_PATH
+ //
+ FvbInstance->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)
AllocateRuntimeCopyPool (sizeof
(FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
+ if (FvbInstance->DevicePath == NULL) {
+ DEBUG ((DEBUG_INFO, "SpiFvbServiceSmm.c: Memory allocation for
MEMMAP_DEVICE_PATH failed\n"));
+ return;
+ }
+ ((FV_MEMMAP_DEVICE_PATH *) FvbInstance->DevicePath)-
MemMapDevPath.StartingAddress = FvbInstance->FvBase;
+ ((FV_MEMMAP_DEVICE_PATH *) FvbInstance->DevicePath)-
MemMapDevPath.EndingAddress = FvbInstance->FvBase +
FvHeader->FvLength - 1;
+ } else {
+ FvbInstance->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)
AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH),
&mFvPIWGDevicePathTemplate);
+ if (FvbInstance->DevicePath == NULL) {
+ DEBUG ((DEBUG_INFO, "SpiFvbServiceSmm.c: Memory allocation for
FV_PIWG_DEVICE_PATH failed\n"));
+ return;
+ }
+ CopyGuid (
+ &((FV_PIWG_DEVICE_PATH *)FvbInstance->DevicePath)-
FvDevPath.FvName,
+ (GUID *)(UINTN)(FvbInstance->FvBase + FvHeader->ExtHeaderOffset)
+ );
+ }
+
+ //
+ // LocateDevicePath fails so install a new interface and device path
+ //
+ FvbHandle = NULL;
+
+ Status = gMmst->MmInstallProtocolInterface (
+ &FvbHandle,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &(FvbInstance->FvbProtocol)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gMmst->MmInstallProtocolInterface (
+ &FvbHandle,
+ &gEfiDevicePathProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &(FvbInstance->DevicePath)
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ The function does the necessary initialization work for
+ Firmware Volume Block Driver.
+
+**/
+VOID
+FvbInitialize (
+ VOID
+ )
+{
+ EFI_FVB_INSTANCE *FvbInstance;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ UINTN Idx;
+ UINT32 MaxLbaSize;
+ UINT32 BytesWritten;
+ UINTN BytesErased;
+
+ mPlatformFvBaseAddress[0].FvBase =
PcdGet32(PcdFlashNvStorageVariableBase);
+ mPlatformFvBaseAddress[0].FvSize =
PcdGet32(PcdFlashNvStorageVariableSize);
+ mPlatformFvBaseAddress[1].FvBase =
PcdGet32(PcdFlashMicrocodeFvBase);
+ mPlatformFvBaseAddress[1].FvSize =
PcdGet32(PcdFlashMicrocodeFvSize);
+ mPlatformDefaultBaseAddress[0].FvBase =
PcdGet32(PcdFlashNvStorageVariableBase);
+ mPlatformDefaultBaseAddress[0].FvSize =
PcdGet32(PcdFlashNvStorageVariableSize);
+ mPlatformDefaultBaseAddress[1].FvBase =
PcdGet32(PcdFlashMicrocodeFvBase);
+ mPlatformDefaultBaseAddress[1].FvSize =
PcdGet32(PcdFlashMicrocodeFvSize);
+
+ //
+ // We will only continue with FVB installation if the
+ // SPI is the active BIOS state
+ //
+ {
+ //
+ // Make sure all FVB are valid and/or fix if possible
+ //
+ for (Idx = 0;; Idx++) {
+ if (mPlatformFvBaseAddress[Idx].FvSize == 0 &&
mPlatformFvBaseAddress[Idx].FvBase == 0) {
+ break;
+ }
+
+ BaseAddress = mPlatformFvBaseAddress[Idx].FvBase;
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
BaseAddress;
+
+ if (!IsFvHeaderValid (BaseAddress, FvHeader)) {
+ BytesWritten = 0;
+ BytesErased = 0;
+ DEBUG ((DEBUG_ERROR, "ERROR - The FV in 0x%x is invalid!\n",
FvHeader));
+ Status = GetFvbInfo (BaseAddress, &FvHeader);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "ERROR - Can't recovery FV header at 0x%x.
GetFvbInfo Status %r\n", BaseAddress, Status));
+ continue;
+ }
+ DEBUG ((DEBUG_INFO, "Rewriting FV header at 0x%X with static
data\n", BaseAddress));
+ //
+ // Spi erase
+ //
+ BytesErased = (UINTN) FvHeader->BlockMap->Length;
+ Status = SpiFlashBlockErase( (UINTN) BaseAddress, &BytesErased);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "ERROR - SpiFlashBlockErase Error %r\n",
Status));
+ continue;
+ }
+ if (BytesErased != FvHeader->BlockMap->Length) {
+ DEBUG ((DEBUG_WARN, "ERROR - BytesErased != FvHeader-
BlockMap->Length\n"));
+ DEBUG ((DEBUG_INFO, " BytesErased = 0x%X\n Length = 0x%X\n",
BytesErased, FvHeader->BlockMap->Length));
+ continue;
+ }
+ BytesWritten = FvHeader->HeaderLength;
+ Status = SpiFlashWrite ((UINTN)BaseAddress, &BytesWritten,
(UINT8*)FvHeader);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "ERROR - SpiFlashWrite Error %r\n",
Status));
+ continue;
+ }
+ if (BytesWritten != FvHeader->HeaderLength) {
+ DEBUG ((DEBUG_WARN, "ERROR - BytesWritten !=
HeaderLength\n"));
+ DEBUG ((DEBUG_INFO, " BytesWritten = 0x%X\n HeaderLength =
0x%X\n", BytesWritten, FvHeader->HeaderLength));
+ continue;
+ }
+ Status = SpiFlashLock ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "ERROR - SpiFlashLock Error %r\n", Status));
+ continue;
+ }
+ DEBUG ((DEBUG_INFO, "FV Header @ 0x%X restored with static
data\n", BaseAddress));
+ //
+ // Clear cache for this range.
+ //
+ WriteBackInvalidateDataCacheRange ( (VOID *) (UINTN) BaseAddress,
FvHeader->BlockMap->Length);
+ }
+ }
+
+ //
+ // Calculate the total size for all firmware volume block instances
+ //
+ BufferSize = 0;
+ for (Idx = 0; ; Idx++) {
+ if (mPlatformFvBaseAddress[Idx].FvSize == 0 &&
mPlatformFvBaseAddress[Idx].FvBase == 0) {
+ break;
+ }
+ BaseAddress = mPlatformFvBaseAddress[Idx].FvBase;
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
BaseAddress;
+
+ if (!IsFvHeaderValid (BaseAddress, FvHeader)) {
+ DEBUG ((DEBUG_WARN, "ERROR - The FV in 0x%x is invalid!\n",
FvHeader));
+ continue;
+ }
+
+ BufferSize += (FvHeader->HeaderLength +
+ sizeof (EFI_FVB_INSTANCE) -
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER)
+ );
+ }
+
+ mFvbModuleGlobal.FvbInstance = (EFI_FVB_INSTANCE *)
AllocateRuntimeZeroPool (BufferSize);
+ if (mFvbModuleGlobal.FvbInstance == NULL) {
+ ASSERT (FALSE);
+ return;
+ }
+
+ MaxLbaSize = 0;
+ FvbInstance = mFvbModuleGlobal.FvbInstance;
+ mFvbModuleGlobal.NumFv = 0;
+
+ for (Idx = 0; ; Idx++) {
+ if (mPlatformFvBaseAddress[Idx].FvSize == 0 &&
mPlatformFvBaseAddress[Idx].FvBase == 0) {
+ break;
+ }
+ BaseAddress = mPlatformFvBaseAddress[Idx].FvBase;
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
BaseAddress;
+
+ if (!IsFvHeaderValid (BaseAddress, FvHeader)) {
+ DEBUG ((DEBUG_WARN, "ERROR - The FV in 0x%x is invalid!\n",
FvHeader));
+ continue;
+ }
+
+ FvbInstance->Signature = FVB_INSTANCE_SIGNATURE;
+ CopyMem (&(FvbInstance->FvHeader), FvHeader, FvHeader-
HeaderLength);
+
+ FvHeader = &(FvbInstance->FvHeader);
+ FvbInstance->FvBase = (UINTN)BaseAddress;
+
+ //
+ // Process the block map for each FV
+ //
+ FvbInstance->NumOfBlocks = 0;
+ for (PtrBlockMapEntry = FvHeader->BlockMap;
+ PtrBlockMapEntry->NumBlocks != 0;
+ PtrBlockMapEntry++) {
+ //
+ // Get the maximum size of a block.
+ //
+ if (MaxLbaSize < PtrBlockMapEntry->Length) {
+ MaxLbaSize = PtrBlockMapEntry->Length;
+ }
+ FvbInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks;
+ }
+
+ //
+ // Add a FVB Protocol Instance
+ //
+ InstallFvbProtocol (FvbInstance);
+ mFvbModuleGlobal.NumFv++;
+
+ //
+ // Move on to the next FvbInstance
+ //
+ FvbInstance = (EFI_FVB_INSTANCE *) ((UINTN)((UINT8 *)FvbInstance)
+
+ FvHeader->HeaderLength +
+ (sizeof (EFI_FVB_INSTANCE) - sizeof
(EFI_FIRMWARE_VOLUME_HEADER)));
+
+ }
+ }
+}
diff --git
a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
ndaloneMm.c
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
ndaloneMm.c
new file mode 100644
index 000000000000..252c818d6551
--- /dev/null
+++
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
ndaloneMm.c
@@ -0,0 +1,32 @@
+/** @file
+ MM driver source for several Serial Flash devices
+ which are compliant with the Intel(R) Serial Flash Interface Compatibility
Specification.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SpiFvbServiceCommon.h"
+#include "SpiFvbServiceMm.h"
+
+/**
+ The driver Standalone MM entry point.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] MmSystemTable A pointer to the MM system table.
+
+ @retval EFI_SUCCESS This function always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFvbStandaloneMmInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *MmSystemTable
+ )
+{
+ FvbInitialize ();
+
+ return EFI_SUCCESS;
+}
diff --git
a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceTra
ditionalMm.c
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceTra
ditionalMm.c
new file mode 100644
index 000000000000..1c2dac70e3c6
--- /dev/null
+++
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceTra
ditionalMm.c
@@ -0,0 +1,32 @@
+/** @file
+ MM driver source for several Serial Flash devices
+ which are compliant with the Intel(R) Serial Flash Interface Compatibility
Specification.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SpiFvbServiceCommon.h"
+#include "SpiFvbServiceMm.h"
+
+/**
+ The driver Traditional MM entry point.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable A pointer to the EFI system table.
+
+ @retval EFI_SUCCESS This function always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFvbTraditionalMmInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ FvbInitialize ();
+
+ return EFI_SUCCESS;
+}
diff --git
a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
mmon.h
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
mmon.h
new file mode 100644
index 000000000000..e9d69e985814
--- /dev/null
+++
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
mmon.h
@@ -0,0 +1,158 @@
+/** @file
+ Common source definitions used in serial flash drivers
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SPI_FVB_SERVICE_COMMON_H
+#define _SPI_FVB_SERVICE_COMMON_H
+
+#include <Guid/EventGroup.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Guid/SystemNvDataGuid.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HobLib.h>
+
+#include <Library/SpiFlashCommonLib.h>
+
+//
+// Define two helper macro to extract the Capability field or Status field in
FVB
+// bit fields
+//
+#define EFI_FVB2_CAPABILITIES (EFI_FVB2_READ_DISABLED_CAP | \
+ EFI_FVB2_READ_ENABLED_CAP | \
+ EFI_FVB2_WRITE_DISABLED_CAP | \
+ EFI_FVB2_WRITE_ENABLED_CAP | \
+ EFI_FVB2_LOCK_CAP \
+ )
+
+#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS |
EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS)
+
+#define FVB_INSTANCE_SIGNATURE SIGNATURE_32('F','V','B','I')
+
+typedef struct {
+ UINT32 Signature;
+ UINTN FvBase;
+ UINTN NumOfBlocks;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FvbProtocol;
+ EFI_FIRMWARE_VOLUME_HEADER FvHeader;
+} EFI_FVB_INSTANCE;
+
+typedef struct {
+ EFI_FVB_INSTANCE *FvbInstance;
+ UINT32 NumFv;
+} FVB_GLOBAL;
+
+//
+// Fvb Protocol instance data
+//
+#define FVB_INSTANCE_FROM_THIS(a) CR(a, EFI_FVB_INSTANCE,
FvbProtocol, FVB_INSTANCE_SIGNATURE)
+
+typedef struct {
+ MEDIA_FW_VOL_DEVICE_PATH FvDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_PIWG_DEVICE_PATH;
+
+typedef struct {
+ MEMMAP_DEVICE_PATH MemMapDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_MEMMAP_DEVICE_PATH;
+
+typedef struct {
+ UINT32 FvBase;
+ UINT32 FvSize;
+} FV_INFO;
+
+//
+// Protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumOfBlocks
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ OUT UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ );
+
+BOOLEAN
+IsFvHeaderValid (
+ IN EFI_PHYSICAL_ADDRESS FvBase,
+ IN CONST EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
+ );
+
+EFI_STATUS
+GetFvbInfo (
+ IN EFI_PHYSICAL_ADDRESS FvBaseAddress,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
+ );
+
+extern FVB_GLOBAL mFvbModuleGlobal;
+extern FV_MEMMAP_DEVICE_PATH
mFvMemmapDevicePathTemplate;
+extern FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate;
+extern EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
mFvbProtocolTemplate;
+extern FV_INFO mPlatformFvBaseAddress[];
+extern FV_INFO mPlatformDefaultBaseAddress[];
+
+#endif
diff --git
a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
m.h
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
m.h
new file mode 100644
index 000000000000..36af1130c8ee
--- /dev/null
+++
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
m.h
@@ -0,0 +1,22 @@
+/** @file
+ Definitions common to MM implementation in this driver.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SPI_FVB_SERVICE_MM_H_
+#define _SPI_FVB_SERVICE_MM_H_
+
+/**
+ The function does the necessary initialization work for
+ Firmware Volume Block Driver.
+
+**/
+VOID
+FvbInitialize (
+ VOID
+ );
+
+#endif
diff --git
a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSm
m.inf
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSm
m.inf
new file mode 100644
index 000000000000..bf1306f00201
--- /dev/null
+++
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSm
m.inf
@@ -0,0 +1,68 @@
+### @file
+# Component description file for the Serial Flash device Runtime driver.
+#
+# Copyright (c) 2017-2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) Microsoft Corporation.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = SpiFvbServiceSmm
+ FILE_GUID = 68A10D85-6858-4402-B070-028B3EA21747
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_SMM_DRIVER
+ PI_SPECIFICATION_VERSION = 1.10
+ ENTRY_POINT = SpiFvbTraditionalMmInitialize
+
+#
+# The following information is for reference only and not required by the
build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[LibraryClasses]
+ PcdLib
+ MemoryAllocationLib
+ CacheMaintenanceLib
+ BaseMemoryLib
+ DebugLib
+ BaseLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ SpiFlashCommonLib
+ MmServicesTableLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ##
CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
## CONSUMES
+ gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase ##
CONSUMES
+ gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize ##
CONSUMES
+
+[Sources]
+ FvbInfo.c
+ SpiFvbServiceCommon.h
+ SpiFvbServiceCommon.c
+ SpiFvbServiceMm.h
+ SpiFvbServiceMm.c
+ SpiFvbServiceTraditionalMm.c
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiSmmFirmwareVolumeBlockProtocolGuid ## PRODUCES
+
+[Guids]
+ gEfiFirmwareFileSystem2Guid ## CONSUMES
+ gEfiSystemNvDataFvGuid ## CONSUMES
+
+[Depex]
+ TRUE
diff --git
a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
ndaloneMm.inf
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
ndaloneMm.inf
new file mode 100644
index 000000000000..b66233968247
--- /dev/null
+++
b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
ndaloneMm.inf
@@ -0,0 +1,67 @@
+### @file
+# Component description file for the Serial Flash device Standalone MM
driver.
+#
+# Copyright (c) 2017-2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) Microsoft Corporation.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = SpiFvbServiceStandaloneMm
+ FILE_GUID = E6313655-8BD0-4EAB-B319-AD5E212CE6AB
+ VERSION_STRING = 1.0
+ MODULE_TYPE = MM_STANDALONE
+ PI_SPECIFICATION_VERSION = 0x00010032
+ ENTRY_POINT = SpiFvbStandaloneMmInitialize
+
+#
+# The following information is for reference only and not required by the
build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CacheMaintenanceLib
+ DebugLib
+ MemoryAllocationLib
+ PcdLib
+ MmServicesTableLib
+ SpiFlashCommonLib
+ StandaloneMmDriverEntryPoint
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ##
CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
## CONSUMES
+ gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase ##
CONSUMES
+ gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize ##
CONSUMES
+
+[Sources]
+ FvbInfo.c
+ SpiFvbServiceCommon.h
+ SpiFvbServiceCommon.c
+ SpiFvbServiceMm.h
+ SpiFvbServiceMm.c
+ SpiFvbServiceStandaloneMm.c
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiSmmFirmwareVolumeBlockProtocolGuid ## PRODUCES
+
+[Guids]
+ gEfiFirmwareFileSystem2Guid ## CONSUMES
+ gEfiSystemNvDataFvGuid ## CONSUMES
+
+[Depex]
+ TRUE
diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
index 7eb9c9def60a..7e446c97a5fb 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
@@ -40,6 +40,9 @@ [LibraryClasses]
PeiGetVtdPmrAlignmentLib|IntelSiliconPkg/Library/PeiGetVtdPmrAlignment
Lib/PeiGetVtdPmrAlignmentLib.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
mMeasurementLibNull.inf
MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
+
SpiFlashCommonLib|IntelSiliconPkg/Library/SpiFlashCommonLibNull/SpiFlas
hCommonLibNull.inf
+
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBo
otServicesTableLib.inf
+
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry
Point.inf

[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
@@ -61,8 +64,14 @@ [LibraryClasses.common.DXE_DRIVER]

[LibraryClasses.common.DXE_SMM_DRIVER]
MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMe
moryAllocationLib.inf
+
MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTabl
eLib.inf
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesT
ableLib.inf

+[LibraryClasses.common.MM_STANDALONE]
+
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAll
ocationLib/StandaloneMmMemoryAllocationLib.inf
+
MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Stan
daloneMmServicesTableLib.inf
+
StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntry
Point/StandaloneMmDriverEntryPoint.inf
+
##########################################################
#########################################
#
# Components Section - list of the modules and components that will be
processed by compilation
@@ -86,6 +95,8 @@ [Components]
IntelSiliconPkg/Library/DxeSmbiosDataHobLib/DxeSmbiosDataHobLib.inf
IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDevi
ceSecurityDxe.inf
IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/Sampl
ePlatformDevicePolicyDxe.inf
+ IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+
IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceStandaloneMm.in
f
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.inf
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
--
2.28.0.windows.1


Re: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

Yao, Jiewen
 

Hi Sachin
May I know why you hardcode PSS salt length to be RSA_PSS_SALTLEN_AUTO ?

Thank you
Yao Jiewen

-----Original Message-----
From: Agrawal, Sachin <sachin.agrawal@intel.com>
Sent: Tuesday, April 20, 2021 10:02 AM
To: devel@edk2.groups.io
Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>;
Lu, XiaoyuX <xiaoyux.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>;
Agrawal, Sachin <sachin.agrawal@intel.com>
Subject: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

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

This patch uses Openssl's EVP API's to perform RSASSA-PSS verification
of a binary blob.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>

Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
---
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 139
++++++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 43 ++++++
CryptoPkg/Include/Library/BaseCryptLib.h | 27 ++++
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
7 files changed, 213 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
new file mode 100644
index 000000000000..acf5eb689cd8
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
@@ -0,0 +1,139 @@
+/** @file
+ RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file implements following APIs which provide basic capabilities for RSA:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+
+/**
+ Retrieve a pointer to EVP message digest object.
+
+ @param[in] DigestLen Length of the message digest.
+
+**/
+static
+EVP_MD*
+GetEvpMD (
+ IN UINT16 DigestLen
+ )
+{
+ switch (DigestLen){
+ case SHA256_DIGEST_SIZE:
+ return EVP_sha256();
+ break;
+ case SHA384_DIGEST_SIZE:
+ return EVP_sha384();
+ break;
+ case SHA512_DIGEST_SIZE:
+ return EVP_sha512();
+ break;
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC
8017.
+ Implementation determines salt length automatically from the signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ BOOLEAN Result;
+ EVP_PKEY *pEvpRsaKey = NULL;
+ EVP_MD_CTX *pEvpVerifyCtx = NULL;
+ EVP_PKEY_CTX *pKeyCtx = NULL;
+ CONST EVP_MD *HashAlg = NULL;
+
+ if (RsaContext == NULL) {
+ return FALSE;
+ }
+ if (Message == NULL || MsgSize == 0 || MsgSize > INT_MAX) {
+ return FALSE;
+ }
+ if (Signature == NULL || SigSize == 0 || SigSize > INT_MAX) {
+ return FALSE;
+ }
+
+ HashAlg = GetEvpMD(DigestLen);
+
+ if (HashAlg == NULL) {
+ return FALSE;
+ }
+
+ pEvpRsaKey = EVP_PKEY_new();
+ if (pEvpRsaKey == NULL) {
+ goto _Exit;
+ }
+
+ EVP_PKEY_set1_RSA(pEvpRsaKey, RsaContext);
+
+ pEvpVerifyCtx = EVP_MD_CTX_create();
+ if (pEvpVerifyCtx == NULL) {
+ goto _Exit;
+ }
+
+ Result = EVP_DigestVerifyInit(pEvpVerifyCtx, &pKeyCtx, HashAlg, NULL,
pEvpRsaKey) > 0;
+ if (pKeyCtx == NULL) {
+ goto _Exit;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_padding(pKeyCtx,
RSA_PKCS1_PSS_PADDING) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx,
RSA_PSS_SALTLEN_AUTO) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestVerifyUpdate(pEvpVerifyCtx, Message,
(UINT32)MsgSize) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestVerifyFinal(pEvpVerifyCtx, Signature, (UINT32)SigSize) > 0;
+ }
+
+_Exit :
+ if (pEvpRsaKey) {
+ EVP_PKEY_free(pEvpRsaKey);
+ }
+ if (pEvpVerifyCtx) {
+ EVP_MD_CTX_destroy(pEvpVerifyCtx);
+ }
+
+ return Result;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
new file mode 100644
index 000000000000..8d84b4c1426c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
@@ -0,0 +1,43 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC
8017.
+ Implementation determines salt length automatically from the signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
b/CryptoPkg/Include/Library/BaseCryptLib.h
index 496121e6a4ed..36d560b8d691 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1363,6 +1363,33 @@ RsaPkcs1Verify (
IN UINTN SigSize
);

+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC
8017.
+ Implementation determines salt length automatically from the signature
encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ );
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.


[PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support

Agrawal, Sachin
 

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

This patch uses Openssl's EVP API's to perform RSASSA-PSS verification
of a binary blob.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>

Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
---
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 139 ++++++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 43 ++++++
CryptoPkg/Include/Library/BaseCryptLib.h | 27 ++++
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
7 files changed, 213 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
new file mode 100644
index 000000000000..acf5eb689cd8
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
@@ -0,0 +1,139 @@
+/** @file
+ RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file implements following APIs which provide basic capabilities for RSA:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+
+/**
+ Retrieve a pointer to EVP message digest object.
+
+ @param[in] DigestLen Length of the message digest.
+
+**/
+static
+EVP_MD*
+GetEvpMD (
+ IN UINT16 DigestLen
+ )
+{
+ switch (DigestLen){
+ case SHA256_DIGEST_SIZE:
+ return EVP_sha256();
+ break;
+ case SHA384_DIGEST_SIZE:
+ return EVP_sha384();
+ break;
+ case SHA512_DIGEST_SIZE:
+ return EVP_sha512();
+ break;
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC 8017.
+ Implementation determines salt length automatically from the signature encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ BOOLEAN Result;
+ EVP_PKEY *pEvpRsaKey = NULL;
+ EVP_MD_CTX *pEvpVerifyCtx = NULL;
+ EVP_PKEY_CTX *pKeyCtx = NULL;
+ CONST EVP_MD *HashAlg = NULL;
+
+ if (RsaContext == NULL) {
+ return FALSE;
+ }
+ if (Message == NULL || MsgSize == 0 || MsgSize > INT_MAX) {
+ return FALSE;
+ }
+ if (Signature == NULL || SigSize == 0 || SigSize > INT_MAX) {
+ return FALSE;
+ }
+
+ HashAlg = GetEvpMD(DigestLen);
+
+ if (HashAlg == NULL) {
+ return FALSE;
+ }
+
+ pEvpRsaKey = EVP_PKEY_new();
+ if (pEvpRsaKey == NULL) {
+ goto _Exit;
+ }
+
+ EVP_PKEY_set1_RSA(pEvpRsaKey, RsaContext);
+
+ pEvpVerifyCtx = EVP_MD_CTX_create();
+ if (pEvpVerifyCtx == NULL) {
+ goto _Exit;
+ }
+
+ Result = EVP_DigestVerifyInit(pEvpVerifyCtx, &pKeyCtx, HashAlg, NULL, pEvpRsaKey) > 0;
+ if (pKeyCtx == NULL) {
+ goto _Exit;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, RSA_PSS_SALTLEN_AUTO) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestVerifyUpdate(pEvpVerifyCtx, Message, (UINT32)MsgSize) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestVerifyFinal(pEvpVerifyCtx, Signature, (UINT32)SigSize) > 0;
+ }
+
+_Exit :
+ if (pEvpRsaKey) {
+ EVP_PKEY_free(pEvpRsaKey);
+ }
+ if (pEvpVerifyCtx) {
+ EVP_MD_CTX_destroy(pEvpVerifyCtx);
+ }
+
+ return Result;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
new file mode 100644
index 000000000000..8d84b4c1426c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
@@ -0,0 +1,43 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssVerify
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC 8017.
+ Implementation determines salt length automatically from the signature encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index 496121e6a4ed..36d560b8d691 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1363,6 +1363,33 @@ RsaPkcs1Verify (
IN UINTN SigSize
);

+/**
+ Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC 8017.
+ Implementation determines salt length automatically from the signature encoding.
+ Mask generation function is the same as the message digest algorithm.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Message Pointer to octet message to be verified.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+ @param[in] DigestLen Length of digest for RSA operation.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen
+ );
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.


[PATCH v1 0/1] CryptoPkg: Add RSA PSS verify support

Agrawal, Sachin
 

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

This patch uses Openssl's EVP API's to perform RSASSA-PSS verification
of a binary blob.

https://github.com/sagraw2/edk2/tree/pss_1

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>

Sachin Agrawal (1):
CryptoPkg: BaseCryptLib: Add RSA PSS verify support

CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 139 ++++++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 43 ++++++
CryptoPkg/Include/Library/BaseCryptLib.h | 27 ++++
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
7 files changed, 213 insertions(+)
create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c

--
2.14.3.windows.1


Re: The status of ACPI S4 support in OVMF

Gary Lin
 

On Mon, Apr 19, 2021 at 02:32:25PM +0200, Laszlo Ersek wrote:
On 04/19/21 11:54, Gary Lin via groups.io wrote:
Hi,

Years ago, the bug(*) for PEI variable driver was filed against OVMF
and it used to be one reason to block S4 support in OVMF. The bug is
fixed now, and there are several MemTypeInfo fixes merged into OVMF.

I'm curious about the current status of S4 support in OVMF. Is it
still considered as unsupported due to some other bugs?

Thanks,

Gary Lin

(*) https://bugzilla.tianocore.org/show_bug.cgi?id=386
I recall the last related discussion from February:

* [edk2-devel] [PATCH 0/2] Improve hibernation safety

https://edk2.groups.io/g/devel/message/71790
https://listman.redhat.com/archives/edk2-devel-archive/2021-February/msg00842.html
http://mid.mail-archive.com/20210218200953.20943-1-graf@amazon.com

No patches needed to be merged (Alex was missing some commits that had
been upstreamed by then).

My understanding is that S4 should work at this point, although I've
never really tested it myself.
Thanks for the information. I was reviewing the libvirt descriptor for
ovmf and wondering if it's ready for the "acpi-s4" tag. Maybe it's a
good to give it a try.

Thanks,

Gary Lin


TianoCore Bug Triage - APAC / NAMO - Tue, 04/20/2021 6:30pm-7:30pm #cal-reminder

devel@edk2.groups.io Calendar <devel@...>
 

Reminder: TianoCore Bug Triage - APAC / NAMO

When: Tuesday, 20 April 2021, 6:30pm to 7:30pm, (GMT-07:00) America/Los Angeles

Where:https://meetingsamer34.webex.com/meetingsamer34/j.php?MTID=mb96c5bd411bd010e1e6d43a6f6c65f45

View Event

Organizer: Liming Gao gaoliming@...

Description:

TianoCore Bug Triage - APAC / NAMO

Hosted by Liming Gao

 

https://meetingsamer34.webex.com/meetingsamer34/j.php?MTID=mb96c5bd411bd010e1e6d43a6f6c65f45

Wednesday, Jan 20, 2021 10:30 am | 50 minutes | (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi

Occurs every Wednesday effective 1/20/2021 from 10:30 AM to 11:20 AM, (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi

Meeting number: 126 867 1239

Password: ZhqYQunw246 (94797869 from video systems)

d8edc6c9604344b08f727b4bf054eaac_20210120T023000Z

 

Join by video system

Dial 1268671239@...

You can also dial 173.243.2.68 and enter your meeting number.

 

Join by phone

Use VoIP only


Re: [PATCH v2 1/1] UefiCpuPkg: PiSmmCpuDxeSmm: Not to Change Bitwidth During Static Paging

Ni, Ray
 

Reviewed-by: ray.ni@...


Re: [RFC PATCH 01/19] OvmfPkg: Reserve the Secrets and Cpuid page for the SEV-SNP guest

Brijesh Singh
 

On 4/13/21 4:49 AM, Laszlo Ersek wrote:
On 04/12/21 16:52, Brijesh Singh wrote:
Hi James and Laszlo,

I was planning to work to add the support to reserve the Secrets and
CPUID page in E820 map and then create the EFI configuration table entry
for it so that guest OS can reach to it. We have two packages
"SecretDxe" and "SecretPei" in OvmfPkg/AmdSev. Any issues if I use them
in the OvmfPkg.dsc ? Here is what I was thinking:

1) Rename the PcdSevLaunchSecretBase -> PcdSevSecretsBase

2) When SNP is enabled then VMM use this page as secrets page for the SNP

3) When SEV or SEV-ES is enabled then VMM uses this page as a launch
secret page

This will allow me to drop PcdOvmfSnpSecretsBase. This will not just
save 4-bytes but also minimize the code duplication.
I'm pretty unhappy about needing a separate page for each such purpose.
We're wasting room in MEMFD. The GUIDed structs that we expose to QEMU
seem to be flexible enough to describe non-page-aligned addresses,
right? Can we pack larger amounts of cruft into MEMFD pages?

I'm not looking forward to the day when we run out of slack in MEMFD and
we get to shift PEIFV / DXEFV. (Every time we need to increase the DXEFV
size, the same risk exists -- which is why I've been thinking for a
while now that OVMF includes too many features already.) This can
introduce obscure changes to the UEFI memory map, which has caused
compat problems in the past, for example with the "crash" utility.

What's your take to move all SEV-specific reserved pages at the end of
PcdOvmfDecompressionScratchEnd ? I have not tried yet, but I can give
try to make sure the ES works after such moves.

What is a general rule of thump to what goes in MEMFD ? Is this all the
data pages accessed during the SEC phase ? If so, then we probably can't
do everything after the PcdOvmfDecompressionScratchEnd. The only thing
which we can quickly move out is a secret page.


The feature creep in OVMF has gone off the rails in the last few years,
really. (Not that I'm not guilty myself.)

Thanks,
Laszlo


Re: [edk2-platforms][PATCH v1 26/35] CoffeelakeSiliconPkg: Remove SmmSpiFlashCommonLib

Michael Kubacki
 

Thanks for pointing this out. I'm not sure how, but it appears locally that patch 27 had an "ENQ" character introduced at the beginning of the patch file. This resulted in:

1. Actual patch 26 (correct): https://edk2.groups.io/g/devel/message/74179
2. This version of patch 27 (incorrect): https://edk2.groups.io/g/devel/message/74180 which retains the subject line from actual patch 26 ("CoffeelakeSiliconPkg...") but the contents from actual patch 27 (KabylakeSiliconPkg files modified).

Patch 27 should have had the subject "KabylakeSiliconPkg: Remove SmmSpiFlashCommonLib" (as indicated in the cover letter).

I am still collecting feedback on v1. I will check for this in the v2 patch files.

- Michael

On 4/19/2021 2:07 AM, Chiu, Chasel wrote:
Hi Michael,
Please rename subject to "KabylakeSiliconPkg".
With above change, Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
Thanks,
Chasel

-----Original Message-----
From: mikuback@linux.microsoft.com <mikuback@linux.microsoft.com>
Sent: Friday, April 16, 2021 10:32 AM
To: devel@edk2.groups.io
Cc: Chiu, Chasel <chasel.chiu@intel.com>; Chaganty, Rangasai V
<rangasai.v.chaganty@intel.com>
Subject: [edk2-platforms][PATCH v1 26/35] CoffeelakeSiliconPkg: Remove
SmmSpiFlashCommonLib

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

The library has been consolidated with instances in other Intel silicon packages
as a single instance in IntelSiliconPkg

Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---

Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashC
ommon.c | 196 --------------------

Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashC
ommonSmmLib.c | 54 ------
Silicon/Intel/KabylakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
| 98 ----------

Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFl
ashCommonLib.inf | 53 ------
4 files changed, 401 deletions(-)

diff --git
a/Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlas
hCommon.c
b/Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlas
hCommon.c
deleted file mode 100644
index 7ee7ffab5001..000000000000
---
a/Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlas
hCommon.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/** @file
- Wrap EFI_SPI_PROTOCOL to provide some library level interfaces
- for module use.
-
-Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/SpiFlashCommonLib.h>
-#include <Library/IoLib.h>
-#include <Library/PciLib.h>
-#include <PchAccess.h>
-#include <Library/MmPciLib.h>
-#include <Protocol/Spi.h>
-
-
-PCH_SPI_PROTOCOL *mSpiProtocol;
-
-//
-// FlashAreaBaseAddress and Size for boottime and runtime usage.
-//
-UINTN mFlashAreaBaseAddress = 0;
-UINTN mFlashAreaSize = 0;
-
-/**
- Enable block protection on the Serial Flash device.
-
- @retval EFI_SUCCESS Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
-
-**/
-EFI_STATUS
-EFIAPI
-SpiFlashLock (
- VOID
- )
-{
- return EFI_SUCCESS;
-}
-
-/**
- Read NumBytes bytes of data from the address specified by
- PAddress into Buffer.
-
- @param[in] Address The starting physical address of the read.
- @param[in,out] NumBytes On input, the number of bytes to read. On
output, the number
- of bytes actually read.
- @param[out] Buffer The destination data buffer for the read.
-
- @retval EFI_SUCCESS Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
-
-**/
-EFI_STATUS
-EFIAPI
-SpiFlashRead (
- IN UINTN Address,
- IN OUT UINT32 *NumBytes,
- OUT UINT8 *Buffer
- )
-{
- ASSERT ((NumBytes != NULL) && (Buffer != NULL));
- if ((NumBytes == NULL) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // This function is implemented specifically for those platforms
- // at which the SPI device is memory mapped for read. So this
- // function just do a memory copy for Spi Flash Read.
- //
- CopyMem (Buffer, (VOID *) Address, *NumBytes);
-
- return EFI_SUCCESS;
-}
-
-/**
- Write NumBytes bytes of data from Buffer to the address specified by
- PAddresss.
-
- @param[in] Address The starting physical address of the write.
- @param[in,out] NumBytes On input, the number of bytes to write. On
output,
- the actual number of bytes written.
- @param[in] Buffer The source data buffer for the write.
-
- @retval EFI_SUCCESS Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
-
-**/
-EFI_STATUS
-EFIAPI
-SpiFlashWrite (
- IN UINTN Address,
- IN OUT UINT32 *NumBytes,
- IN UINT8 *Buffer
- )
-{
- EFI_STATUS Status;
- UINTN Offset;
- UINT32 Length;
- UINT32 RemainingBytes;
-
- ASSERT ((NumBytes != NULL) && (Buffer != NULL));
- if ((NumBytes == NULL) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- ASSERT (Address >= mFlashAreaBaseAddress);
-
- Offset = Address - mFlashAreaBaseAddress;
-
- ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
-
- Status = EFI_SUCCESS;
- RemainingBytes = *NumBytes;
-
-
- while (RemainingBytes > 0) {
- if (RemainingBytes > SECTOR_SIZE_4KB) {
- Length = SECTOR_SIZE_4KB;
- } else {
- Length = RemainingBytes;
- }
- Status = mSpiProtocol->FlashWrite (
- mSpiProtocol,
- FlashRegionBios,
- (UINT32) Offset,
- Length,
- Buffer
- );
- if (EFI_ERROR (Status)) {
- break;
- }
- RemainingBytes -= Length;
- Offset += Length;
- Buffer += Length;
- }
-
- //
- // Actual number of bytes written
- //
- *NumBytes -= RemainingBytes;
-
- return Status;
-}
-
-/**
- Erase the block starting at Address.
-
- @param[in] Address The starting physical address of the block to be
erased.
- This library assume that caller garantee that the PAddress
- is at the starting address of this block.
- @param[in] NumBytes On input, the number of bytes of the logical block
to be erased.
- On output, the actual number of bytes erased.
-
- @retval EFI_SUCCESS. Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
-
-**/
-EFI_STATUS
-EFIAPI
-SpiFlashBlockErase (
- IN UINTN Address,
- IN UINTN *NumBytes
- )
-{
- EFI_STATUS Status;
- UINTN Offset;
- UINTN RemainingBytes;
-
- ASSERT (NumBytes != NULL);
- if (NumBytes == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ASSERT (Address >= mFlashAreaBaseAddress);
-
- Offset = Address - mFlashAreaBaseAddress;
-
- ASSERT ((*NumBytes % SECTOR_SIZE_4KB) == 0);
- ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
-
- Status = EFI_SUCCESS;
- RemainingBytes = *NumBytes;
-
-
- Status = mSpiProtocol->FlashErase (
- mSpiProtocol,
- FlashRegionBios,
- (UINT32) Offset,
- (UINT32) RemainingBytes
- );
- return Status;
-}
-
diff --git
a/Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlas
hCommonSmmLib.c
b/Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlas
hCommonSmmLib.c
deleted file mode 100644
index 11133163d2d4..000000000000
---
a/Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlas
hCommonSmmLib.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/** @file
- SMM Library instance of SPI Flash Common Library Class
-
-Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/SpiFlashCommonLib.h>
-#include <Library/SmmServicesTableLib.h> -#include <Protocol/Spi.h>
-
-extern PCH_SPI_PROTOCOL *mSpiProtocol;
-
-extern UINTN mFlashAreaBaseAddress;
-extern UINTN mFlashAreaSize;
-
-/**
- The library constructuor.
-
- The function does the necessary initialization work for this library
- instance.
-
- @param[in] ImageHandle The firmware allocated handle for the UEFI
image.
- @param[in] SystemTable A pointer to the EFI system table.
-
- @retval EFI_SUCCESS The function always return EFI_SUCCESS for now.
- It will ASSERT on error for debug version.
- @retval EFI_ERROR Please reference LocateProtocol for error code
details.
-**/
-EFI_STATUS
-EFIAPI
-SmmSpiFlashCommonLibConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mFlashAreaBaseAddress = (UINTN)PcdGet32 (PcdFlashAreaBaseAddress);
- mFlashAreaSize = (UINTN)PcdGet32 (PcdFlashAreaSize);
-
- //
- // Locate the SMM SPI protocol.
- //
- Status = gSmst->SmmLocateProtocol (
- &gPchSmmSpiProtocolGuid,
- NULL,
- (VOID **) &mSpiProtocol
- );
- ASSERT_EFI_ERROR (Status);
-
- return Status;
-}
diff --git
a/Silicon/Intel/KabylakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
b/Silicon/Intel/KabylakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
deleted file mode 100644
index 0c5e72258c2d..000000000000
--- a/Silicon/Intel/KabylakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/** @file
- The header file includes the common header files, defines
- internal structure and functions used by SpiFlashCommonLib.
-
-Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __SPI_FLASH_COMMON_LIB_H__
-#define __SPI_FLASH_COMMON_LIB_H__
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/PcdLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h> -#include
<Library/UefiDriverEntryPoint.h> -#include
<Library/UefiBootServicesTableLib.h>
-
-#define SECTOR_SIZE_4KB 0x1000 // Common 4kBytes sector size
-/**
- Enable block protection on the Serial Flash device.
-
- @retval EFI_SUCCESS Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
-
-**/
-EFI_STATUS
-EFIAPI
-SpiFlashLock (
- VOID
- );
-
-/**
- Read NumBytes bytes of data from the address specified by
- PAddress into Buffer.
-
- @param[in] Address The starting physical address of the read.
- @param[in,out] NumBytes On input, the number of bytes to read. On
output, the number
- of bytes actually read.
- @param[out] Buffer The destination data buffer for the read.
-
- @retval EFI_SUCCESS Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
-
-**/
-EFI_STATUS
-EFIAPI
-SpiFlashRead (
- IN UINTN Address,
- IN OUT UINT32 *NumBytes,
- OUT UINT8 *Buffer
- );
-
-/**
- Write NumBytes bytes of data from Buffer to the address specified by
- PAddresss.
-
- @param[in] Address The starting physical address of the write.
- @param[in,out] NumBytes On input, the number of bytes to write. On
output,
- the actual number of bytes written.
- @param[in] Buffer The source data buffer for the write.
-
- @retval EFI_SUCCESS Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
-
-**/
-EFI_STATUS
-EFIAPI
-SpiFlashWrite (
- IN UINTN Address,
- IN OUT UINT32 *NumBytes,
- IN UINT8 *Buffer
- );
-
-/**
- Erase the block starting at Address.
-
- @param[in] Address The starting physical address of the block to be
erased.
- This library assume that caller garantee that the PAddress
- is at the starting address of this block.
- @param[in] NumBytes On input, the number of bytes of the logical block
to be erased.
- On output, the actual number of bytes erased.
-
- @retval EFI_SUCCESS. Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
-
-**/
-EFI_STATUS
-EFIAPI
-SpiFlashBlockErase (
- IN UINTN Address,
- IN UINTN *NumBytes
- );
-
-#endif
diff --git
a/Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSp
iFlashCommonLib.inf
b/Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSp
iFlashCommonLib.inf
deleted file mode 100644
index d712b9e5f769..000000000000
---
a/Silicon/Intel/KabylakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSp
iFlashCommonLib.inf
+++ /dev/null
@@ -1,53 +0,0 @@
-### @file
-# SMM Library instance of Spi Flash Common Library Class -# -# Copyright (c)
2017, Intel Corporation. All rights reserved.<BR> -# -# SPDX-License-Identifier:
BSD-2-Clause-Patent -# -###
-
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = SmmSpiFlashCommonLib
- FILE_GUID = 9632D96E-E849-4217-9217-DC500B8AAE47
- VERSION_STRING = 1.0
- MODULE_TYPE = DXE_SMM_DRIVER
- LIBRARY_CLASS = SpiFlashCommonLib|DXE_SMM_DRIVER
- CONSTRUCTOR = SmmSpiFlashCommonLibConstructor
-#
-# The following information is for reference only and not required by the build
tools.
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[LibraryClasses]
- PciLib
- IoLib
- MemoryAllocationLib
- BaseLib
- UefiLib
- SmmServicesTableLib
- BaseMemoryLib
- DebugLib
- MmPciLib
-
-[Packages]
- MdePkg/MdePkg.dec
- KabylakeSiliconPkg/SiPkg.dec
-
-[Pcd]
- gSiPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
- gSiPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
- gSiPkgTokenSpaceGuid.PcdBiosGuardEnable ## CONSUMES
-
-[Sources]
- SpiFlashCommonSmmLib.c
- SpiFlashCommon.c
-
-[Protocols]
- gPchSmmSpiProtocolGuid ## CONSUMES
- gSmmBiosGuardProtocolGuid ## CONSUMES
-
-[Depex.X64.DXE_SMM_DRIVER]
- gPchSmmSpiProtocolGuid
--
2.28.0.windows.1

1 - 20 of 74226