Date   

Re: [tianocore.github.io.wiki PATCH 1/1] Xcode.md: Update instructions to work on modern macOS and Xcode versions

Rebecca Cran
 

Andrew, could you review this please?

Thanks.
Rebecca Cran

On 5/9/21 1:18 PM, Rebecca Cran wrote:
The existing instructions no longer work on macOS Big Sur and Xcode 12.5.
Update them to include for example using lldb instead of gdb, installing
XQuartz, and using modern names such as macOS instead of Mac OS X.
Signed-off-by: Rebecca Cran <rebecca@...>
---
Xcode.md | 142 +++++++++++---------
1 file changed, 78 insertions(+), 64 deletions(-)
diff --git a/Xcode.md b/Xcode.md
index 3d220a5..c494d9d 100644
--- a/Xcode.md
+++ b/Xcode.md
@@ -1,12 +1,12 @@
-This page provides step-by-step instructions for setting up a [http://www.tianocore.org/edk2/ EDK II] build environment on Mac OS X systems using the Xcode development tools. These steps have been verified with macOS Sierra Version 10.12.4
+This page provides step-by-step instructions for setting up a [EDK II](https://github.com/tianocore/tianocore.github.io/wiki/EDK-II) build environment on macOS systems using the Xcode development tools. These steps have been verified with macOS Big Sur 11.3.1
-# Mac OS X Xcode
-Download the latest version of [Xcode](https://developer.apple.com/xcode) (9.4.1 as of this writing) from the Mac App Store. After installing Xcode, you will additionally need to install the extra command-line tools. To do this, at a Terminal prompt, enter:
+# macOS Xcode
+Download the latest version of [Xcode](https://developer.apple.com/xcode) (12.5 as of 2021-05-09) from the Mac App Store. After installing Xcode, you will additionally need to install the extra command-line tools. To do this, at a Terminal prompt, enter:
```
$ xcode-select --install
```
## Additional Development Tools
-While Xcode provides a full development environment as well as a suite of different utilities, it does not provide all tools required for Tianocore development. These tools can be provided in a number of ways, but the two most popular ways come from [Brew](https://brew.sh) and [MacPorts](https://www.macports.org/install.php). Installation information is provided at the previous links.
+While Xcode provides a full development environment as well as a suite of different utilities, it does not provide all tools required for TianoCore development. These tools can be provided in a number of ways, but the two most popular ways come from [Brew](https://brew.sh) and [MacPorts](https://www.macports.org/install.php). Installation information is provided at the previous links.
### MacPorts Tips
* If you work behind a firewall and need to pass your network traffic through a proxy, ensure you set the environment variable RSYNC_PROXY to your http proxy in the form of `proxy.dns.name:port_number`.
@@ -18,7 +18,7 @@ The mtoc utility is required to convert from the macOS Mach-O image format to th
### Brew Instructions
```
-$ brew install mtoc
+$ brew install mtoc
```
## MacPorts Instructions
```
@@ -27,7 +27,7 @@ $ sudo port install cctools
By default, this will install `mtoc` at `/opt/local/bin/mtoc`.
# Install NASM
-The assembler used for EDK II builds is Netwide Assembler (NASM). The latest version of NASM is available from http://www.nasm.us/.
+The assembler used for EDK II builds is Netwide Assembler (NASM). The latest version of NASM is available from https://nasm.us/.
## Brew Instructions
```
$ brew install nasm
@@ -53,9 +53,13 @@ $ sudo port install acpica
```
By default this installs `iasl` at `/opt/local/bin/iasl`
+# Install XQuartz
+
+The EmulatorPkg requires headers from X11, which are provided by the XQuartz project. Install it from https://www.xquartz.org/.
+
# Install QEMU Emulator
-On order to support running the OVMF platforms from the OvmfPkg, the QEMU emulator from http://www.qemu.org/ must be installed.
+On order to support running the OVMF platforms from the OvmfPkg, the QEMU emulator from https://www.qemu.org/ must be installed.
## Brew Install
```
@@ -97,84 +101,94 @@ Pick the location you want to down load the files to and `cd` to that directory:
```
cd ~/work
git clone https://github.com/tianocore/edk2.git
+cd edk2
+git submodule update --init
```
-# Build from Command Line/Debug with gdb
+# Build from Command Line/Debug with lldb
-Build the UnixPkg:
+Build the EmulatorPkg:
```
-cd ~/work/edk2/UnixPkg
+cd ~/work/edk2/EmulatorPkg
./build.sh
```
-Debug the UnixPkg
+Debug the EmulatorPkg
```
./build.sh run
-Building from: /Users/fish/work/edk2
+Initializing workspace
+/Users/bcran/src/edk2/BaseTools
+Loading previous configuration from /Users/bcran/src/edk2/Conf/BuildEnv.sh
+Using EDK2 in-source Basetools
+WORKSPACE: /Users/bcran/src/edk2
+EDK_TOOLS_PATH: /Users/bcran/src/edk2/BaseTools
+CONF_PATH: /Users/bcran/src/edk2/Conf
using prebuilt tools
-Reading symbols for shared libraries ...... done
-Breakpoint 1 at 0xce84: file /Users/fish/work/edk2/UnixPkg/Sec/SecMain.c, line 1070.
-(gdb)
-```
-
-Type `r` at the gdb prompt (don't forget to hit carriage return) to boot the emulator. Ctrl-c in the terminal window will break in to gdb. bt is the stack backtrace command:
-
-```
-^C
-Program received signal SIGINT, Interrupt.
-0x92423806 in __semwait_signal ()
-(gdb) bt
-#0 0x92423806 in __semwait_signal ()
-#1 0x9244f441 in nanosleep$UNIX2003 ()
-#2 0x0000b989 in msSleep (Milliseconds=0x14) at /Users/fish/work/Migration/edk2/UnixPkg/Sec/UnixThunk.c:102
-#3 0x0000acf5 in UgaCheckKey (UgaIo=0x2078d0) at /Users/fish/work/Migration/edk2/UnixPkg/Sec/UgaX11.c:380
-#4 0x0000d8b7 in _GasketUintn () at /Users/fish/work/Migration/edk2/Build/Unix/DEBUG_XCODE32/IA32/UnixPkg/Sec/SecMain/OUTPUT/Ia32/Gasket.iii:63
-#5 0x0000d801 in GasketUgaCheckKey (UgaIo=0x2078d0) at /Users/fish/work/Migration/edk2/UnixPkg/Sec/Gasket.c:406
-#6 0x454a25fb in UnixUgaSimpleTextInWaitForKey (Event=0x45603610, Context=0x45382110) at /Users/fish/work/Migration/edk2/UnixPkg/UnixUgaDxe/UnixUgaInput.c:169
-#7 0x45faad3a in CoreDispatchEventNotifies (Priority=0x10) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:185
-#8 0x45faa639 in CoreRestoreTpl (NewTpl=0x4) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c:114
-#9 0x45f9f197 in CoreReleaseLock (Lock=0x45fb1024) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Library/Library.c:102
-#10 0x45faabd6 in CoreReleaseEventLock () at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:113
-#11 0x45fab26c in CoreCheckEvent (UserEvent=0x45603210) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:562
-#12 0x45fab2db in CoreWaitForEvent (NumberOfEvents=0x1, UserEvents=0x45f94cc4, UserIndex=0x45f94cb8) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:621
-#13 0x49ce9557 in ?? ()
-#14 0x49cf0344 in ?? ()
-#15 0x49ce3bc2 in ?? ()
-#16 0x49ce3ae1 in ?? ()
-#17 0x45f9e4e3 in CoreStartImage (ImageHandle=0x49e31e10, ExitDataSize=0x45f94eec, ExitData=0x45f94ee8) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Image/Image.c:1260
-#18 0x4550cccc in BdsLibBootViaBootOption (Option=0x49ffa110, DevicePath=0x49ffa190, ExitDataSize=0x45f94eec, ExitData=0x45f94ee8) at /Users/fish/work/Migration/edk2/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c:382
-#19 0x455252a9 in BdsBootDeviceSelect () at /Users/fish/work/Migration/edk2/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c:214
-#20 0x455255bc in BdsEntry (This=0x4552d01c) at /Users/fish/work/Migration/edk2/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c:356
-#21 0x45fad7e8 in DxeMain (HobStart=0x45f70010) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c:425
-#22 0x45fadd1d in ProcessModuleEntryPointList (HobStart=0x42020000) at /Users/fish/work/Migration/edk2/Build/Unix/DEBUG_XCODE32/IA32/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/AutoGen.c:287
-#23 0x45f97773 in _ModuleEntryPoint (HobStart=0x42020000) at /Users/fish/work/Migration/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c:54
-(gdb)
+(lldb) target create "./Host"
+Current executable set to '/Users/bcran/src/edk2/Build/EmulatorX64/DEBUG_XCODE5/X64/Host' (x86_64).
+(lldb) command script import /Users/bcran/src/edk2/EmulatorPkg/Unix/lldbefi.py
+Type r to run emulator. SecLldbScriptBreak armed. EFI modules should now get source level debugging in the emulator.
+(lldb) script lldb.debugger.SetAsync(True)
+(lldb) run
+Process 12155 launched: '/Users/bcran/src/edk2/Build/EmulatorX64/DEBUG_XCODE5/X64/Host' (x86_64)
+
+EDK II UNIX Host Emulation Environment from http://www.tianocore.org/edk2/
+ BootMode 0x00
+ OS Emulator passing in 128 KB of temp RAM at 0x102000000 to SEC
+ FD loaded from ../FV/FV_RECOVERY.fd at 0x102020000 contains SEC Core
+...
+```
+
+Type `process interrupt` at the lldb prompt (don't forget to hit carriage return) to pause execution. Ctrl-c in the terminal window will quit lldb. `bt` is the stack backtrace command:
+
+```
+Process 12420 stopped
+* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
+ frame #0: 0x00007fff2033cc22 libsystem_kernel.dylib:__semwait_signal() + 10
+libsystem_kernel.dylib`__semwait_signal:
+-> 0x7fff2033cc22 <+10>: jae 0x7fff2033cc2c ; <+20>
+ 0x7fff2033cc24 <+12>: movq %rax, %rdi
+ 0x7fff2033cc27 <+15>: jmp 0x7fff2033b72d ; cerror
+ 0x7fff2033cc2c <+20>: retq
+Target 0: (Host) stopped.
+(lldb) bt
+* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
+ * frame #0: 0x00007fff2033cc22 libsystem_kernel.dylib:__semwait_signal() + 10
+ frame #1: 0x00007fff202bcc2a libsystem_c.dylib:nanosleep() + 196
+ frame #2: 0x0000000100005e55 Host:SecCpuSleep() + 37 at /Users/bcran/src/edk2/EmulatorPkg/Unix/Host/EmuThunk.c:334
+ frame #3: 0x000000010000e96e Host:GasketSecCpuSleep() + 11 at /Users/bcran/src/edk2/Build/EmulatorX64/DEBUG_XCODE5/X64/EmulatorPkg/Unix/Host/Host/OUTPUT/X64/Gasket.iiii:283
+ frame #4: 0x0000000106f985e9 DxeCore.dll:CoreDispatchEventNotifies() + 264 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:194
+ frame #5: 0x0000000106f97fce DxeCore.dll:CoreRestoreTpl() + 227 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c:131
+ frame #6: 0x0000000106f989db DxeCore.dll:CoreSignalEvent() + 111 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:566
+ frame #7: 0x0000000106f98b01 DxeCore.dll:CoreWaitForEvent() + 94 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:707
+ frame #8: 0x0000000113e8e54c BdsDxe.dll:BdsWaitForSingleEvent() + 127 at /Users/bcran/src/edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c:250
+ frame #9: 0x0000000113e8e70b BdsDxe.dll:BdsWait() + 215 at /Users/bcran/src/edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c:328
+ frame #10: 0x0000000113e8dffb BdsDxe.dll:BdsEntry() + 2612 at /Users/bcran/src/edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c:1012
+ frame #11: 0x0000000106f9bbd6 DxeCore.dll:DxeMain() + 2791 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c:551
+ frame #12: 0x0000000106f9ed8f DxeCore.dll:_ModuleEntryPoint() + 20 at /Users/bcran/src/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c:48
+ frame #13: 0x0000000106fdd02f DxeIpl.dll:InternalSwitchStack() + 15
+ frame #14: 0x0000000106fdc0b6 DxeIpl.dll:HandOffToDxeCore() + 546 at /Users/bcran/src/edk2/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c:126
+ frame #15: 0x0000000106fda78a DxeIpl.dll:DxeLoadCore() + 1354 at /Users/bcran/src/edk2/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c:449
+ frame #16: 0x0000000106ff1d7c
+ frame #17: 0x00000001020255c6 PeiCore.dll:PeiCore() + 1982 at /Users/bcran/src/edk2/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c:331
+ frame #18: 0x000000010202a82c PeiCore.dll:PeiCheckAndSwitchStack() + 1171 at /Users/bcran/src/edk2/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c:842
+ frame #19: 0x000000010202b853 PeiCore.dll:PeiDispatcher() + 1206 at /Users/bcran/src/edk2/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c:1609
+(lldb)
+
```
# Build and Debug from Xcode
-To build from the Xcode GUI open ~/work/edk2/UnixPkg/Xcode/xcode_project/xcode_project.xcodeproj. You can build, clean, and source level debug from the Xcode GUI. You can hit the Build and Debug button to start the build process. You need to need to hit command-shift-B to show the output of the build. Click Pause to break into the debugger.
-
-[[File:Xcode.jpg]]
+To build from the Xcode GUI open ~/work/edk2/EmulatorPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj. You can build, clean, and source level debug from the Xcode GUI. You can hit the Build and Debug button to start the build process. You need to need to hit command-shift-B to show the output of the build. Click Pause to break into the debugger.
The stack trace contains items that show as ?? since the default shell is checked in as a binary. `nanosleep$UNIX2003` and `__semwait_signal` are POSIX library calls and you do not get C source debug with these symbols.
-# Source Level Debug Shell
-
-It is possible to get source level debug for the EFI Shell by pulling these projects from source control and building them.
-
-Instructions for building and hooking in the shell are located in the [https://sourceforge.net/apps/mediawiki/tianocore/index.php?title=Gcc-shell gcc-shell] project.
-
-Please note the gcc-shell and UnixPkg build separately, so if you update shell code you need to build the shell to see the changes. The following screen shot shows being able to source level debug the shell:
-
-[[File:Xcode_good.jpg]]
+*Note* The Xcode project is currently (as of 2021-05-09) broken.
# See Also
-* [[Step-by-step instructions]]
-
# Continue with common instructions
-The [remaining instructions](../Common-instructions) are common for most UNIX-like systems.
+The [remaining instructions](https://github.com/tianocore/tianocore.github.io/wiki/Common-instructions-for-Unix) are common for most UNIX-like systems.


Re: [edk2-platforms][PATCH v2 6/6] Platform/StandaloneMm: build StandaloneMmRpmb for 32bit architectures

Ilias Apalodimas
 

On Mon, May 17, 2021 at 07:50:47AM +0200, Etienne Carriere wrote:
Build PlatformStandaloneMmRpmb for ARM architecture (32bit arm machine).
The generated image targets an execution environment similar to AArch64
StMM secure partition in OP-TEE but in 32bit mode.

GCC flag -fno-stack-protector
added. The stack protection code bring
GOT dependencies we prefer avoid when StMM runs in OP-TEE.

Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Ilias Apalodimas <ilias.apalodimas@...>
Cc: Leif Lindholm <leif@...>
Cc: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
Changes since v1:
- Remove useless duplication of ArmSvcLib loading.
- Move BaseStackCheckLib to generic library classes instead of ARM only.
- include MdePkg/MdeLibs.dsc.inc
instead of loading
RegisterFilterLibNull.inf for ARM architecture.
---
Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc b/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc
index cb3f1ddf52..33364deb1e 100644
--- a/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc
+++ b/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc
@@ -16,12 +16,14 @@
PLATFORM_VERSION = 1.0
DSC_SPECIFICATION = 0x0001001C
OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)
- SUPPORTED_ARCHITECTURES = AARCH64
+ SUPPORTED_ARCHITECTURES = ARM|AARCH64
BUILD_TARGETS = DEBUG|RELEASE|NOOPT
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.fdf
DEFINE DEBUG_MESSAGE = TRUE

+!include MdePkg/MdeLibs.dsc.inc
+
################################################################################
#
# Library Class section - list of all Library Classes needed by this Platform.
@@ -39,6 +41,7 @@
FvLib|StandaloneMmPkg/Library/FvLib/FvLib.inf
HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+ NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
MemLib|StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@@ -68,6 +71,9 @@
#
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf

+[LibraryClasses.ARM]
+ ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
+
[LibraryClasses.common.MM_STANDALONE]
HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
@@ -160,3 +166,7 @@
[BuildOptions.AARCH64]
GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -march=armv8-a+nofp
GCC:*_*_*_CC_FLAGS = -mstrict-align
+
+[BuildOptions.ARM]
+GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -march=armv7-a
+GCC:*_*_*_CC_FLAGS = -fno-stack-protector
--
2.17.1
Acked-by: Ilias Apalodimas <ilias.apalodimas@...>


Re: [edk2-platforms][PATCH v2 5/6] Drivers/OpTee: address cast build warning issue in 32b mode

Ilias Apalodimas
 

On Mon, May 17, 2021 at 07:50:46AM +0200, Etienne Carriere wrote:
Use (UINTN) cast to cast physical or virtual address values to the
pointer size before casting from/to a pointer value.

Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Ilias Apalodimas <ilias.apalodimas@...>
Cc: Leif Lindholm <leif@...>
Cc: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
No change since v1
---
Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c | 21 +++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c b/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c
index 6eb19bed0e..83c2750368 100644
--- a/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c
+++ b/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c
@@ -305,7 +305,8 @@ OpTeeRpmbFvbRead (
}
}

- Base = (VOID *)Instance->MemBaseAddress + (Lba * Instance->BlockSize) + Offset;
+ Base = (VOID *)(UINTN)Instance->MemBaseAddress + (Lba * Instance->BlockSize) +
+ Offset;
// We could read the data from the RPMB instead of memory
// The 2 copies should already be identical
// Copy from memory image
@@ -387,7 +388,8 @@ OpTeeRpmbFvbWrite (
return Status;
}
}
- Base = (VOID *)Instance->MemBaseAddress + Lba * Instance->BlockSize + Offset;
+ Base = (VOID *)(UINTN)Instance->MemBaseAddress + (Lba * Instance->BlockSize) +
+ Offset;
Status = ReadWriteRpmb (
SP_SVC_RPMB_WRITE,
(UINTN)Buffer,
@@ -477,7 +479,8 @@ OpTeeRpmbFvbErase (
return EFI_INVALID_PARAMETER;
}
NumBytes = NumLba * Instance->BlockSize;
- Base = (VOID *)Instance->MemBaseAddress + Start * Instance->BlockSize;
+ Base = (VOID *)(UINTN)Instance->MemBaseAddress +
+ (Start * Instance->BlockSize);
Buf = AllocatePool (NumLba * Instance->BlockSize);
if (Buf == NULL) {
return EFI_DEVICE_ERROR;
@@ -689,7 +692,7 @@ InitializeFvAndVariableStoreHeaders (
goto Exit;
}
// Install the combined header in memory
- CopyMem ((VOID*)Instance->MemBaseAddress, Headers, HeadersLength);
+ CopyMem ((VOID*)(UINTN)Instance->MemBaseAddress, Headers, HeadersLength);

Exit:
FreePool (Headers);
@@ -747,14 +750,18 @@ FvbInitialize (
// Read the file from disk and copy it to memory
ReadEntireFlash (Instance);

- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Instance->MemBaseAddress;
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)Instance->MemBaseAddress;
Status = ValidateFvHeader (FwVolHeader);
if (EFI_ERROR (Status)) {
// There is no valid header, so time to install one.
DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));

// Reset memory
- SetMem64 ((VOID *)Instance->MemBaseAddress, Instance->NBlocks * Instance->BlockSize, ~0UL);
+ SetMem64 (
+ (VOID *)(UINTN)Instance->MemBaseAddress,
+ Instance->NBlocks * Instance->BlockSize,
+ ~0UL
+ );
DEBUG ((DEBUG_INFO, "%a: Erasing Flash.\n", __FUNCTION__));
Status = ReadWriteRpmb (
SP_SVC_RPMB_WRITE,
@@ -827,7 +834,7 @@ OpTeeRpmbFvbInit (
mInstance.FvbProtocol.Write = OpTeeRpmbFvbWrite;
mInstance.FvbProtocol.Read = OpTeeRpmbFvbRead;

- mInstance.MemBaseAddress = (EFI_PHYSICAL_ADDRESS)Addr;
+ mInstance.MemBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Addr;
mInstance.Signature = FLASH_SIGNATURE;
mInstance.Initialize = FvbInitialize;
mInstance.BlockSize = EFI_PAGE_SIZE;
--
2.17.1
Acked-by: Ilias Apalodimas <ilias.apalodimas@...>


Re: [edk2-platforms][PATCH v2 4/6] Drivers/OpTee: Add Aarch32 SVC IDs for 32bit Arm targets

Ilias Apalodimas
 

On Mon, May 17, 2021 at 07:50:45AM +0200, Etienne Carriere wrote:
Add SMCCC function IDs for RPMB read/write service on 32bit architectures.
Define generic SP_SVC_RPMB_READ/SP_SVC_RPMB_WRITE IDs for native target
architecture (32b or 64b).

Changes OpTeeRpmbFvb.c to use architecture agnostic macro
ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ for 32b and 64b support.

Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Ilias Apalodimas <ilias.apalodimas@...>
Cc: Leif Lindholm <leif@...>
Cc: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
Changes since v1:
- Use _AARCH64 (resp. _AARCH32) suffix instead of _64 (resp. _32) in
the added macros.
---
Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c | 2 +-
Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.h | 16 ++++++++++++++--
2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c b/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c
index 5197c95abd..6eb19bed0e 100644
--- a/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c
+++ b/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.c
@@ -68,7 +68,7 @@ ReadWriteRpmb (

ZeroMem (&SvcArgs, sizeof (SvcArgs));

- SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;
+ SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ;
SvcArgs.Arg1 = mStorageId;
SvcArgs.Arg2 = 0;
SvcArgs.Arg3 = SvcAct;
diff --git a/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.h b/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.h
index c17fc287ef..9c2a4ea6a5 100644
--- a/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.h
+++ b/Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFvb.h
@@ -13,8 +13,20 @@
contract between OP-TEE and EDK2.
For more details check core/arch/arm/include/kernel/stmm_sp.h in OP-TEE
**/
-#define SP_SVC_RPMB_READ 0xC4000066
-#define SP_SVC_RPMB_WRITE 0xC4000067
+#define SP_SVC_RPMB_READ_AARCH64 0xC4000066
+#define SP_SVC_RPMB_WRITE_AARCH64 0xC4000067
+
+#define SP_SVC_RPMB_READ_AARCH32 0x84000066
+#define SP_SVC_RPMB_WRITE_AARCH32 0x84000067
+
+#ifdef MDE_CPU_AARCH64
+#define SP_SVC_RPMB_READ SP_SVC_RPMB_READ_AARCH64
+#define SP_SVC_RPMB_WRITE SP_SVC_RPMB_WRITE_AARCH64
+#endif
+#ifdef MDE_CPU_ARM
+#define SP_SVC_RPMB_READ SP_SVC_RPMB_READ_AARCH32
+#define SP_SVC_RPMB_WRITE SP_SVC_RPMB_WRITE_AARCH32
+#endif

#define FLASH_SIGNATURE SIGNATURE_32 ('r', 'p', 'm', 'b')
#define INSTANCE_FROM_FVB_THIS(a) CR (a, MEM_INSTANCE, FvbProtocol, \
--
2.17.1
Acked-by: Ilias Apalodimas <ilias.apalodimas@...>


Re: [edk2-platforms][PATCH v2 3/6] Platform/StandaloneMm: sync with edk2 StandaloneMmCpu path change

Ilias Apalodimas
 

On Mon, May 17, 2021 at 07:50:44AM +0200, Etienne Carriere wrote:
Synchronize with edk2 package where StandaloneMmCpu component has moved
from StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
to StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf

Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Ilias Apalodimas <ilias.apalodimas@...>
Cc: Leif Lindholm <leif@...>
Cc: Sami Mujawar <sami.mujawar@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Cc: Thomas Abraham <thomas.abraham@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
Changes since v1:
- split change in 3: this change relates to StandaloneMm package only.
---
Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc | 2 +-
Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.fdf | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc b/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc
index f99a47ebf6..cb3f1ddf52 100644
--- a/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc
+++ b/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.dsc
@@ -133,7 +133,7 @@
#
Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFv.inf
StandaloneMmPkg/Core/StandaloneMmCore.inf
- StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
+ StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf {
<LibraryClasses>
NULL|Drivers/OpTee/OpteeRpmbPkg/FixupPcd.inf
diff --git a/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.fdf b/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.fdf
index e175dc7b2d..c4295a3e63 100644
--- a/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.fdf
+++ b/Platform/StandaloneMm/PlatformStandaloneMmPkg/PlatformStandaloneMmRpmb.fdf
@@ -68,7 +68,8 @@ READ_LOCK_STATUS = TRUE
INF Drivers/OpTee/OpteeRpmbPkg/OpTeeRpmbFv.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
- INF StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
+ INF StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf
+
################################################################################
#
# Rules are use with the [FV] section's module INF type to define
--
2.17.1
Acked-by: Ilias Apalodimas <ilias.apalodimas@...>


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

Ard Biesheuvel
 

On Mon, 17 May 2021 at 10:49, Yao, Jiewen <jiewen.yao@...> wrote:

Hi Ard
Can it be resolved in patch - https://edk2.groups.io/g/devel/message/75135?p=,,,20,0,0,0::Created,,cryptopkg,20,2,0,82822574 ?
That looks like the same issue, yes.

I really hope to improve CI to catch this earlier...
Yes, I am also a bit surprised that it was not caught before.

Hi Jian
Would you please merge this ASAP?



-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Ard
Biesheuvel
Sent: Monday, May 17, 2021 4:36 PM
To: edk2-devel-groups-io <devel@edk2.groups.io>; Agrawal, Sachin
<sachin.agrawal@...>
Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>;
Lu, XiaoyuX <xiaoyux.lu@...>; Jiang, Guomin <guomin.jiang@...>
Subject: Re: [edk2-devel] [PATCH v3 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS
verify support

On Tue, 4 May 2021 at 19:54, Agrawal, Sachin <sachin.agrawal@...>
wrote:

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@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Xiaoyu Lu <xiaoyux.lu@...>
Cc: Guomin Jiang <guomin.jiang@...>

Signed-off-by: Sachin Agrawal <sachin.agrawal@...>
This patch is now merged, and is breaking the build on AARCH64/CLANG38:

CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c:117:7: error: variable
'Result' is used uninitialized whenever 'if' condition is true
[-Werror,-Wsometimes-uninitialized]
if (EvpVerifyCtx == NULL) {
^~~~~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:150:10: note:
uninitialized use occurs here
return Result;
^~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:117:3: note: remove
the 'if' if its condition is always false
if (EvpVerifyCtx == NULL) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:110:7: error:
variable 'Result' is used uninitialized whenever 'if' condition is
true [-Werror,-Wsometimes-uninitialized]
if (EvpRsaKey == NULL) {
^~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:150:10: note:
uninitialized use occurs here
return Result;
^~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:110:3: note: remove
the 'if' if its condition is always false
if (EvpRsaKey == NULL) {
^~~~~~~~~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:79:17: note:
initialize the variable 'Result' to silence this warning
BOOLEAN Result;
^

The diagnostic seems accurate: 'Result' is returned on the _Exit path,
regardless of whether is has ever been initialized or not.

Please fix this asap - it is affecting our CI.

Thanks,
Ard.



---

Notes:
v3:
- Fixed gcc compilation error [CI System]

CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 146
+++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 46 +++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c | 169
+++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c | 60
++++++
CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c | 46 +++++
CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c | 60
++++++
CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 66
+++++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c | 1
+
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c | 191
++++++++++++++++++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c | 2 +
CryptoPkg/Include/Library/BaseCryptLib.h | 74 ++++++++
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 2 +
CryptoPkg/Private/Protocol/Crypto.h | 78 ++++++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h | 3 +
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf | 1
+
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf | 1
+
21 files changed, 956 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
new file mode 100644
index 000000000000..af7cdafa4c47
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
@@ -0,0 +1,146 @@
+/** @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
+const
+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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ 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;
+ }
+ if (SaltLen < DigestLen) {
+ 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, SaltLen) > 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..69c6889fbc4b
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
@@ -0,0 +1,46 @@
+/** @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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c
new file mode 100644
index 000000000000..1ed076e4192c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c
@@ -0,0 +1,169 @@
+/** @file
+ RSA PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file implements following APIs which provide basic capabilities for RSA:
+ 1) RsaPssSign
+
+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
+const
+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;
+ }
+}
+
+
+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ BOOLEAN Result;
+ UINTN RsaSigSize;
+ 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;
+ }
+
+ RsaSigSize = RSA_size (RsaContext);
+ if (*SigSize < RsaSigSize) {
+ *SigSize = RsaSigSize;
+ return FALSE;
+ }
+
+ if (Signature == NULL) {
+ return FALSE;
+ }
+
+ if (SaltLen < DigestLen) {
+ 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_DigestSignInit(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, SaltLen) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestSignUpdate(pEvpVerifyCtx, Message,
(UINT32)MsgSize) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestSignFinal(pEvpVerifyCtx, Signature, 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/CryptRsaPssSignNull.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c
new file mode 100644
index 000000000000..4ed2dfce992a
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c
@@ -0,0 +1,60 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssSign
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c
b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c
new file mode 100644
index 000000000000..69c6889fbc4b
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c
@@ -0,0 +1,46 @@
+/** @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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c
b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c
new file mode 100644
index 000000000000..4ed2dfce992a
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c
@@ -0,0 +1,60 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssSign
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
index 8b43d1363cb9..412fbdbff52c 100644
--- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
+++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
@@ -1552,6 +1552,72 @@ RsaPkcs1Verify (
CALL_CRYPTO_SERVICE (RsaPkcs1Verify, (RsaContext, MessageHash,
HashSize, Signature, SigSize), FALSE);
}

+/**
+ 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ CALL_CRYPTO_SERVICE (RsaPssVerify, (RsaContext, Message, MsgSize,
Signature, SigSize, DigestLen, SaltLen), FALSE);
+}
+
+/**
+ 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ CALL_CRYPTO_SERVICE (RsaPssSign, (RsaContext, Message, MsgSize,
DigestLen, SaltLen, Signature, SigSize), FALSE);
+}
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.

diff --git
a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
index b7fcea3ff7e4..3873de973064 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
@@ -16,6 +16,7 @@ SUITE_DESC mSuiteDesc[] = {
{"HMAC verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mHmacTestNum, mHmacTest},
{"BlockCipher verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mBlockCipherTestNum, mBlockCipherTest},
{"RSA verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mRsaTestNum, mRsaTest},
+ {"RSA PSS verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mRsaPssTestNum, mRsaPssTest},
{"RSACert verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mRsaCertTestNum, mRsaCertTest},
{"PKCS7 verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mPkcs7TestNum, mPkcs7Test},
{"PKCS5 verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mPkcs5TestNum, mPkcs5Test},
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c
new file mode 100644
index 000000000000..5ac2f325fbdd
--- /dev/null
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c
@@ -0,0 +1,191 @@
+/** @file
+ Application for RSA PSS Primitives Validation.
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "TestBaseCryptLib.h"
+
+//
+// RSA PSS test vectors from NIST FIPS 186-3 RSA files
+//
+
+//
+// Public Modulus of RSA Key
+//
+UINT8 RsaPssN[]={
+ 0xa4, 0x7d, 0x04, 0xe7, 0xca, 0xcd, 0xba, 0x4e, 0xa2, 0x6e, 0xca, 0x8a,
0x4c, 0x6e, 0x14, 0x56,
+ 0x3c, 0x2c, 0xe0, 0x3b, 0x62, 0x3b, 0x76, 0x8c, 0x0d, 0x49, 0x86, 0x8a,
0x57, 0x12, 0x13, 0x01,
+ 0xdb, 0xf7, 0x83, 0xd8, 0x2f, 0x4c, 0x05, 0x5e, 0x73, 0x96, 0x0e, 0x70,
0x55, 0x01, 0x87, 0xd0,
+ 0xaf, 0x62, 0xac, 0x34, 0x96, 0xf0, 0xa3, 0xd9, 0x10, 0x3c, 0x2e, 0xb7,
0x91, 0x9a, 0x72, 0x75,
+ 0x2f, 0xa7, 0xce, 0x8c, 0x68, 0x8d, 0x81, 0xe3, 0xae, 0xe9, 0x94, 0x68,
0x88, 0x7a, 0x15, 0x28,
+ 0x8a, 0xfb, 0xb7, 0xac, 0xb8, 0x45, 0xb7, 0xc5, 0x22, 0xb5, 0xc6, 0x4e,
0x67, 0x8f, 0xcd, 0x3d,
+ 0x22, 0xfe, 0xb8, 0x4b, 0x44, 0x27, 0x27, 0x00, 0xbe, 0x52, 0x7d, 0x2b,
0x20, 0x25, 0xa3, 0xf8,
+ 0x3c, 0x23, 0x83, 0xbf, 0x6a, 0x39, 0xcf, 0x5b, 0x4e, 0x48, 0xb3, 0xcf, 0x2f,
0x56, 0xee, 0xf0,
+ 0xdf, 0xff, 0x18, 0x55, 0x5e, 0x31, 0x03, 0x7b, 0x91, 0x52, 0x48, 0x69,
0x48, 0x76, 0xf3, 0x04,
+ 0x78, 0x14, 0x41, 0x51, 0x64, 0xf2, 0xc6, 0x60, 0x88, 0x1e, 0x69, 0x4b,
0x58, 0xc2, 0x80, 0x38,
+ 0xa0, 0x32, 0xad, 0x25, 0x63, 0x4a, 0xad, 0x7b, 0x39, 0x17, 0x1d, 0xee,
0x36, 0x8e, 0x3d, 0x59,
+ 0xbf, 0xb7, 0x29, 0x9e, 0x46, 0x01, 0xd4, 0x58, 0x7e, 0x68, 0xca, 0xaf,
0x8d, 0xb4, 0x57, 0xb7,
+ 0x5a, 0xf4, 0x2f, 0xc0, 0xcf, 0x1a, 0xe7, 0xca, 0xce, 0xd2, 0x86, 0xd7, 0x7f,
0xac, 0x6c, 0xed,
+ 0xb0, 0x3a, 0xd9, 0x4f, 0x14, 0x33, 0xd2, 0xc9, 0x4d, 0x08, 0xe6, 0x0b,
0xc1, 0xfd, 0xef, 0x05,
+ 0x43, 0xcd, 0x29, 0x51, 0xe7, 0x65, 0xb3, 0x82, 0x30, 0xfd, 0xd1, 0x8d,
0xe5, 0xd2, 0xca, 0x62,
+ 0x7d, 0xdc, 0x03, 0x2f, 0xe0, 0x5b, 0xbd, 0x2f, 0xf2, 0x1e, 0x2d, 0xb1,
0xc2, 0xf9, 0x4d, 0x8b,
+ };
+
+//
+// Public Exponent of RSA Key
+//
+UINT8 RsaPssE[]={ 0x10, 0xe4, 0x3f };
+
+//
+// Private Exponent of RSA Key
+//
+UINT8 RsaPssD[]={
+ 0x11, 0xa0, 0xdd, 0x28, 0x5f, 0x66, 0x47, 0x1a, 0x8d, 0xa3, 0x0b, 0xcb,
0x8c, 0x24, 0xa1, 0xd5,
+ 0xc8, 0xdb, 0x94, 0x2f, 0xc9, 0x92, 0x07, 0x97, 0xca, 0x44, 0x24, 0x60,
0xa8, 0x00, 0xb7, 0x5b,
+ 0xbc, 0x73, 0x8b, 0xeb, 0x8e, 0xe0, 0xe8, 0x74, 0xb0, 0x53, 0xe6, 0x47,
0x07, 0xdf, 0x4c, 0xfc,
+ 0x78, 0x37, 0xc4, 0x0e, 0x5b, 0xe6, 0x8b, 0x8a, 0x8e, 0x1d, 0x01, 0x45,
0x16, 0x9c, 0xa6, 0x27,
+ 0x1d, 0x81, 0x88, 0x7e, 0x19, 0xa1, 0xcd, 0x95, 0xb2, 0xfd, 0x0d, 0xe0,
0xdb, 0xa3, 0x47, 0xfe,
+ 0x63, 0x7b, 0xcc, 0x6c, 0xdc, 0x24, 0xee, 0xbe, 0x03, 0xc2, 0x4d, 0x4c,
0xf3, 0xa5, 0xc6, 0x15,
+ 0x4d, 0x78, 0xf1, 0x41, 0xfe, 0x34, 0x16, 0x99, 0x24, 0xd0, 0xf8, 0x95,
0x33, 0x65, 0x8e, 0xac,
+ 0xfd, 0xea, 0xe9, 0x9c, 0xe1, 0xa8, 0x80, 0x27, 0xc1, 0x8f, 0xf9, 0x26,
0x53, 0xa8, 0x35, 0xaa,
+ 0x38, 0x91, 0xbf, 0xff, 0xcd, 0x38, 0x8f, 0xfc, 0x23, 0x88, 0xce, 0x2b, 0x10,
0x56, 0x85, 0x43,
+ 0x75, 0x05, 0x02, 0xcc, 0xbc, 0x69, 0xc0, 0x08, 0x8f, 0x1d, 0x69, 0x0e,
0x97, 0xa5, 0xf5, 0xbd,
+ 0xd1, 0x88, 0x8c, 0xd2, 0xfa, 0xa4, 0x3c, 0x04, 0xae, 0x24, 0x53, 0x95,
0x22, 0xdd, 0xe2, 0xd9,
+ 0xc2, 0x02, 0xf6, 0x55, 0xfc, 0x55, 0x75, 0x44, 0x40, 0xb5, 0x3a, 0x15,
0x32, 0xaa, 0xb4, 0x78,
+ 0x51, 0xf6, 0x0b, 0x7a, 0x06, 0x7e, 0x24, 0x0b, 0x73, 0x8e, 0x1b, 0x1d,
0xaa, 0xe6, 0xca, 0x0d,
+ 0x59, 0xee, 0xae, 0x27, 0x68, 0x6c, 0xd8, 0x88, 0x57, 0xe9, 0xad, 0xad,
0xc2, 0xd4, 0xb8, 0x2b,
+ 0x07, 0xa6, 0x1a, 0x35, 0x84, 0x56, 0xaa, 0xf8, 0x07, 0x66, 0x96, 0x93,
0xff, 0xb1, 0x3c, 0x99,
+ 0x64, 0xa6, 0x36, 0x54, 0xca, 0xdc, 0x81, 0xee, 0x59, 0xdf, 0x51, 0x1c,
0xa3, 0xa4, 0xbd, 0x67,
+ };
+
+//
+// Binary message to be signed and verified
+//
+UINT8 PssMessage[]={
+ 0xe0, 0x02, 0x37, 0x7a, 0xff, 0xb0, 0x4f, 0x0f, 0xe4, 0x59, 0x8d, 0xe9,
0xd9, 0x2d, 0x31, 0xd6,
+ 0xc7, 0x86, 0x04, 0x0d, 0x57, 0x76, 0x97, 0x65, 0x56, 0xa2, 0xcf, 0xc5,
0x5e, 0x54, 0xa1, 0xdc,
+ 0xb3, 0xcb, 0x1b, 0x12, 0x6b, 0xd6, 0xa4, 0xbe, 0xd2, 0xa1, 0x84, 0x99,
0x0c, 0xce, 0xa7, 0x73,
+ 0xfc, 0xc7, 0x9d, 0x24, 0x65, 0x53, 0xe6, 0xc6, 0x4f, 0x68, 0x6d, 0x21,
0xad, 0x41, 0x52, 0x67,
+ 0x3c, 0xaf, 0xec, 0x22, 0xae, 0xb4, 0x0f, 0x6a, 0x08, 0x4e, 0x8a, 0x5b,
0x49, 0x91, 0xf4, 0xc6,
+ 0x4c, 0xf8, 0xa9, 0x27, 0xef, 0xfd, 0x0f, 0xd7, 0x75, 0xe7, 0x1e, 0x83, 0x29,
0xe4, 0x1f, 0xdd,
+ 0x44, 0x57, 0xb3, 0x91, 0x11, 0x73, 0x18, 0x7b, 0x4f, 0x09, 0xa8, 0x17,
0xd7, 0x9e, 0xa2, 0x39,
+ 0x7f, 0xc1, 0x2d, 0xfe, 0x3d, 0x9c, 0x9a, 0x02, 0x90, 0xc8, 0xea, 0xd3,
0x1b, 0x66, 0x90, 0xa6,
+ };
+
+//
+// Binary message to be signed and verified
+//
+UINT8 PssSalt[]={
+ 0xd6, 0x6f, 0x72, 0xf1, 0x0b, 0x69, 0x00, 0x1a, 0x5b, 0x59, 0xcf, 0x10,
0x92, 0xad, 0x27, 0x4d,
+ 0x50, 0x56, 0xc4, 0xe9, 0x5c, 0xcc, 0xcf, 0xbe, 0x3b, 0x53, 0x0d, 0xcb,
0x02, 0x7e, 0x57, 0xd6
+ };
+
+//
+// RSASSA-PSS Signature over above message using above keys, salt and
SHA256 digest(and MGF1) algo.
+//
+UINT8 TestVectorSignature[]={
+ 0x4f, 0x9b, 0x42, 0x5c, 0x20, 0x58, 0x46, 0x0e, 0x4a, 0xb2, 0xf5, 0xc9,
0x63, 0x84, 0xda, 0x23,
+ 0x27, 0xfd, 0x29, 0x15, 0x0f, 0x01, 0x95, 0x5a, 0x76, 0xb4, 0xef, 0xe9,
0x56, 0xaf, 0x06, 0xdc,
+ 0x08, 0x77, 0x9a, 0x37, 0x4e, 0xe4, 0x60, 0x7e, 0xab, 0x61, 0xa9, 0x3a,
0xdc, 0x56, 0x08, 0xf4,
+ 0xec, 0x36, 0xe4, 0x7f, 0x2a, 0x0f, 0x75, 0x4e, 0x8f, 0xf8, 0x39, 0xa8, 0xa1,
0x9b, 0x1d, 0xb1,
+ 0xe8, 0x84, 0xea, 0x4c, 0xf3, 0x48, 0xcd, 0x45, 0x50, 0x69, 0xeb, 0x87,
0xaf, 0xd5, 0x36, 0x45,
+ 0xb4, 0x4e, 0x28, 0xa0, 0xa5, 0x68, 0x08, 0xf5, 0x03, 0x1d, 0xa5, 0xba,
0x91, 0x12, 0x76, 0x8d,
+ 0xfb, 0xfc, 0xa4, 0x4e, 0xbe, 0x63, 0xa0, 0xc0, 0x57, 0x2b, 0x73, 0x1d,
0x66, 0x12, 0x2f, 0xb7,
+ 0x16, 0x09, 0xbe, 0x14, 0x80, 0xfa, 0xa4, 0xe4, 0xf7, 0x5e, 0x43, 0x95,
0x51, 0x59, 0xd7, 0x0f,
+ 0x08, 0x1e, 0x2a, 0x32, 0xfb, 0xb1, 0x9a, 0x48, 0xb9, 0xf1, 0x62, 0xcf,
0x6b, 0x2f, 0xb4, 0x45,
+ 0xd2, 0xd6, 0x99, 0x4b, 0xc5, 0x89, 0x10, 0xa2, 0x6b, 0x59, 0x43, 0x47,
0x78, 0x03, 0xcd, 0xaa,
+ 0xa1, 0xbd, 0x74, 0xb0, 0xda, 0x0a, 0x5d, 0x05, 0x3d, 0x8b, 0x1d, 0xc5,
0x93, 0x09, 0x1d, 0xb5,
+ 0x38, 0x83, 0x83, 0xc2, 0x60, 0x79, 0xf3, 0x44, 0xe2, 0xae, 0xa6, 0x00,
0xd0, 0xe3, 0x24, 0x16,
+ 0x4b, 0x45, 0x0f, 0x7b, 0x9b, 0x46, 0x51, 0x11, 0xb7, 0x26, 0x5f, 0x3b,
0x1b, 0x06, 0x30, 0x89,
+ 0xae, 0x7e, 0x26, 0x23, 0xfc, 0x0f, 0xda, 0x80, 0x52, 0xcf, 0x4b, 0xf3, 0x37,
0x91, 0x02, 0xfb,
+ 0xf7, 0x1d, 0x7c, 0x98, 0xe8, 0x25, 0x86, 0x64, 0xce, 0xed, 0x63, 0x7d,
0x20, 0xf9, 0x5f, 0xf0,
+ 0x11, 0x18, 0x81, 0xe6, 0x50, 0xce, 0x61, 0xf2, 0x51, 0xd9, 0xc3, 0xa6,
0x29, 0xef, 0x22, 0x2d,
+ };
+
+
+VOID *mRsa;
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyRsaPssPreReq (
+ UNIT_TEST_CONTEXT Context
+ )
+{
+ mRsa = RsaNew ();
+
+ if (mRsa == NULL) {
+ return UNIT_TEST_ERROR_TEST_FAILED;
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+VOID
+EFIAPI
+TestVerifyRsaPssCleanUp (
+ UNIT_TEST_CONTEXT Context
+ )
+{
+ if (mRsa != NULL) {
+ RsaFree (mRsa);
+ mRsa = NULL;
+ }
+}
+
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyRsaPssSignVerify (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ UINT8 *Signature;
+ UINTN SigSize;
+ BOOLEAN Status;
+
+ Status = RsaSetKey (mRsa, RsaKeyN, RsaPssN, sizeof (RsaPssN));
+ UT_ASSERT_TRUE (Status);
+
+ Status = RsaSetKey (mRsa, RsaKeyE, RsaPssE, sizeof (RsaPssE));
+ UT_ASSERT_TRUE (Status);
+
+ Status = RsaSetKey (mRsa, RsaKeyD, RsaPssD, sizeof (RsaPssD));
+ UT_ASSERT_TRUE (Status);
+
+ SigSize = 0;
+ Status = RsaPssSign (mRsa, PssMessage, sizeof(PssMessage),
SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE, NULL, &SigSize);
+ UT_ASSERT_FALSE (Status);
+ UT_ASSERT_NOT_EQUAL (SigSize, 0);
+
+ Signature = AllocatePool (SigSize);
+ Status = RsaPssSign (mRsa, PssMessage, sizeof(PssMessage),
SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE, Signature, &SigSize);
+ UT_ASSERT_TRUE (Status);
+
+ //
+ // Verify RSA PSS encoded Signature generated in above step
+ //
+ Status = RsaPssVerify (mRsa, PssMessage, sizeof(PssMessage), Signature,
SigSize, SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE);
+ UT_ASSERT_TRUE (Status);
+
+ //
+ // Verify NIST FIPS 186-3 RSA test vector signature
+ //
+ Status = RsaPssVerify (mRsa, PssMessage, sizeof(PssMessage),
TestVectorSignature, sizeof(TestVectorSignature), SHA256_DIGEST_SIZE,
SHA256_DIGEST_SIZE);
+ UT_ASSERT_TRUE (Status);
+
+ FreePool(Signature);
+ return UNIT_TEST_PASSED;
+}
+
+
+TEST_DESC mRsaPssTest[] = {
+ //
+ // -----Description--------------------------------------Class----------------------
Function---------------------------------Pre---------------------Post---------Context
+ //
+ {"TestVerifyRsaPssSignVerify()", "CryptoPkg.BaseCryptLib.Rsa",
TestVerifyRsaPssSignVerify, TestVerifyRsaPssPreReq,
TestVerifyRsaPssCleanUp, NULL},
+};
+
+UINTN mRsaPssTestNum = ARRAY_SIZE(mRsaPssTest);
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
index 7ce20d2e778f..0969b6aea660 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
@@ -295,6 +295,8 @@ TestVerifyRsaPkcs1SignVerify (
Status = RsaPkcs1Verify (mRsa, HashValue, HashSize, Signature, SigSize);
UT_ASSERT_TRUE (Status);

+ FreePool(Signature);
+
return UNIT_TEST_PASSED;
}

diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
b/CryptoPkg/Include/Library/BaseCryptLib.h
index 496121e6a4ed..8c7d5922ef96 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1363,6 +1363,80 @@ RsaPkcs1Verify (
IN UINTN SigSize
);

+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ );
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.

diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index 4aae2aba95d6..49703fa4c963 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -49,6 +49,8 @@
Pk/CryptX509.c
Pk/CryptAuthenticode.c
Pk/CryptTs.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSign.c
Pem/CryptPem.c

SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
index 7509e4273028..0cab5f3ce36c 100644
--- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
@@ -55,6 +55,8 @@
Pk/CryptX509Null.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSignNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c

diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
index 70c985ec93dc..3d3a6fb94a77 100644
--- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
@@ -55,6 +55,8 @@
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
+ Pk/CryptRsaPssNull.c
+ Pk/CryptRsaPssSignNull.c
Pem/CryptPem.c

SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
index 91ec3e03bf5e..07c376ce04bb 100644
--- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
@@ -53,6 +53,8 @@
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSignNull.c
Pem/CryptPem.c

SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
index db506c32f724..b98f9635b27b 100644
--- a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
@@ -44,6 +44,8 @@
Pk/CryptAuthenticode.c
Pk/CryptTs.c
Pem/CryptPem.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSign.c

SysCall/UnitTestHostCrtWrapper.c

diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
index 689af4fedd68..faf959827b90 100644
--- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
+++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
@@ -50,6 +50,8 @@
Pk/CryptTsNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c
+ Pk/CryptRsaPssNull.c
+ Pk/CryptRsaPssSignNull.c

[Packages]
MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Private/Protocol/Crypto.h
b/CryptoPkg/Private/Protocol/Crypto.h
index 17930a77a60e..e304302c9445 100644
--- a/CryptoPkg/Private/Protocol/Crypto.h
+++ b/CryptoPkg/Private/Protocol/Crypto.h
@@ -3408,6 +3408,81 @@ EFI_STATUS
IN OUT UINTN *DataSize
);

+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_RSA_PSS_SIGN)(
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_RSA_PSS_VERIFY)(
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen
+ );
+
+

///
/// EDK II Crypto Protocol
@@ -3593,6 +3668,9 @@ struct _EDKII_CRYPTO_PROTOCOL {
EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT TlsGetHostPublicCert;
EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY TlsGetHostPrivateKey;
EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST
TlsGetCertRevocationList;
+ /// RSA PSS
+ EDKII_CRYPTO_RSA_PSS_SIGN RsaPssSign;
+ EDKII_CRYPTO_RSA_PSS_VERIFY RsaPssVerify;
};

extern GUID gEdkiiCryptoProtocolGuid;
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
index 9d1cb150a113..25c1379f1a77 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
@@ -83,6 +83,9 @@ extern TEST_DESC mPrngTest[];
extern UINTN mOaepTestNum;
extern TEST_DESC mOaepTest[];

+extern UINTN mRsaPssTestNum;
+extern TEST_DESC mRsaPssTest[];
+
/** Creates a framework you can use */
EFI_STATUS
EFIAPI
diff --git
a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
index 300b98e40b33..00c869265080 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
+++
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
@@ -34,6 +34,7 @@
RandTests.c
Pkcs7EkuTests.c
OaepEncryptTests.c
+ RsaPssTests.c

[Packages]
MdePkg/MdePkg.dec
diff --git
a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
index d5e7e0d01446..ca789aa6ada3 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
+++
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
@@ -35,6 +35,7 @@
RandTests.c
Pkcs7EkuTests.c
OaepEncryptTests.c
+ RsaPssTests.c

[Packages]
MdePkg/MdePkg.dec
--
2.14.3.windows.1








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

Yao, Jiewen
 

Hi Ard
Can it be resolved in patch - https://edk2.groups.io/g/devel/message/75135?p=,,,20,0,0,0::Created,,cryptopkg,20,2,0,82822574 ?

I really hope to improve CI to catch this earlier...

Hi Jian
Would you please merge this ASAP?

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Ard
Biesheuvel
Sent: Monday, May 17, 2021 4:36 PM
To: edk2-devel-groups-io <devel@edk2.groups.io>; Agrawal, Sachin
<sachin.agrawal@...>
Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>;
Lu, XiaoyuX <xiaoyux.lu@...>; Jiang, Guomin <guomin.jiang@...>
Subject: Re: [edk2-devel] [PATCH v3 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS
verify support

On Tue, 4 May 2021 at 19:54, Agrawal, Sachin <sachin.agrawal@...>
wrote:

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@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Xiaoyu Lu <xiaoyux.lu@...>
Cc: Guomin Jiang <guomin.jiang@...>

Signed-off-by: Sachin Agrawal <sachin.agrawal@...>
This patch is now merged, and is breaking the build on AARCH64/CLANG38:

CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c:117:7: error: variable
'Result' is used uninitialized whenever 'if' condition is true
[-Werror,-Wsometimes-uninitialized]
if (EvpVerifyCtx == NULL) {
^~~~~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:150:10: note:
uninitialized use occurs here
return Result;
^~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:117:3: note: remove
the 'if' if its condition is always false
if (EvpVerifyCtx == NULL) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:110:7: error:
variable 'Result' is used uninitialized whenever 'if' condition is
true [-Werror,-Wsometimes-uninitialized]
if (EvpRsaKey == NULL) {
^~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:150:10: note:
uninitialized use occurs here
return Result;
^~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:110:3: note: remove
the 'if' if its condition is always false
if (EvpRsaKey == NULL) {
^~~~~~~~~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:79:17: note:
initialize the variable 'Result' to silence this warning
BOOLEAN Result;
^

The diagnostic seems accurate: 'Result' is returned on the _Exit path,
regardless of whether is has ever been initialized or not.

Please fix this asap - it is affecting our CI.

Thanks,
Ard.



---

Notes:
v3:
- Fixed gcc compilation error [CI System]

CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 146
+++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 46 +++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c | 169
+++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c | 60
++++++
CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c | 46 +++++
CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c | 60
++++++
CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 66
+++++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c | 1
+
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c | 191
++++++++++++++++++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c | 2 +
CryptoPkg/Include/Library/BaseCryptLib.h | 74 ++++++++
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 2 +
CryptoPkg/Private/Protocol/Crypto.h | 78 ++++++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h | 3 +
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf | 1
+
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf | 1
+
21 files changed, 956 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
new file mode 100644
index 000000000000..af7cdafa4c47
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
@@ -0,0 +1,146 @@
+/** @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
+const
+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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ 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;
+ }
+ if (SaltLen < DigestLen) {
+ 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, SaltLen) > 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..69c6889fbc4b
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
@@ -0,0 +1,46 @@
+/** @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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c
new file mode 100644
index 000000000000..1ed076e4192c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c
@@ -0,0 +1,169 @@
+/** @file
+ RSA PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file implements following APIs which provide basic capabilities for RSA:
+ 1) RsaPssSign
+
+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
+const
+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;
+ }
+}
+
+
+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ BOOLEAN Result;
+ UINTN RsaSigSize;
+ 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;
+ }
+
+ RsaSigSize = RSA_size (RsaContext);
+ if (*SigSize < RsaSigSize) {
+ *SigSize = RsaSigSize;
+ return FALSE;
+ }
+
+ if (Signature == NULL) {
+ return FALSE;
+ }
+
+ if (SaltLen < DigestLen) {
+ 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_DigestSignInit(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, SaltLen) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestSignUpdate(pEvpVerifyCtx, Message,
(UINT32)MsgSize) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestSignFinal(pEvpVerifyCtx, Signature, 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/CryptRsaPssSignNull.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c
new file mode 100644
index 000000000000..4ed2dfce992a
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c
@@ -0,0 +1,60 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssSign
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c
b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c
new file mode 100644
index 000000000000..69c6889fbc4b
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c
@@ -0,0 +1,46 @@
+/** @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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c
b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c
new file mode 100644
index 000000000000..4ed2dfce992a
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c
@@ -0,0 +1,60 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssSign
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
index 8b43d1363cb9..412fbdbff52c 100644
--- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
+++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
@@ -1552,6 +1552,72 @@ RsaPkcs1Verify (
CALL_CRYPTO_SERVICE (RsaPkcs1Verify, (RsaContext, MessageHash,
HashSize, Signature, SigSize), FALSE);
}

+/**
+ 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ CALL_CRYPTO_SERVICE (RsaPssVerify, (RsaContext, Message, MsgSize,
Signature, SigSize, DigestLen, SaltLen), FALSE);
+}
+
+/**
+ 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ CALL_CRYPTO_SERVICE (RsaPssSign, (RsaContext, Message, MsgSize,
DigestLen, SaltLen, Signature, SigSize), FALSE);
+}
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.

diff --git
a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
index b7fcea3ff7e4..3873de973064 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
@@ -16,6 +16,7 @@ SUITE_DESC mSuiteDesc[] = {
{"HMAC verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mHmacTestNum, mHmacTest},
{"BlockCipher verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mBlockCipherTestNum, mBlockCipherTest},
{"RSA verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mRsaTestNum, mRsaTest},
+ {"RSA PSS verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mRsaPssTestNum, mRsaPssTest},
{"RSACert verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mRsaCertTestNum, mRsaCertTest},
{"PKCS7 verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mPkcs7TestNum, mPkcs7Test},
{"PKCS5 verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,
&mPkcs5TestNum, mPkcs5Test},
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c
new file mode 100644
index 000000000000..5ac2f325fbdd
--- /dev/null
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c
@@ -0,0 +1,191 @@
+/** @file
+ Application for RSA PSS Primitives Validation.
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "TestBaseCryptLib.h"
+
+//
+// RSA PSS test vectors from NIST FIPS 186-3 RSA files
+//
+
+//
+// Public Modulus of RSA Key
+//
+UINT8 RsaPssN[]={
+ 0xa4, 0x7d, 0x04, 0xe7, 0xca, 0xcd, 0xba, 0x4e, 0xa2, 0x6e, 0xca, 0x8a,
0x4c, 0x6e, 0x14, 0x56,
+ 0x3c, 0x2c, 0xe0, 0x3b, 0x62, 0x3b, 0x76, 0x8c, 0x0d, 0x49, 0x86, 0x8a,
0x57, 0x12, 0x13, 0x01,
+ 0xdb, 0xf7, 0x83, 0xd8, 0x2f, 0x4c, 0x05, 0x5e, 0x73, 0x96, 0x0e, 0x70,
0x55, 0x01, 0x87, 0xd0,
+ 0xaf, 0x62, 0xac, 0x34, 0x96, 0xf0, 0xa3, 0xd9, 0x10, 0x3c, 0x2e, 0xb7,
0x91, 0x9a, 0x72, 0x75,
+ 0x2f, 0xa7, 0xce, 0x8c, 0x68, 0x8d, 0x81, 0xe3, 0xae, 0xe9, 0x94, 0x68,
0x88, 0x7a, 0x15, 0x28,
+ 0x8a, 0xfb, 0xb7, 0xac, 0xb8, 0x45, 0xb7, 0xc5, 0x22, 0xb5, 0xc6, 0x4e,
0x67, 0x8f, 0xcd, 0x3d,
+ 0x22, 0xfe, 0xb8, 0x4b, 0x44, 0x27, 0x27, 0x00, 0xbe, 0x52, 0x7d, 0x2b,
0x20, 0x25, 0xa3, 0xf8,
+ 0x3c, 0x23, 0x83, 0xbf, 0x6a, 0x39, 0xcf, 0x5b, 0x4e, 0x48, 0xb3, 0xcf, 0x2f,
0x56, 0xee, 0xf0,
+ 0xdf, 0xff, 0x18, 0x55, 0x5e, 0x31, 0x03, 0x7b, 0x91, 0x52, 0x48, 0x69,
0x48, 0x76, 0xf3, 0x04,
+ 0x78, 0x14, 0x41, 0x51, 0x64, 0xf2, 0xc6, 0x60, 0x88, 0x1e, 0x69, 0x4b,
0x58, 0xc2, 0x80, 0x38,
+ 0xa0, 0x32, 0xad, 0x25, 0x63, 0x4a, 0xad, 0x7b, 0x39, 0x17, 0x1d, 0xee,
0x36, 0x8e, 0x3d, 0x59,
+ 0xbf, 0xb7, 0x29, 0x9e, 0x46, 0x01, 0xd4, 0x58, 0x7e, 0x68, 0xca, 0xaf,
0x8d, 0xb4, 0x57, 0xb7,
+ 0x5a, 0xf4, 0x2f, 0xc0, 0xcf, 0x1a, 0xe7, 0xca, 0xce, 0xd2, 0x86, 0xd7, 0x7f,
0xac, 0x6c, 0xed,
+ 0xb0, 0x3a, 0xd9, 0x4f, 0x14, 0x33, 0xd2, 0xc9, 0x4d, 0x08, 0xe6, 0x0b,
0xc1, 0xfd, 0xef, 0x05,
+ 0x43, 0xcd, 0x29, 0x51, 0xe7, 0x65, 0xb3, 0x82, 0x30, 0xfd, 0xd1, 0x8d,
0xe5, 0xd2, 0xca, 0x62,
+ 0x7d, 0xdc, 0x03, 0x2f, 0xe0, 0x5b, 0xbd, 0x2f, 0xf2, 0x1e, 0x2d, 0xb1,
0xc2, 0xf9, 0x4d, 0x8b,
+ };
+
+//
+// Public Exponent of RSA Key
+//
+UINT8 RsaPssE[]={ 0x10, 0xe4, 0x3f };
+
+//
+// Private Exponent of RSA Key
+//
+UINT8 RsaPssD[]={
+ 0x11, 0xa0, 0xdd, 0x28, 0x5f, 0x66, 0x47, 0x1a, 0x8d, 0xa3, 0x0b, 0xcb,
0x8c, 0x24, 0xa1, 0xd5,
+ 0xc8, 0xdb, 0x94, 0x2f, 0xc9, 0x92, 0x07, 0x97, 0xca, 0x44, 0x24, 0x60,
0xa8, 0x00, 0xb7, 0x5b,
+ 0xbc, 0x73, 0x8b, 0xeb, 0x8e, 0xe0, 0xe8, 0x74, 0xb0, 0x53, 0xe6, 0x47,
0x07, 0xdf, 0x4c, 0xfc,
+ 0x78, 0x37, 0xc4, 0x0e, 0x5b, 0xe6, 0x8b, 0x8a, 0x8e, 0x1d, 0x01, 0x45,
0x16, 0x9c, 0xa6, 0x27,
+ 0x1d, 0x81, 0x88, 0x7e, 0x19, 0xa1, 0xcd, 0x95, 0xb2, 0xfd, 0x0d, 0xe0,
0xdb, 0xa3, 0x47, 0xfe,
+ 0x63, 0x7b, 0xcc, 0x6c, 0xdc, 0x24, 0xee, 0xbe, 0x03, 0xc2, 0x4d, 0x4c,
0xf3, 0xa5, 0xc6, 0x15,
+ 0x4d, 0x78, 0xf1, 0x41, 0xfe, 0x34, 0x16, 0x99, 0x24, 0xd0, 0xf8, 0x95,
0x33, 0x65, 0x8e, 0xac,
+ 0xfd, 0xea, 0xe9, 0x9c, 0xe1, 0xa8, 0x80, 0x27, 0xc1, 0x8f, 0xf9, 0x26,
0x53, 0xa8, 0x35, 0xaa,
+ 0x38, 0x91, 0xbf, 0xff, 0xcd, 0x38, 0x8f, 0xfc, 0x23, 0x88, 0xce, 0x2b, 0x10,
0x56, 0x85, 0x43,
+ 0x75, 0x05, 0x02, 0xcc, 0xbc, 0x69, 0xc0, 0x08, 0x8f, 0x1d, 0x69, 0x0e,
0x97, 0xa5, 0xf5, 0xbd,
+ 0xd1, 0x88, 0x8c, 0xd2, 0xfa, 0xa4, 0x3c, 0x04, 0xae, 0x24, 0x53, 0x95,
0x22, 0xdd, 0xe2, 0xd9,
+ 0xc2, 0x02, 0xf6, 0x55, 0xfc, 0x55, 0x75, 0x44, 0x40, 0xb5, 0x3a, 0x15,
0x32, 0xaa, 0xb4, 0x78,
+ 0x51, 0xf6, 0x0b, 0x7a, 0x06, 0x7e, 0x24, 0x0b, 0x73, 0x8e, 0x1b, 0x1d,
0xaa, 0xe6, 0xca, 0x0d,
+ 0x59, 0xee, 0xae, 0x27, 0x68, 0x6c, 0xd8, 0x88, 0x57, 0xe9, 0xad, 0xad,
0xc2, 0xd4, 0xb8, 0x2b,
+ 0x07, 0xa6, 0x1a, 0x35, 0x84, 0x56, 0xaa, 0xf8, 0x07, 0x66, 0x96, 0x93,
0xff, 0xb1, 0x3c, 0x99,
+ 0x64, 0xa6, 0x36, 0x54, 0xca, 0xdc, 0x81, 0xee, 0x59, 0xdf, 0x51, 0x1c,
0xa3, 0xa4, 0xbd, 0x67,
+ };
+
+//
+// Binary message to be signed and verified
+//
+UINT8 PssMessage[]={
+ 0xe0, 0x02, 0x37, 0x7a, 0xff, 0xb0, 0x4f, 0x0f, 0xe4, 0x59, 0x8d, 0xe9,
0xd9, 0x2d, 0x31, 0xd6,
+ 0xc7, 0x86, 0x04, 0x0d, 0x57, 0x76, 0x97, 0x65, 0x56, 0xa2, 0xcf, 0xc5,
0x5e, 0x54, 0xa1, 0xdc,
+ 0xb3, 0xcb, 0x1b, 0x12, 0x6b, 0xd6, 0xa4, 0xbe, 0xd2, 0xa1, 0x84, 0x99,
0x0c, 0xce, 0xa7, 0x73,
+ 0xfc, 0xc7, 0x9d, 0x24, 0x65, 0x53, 0xe6, 0xc6, 0x4f, 0x68, 0x6d, 0x21,
0xad, 0x41, 0x52, 0x67,
+ 0x3c, 0xaf, 0xec, 0x22, 0xae, 0xb4, 0x0f, 0x6a, 0x08, 0x4e, 0x8a, 0x5b,
0x49, 0x91, 0xf4, 0xc6,
+ 0x4c, 0xf8, 0xa9, 0x27, 0xef, 0xfd, 0x0f, 0xd7, 0x75, 0xe7, 0x1e, 0x83, 0x29,
0xe4, 0x1f, 0xdd,
+ 0x44, 0x57, 0xb3, 0x91, 0x11, 0x73, 0x18, 0x7b, 0x4f, 0x09, 0xa8, 0x17,
0xd7, 0x9e, 0xa2, 0x39,
+ 0x7f, 0xc1, 0x2d, 0xfe, 0x3d, 0x9c, 0x9a, 0x02, 0x90, 0xc8, 0xea, 0xd3,
0x1b, 0x66, 0x90, 0xa6,
+ };
+
+//
+// Binary message to be signed and verified
+//
+UINT8 PssSalt[]={
+ 0xd6, 0x6f, 0x72, 0xf1, 0x0b, 0x69, 0x00, 0x1a, 0x5b, 0x59, 0xcf, 0x10,
0x92, 0xad, 0x27, 0x4d,
+ 0x50, 0x56, 0xc4, 0xe9, 0x5c, 0xcc, 0xcf, 0xbe, 0x3b, 0x53, 0x0d, 0xcb,
0x02, 0x7e, 0x57, 0xd6
+ };
+
+//
+// RSASSA-PSS Signature over above message using above keys, salt and
SHA256 digest(and MGF1) algo.
+//
+UINT8 TestVectorSignature[]={
+ 0x4f, 0x9b, 0x42, 0x5c, 0x20, 0x58, 0x46, 0x0e, 0x4a, 0xb2, 0xf5, 0xc9,
0x63, 0x84, 0xda, 0x23,
+ 0x27, 0xfd, 0x29, 0x15, 0x0f, 0x01, 0x95, 0x5a, 0x76, 0xb4, 0xef, 0xe9,
0x56, 0xaf, 0x06, 0xdc,
+ 0x08, 0x77, 0x9a, 0x37, 0x4e, 0xe4, 0x60, 0x7e, 0xab, 0x61, 0xa9, 0x3a,
0xdc, 0x56, 0x08, 0xf4,
+ 0xec, 0x36, 0xe4, 0x7f, 0x2a, 0x0f, 0x75, 0x4e, 0x8f, 0xf8, 0x39, 0xa8, 0xa1,
0x9b, 0x1d, 0xb1,
+ 0xe8, 0x84, 0xea, 0x4c, 0xf3, 0x48, 0xcd, 0x45, 0x50, 0x69, 0xeb, 0x87,
0xaf, 0xd5, 0x36, 0x45,
+ 0xb4, 0x4e, 0x28, 0xa0, 0xa5, 0x68, 0x08, 0xf5, 0x03, 0x1d, 0xa5, 0xba,
0x91, 0x12, 0x76, 0x8d,
+ 0xfb, 0xfc, 0xa4, 0x4e, 0xbe, 0x63, 0xa0, 0xc0, 0x57, 0x2b, 0x73, 0x1d,
0x66, 0x12, 0x2f, 0xb7,
+ 0x16, 0x09, 0xbe, 0x14, 0x80, 0xfa, 0xa4, 0xe4, 0xf7, 0x5e, 0x43, 0x95,
0x51, 0x59, 0xd7, 0x0f,
+ 0x08, 0x1e, 0x2a, 0x32, 0xfb, 0xb1, 0x9a, 0x48, 0xb9, 0xf1, 0x62, 0xcf,
0x6b, 0x2f, 0xb4, 0x45,
+ 0xd2, 0xd6, 0x99, 0x4b, 0xc5, 0x89, 0x10, 0xa2, 0x6b, 0x59, 0x43, 0x47,
0x78, 0x03, 0xcd, 0xaa,
+ 0xa1, 0xbd, 0x74, 0xb0, 0xda, 0x0a, 0x5d, 0x05, 0x3d, 0x8b, 0x1d, 0xc5,
0x93, 0x09, 0x1d, 0xb5,
+ 0x38, 0x83, 0x83, 0xc2, 0x60, 0x79, 0xf3, 0x44, 0xe2, 0xae, 0xa6, 0x00,
0xd0, 0xe3, 0x24, 0x16,
+ 0x4b, 0x45, 0x0f, 0x7b, 0x9b, 0x46, 0x51, 0x11, 0xb7, 0x26, 0x5f, 0x3b,
0x1b, 0x06, 0x30, 0x89,
+ 0xae, 0x7e, 0x26, 0x23, 0xfc, 0x0f, 0xda, 0x80, 0x52, 0xcf, 0x4b, 0xf3, 0x37,
0x91, 0x02, 0xfb,
+ 0xf7, 0x1d, 0x7c, 0x98, 0xe8, 0x25, 0x86, 0x64, 0xce, 0xed, 0x63, 0x7d,
0x20, 0xf9, 0x5f, 0xf0,
+ 0x11, 0x18, 0x81, 0xe6, 0x50, 0xce, 0x61, 0xf2, 0x51, 0xd9, 0xc3, 0xa6,
0x29, 0xef, 0x22, 0x2d,
+ };
+
+
+VOID *mRsa;
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyRsaPssPreReq (
+ UNIT_TEST_CONTEXT Context
+ )
+{
+ mRsa = RsaNew ();
+
+ if (mRsa == NULL) {
+ return UNIT_TEST_ERROR_TEST_FAILED;
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+VOID
+EFIAPI
+TestVerifyRsaPssCleanUp (
+ UNIT_TEST_CONTEXT Context
+ )
+{
+ if (mRsa != NULL) {
+ RsaFree (mRsa);
+ mRsa = NULL;
+ }
+}
+
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyRsaPssSignVerify (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ UINT8 *Signature;
+ UINTN SigSize;
+ BOOLEAN Status;
+
+ Status = RsaSetKey (mRsa, RsaKeyN, RsaPssN, sizeof (RsaPssN));
+ UT_ASSERT_TRUE (Status);
+
+ Status = RsaSetKey (mRsa, RsaKeyE, RsaPssE, sizeof (RsaPssE));
+ UT_ASSERT_TRUE (Status);
+
+ Status = RsaSetKey (mRsa, RsaKeyD, RsaPssD, sizeof (RsaPssD));
+ UT_ASSERT_TRUE (Status);
+
+ SigSize = 0;
+ Status = RsaPssSign (mRsa, PssMessage, sizeof(PssMessage),
SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE, NULL, &SigSize);
+ UT_ASSERT_FALSE (Status);
+ UT_ASSERT_NOT_EQUAL (SigSize, 0);
+
+ Signature = AllocatePool (SigSize);
+ Status = RsaPssSign (mRsa, PssMessage, sizeof(PssMessage),
SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE, Signature, &SigSize);
+ UT_ASSERT_TRUE (Status);
+
+ //
+ // Verify RSA PSS encoded Signature generated in above step
+ //
+ Status = RsaPssVerify (mRsa, PssMessage, sizeof(PssMessage), Signature,
SigSize, SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE);
+ UT_ASSERT_TRUE (Status);
+
+ //
+ // Verify NIST FIPS 186-3 RSA test vector signature
+ //
+ Status = RsaPssVerify (mRsa, PssMessage, sizeof(PssMessage),
TestVectorSignature, sizeof(TestVectorSignature), SHA256_DIGEST_SIZE,
SHA256_DIGEST_SIZE);
+ UT_ASSERT_TRUE (Status);
+
+ FreePool(Signature);
+ return UNIT_TEST_PASSED;
+}
+
+
+TEST_DESC mRsaPssTest[] = {
+ //
+ // -----Description--------------------------------------Class----------------------
Function---------------------------------Pre---------------------Post---------Context
+ //
+ {"TestVerifyRsaPssSignVerify()", "CryptoPkg.BaseCryptLib.Rsa",
TestVerifyRsaPssSignVerify, TestVerifyRsaPssPreReq,
TestVerifyRsaPssCleanUp, NULL},
+};
+
+UINTN mRsaPssTestNum = ARRAY_SIZE(mRsaPssTest);
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
index 7ce20d2e778f..0969b6aea660 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
@@ -295,6 +295,8 @@ TestVerifyRsaPkcs1SignVerify (
Status = RsaPkcs1Verify (mRsa, HashValue, HashSize, Signature, SigSize);
UT_ASSERT_TRUE (Status);

+ FreePool(Signature);
+
return UNIT_TEST_PASSED;
}

diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
b/CryptoPkg/Include/Library/BaseCryptLib.h
index 496121e6a4ed..8c7d5922ef96 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1363,6 +1363,80 @@ RsaPkcs1Verify (
IN UINTN SigSize
);

+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ );
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.

diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index 4aae2aba95d6..49703fa4c963 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -49,6 +49,8 @@
Pk/CryptX509.c
Pk/CryptAuthenticode.c
Pk/CryptTs.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSign.c
Pem/CryptPem.c

SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
index 7509e4273028..0cab5f3ce36c 100644
--- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
@@ -55,6 +55,8 @@
Pk/CryptX509Null.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSignNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c

diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
index 70c985ec93dc..3d3a6fb94a77 100644
--- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
@@ -55,6 +55,8 @@
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
+ Pk/CryptRsaPssNull.c
+ Pk/CryptRsaPssSignNull.c
Pem/CryptPem.c

SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
index 91ec3e03bf5e..07c376ce04bb 100644
--- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
@@ -53,6 +53,8 @@
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSignNull.c
Pem/CryptPem.c

SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
index db506c32f724..b98f9635b27b 100644
--- a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
@@ -44,6 +44,8 @@
Pk/CryptAuthenticode.c
Pk/CryptTs.c
Pem/CryptPem.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSign.c

SysCall/UnitTestHostCrtWrapper.c

diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
index 689af4fedd68..faf959827b90 100644
--- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
+++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
@@ -50,6 +50,8 @@
Pk/CryptTsNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c
+ Pk/CryptRsaPssNull.c
+ Pk/CryptRsaPssSignNull.c

[Packages]
MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Private/Protocol/Crypto.h
b/CryptoPkg/Private/Protocol/Crypto.h
index 17930a77a60e..e304302c9445 100644
--- a/CryptoPkg/Private/Protocol/Crypto.h
+++ b/CryptoPkg/Private/Protocol/Crypto.h
@@ -3408,6 +3408,81 @@ EFI_STATUS
IN OUT UINTN *DataSize
);

+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding
scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS
encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the
signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA
signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS
encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in
bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_RSA_PSS_SIGN)(
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_RSA_PSS_VERIFY)(
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen
+ );
+
+

///
/// EDK II Crypto Protocol
@@ -3593,6 +3668,9 @@ struct _EDKII_CRYPTO_PROTOCOL {
EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT TlsGetHostPublicCert;
EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY TlsGetHostPrivateKey;
EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST
TlsGetCertRevocationList;
+ /// RSA PSS
+ EDKII_CRYPTO_RSA_PSS_SIGN RsaPssSign;
+ EDKII_CRYPTO_RSA_PSS_VERIFY RsaPssVerify;
};

extern GUID gEdkiiCryptoProtocolGuid;
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
index 9d1cb150a113..25c1379f1a77 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
@@ -83,6 +83,9 @@ extern TEST_DESC mPrngTest[];
extern UINTN mOaepTestNum;
extern TEST_DESC mOaepTest[];

+extern UINTN mRsaPssTestNum;
+extern TEST_DESC mRsaPssTest[];
+
/** Creates a framework you can use */
EFI_STATUS
EFIAPI
diff --git
a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
index 300b98e40b33..00c869265080 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
+++
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
@@ -34,6 +34,7 @@
RandTests.c
Pkcs7EkuTests.c
OaepEncryptTests.c
+ RsaPssTests.c

[Packages]
MdePkg/MdePkg.dec
diff --git
a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
index d5e7e0d01446..ca789aa6ada3 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
+++
b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
@@ -35,6 +35,7 @@
RandTests.c
Pkcs7EkuTests.c
OaepEncryptTests.c
+ RsaPssTests.c

[Packages]
MdePkg/MdePkg.dec
--
2.14.3.windows.1








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

Ard Biesheuvel
 

On Tue, 4 May 2021 at 19:54, Agrawal, Sachin <sachin.agrawal@...> wrote:

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@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Xiaoyu Lu <xiaoyux.lu@...>
Cc: Guomin Jiang <guomin.jiang@...>

Signed-off-by: Sachin Agrawal <sachin.agrawal@...>
This patch is now merged, and is breaking the build on AARCH64/CLANG38:

CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c:117:7: error: variable
'Result' is used uninitialized whenever 'if' condition is true
[-Werror,-Wsometimes-uninitialized]
if (EvpVerifyCtx == NULL) {
^~~~~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:150:10: note:
uninitialized use occurs here
return Result;
^~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:117:3: note: remove
the 'if' if its condition is always false
if (EvpVerifyCtx == NULL) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:110:7: error:
variable 'Result' is used uninitialized whenever 'if' condition is
true [-Werror,-Wsometimes-uninitialized]
if (EvpRsaKey == NULL) {
^~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:150:10: note:
uninitialized use occurs here
return Result;
^~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:110:3: note: remove
the 'if' if its condition is always false
if (EvpRsaKey == NULL) {
^~~~~~~~~~~~~~~~~~~~~~~~
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:79:17: note:
initialize the variable 'Result' to silence this warning
BOOLEAN Result;
^

The diagnostic seems accurate: 'Result' is returned on the _Exit path,
regardless of whether is has ever been initialized or not.

Please fix this asap - it is affecting our CI.

Thanks,
Ard.



---

Notes:
v3:
- Fixed gcc compilation error [CI System]

CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 146 +++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 46 +++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c | 169 +++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c | 60 ++++++
CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c | 46 +++++
CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c | 60 ++++++
CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 66 +++++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c | 1 +
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c | 191 ++++++++++++++++++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c | 2 +
CryptoPkg/Include/Library/BaseCryptLib.h | 74 ++++++++
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf | 2 +
CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 2 +
CryptoPkg/Private/Protocol/Crypto.h | 78 ++++++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h | 3 +
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf | 1 +
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf | 1 +
21 files changed, 956 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
new file mode 100644
index 000000000000..af7cdafa4c47
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c
@@ -0,0 +1,146 @@
+/** @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
+const
+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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ 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;
+ }
+ if (SaltLen < DigestLen) {
+ 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, SaltLen) > 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..69c6889fbc4b
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c
@@ -0,0 +1,46 @@
+/** @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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c
new file mode 100644
index 000000000000..1ed076e4192c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c
@@ -0,0 +1,169 @@
+/** @file
+ RSA PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file implements following APIs which provide basic capabilities for RSA:
+ 1) RsaPssSign
+
+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
+const
+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;
+ }
+}
+
+
+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ BOOLEAN Result;
+ UINTN RsaSigSize;
+ 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;
+ }
+
+ RsaSigSize = RSA_size (RsaContext);
+ if (*SigSize < RsaSigSize) {
+ *SigSize = RsaSigSize;
+ return FALSE;
+ }
+
+ if (Signature == NULL) {
+ return FALSE;
+ }
+
+ if (SaltLen < DigestLen) {
+ 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_DigestSignInit(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, SaltLen) > 0;
+ }
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestSignUpdate(pEvpVerifyCtx, Message, (UINT32)MsgSize) > 0;
+ }
+ if (Result) {
+ Result = EVP_DigestSignFinal(pEvpVerifyCtx, Signature, 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/CryptRsaPssSignNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c
new file mode 100644
index 000000000000..4ed2dfce992a
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c
@@ -0,0 +1,60 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssSign
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c
new file mode 100644
index 000000000000..69c6889fbc4b
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c
@@ -0,0 +1,46 @@
+/** @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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c
new file mode 100644
index 000000000000..4ed2dfce992a
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c
@@ -0,0 +1,60 @@
+/** @file
+ RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
+
+ This file does not provide real capabilities for following APIs in RSA handling:
+ 1) RsaPssSign
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
index 8b43d1363cb9..412fbdbff52c 100644
--- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
+++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
@@ -1552,6 +1552,72 @@ RsaPkcs1Verify (
CALL_CRYPTO_SERVICE (RsaPkcs1Verify, (RsaContext, MessageHash, HashSize, Signature, SigSize), FALSE);
}

+/**
+ 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ )
+{
+ CALL_CRYPTO_SERVICE (RsaPssVerify, (RsaContext, Message, MsgSize, Signature, SigSize, DigestLen, SaltLen), FALSE);
+}
+
+/**
+ 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ CALL_CRYPTO_SERVICE (RsaPssSign, (RsaContext, Message, MsgSize, DigestLen, SaltLen, Signature, SigSize), FALSE);
+}
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.

diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
index b7fcea3ff7e4..3873de973064 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
@@ -16,6 +16,7 @@ SUITE_DESC mSuiteDesc[] = {
{"HMAC verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mHmacTestNum, mHmacTest},
{"BlockCipher verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mBlockCipherTestNum, mBlockCipherTest},
{"RSA verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mRsaTestNum, mRsaTest},
+ {"RSA PSS verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mRsaPssTestNum, mRsaPssTest},
{"RSACert verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mRsaCertTestNum, mRsaCertTest},
{"PKCS7 verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mPkcs7TestNum, mPkcs7Test},
{"PKCS5 verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mPkcs5TestNum, mPkcs5Test},
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c
new file mode 100644
index 000000000000..5ac2f325fbdd
--- /dev/null
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c
@@ -0,0 +1,191 @@
+/** @file
+ Application for RSA PSS Primitives Validation.
+
+Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "TestBaseCryptLib.h"
+
+//
+// RSA PSS test vectors from NIST FIPS 186-3 RSA files
+//
+
+//
+// Public Modulus of RSA Key
+//
+UINT8 RsaPssN[]={
+ 0xa4, 0x7d, 0x04, 0xe7, 0xca, 0xcd, 0xba, 0x4e, 0xa2, 0x6e, 0xca, 0x8a, 0x4c, 0x6e, 0x14, 0x56,
+ 0x3c, 0x2c, 0xe0, 0x3b, 0x62, 0x3b, 0x76, 0x8c, 0x0d, 0x49, 0x86, 0x8a, 0x57, 0x12, 0x13, 0x01,
+ 0xdb, 0xf7, 0x83, 0xd8, 0x2f, 0x4c, 0x05, 0x5e, 0x73, 0x96, 0x0e, 0x70, 0x55, 0x01, 0x87, 0xd0,
+ 0xaf, 0x62, 0xac, 0x34, 0x96, 0xf0, 0xa3, 0xd9, 0x10, 0x3c, 0x2e, 0xb7, 0x91, 0x9a, 0x72, 0x75,
+ 0x2f, 0xa7, 0xce, 0x8c, 0x68, 0x8d, 0x81, 0xe3, 0xae, 0xe9, 0x94, 0x68, 0x88, 0x7a, 0x15, 0x28,
+ 0x8a, 0xfb, 0xb7, 0xac, 0xb8, 0x45, 0xb7, 0xc5, 0x22, 0xb5, 0xc6, 0x4e, 0x67, 0x8f, 0xcd, 0x3d,
+ 0x22, 0xfe, 0xb8, 0x4b, 0x44, 0x27, 0x27, 0x00, 0xbe, 0x52, 0x7d, 0x2b, 0x20, 0x25, 0xa3, 0xf8,
+ 0x3c, 0x23, 0x83, 0xbf, 0x6a, 0x39, 0xcf, 0x5b, 0x4e, 0x48, 0xb3, 0xcf, 0x2f, 0x56, 0xee, 0xf0,
+ 0xdf, 0xff, 0x18, 0x55, 0x5e, 0x31, 0x03, 0x7b, 0x91, 0x52, 0x48, 0x69, 0x48, 0x76, 0xf3, 0x04,
+ 0x78, 0x14, 0x41, 0x51, 0x64, 0xf2, 0xc6, 0x60, 0x88, 0x1e, 0x69, 0x4b, 0x58, 0xc2, 0x80, 0x38,
+ 0xa0, 0x32, 0xad, 0x25, 0x63, 0x4a, 0xad, 0x7b, 0x39, 0x17, 0x1d, 0xee, 0x36, 0x8e, 0x3d, 0x59,
+ 0xbf, 0xb7, 0x29, 0x9e, 0x46, 0x01, 0xd4, 0x58, 0x7e, 0x68, 0xca, 0xaf, 0x8d, 0xb4, 0x57, 0xb7,
+ 0x5a, 0xf4, 0x2f, 0xc0, 0xcf, 0x1a, 0xe7, 0xca, 0xce, 0xd2, 0x86, 0xd7, 0x7f, 0xac, 0x6c, 0xed,
+ 0xb0, 0x3a, 0xd9, 0x4f, 0x14, 0x33, 0xd2, 0xc9, 0x4d, 0x08, 0xe6, 0x0b, 0xc1, 0xfd, 0xef, 0x05,
+ 0x43, 0xcd, 0x29, 0x51, 0xe7, 0x65, 0xb3, 0x82, 0x30, 0xfd, 0xd1, 0x8d, 0xe5, 0xd2, 0xca, 0x62,
+ 0x7d, 0xdc, 0x03, 0x2f, 0xe0, 0x5b, 0xbd, 0x2f, 0xf2, 0x1e, 0x2d, 0xb1, 0xc2, 0xf9, 0x4d, 0x8b,
+ };
+
+//
+// Public Exponent of RSA Key
+//
+UINT8 RsaPssE[]={ 0x10, 0xe4, 0x3f };
+
+//
+// Private Exponent of RSA Key
+//
+UINT8 RsaPssD[]={
+ 0x11, 0xa0, 0xdd, 0x28, 0x5f, 0x66, 0x47, 0x1a, 0x8d, 0xa3, 0x0b, 0xcb, 0x8c, 0x24, 0xa1, 0xd5,
+ 0xc8, 0xdb, 0x94, 0x2f, 0xc9, 0x92, 0x07, 0x97, 0xca, 0x44, 0x24, 0x60, 0xa8, 0x00, 0xb7, 0x5b,
+ 0xbc, 0x73, 0x8b, 0xeb, 0x8e, 0xe0, 0xe8, 0x74, 0xb0, 0x53, 0xe6, 0x47, 0x07, 0xdf, 0x4c, 0xfc,
+ 0x78, 0x37, 0xc4, 0x0e, 0x5b, 0xe6, 0x8b, 0x8a, 0x8e, 0x1d, 0x01, 0x45, 0x16, 0x9c, 0xa6, 0x27,
+ 0x1d, 0x81, 0x88, 0x7e, 0x19, 0xa1, 0xcd, 0x95, 0xb2, 0xfd, 0x0d, 0xe0, 0xdb, 0xa3, 0x47, 0xfe,
+ 0x63, 0x7b, 0xcc, 0x6c, 0xdc, 0x24, 0xee, 0xbe, 0x03, 0xc2, 0x4d, 0x4c, 0xf3, 0xa5, 0xc6, 0x15,
+ 0x4d, 0x78, 0xf1, 0x41, 0xfe, 0x34, 0x16, 0x99, 0x24, 0xd0, 0xf8, 0x95, 0x33, 0x65, 0x8e, 0xac,
+ 0xfd, 0xea, 0xe9, 0x9c, 0xe1, 0xa8, 0x80, 0x27, 0xc1, 0x8f, 0xf9, 0x26, 0x53, 0xa8, 0x35, 0xaa,
+ 0x38, 0x91, 0xbf, 0xff, 0xcd, 0x38, 0x8f, 0xfc, 0x23, 0x88, 0xce, 0x2b, 0x10, 0x56, 0x85, 0x43,
+ 0x75, 0x05, 0x02, 0xcc, 0xbc, 0x69, 0xc0, 0x08, 0x8f, 0x1d, 0x69, 0x0e, 0x97, 0xa5, 0xf5, 0xbd,
+ 0xd1, 0x88, 0x8c, 0xd2, 0xfa, 0xa4, 0x3c, 0x04, 0xae, 0x24, 0x53, 0x95, 0x22, 0xdd, 0xe2, 0xd9,
+ 0xc2, 0x02, 0xf6, 0x55, 0xfc, 0x55, 0x75, 0x44, 0x40, 0xb5, 0x3a, 0x15, 0x32, 0xaa, 0xb4, 0x78,
+ 0x51, 0xf6, 0x0b, 0x7a, 0x06, 0x7e, 0x24, 0x0b, 0x73, 0x8e, 0x1b, 0x1d, 0xaa, 0xe6, 0xca, 0x0d,
+ 0x59, 0xee, 0xae, 0x27, 0x68, 0x6c, 0xd8, 0x88, 0x57, 0xe9, 0xad, 0xad, 0xc2, 0xd4, 0xb8, 0x2b,
+ 0x07, 0xa6, 0x1a, 0x35, 0x84, 0x56, 0xaa, 0xf8, 0x07, 0x66, 0x96, 0x93, 0xff, 0xb1, 0x3c, 0x99,
+ 0x64, 0xa6, 0x36, 0x54, 0xca, 0xdc, 0x81, 0xee, 0x59, 0xdf, 0x51, 0x1c, 0xa3, 0xa4, 0xbd, 0x67,
+ };
+
+//
+// Binary message to be signed and verified
+//
+UINT8 PssMessage[]={
+ 0xe0, 0x02, 0x37, 0x7a, 0xff, 0xb0, 0x4f, 0x0f, 0xe4, 0x59, 0x8d, 0xe9, 0xd9, 0x2d, 0x31, 0xd6,
+ 0xc7, 0x86, 0x04, 0x0d, 0x57, 0x76, 0x97, 0x65, 0x56, 0xa2, 0xcf, 0xc5, 0x5e, 0x54, 0xa1, 0xdc,
+ 0xb3, 0xcb, 0x1b, 0x12, 0x6b, 0xd6, 0xa4, 0xbe, 0xd2, 0xa1, 0x84, 0x99, 0x0c, 0xce, 0xa7, 0x73,
+ 0xfc, 0xc7, 0x9d, 0x24, 0x65, 0x53, 0xe6, 0xc6, 0x4f, 0x68, 0x6d, 0x21, 0xad, 0x41, 0x52, 0x67,
+ 0x3c, 0xaf, 0xec, 0x22, 0xae, 0xb4, 0x0f, 0x6a, 0x08, 0x4e, 0x8a, 0x5b, 0x49, 0x91, 0xf4, 0xc6,
+ 0x4c, 0xf8, 0xa9, 0x27, 0xef, 0xfd, 0x0f, 0xd7, 0x75, 0xe7, 0x1e, 0x83, 0x29, 0xe4, 0x1f, 0xdd,
+ 0x44, 0x57, 0xb3, 0x91, 0x11, 0x73, 0x18, 0x7b, 0x4f, 0x09, 0xa8, 0x17, 0xd7, 0x9e, 0xa2, 0x39,
+ 0x7f, 0xc1, 0x2d, 0xfe, 0x3d, 0x9c, 0x9a, 0x02, 0x90, 0xc8, 0xea, 0xd3, 0x1b, 0x66, 0x90, 0xa6,
+ };
+
+//
+// Binary message to be signed and verified
+//
+UINT8 PssSalt[]={
+ 0xd6, 0x6f, 0x72, 0xf1, 0x0b, 0x69, 0x00, 0x1a, 0x5b, 0x59, 0xcf, 0x10, 0x92, 0xad, 0x27, 0x4d,
+ 0x50, 0x56, 0xc4, 0xe9, 0x5c, 0xcc, 0xcf, 0xbe, 0x3b, 0x53, 0x0d, 0xcb, 0x02, 0x7e, 0x57, 0xd6
+ };
+
+//
+// RSASSA-PSS Signature over above message using above keys, salt and SHA256 digest(and MGF1) algo.
+//
+UINT8 TestVectorSignature[]={
+ 0x4f, 0x9b, 0x42, 0x5c, 0x20, 0x58, 0x46, 0x0e, 0x4a, 0xb2, 0xf5, 0xc9, 0x63, 0x84, 0xda, 0x23,
+ 0x27, 0xfd, 0x29, 0x15, 0x0f, 0x01, 0x95, 0x5a, 0x76, 0xb4, 0xef, 0xe9, 0x56, 0xaf, 0x06, 0xdc,
+ 0x08, 0x77, 0x9a, 0x37, 0x4e, 0xe4, 0x60, 0x7e, 0xab, 0x61, 0xa9, 0x3a, 0xdc, 0x56, 0x08, 0xf4,
+ 0xec, 0x36, 0xe4, 0x7f, 0x2a, 0x0f, 0x75, 0x4e, 0x8f, 0xf8, 0x39, 0xa8, 0xa1, 0x9b, 0x1d, 0xb1,
+ 0xe8, 0x84, 0xea, 0x4c, 0xf3, 0x48, 0xcd, 0x45, 0x50, 0x69, 0xeb, 0x87, 0xaf, 0xd5, 0x36, 0x45,
+ 0xb4, 0x4e, 0x28, 0xa0, 0xa5, 0x68, 0x08, 0xf5, 0x03, 0x1d, 0xa5, 0xba, 0x91, 0x12, 0x76, 0x8d,
+ 0xfb, 0xfc, 0xa4, 0x4e, 0xbe, 0x63, 0xa0, 0xc0, 0x57, 0x2b, 0x73, 0x1d, 0x66, 0x12, 0x2f, 0xb7,
+ 0x16, 0x09, 0xbe, 0x14, 0x80, 0xfa, 0xa4, 0xe4, 0xf7, 0x5e, 0x43, 0x95, 0x51, 0x59, 0xd7, 0x0f,
+ 0x08, 0x1e, 0x2a, 0x32, 0xfb, 0xb1, 0x9a, 0x48, 0xb9, 0xf1, 0x62, 0xcf, 0x6b, 0x2f, 0xb4, 0x45,
+ 0xd2, 0xd6, 0x99, 0x4b, 0xc5, 0x89, 0x10, 0xa2, 0x6b, 0x59, 0x43, 0x47, 0x78, 0x03, 0xcd, 0xaa,
+ 0xa1, 0xbd, 0x74, 0xb0, 0xda, 0x0a, 0x5d, 0x05, 0x3d, 0x8b, 0x1d, 0xc5, 0x93, 0x09, 0x1d, 0xb5,
+ 0x38, 0x83, 0x83, 0xc2, 0x60, 0x79, 0xf3, 0x44, 0xe2, 0xae, 0xa6, 0x00, 0xd0, 0xe3, 0x24, 0x16,
+ 0x4b, 0x45, 0x0f, 0x7b, 0x9b, 0x46, 0x51, 0x11, 0xb7, 0x26, 0x5f, 0x3b, 0x1b, 0x06, 0x30, 0x89,
+ 0xae, 0x7e, 0x26, 0x23, 0xfc, 0x0f, 0xda, 0x80, 0x52, 0xcf, 0x4b, 0xf3, 0x37, 0x91, 0x02, 0xfb,
+ 0xf7, 0x1d, 0x7c, 0x98, 0xe8, 0x25, 0x86, 0x64, 0xce, 0xed, 0x63, 0x7d, 0x20, 0xf9, 0x5f, 0xf0,
+ 0x11, 0x18, 0x81, 0xe6, 0x50, 0xce, 0x61, 0xf2, 0x51, 0xd9, 0xc3, 0xa6, 0x29, 0xef, 0x22, 0x2d,
+ };
+
+
+VOID *mRsa;
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyRsaPssPreReq (
+ UNIT_TEST_CONTEXT Context
+ )
+{
+ mRsa = RsaNew ();
+
+ if (mRsa == NULL) {
+ return UNIT_TEST_ERROR_TEST_FAILED;
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+VOID
+EFIAPI
+TestVerifyRsaPssCleanUp (
+ UNIT_TEST_CONTEXT Context
+ )
+{
+ if (mRsa != NULL) {
+ RsaFree (mRsa);
+ mRsa = NULL;
+ }
+}
+
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyRsaPssSignVerify (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ UINT8 *Signature;
+ UINTN SigSize;
+ BOOLEAN Status;
+
+ Status = RsaSetKey (mRsa, RsaKeyN, RsaPssN, sizeof (RsaPssN));
+ UT_ASSERT_TRUE (Status);
+
+ Status = RsaSetKey (mRsa, RsaKeyE, RsaPssE, sizeof (RsaPssE));
+ UT_ASSERT_TRUE (Status);
+
+ Status = RsaSetKey (mRsa, RsaKeyD, RsaPssD, sizeof (RsaPssD));
+ UT_ASSERT_TRUE (Status);
+
+ SigSize = 0;
+ Status = RsaPssSign (mRsa, PssMessage, sizeof(PssMessage), SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE, NULL, &SigSize);
+ UT_ASSERT_FALSE (Status);
+ UT_ASSERT_NOT_EQUAL (SigSize, 0);
+
+ Signature = AllocatePool (SigSize);
+ Status = RsaPssSign (mRsa, PssMessage, sizeof(PssMessage), SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE, Signature, &SigSize);
+ UT_ASSERT_TRUE (Status);
+
+ //
+ // Verify RSA PSS encoded Signature generated in above step
+ //
+ Status = RsaPssVerify (mRsa, PssMessage, sizeof(PssMessage), Signature, SigSize, SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE);
+ UT_ASSERT_TRUE (Status);
+
+ //
+ // Verify NIST FIPS 186-3 RSA test vector signature
+ //
+ Status = RsaPssVerify (mRsa, PssMessage, sizeof(PssMessage), TestVectorSignature, sizeof(TestVectorSignature), SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE);
+ UT_ASSERT_TRUE (Status);
+
+ FreePool(Signature);
+ return UNIT_TEST_PASSED;
+}
+
+
+TEST_DESC mRsaPssTest[] = {
+ //
+ // -----Description--------------------------------------Class----------------------Function---------------------------------Pre---------------------Post---------Context
+ //
+ {"TestVerifyRsaPssSignVerify()", "CryptoPkg.BaseCryptLib.Rsa", TestVerifyRsaPssSignVerify, TestVerifyRsaPssPreReq, TestVerifyRsaPssCleanUp, NULL},
+};
+
+UINTN mRsaPssTestNum = ARRAY_SIZE(mRsaPssTest);
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
index 7ce20d2e778f..0969b6aea660 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
@@ -295,6 +295,8 @@ TestVerifyRsaPkcs1SignVerify (
Status = RsaPkcs1Verify (mRsa, HashValue, HashSize, Signature, SigSize);
UT_ASSERT_TRUE (Status);

+ FreePool(Signature);
+
return UNIT_TEST_PASSED;
}

diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index 496121e6a4ed..8c7d5922ef96 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1363,6 +1363,80 @@ RsaPkcs1Verify (
IN UINTN SigSize
);

+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @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,
+ IN UINT16 SaltLen
+ );
+
/**
Retrieve the RSA Private Key from the password-protected PEM key data.

diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index 4aae2aba95d6..49703fa4c963 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -49,6 +49,8 @@
Pk/CryptX509.c
Pk/CryptAuthenticode.c
Pk/CryptTs.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSign.c
Pem/CryptPem.c

SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
index 7509e4273028..0cab5f3ce36c 100644
--- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
@@ -55,6 +55,8 @@
Pk/CryptX509Null.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSignNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c

diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
index 70c985ec93dc..3d3a6fb94a77 100644
--- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
@@ -55,6 +55,8 @@
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
+ Pk/CryptRsaPssNull.c
+ Pk/CryptRsaPssSignNull.c
Pem/CryptPem.c

SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
index 91ec3e03bf5e..07c376ce04bb 100644
--- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
@@ -53,6 +53,8 @@
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSignNull.c
Pem/CryptPem.c

SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
index db506c32f724..b98f9635b27b 100644
--- a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
@@ -44,6 +44,8 @@
Pk/CryptAuthenticode.c
Pk/CryptTs.c
Pem/CryptPem.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSign.c

SysCall/UnitTestHostCrtWrapper.c

diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
index 689af4fedd68..faf959827b90 100644
--- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
+++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
@@ -50,6 +50,8 @@
Pk/CryptTsNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c
+ Pk/CryptRsaPssNull.c
+ Pk/CryptRsaPssSignNull.c

[Packages]
MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h
index 17930a77a60e..e304302c9445 100644
--- a/CryptoPkg/Private/Protocol/Crypto.h
+++ b/CryptoPkg/Private/Protocol/Crypto.h
@@ -3408,6 +3408,81 @@ EFI_STATUS
IN OUT UINTN *DataSize
);

+/**
+ Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
+
+ This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Message is NULL, then return FALSE.
+ If MsgSize is zero or > INT_MAX, then return FALSE.
+ If DigestLen is NOT 32, 48 or 64, return FALSE.
+ If SaltLen is < DigestLen, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Message Pointer to octet message to be signed.
+ @param[in] MsgSize Size of the message in bytes.
+ @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation.
+ @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding.
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_RSA_PSS_SIGN)(
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen,
+ OUT UINT8 *Signature,
+ IN OUT 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.
+ Salt length should atleast be equal to digest length.
+
+ @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.
+ @param[in] SaltLen Salt length for PSS encoding.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_RSA_PSS_VERIFY)(
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Message,
+ IN UINTN MsgSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize,
+ IN UINT16 DigestLen,
+ IN UINT16 SaltLen
+ );
+
+

///
/// EDK II Crypto Protocol
@@ -3593,6 +3668,9 @@ struct _EDKII_CRYPTO_PROTOCOL {
EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT TlsGetHostPublicCert;
EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY TlsGetHostPrivateKey;
EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST TlsGetCertRevocationList;
+ /// RSA PSS
+ EDKII_CRYPTO_RSA_PSS_SIGN RsaPssSign;
+ EDKII_CRYPTO_RSA_PSS_VERIFY RsaPssVerify;
};

extern GUID gEdkiiCryptoProtocolGuid;
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
index 9d1cb150a113..25c1379f1a77 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
@@ -83,6 +83,9 @@ extern TEST_DESC mPrngTest[];
extern UINTN mOaepTestNum;
extern TEST_DESC mOaepTest[];

+extern UINTN mRsaPssTestNum;
+extern TEST_DESC mRsaPssTest[];
+
/** Creates a framework you can use */
EFI_STATUS
EFIAPI
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
index 300b98e40b33..00c869265080 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
@@ -34,6 +34,7 @@
RandTests.c
Pkcs7EkuTests.c
OaepEncryptTests.c
+ RsaPssTests.c

[Packages]
MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
index d5e7e0d01446..ca789aa6ada3 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
@@ -35,6 +35,7 @@
RandTests.c
Pkcs7EkuTests.c
OaepEncryptTests.c
+ RsaPssTests.c

[Packages]
MdePkg/MdePkg.dec
--
2.14.3.windows.1






Re: [PATCH v2 3/5] GenFv: Arm: support images entered in Thumb mode

Etienne Carriere
 

On Mon, 17 May 2021 at 09:48, gaoliming <gaoliming@...> wrote:

Etienne:
Thanks for your reminder. I try VS compiler and meet with the compiler error on this line.

Here, does if ((SecCoreEntryAddress & 1) != 0) mean the lowest bit of this address is 1?
Yes it does.



Thanks
Liming
-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Etienne
Carriere
发送时间: 2021年5月17日 15:35
收件人: gaoliming <gaoliming@...>
抄送: devel@edk2.groups.io; Achin Gupta <achin.gupta@...>; Ard
Biesheuvel <ardb+tianocore@...>; Jiewen Yao
<jiewen.yao@...>; Leif Lindholm <leif@...>; Sami Mujawar
<sami.mujawar@...>; Sughosh Ganu <sughosh.ganu@...>; Bob
Feng <bob.c.feng@...>
主题: Re: [edk2-devel] [PATCH v2 3/5] GenFv: Arm: support images entered in
Thumb mode

On Mon, 17 May 2021 at 09:24, gaoliming <gaoliming@...>
wrote:

Acked-by: Liming Gao <gaoliming@...>

-----邮件原件-----
发件人: Etienne Carriere <etienne.carriere@...>
发送时间: 2021年5月17日 13:49
收件人: devel@edk2.groups.io
抄送: Achin Gupta <achin.gupta@...>; Ard Biesheuvel
<ardb+tianocore@...>; Jiewen Yao <jiewen.yao@...>; Leif
Lindholm <leif@...>; Sami Mujawar
<sami.mujawar@...>;
Sughosh Ganu <sughosh.ganu@...>; Etienne Carriere
<etienne.carriere@...>; Bob Feng <bob.c.feng@...>; Liming
Gao <gaoliming@...>
主题: [PATCH v2 3/5] GenFv: Arm: support images entered in Thumb
mode

Change GenFv for Arm architecture to generate a specific jump
instruction as image entry instruction, when the target entry label
is assembled with Thumb instruction set. This is possible since
SecCoreEntryAddress value fetched from the PE32 has its LSBit set when
the entry instruction executes in Thumb mode.

Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Cc: Achin Gupta <achin.gupta@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Leif Lindholm <leif@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
Changes since v1:
- Fix typos in commit log and inline comments
- Change if() test operand to be an explicit boolean
---
BaseTools/Source/C/GenFv/GenFvInternalLib.c | 38
+++++++++++++++-----
1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index 6e296b8ad6..5f3fd4f808 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -34,9 +34,27 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "FvLib.h"
#include "PeCoffLib.h"

-#define ARMT_UNCONDITIONAL_JUMP_INSTRUCTION
0xEB000000
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION
0x14000000

+/*
+ * Arm instruction to jump to Fv entry instruction in Arm or Thumb mode.
+ * From ARM Arch Ref Manual versions b/c/d, section A8.8.25 BL, BLX
(immediate)
+ * BLX (encoding A2) branches to offset in Thumb instruction set mode.
+ * BL (encoding A1) branches to offset in Arm instruction set mode.
+ */
+#define ARM_JUMP_OFFSET_MAX 0xffffff
+#define ARM_JUMP_TO_ARM(Offset) (0xeb000000 | ((Offset - 8) >>
2))
+
+#define _ARM_JUMP_TO_THUMB(Imm32) (0xfa000000 | \
+ (((Imm32) & (1 << 1)) << (24
- 1))
| \
+ (((Imm32) >> 2) & 0x7fffff))
+#define ARM_JUMP_TO_THUMB(Offset)
_ARM_JUMP_TO_THUMB((Offset) - 8)
+
+/*
+ * Arm instruction to retrun from exception (MOVS PC, LR)
+ */
+#define ARM_RETURN_FROM_EXCEPTION 0xE1B0F07E
+
BOOLEAN mArm = FALSE;
BOOLEAN mRiscV = FALSE;
STATIC UINT32 MaxFfsAlignment = 0;
@@ -2203,23 +2221,25 @@ Returns:
// if we found an SEC core entry point then generate a branch
instruction
// to it and populate a debugger SWI entry as well
if (UpdateVectorSec) {
+ UINT32 EntryOffset;

VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM
SEC
vector");

- // B SecEntryPoint - signed_immed_24 part +/-32MB offset
- // on ARM, the PC is always 8 ahead, so we're not really jumping
from
the base address, but from base address + 8
- ResetVector[0] = (INT32)(SecCoreEntryAddress -
FvInfo->BaseAddress - 8) >> 2;
+ EntryOffset = (INT32)(SecCoreEntryAddress -
FvInfo->BaseAddress);

- if (ResetVector[0] > 0x00FFFFFF) {
- Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within
32MB of the start of the FV");
+ if (EntryOffset > ARM_JUMP_OFFSET_MAX) {
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point offset above
1MB of the start of the FV");
return EFI_ABORTED;
}

- // Add opcode for an unconditional branch with no link. i.e.: " B
SecEntryPoint"
- ResetVector[0] |=
ARMT_UNCONDITIONAL_JUMP_INSTRUCTION;
+ if (SecCoreEntryAddress & 1 != 0) {
Sorry, I missed this one.
This needs extra parantheses.

I'll sent a v3. My apologies...

etienne

+ ResetVector[0] = ARM_JUMP_TO_THUMB(EntryOffset);
+ } else {
+ ResetVector[0] = ARM_JUMP_TO_ARM(EntryOffset);
+ }

// SWI handler movs pc,lr. Just in case a debugger uses SWI
- ResetVector[2] = 0xE1B0F07E;
+ ResetVector[2] = ARM_RETURN_FROM_EXCEPTION;

// Place holder to support a common interrupt handler from
ROM.
// Currently not supported. For this to be used the reset vector
would
not be in this FV
--
2.17.1





回复: [edk2-devel] [PATCH v2 3/5] GenFv: Arm: support images entered in Thumb mode

gaoliming
 

Etienne:
Thanks for your reminder. I try VS compiler and meet with the compiler error on this line.

Here, does if ((SecCoreEntryAddress & 1) != 0) mean the lowest bit of this address is 1?

Thanks
Liming

-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Etienne
Carriere
发送时间: 2021年5月17日 15:35
收件人: gaoliming <gaoliming@...>
抄送: devel@edk2.groups.io; Achin Gupta <achin.gupta@...>; Ard
Biesheuvel <ardb+tianocore@...>; Jiewen Yao
<jiewen.yao@...>; Leif Lindholm <leif@...>; Sami Mujawar
<sami.mujawar@...>; Sughosh Ganu <sughosh.ganu@...>; Bob
Feng <bob.c.feng@...>
主题: Re: [edk2-devel] [PATCH v2 3/5] GenFv: Arm: support images entered in
Thumb mode

On Mon, 17 May 2021 at 09:24, gaoliming <gaoliming@...>
wrote:

Acked-by: Liming Gao <gaoliming@...>

-----邮件原件-----
发件人: Etienne Carriere <etienne.carriere@...>
发送时间: 2021年5月17日 13:49
收件人: devel@edk2.groups.io
抄送: Achin Gupta <achin.gupta@...>; Ard Biesheuvel
<ardb+tianocore@...>; Jiewen Yao <jiewen.yao@...>; Leif
Lindholm <leif@...>; Sami Mujawar
<sami.mujawar@...>;
Sughosh Ganu <sughosh.ganu@...>; Etienne Carriere
<etienne.carriere@...>; Bob Feng <bob.c.feng@...>; Liming
Gao <gaoliming@...>
主题: [PATCH v2 3/5] GenFv: Arm: support images entered in Thumb
mode

Change GenFv for Arm architecture to generate a specific jump
instruction as image entry instruction, when the target entry label
is assembled with Thumb instruction set. This is possible since
SecCoreEntryAddress value fetched from the PE32 has its LSBit set when
the entry instruction executes in Thumb mode.

Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Cc: Achin Gupta <achin.gupta@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Leif Lindholm <leif@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
Changes since v1:
- Fix typos in commit log and inline comments
- Change if() test operand to be an explicit boolean
---
BaseTools/Source/C/GenFv/GenFvInternalLib.c | 38
+++++++++++++++-----
1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index 6e296b8ad6..5f3fd4f808 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -34,9 +34,27 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "FvLib.h"
#include "PeCoffLib.h"

-#define ARMT_UNCONDITIONAL_JUMP_INSTRUCTION
0xEB000000
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION
0x14000000

+/*
+ * Arm instruction to jump to Fv entry instruction in Arm or Thumb mode.
+ * From ARM Arch Ref Manual versions b/c/d, section A8.8.25 BL, BLX
(immediate)
+ * BLX (encoding A2) branches to offset in Thumb instruction set mode.
+ * BL (encoding A1) branches to offset in Arm instruction set mode.
+ */
+#define ARM_JUMP_OFFSET_MAX 0xffffff
+#define ARM_JUMP_TO_ARM(Offset) (0xeb000000 | ((Offset - 8) >>
2))
+
+#define _ARM_JUMP_TO_THUMB(Imm32) (0xfa000000 | \
+ (((Imm32) & (1 << 1)) << (24
- 1))
| \
+ (((Imm32) >> 2) & 0x7fffff))
+#define ARM_JUMP_TO_THUMB(Offset)
_ARM_JUMP_TO_THUMB((Offset) - 8)
+
+/*
+ * Arm instruction to retrun from exception (MOVS PC, LR)
+ */
+#define ARM_RETURN_FROM_EXCEPTION 0xE1B0F07E
+
BOOLEAN mArm = FALSE;
BOOLEAN mRiscV = FALSE;
STATIC UINT32 MaxFfsAlignment = 0;
@@ -2203,23 +2221,25 @@ Returns:
// if we found an SEC core entry point then generate a branch
instruction
// to it and populate a debugger SWI entry as well
if (UpdateVectorSec) {
+ UINT32 EntryOffset;

VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM
SEC
vector");

- // B SecEntryPoint - signed_immed_24 part +/-32MB offset
- // on ARM, the PC is always 8 ahead, so we're not really jumping
from
the base address, but from base address + 8
- ResetVector[0] = (INT32)(SecCoreEntryAddress -
FvInfo->BaseAddress - 8) >> 2;
+ EntryOffset = (INT32)(SecCoreEntryAddress -
FvInfo->BaseAddress);

- if (ResetVector[0] > 0x00FFFFFF) {
- Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within
32MB of the start of the FV");
+ if (EntryOffset > ARM_JUMP_OFFSET_MAX) {
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point offset above
1MB of the start of the FV");
return EFI_ABORTED;
}

- // Add opcode for an unconditional branch with no link. i.e.: " B
SecEntryPoint"
- ResetVector[0] |=
ARMT_UNCONDITIONAL_JUMP_INSTRUCTION;
+ if (SecCoreEntryAddress & 1 != 0) {
Sorry, I missed this one.
This needs extra parantheses.

I'll sent a v3. My apologies...

etienne

+ ResetVector[0] = ARM_JUMP_TO_THUMB(EntryOffset);
+ } else {
+ ResetVector[0] = ARM_JUMP_TO_ARM(EntryOffset);
+ }

// SWI handler movs pc,lr. Just in case a debugger uses SWI
- ResetVector[2] = 0xE1B0F07E;
+ ResetVector[2] = ARM_RETURN_FROM_EXCEPTION;

// Place holder to support a common interrupt handler from
ROM.
// Currently not supported. For this to be used the reset vector
would
not be in this FV
--
2.17.1




[PATCH v3 5/5] StandaloneMmPkg: build for 32bit arm machines

Etienne Carriere
 

This change allows to build StandaloneMmPkg components for 32bit Arm
StandaloneMm firmware.

This change mainly moves AArch64/ source files to Arm/ side directory
for several components: StandaloneMmCpu, StandaloneMmCoreEntryPoint
and StandaloneMmMemLib. The source file is built for both 32b and 64b
Arm targets.

Cc: Achin Gupta <achin.gupta@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Leif Lindholm <leif@...>
Cc: Sami Mujawar <sami.mujawar@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
No change since v2

Changes since v1:
- ARM_SMC_ID_MM_COMMUNICATE 32b/64b agnostic helper ID is defined
in ArmStdSmc.h (see 1st commit in this series) instead of being
local to EventHandle.c.
- Fix void occurrence to VOID.
- Fix path in StandaloneMmPkg/StandaloneMmPkg.dsc
---
StandaloneMmPkg/Core/StandaloneMmCore.inf | 2 +-
StandaloneMmPkg/Drivers/StandaloneMmCpu/{AArch64 => }/EventHandle.c | 5 +++--
StandaloneMmPkg/Drivers/StandaloneMmCpu/{AArch64 => }/StandaloneMmCpu.c | 2 +-
StandaloneMmPkg/Drivers/StandaloneMmCpu/{AArch64 => }/StandaloneMmCpu.h | 0
StandaloneMmPkg/Drivers/StandaloneMmCpu/{AArch64 => }/StandaloneMmCpu.inf | 0
StandaloneMmPkg/Include/Library/{AArch64 => Arm}/StandaloneMmCoreEntryPoint.h | 0
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/{AArch64 => Arm}/CreateHobList.c | 2 +-
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/{AArch64 => Arm}/SetPermissions.c | 2 +-
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/{AArch64 => Arm}/StandaloneMmCoreEntryPoint.c | 16 ++++++++--------
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf | 14 +++++++-------
StandaloneMmPkg/Library/StandaloneMmCoreHobLib/{AArch64 => Arm}/StandaloneMmCoreHobLib.c | 0
StandaloneMmPkg/Library/StandaloneMmCoreHobLib/{AArch64 => Arm}/StandaloneMmCoreHobLibInternal.c | 0
StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf | 8 ++++----
StandaloneMmPkg/Library/StandaloneMmMemLib/{AArch64/StandaloneMmMemLibInternal.c => ArmStandaloneMmMemLibInternal.c} | 9 ++++++++-
StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf | 6 +++---
StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf | 2 +-
StandaloneMmPkg/StandaloneMmPkg.dsc | 10 +++++-----
17 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf
index 87bf6e9440..56042b7b39 100644
--- a/StandaloneMmPkg/Core/StandaloneMmCore.inf
+++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf
@@ -17,7 +17,7 @@
PI_SPECIFICATION_VERSION = 0x00010032
ENTRY_POINT = StandaloneMmMain

-# VALID_ARCHITECTURES = IA32 X64 AARCH64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64 ARM

[Sources]
StandaloneMmCore.c
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/EventHandle.c b/StandaloneMmPkg/Drivers/StandaloneMmCpu/EventHandle.c
similarity index 95%
rename from StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/EventHandle.c
rename to StandaloneMmPkg/Drivers/StandaloneMmCpu/EventHandle.c
index 63fbe26642..165d696f99 100644
--- a/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/EventHandle.c
+++ b/StandaloneMmPkg/Drivers/StandaloneMmCpu/EventHandle.c
@@ -2,6 +2,7 @@

Copyright (c) 2016 HP Development Company, L.P.
Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
+ Copyright (c) 2021, Linaro Limited

SPDX-License-Identifier: BSD-2-Clause-Patent

@@ -92,8 +93,8 @@ PiMmStandaloneArmTfCpuDriverEntry (
// receipt of a synchronous MM request. Use the Event ID to distinguish
// between synchronous and asynchronous events.
//
- if ((ARM_SMC_ID_MM_COMMUNICATE_AARCH64 != EventId) &&
- (ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64 != EventId)) {
+ if ((ARM_SMC_ID_MM_COMMUNICATE != EventId) &&
+ (ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ != EventId)) {
DEBUG ((DEBUG_INFO, "UnRecognized Event - 0x%x\n", EventId));
return EFI_INVALID_PARAMETER;
}
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c b/StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.c
similarity index 96%
rename from StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c
rename to StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.c
index d4590bcd19..10097f792f 100644
--- a/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c
+++ b/StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.c
@@ -10,7 +10,7 @@

#include <Base.h>
#include <Pi/PiMmCis.h>
-#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>
+#include <Library/Arm/StandaloneMmCoreEntryPoint.h>
#include <Library/DebugLib.h>
#include <Library/ArmSvcLib.h>
#include <Library/ArmLib.h>
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.h b/StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.h
similarity index 100%
rename from StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.h
rename to StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.h
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf b/StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf
similarity index 100%
rename from StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
rename to StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf
diff --git a/StandaloneMmPkg/Include/Library/AArch64/StandaloneMmCoreEntryPoint.h b/StandaloneMmPkg/Include/Library/Arm/StandaloneMmCoreEntryPoint.h
similarity index 100%
rename from StandaloneMmPkg/Include/Library/AArch64/StandaloneMmCoreEntryPoint.h
rename to StandaloneMmPkg/Include/Library/Arm/StandaloneMmCoreEntryPoint.h
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/CreateHobList.c
similarity index 97%
rename from StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
rename to StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/CreateHobList.c
index 4d4cf3d5ff..85f8194687 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/CreateHobList.c
@@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/MmramMemoryReserve.h>
#include <Guid/MpInformation.h>

-#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>
+#include <Library/Arm/StandaloneMmCoreEntryPoint.h>
#include <Library/ArmMmuLib.h>
#include <Library/ArmSvcLib.h>
#include <Library/DebugLib.h>
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/SetPermissions.c b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/SetPermissions.c
similarity index 96%
rename from StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/SetPermissions.c
rename to StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/SetPermissions.c
index 4a380df4a6..cd4b90823e 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/SetPermissions.c
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/SetPermissions.c
@@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/MmramMemoryReserve.h>
#include <Guid/MpInformation.h>

-#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>
+#include <Library/Arm/StandaloneMmCoreEntryPoint.h>
#include <Library/ArmMmuLib.h>
#include <Library/ArmSvcLib.h>
#include <Library/DebugLib.h>
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/StandaloneMmCoreEntryPoint.c
similarity index 94%
rename from StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c
rename to StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/StandaloneMmCoreEntryPoint.c
index b445d6942e..49cf51a789 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/StandaloneMmCoreEntryPoint.c
@@ -10,7 +10,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent

#include <PiMm.h>

-#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>
+#include <Library/Arm/StandaloneMmCoreEntryPoint.h>

#include <PiPei.h>
#include <Guid/MmramMemoryReserve.h>
@@ -182,13 +182,13 @@ DelegatedEventLoop (
}

if (FfaEnabled) {
- EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64;
+ EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;
EventCompleteSvcArgs->Arg1 = 0;
EventCompleteSvcArgs->Arg2 = 0;
- EventCompleteSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;
+ EventCompleteSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;
EventCompleteSvcArgs->Arg4 = SvcStatus;
} else {
- EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;
+ EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;
EventCompleteSvcArgs->Arg1 = SvcStatus;
}
}
@@ -273,13 +273,13 @@ InitArmSvcArgs (
)
{
if (FeaturePcdGet (PcdFfaEnable)) {
- InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64;
+ InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;
InitMmFoundationSvcArgs->Arg1 = 0;
InitMmFoundationSvcArgs->Arg2 = 0;
- InitMmFoundationSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;
+ InitMmFoundationSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;
InitMmFoundationSvcArgs->Arg4 = *Ret;
} else {
- InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;
+ InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;
InitMmFoundationSvcArgs->Arg1 = *Ret;
}
}
@@ -395,7 +395,7 @@ _ModuleEntryPoint (
//
ProcessModuleEntryPointList (HobStart);

- DEBUG ((DEBUG_INFO, "Shared Cpu Driver EP 0x%lx\n", (UINT64) CpuDriverEntryPoint));
+ DEBUG ((DEBUG_INFO, "Shared Cpu Driver EP %p\n", (VOID *) CpuDriverEntryPoint));

finish:
if (Status == RETURN_UNSUPPORTED) {
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
index 4fa426f58e..1762586cfa 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
@@ -21,10 +21,10 @@
# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only)
#

-[Sources.AARCH64]
- AArch64/StandaloneMmCoreEntryPoint.c
- AArch64/SetPermissions.c
- AArch64/CreateHobList.c
+[Sources.AARCH64, Sources.ARM]
+ Arm/StandaloneMmCoreEntryPoint.c
+ Arm/SetPermissions.c
+ Arm/CreateHobList.c

[Sources.X64]
X64/StandaloneMmCoreEntryPoint.c
@@ -34,14 +34,14 @@
MdeModulePkg/MdeModulePkg.dec
StandaloneMmPkg/StandaloneMmPkg.dec

-[Packages.AARCH64]
+[Packages.ARM, Packages.AARCH64]
ArmPkg/ArmPkg.dec

[LibraryClasses]
BaseLib
DebugLib

-[LibraryClasses.AARCH64]
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
StandaloneMmMmuLib
ArmSvcLib

@@ -51,7 +51,7 @@
gEfiStandaloneMmNonSecureBufferGuid
gEfiArmTfCpuDriverEpDescriptorGuid

-[FeaturePcd.AARCH64]
+[FeaturePcd.ARM, FeaturePcd.AARCH64]
gArmTokenSpaceGuid.PcdFfaEnable

[BuildOptions]
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/AArch64/StandaloneMmCoreHobLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c
similarity index 100%
rename from StandaloneMmPkg/Library/StandaloneMmCoreHobLib/AArch64/StandaloneMmCoreHobLib.c
rename to StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/AArch64/StandaloneMmCoreHobLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLibInternal.c
similarity index 100%
rename from StandaloneMmPkg/Library/StandaloneMmCoreHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
rename to StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLibInternal.c
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
index a2559920e8..34ed536480 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
@@ -22,7 +22,7 @@
LIBRARY_CLASS = HobLib|MM_CORE_STANDALONE

#
-# VALID_ARCHITECTURES = X64 AARCH64
+# VALID_ARCHITECTURES = X64 AARCH64 ARM
#
[Sources.common]
Common.c
@@ -30,9 +30,9 @@
[Sources.X64]
X64/StandaloneMmCoreHobLib.c

-[Sources.AARCH64]
- AArch64/StandaloneMmCoreHobLib.c
- AArch64/StandaloneMmCoreHobLibInternal.c
+[Sources.AARCH64, Sources.ARM]
+ Arm/StandaloneMmCoreHobLib.c
+ Arm/StandaloneMmCoreHobLibInternal.c

[Packages]
MdePkg/MdePkg.dec
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/ArmStandaloneMmMemLibInternal.c
similarity index 86%
rename from StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c
rename to StandaloneMmPkg/Library/StandaloneMmMemLib/ArmStandaloneMmMemLibInternal.c
index 4124959e04..fa7df46413 100644
--- a/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c
+++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/ArmStandaloneMmMemLibInternal.c
@@ -20,6 +20,13 @@
//
extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress;

+#ifdef MDE_CPU_AARCH64
+#define ARM_PHYSICAL_ADDRESS_BITS 36
+#endif
+#ifdef MDE_CPU_ARM
+#define ARM_PHYSICAL_ADDRESS_BITS 32
+#endif
+
/**
Calculate and save the maximum support address.

@@ -31,7 +38,7 @@ MmMemLibInternalCalculateMaximumSupportAddress (
{
UINT8 PhysicalAddressBits;

- PhysicalAddressBits = 36;
+ PhysicalAddressBits = ARM_PHYSICAL_ADDRESS_BITS;

//
// Save the maximum support address in one global variable
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
index 062b0d7a11..b29d97a746 100644
--- a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
+++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
@@ -28,7 +28,7 @@
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64 AARCH64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64 ARM
#

[Sources.Common]
@@ -37,8 +37,8 @@
[Sources.IA32, Sources.X64]
X86StandaloneMmMemLibInternal.c

-[Sources.AARCH64]
- AArch64/StandaloneMmMemLibInternal.c
+[Sources.AARCH64, Sources.ARM]
+ ArmStandaloneMmMemLibInternal.c

[Packages]
MdePkg/MdePkg.dec
diff --git a/StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf b/StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf
index a2a059c5d6..ffb2a6d083 100644
--- a/StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf
+++ b/StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf
@@ -20,7 +20,7 @@
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = AARCH64
+# VALID_ARCHITECTURES = AARCH64|ARM
#
#

diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc
index 0c45df95e2..772af1b72b 100644
--- a/StandaloneMmPkg/StandaloneMmPkg.dsc
+++ b/StandaloneMmPkg/StandaloneMmPkg.dsc
@@ -20,7 +20,7 @@
PLATFORM_VERSION = 1.0
DSC_SPECIFICATION = 0x00010011
OUTPUT_DIRECTORY = Build/StandaloneMm
- SUPPORTED_ARCHITECTURES = AARCH64|X64
+ SUPPORTED_ARCHITECTURES = AARCH64|X64|ARM
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT

@@ -60,7 +60,7 @@
StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf

-[LibraryClasses.AARCH64]
+[LibraryClasses.AARCH64, LibraryClasses.ARM]
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
ArmSvcLib|ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
@@ -118,8 +118,8 @@
StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf

-[Components.AARCH64]
- StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
+[Components.AARCH64, Components.ARM]
+ StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf
StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf

###################################################################################################
@@ -131,7 +131,7 @@
# module style (EDK or EDKII) specified in [Components] section.
#
###################################################################################################
-[BuildOptions.AARCH64]
+[BuildOptions.AARCH64, BuildOptions.ARM]
GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -march=armv8-a+nofp -mstrict-align
GCC:*_*_*_CC_FLAGS = -mstrict-align

--
2.17.1


[PATCH v3 4/5] StandaloneMmPkg: fix pointer/int casts against 32bit architectures

Etienne Carriere
 

Use intermediate (UINTN) cast when casting int from/to pointer. This
is needed as UINT64 values cast from/to 32bit pointer for 32bit
architectures.

Cc: Achin Gupta <achin.gupta@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Leif Lindholm <leif@...>
Cc: Sami Mujawar <sami.mujawar@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
No change since v2
No change since v1
---
StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c | 8 ++++----
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c | 14 +++++++-------
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c | 2 +-
3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c b/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c
index 6884095c49..d4590bcd19 100644
--- a/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c
+++ b/StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c
@@ -164,8 +164,8 @@ StandaloneMmCpuInitialize (

// Share the entry point of the CPU driver
DEBUG ((DEBUG_INFO, "Sharing Cpu Driver EP *0x%lx = 0x%lx\n",
- (UINT64) CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr,
- (UINT64) PiMmStandaloneArmTfCpuDriverEntry));
+ (UINTN) CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr,
+ (UINTN) PiMmStandaloneArmTfCpuDriverEntry));
*(CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr) = PiMmStandaloneArmTfCpuDriverEntry;

// Find the descriptor that contains the whereabouts of the buffer for
@@ -180,8 +180,8 @@ StandaloneMmCpuInitialize (
return Status;
}

- DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINT64) NsCommBufMmramRange->PhysicalStart));
- DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINT64) NsCommBufMmramRange->PhysicalSize));
+ DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINTN) NsCommBufMmramRange->PhysicalStart));
+ DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINTN) NsCommBufMmramRange->PhysicalSize));

CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof(EFI_MMRAM_DESCRIPTOR));
DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.CpuStart, mNsCommBuffer.PhysicalSize));
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
index e8fb96bd6e..4d4cf3d5ff 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
@@ -72,14 +72,14 @@ CreateHobListFromBootInfo (

// Create a hoblist with a PHIT and EOH
HobStart = HobConstructor (
- (VOID *) PayloadBootInfo->SpMemBase,
+ (VOID *) (UINTN) PayloadBootInfo->SpMemBase,
(UINTN) PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase,
- (VOID *) PayloadBootInfo->SpHeapBase,
- (VOID *) (PayloadBootInfo->SpHeapBase + PayloadBootInfo->SpHeapSize)
+ (VOID *) (UINTN) PayloadBootInfo->SpHeapBase,
+ (VOID *) (UINTN) (PayloadBootInfo->SpHeapBase + PayloadBootInfo->SpHeapSize)
);

// Check that the Hoblist starts at the bottom of the Heap
- ASSERT (HobStart == (VOID *) PayloadBootInfo->SpHeapBase);
+ ASSERT (HobStart == (VOID *) (UINTN) PayloadBootInfo->SpHeapBase);

// Build a Boot Firmware Volume HOB
BuildFvHob (PayloadBootInfo->SpImageBase, PayloadBootInfo->SpImageSize);
@@ -190,9 +190,9 @@ CreateHobListFromBootInfo (
MmramRanges[3].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;

// Base and size of heap memory shared by all cpus
- MmramRanges[4].PhysicalStart = (EFI_PHYSICAL_ADDRESS) HobStart;
- MmramRanges[4].CpuStart = (EFI_PHYSICAL_ADDRESS) HobStart;
- MmramRanges[4].PhysicalSize = HobStart->EfiFreeMemoryBottom - (EFI_PHYSICAL_ADDRESS) HobStart;
+ MmramRanges[4].PhysicalStart = (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;
+ MmramRanges[4].CpuStart = (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;
+ MmramRanges[4].PhysicalSize = HobStart->EfiFreeMemoryBottom - (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;
MmramRanges[4].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;

// Base and size of heap memory shared by all cpus
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c
index 6c50f470aa..b445d6942e 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c
@@ -328,7 +328,7 @@ _ModuleEntryPoint (

// Locate PE/COFF File information for the Standalone MM core module
Status = LocateStandaloneMmCorePeCoffData (
- (EFI_FIRMWARE_VOLUME_HEADER *) PayloadBootInfo->SpImageBase,
+ (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PayloadBootInfo->SpImageBase,
&TeData,
&TeDataSize
);
--
2.17.1


[PATCH v3 3/5] GenFv: Arm: support images entered in Thumb mode

Etienne Carriere
 

Change GenFv for Arm architecture to generate a specific jump
instruction as image entry instruction, when the target entry label
is assembled with Thumb instruction set. This is possible since
SecCoreEntryAddress value fetched from the PE32 has its LSBit set when
the entry instruction executes in Thumb mode.

Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Cc: Achin Gupta <achin.gupta@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Leif Lindholm <leif@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
Changes since v2:
- Fix missing parentheses in expression.

Changes since v1:
- Fix typos in commit log and inline comments
- Change if() test operand to be an explicit boolean
---
BaseTools/Source/C/GenFv/GenFvInternalLib.c | 38 +++++++++++++++-----
1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index 6e296b8ad6..6cf9c84e73 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -34,9 +34,27 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "FvLib.h"
#include "PeCoffLib.h"

-#define ARMT_UNCONDITIONAL_JUMP_INSTRUCTION 0xEB000000
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION 0x14000000

+/*
+ * Arm instruction to jump to Fv entry instruction in Arm or Thumb mode.
+ * From ARM Arch Ref Manual versions b/c/d, section A8.8.25 BL, BLX (immediate)
+ * BLX (encoding A2) branches to offset in Thumb instruction set mode.
+ * BL (encoding A1) branches to offset in Arm instruction set mode.
+ */
+#define ARM_JUMP_OFFSET_MAX 0xffffff
+#define ARM_JUMP_TO_ARM(Offset) (0xeb000000 | ((Offset - 8) >> 2))
+
+#define _ARM_JUMP_TO_THUMB(Imm32) (0xfa000000 | \
+ (((Imm32) & (1 << 1)) << (24 - 1)) | \
+ (((Imm32) >> 2) & 0x7fffff))
+#define ARM_JUMP_TO_THUMB(Offset) _ARM_JUMP_TO_THUMB((Offset) - 8)
+
+/*
+ * Arm instruction to retrun from exception (MOVS PC, LR)
+ */
+#define ARM_RETURN_FROM_EXCEPTION 0xE1B0F07E
+
BOOLEAN mArm = FALSE;
BOOLEAN mRiscV = FALSE;
STATIC UINT32 MaxFfsAlignment = 0;
@@ -2203,23 +2221,25 @@ Returns:
// if we found an SEC core entry point then generate a branch instruction
// to it and populate a debugger SWI entry as well
if (UpdateVectorSec) {
+ UINT32 EntryOffset;

VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM SEC vector");

- // B SecEntryPoint - signed_immed_24 part +/-32MB offset
- // on ARM, the PC is always 8 ahead, so we're not really jumping from the base address, but from base address + 8
- ResetVector[0] = (INT32)(SecCoreEntryAddress - FvInfo->BaseAddress - 8) >> 2;
+ EntryOffset = (INT32)(SecCoreEntryAddress - FvInfo->BaseAddress);

- if (ResetVector[0] > 0x00FFFFFF) {
- Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 32MB of the start of the FV");
+ if (EntryOffset > ARM_JUMP_OFFSET_MAX) {
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point offset above 1MB of the start of the FV");
return EFI_ABORTED;
}

- // Add opcode for an unconditional branch with no link. i.e.: " B SecEntryPoint"
- ResetVector[0] |= ARMT_UNCONDITIONAL_JUMP_INSTRUCTION;
+ if ((SecCoreEntryAddress & 1) != 0) {
+ ResetVector[0] = ARM_JUMP_TO_THUMB(EntryOffset);
+ } else {
+ ResetVector[0] = ARM_JUMP_TO_ARM(EntryOffset);
+ }

// SWI handler movs pc,lr. Just in case a debugger uses SWI
- ResetVector[2] = 0xE1B0F07E;
+ ResetVector[2] = ARM_RETURN_FROM_EXCEPTION;

// Place holder to support a common interrupt handler from ROM.
// Currently not supported. For this to be used the reset vector would not be in this FV
--
2.17.1


[PATCH v3 2/5] ArmPkg: prepare 32bit ARM build of StandaloneMmPkg

Etienne Carriere
 

Changes in ArmPkg to prepare building StandaloneMm firmware for
32bit Arm architectures.

Adds MmCommunicationDxe driver and ArmMmuPeiLib and
ArmmmuStandaloneMmLib libraries to the list of the standard
components build for ArmPkg on when ARM architectures.

Changes path of source file AArch64/ArmMmuStandaloneMmLib.c
and compile it for both 32bit and 64bit architectures.

Cc: Achin Gupta <achin.gupta@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Leif Lindholm <leif@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
No change since v2
No change since v1
---
ArmPkg/ArmPkg.dec | 2 +-
ArmPkg/ArmPkg.dsc | 2 +-
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c | 2 +-
ArmPkg/Library/StandaloneMmMmuLib/{AArch64 => }/ArmMmuStandaloneMmLib.c | 15 ++++++++-------
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf | 6 +++---
5 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index 214b2f5892..6ed51edd03 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -137,7 +137,7 @@
# hardware coherency (i.e., no virtualization or cache coherent DMA)
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride|FALSE|BOOLEAN|0x00000043

-[PcdsFeatureFlag.AARCH64]
+[PcdsFeatureFlag.AARCH64, PcdsFeatureFlag.ARM]
## Used to select method for requesting services from S-EL1.<BR><BR>
# TRUE - Selects FF-A calls for communication between S-EL0 and SPMC.<BR>
# FALSE - Selects SVC calls for communication between S-EL0 and SPMC.<BR>
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc
index 926986cf7f..4c79dadf9e 100644
--- a/ArmPkg/ArmPkg.dsc
+++ b/ArmPkg/ArmPkg.dsc
@@ -158,7 +158,7 @@
ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf

-[Components.AARCH64]
+[Components.AARCH64, Components.ARM]
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
diff --git a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c b/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c
index b1e3095809..4ae38a9f22 100644
--- a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c
+++ b/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c
@@ -125,7 +125,7 @@ MmCommunication2Communicate (
}

// SMC Function ID
- CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
+ CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE;

// Cookie
CommunicateSmcArgs.Arg1 = 0;
diff --git a/ArmPkg/Library/StandaloneMmMmuLib/AArch64/ArmMmuStandaloneMmLib.c b/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.c
similarity index 92%
rename from ArmPkg/Library/StandaloneMmMmuLib/AArch64/ArmMmuStandaloneMmLib.c
rename to ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.c
index dd014beec8..20f873e680 100644
--- a/ArmPkg/Library/StandaloneMmMmuLib/AArch64/ArmMmuStandaloneMmLib.c
+++ b/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.c
@@ -2,6 +2,7 @@
File managing the MMU for ARMv8 architecture in S-EL0

Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>
+ Copyright (c) 2021, Linaro Limited
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -62,7 +63,7 @@ SendMemoryPermissionRequest (
// for other Direct Request calls which are not atomic
// We therefore check only for Direct Response by the
// callee.
- if (SvcArgs->Arg0 == ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64) {
+ if (SvcArgs->Arg0 == ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP) {
// A Direct Response means FF-A success
// Now check the payload for errors
// The callee sends back the return value
@@ -164,13 +165,13 @@ GetMemoryPermissions (
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
if (FeaturePcdGet (PcdFfaEnable)) {
// See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.
- SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;
+ SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ;
SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;
SvcArgs.Arg2 = 0;
- SvcArgs.Arg3 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;
+ SvcArgs.Arg3 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES;
SvcArgs.Arg4 = BaseAddress;
} else {
- SvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;
+ SvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES;
SvcArgs.Arg1 = BaseAddress;
SvcArgs.Arg2 = 0;
SvcArgs.Arg3 = 0;
@@ -219,15 +220,15 @@ RequestMemoryPermissionChange (
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
if (FeaturePcdGet (PcdFfaEnable)) {
// See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.
- SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;
+ SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ;
SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;
SvcArgs.Arg2 = 0;
- SvcArgs.Arg3 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;
+ SvcArgs.Arg3 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES;
SvcArgs.Arg4 = BaseAddress;
SvcArgs.Arg5 = EFI_SIZE_TO_PAGES (Length);
SvcArgs.Arg6 = Permissions;
} else {
- SvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;
+ SvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES;
SvcArgs.Arg1 = BaseAddress;
SvcArgs.Arg2 = EFI_SIZE_TO_PAGES (Length);
SvcArgs.Arg3 = Permissions;
diff --git a/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf b/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
index 6c71fe0023..ff20e58980 100644
--- a/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
+++ b/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
@@ -16,14 +16,14 @@
LIBRARY_CLASS = StandaloneMmMmuLib
PI_SPECIFICATION_VERSION = 0x00010032

-[Sources.AARCH64]
- AArch64/ArmMmuStandaloneMmLib.c
+[Sources]
+ ArmMmuStandaloneMmLib.c

[Packages]
ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec

-[FeaturePcd.AARCH64]
+[FeaturePcd.ARM, FeaturePcd.AARCH64]
gArmTokenSpaceGuid.PcdFfaEnable

[LibraryClasses]
--
2.17.1


[PATCH v3 1/5] ArmPkg/IndustryStandard: 32b/64b agnostic FF-A, Mm SVC and Std SMC IDs

Etienne Carriere
 

Defines ARM_SVC_ID_FFA_* and ARM_SVC_ID_SP_* identifiers for 32bit
function IDs as per SMCCC specification. Defines also generic ARM
SVC identifier macros to wrap 32bit or 64bit identifiers upon target
built architecture.

Cc: Achin Gupta <achin.gupta@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Leif Lindholm <leif@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
No change since v2

Changes since v1:
- Define ARM_SMC_ID_MM_COMMUNICATE 32b/64b agnostic helper ID in
ArmStdSmc.h, as expected by few following commits in this series.
---
ArmPkg/Include/IndustryStandard/ArmFfaSvc.h | 12 ++++++++++++
ArmPkg/Include/IndustryStandard/ArmMmSvc.h | 15 +++++++++++++++
ArmPkg/Include/IndustryStandard/ArmStdSmc.h | 8 ++++++++
3 files changed, 35 insertions(+)

diff --git a/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h b/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h
index 65b8343ade..ebcb54b28b 100644
--- a/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h
+++ b/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h
@@ -17,9 +17,21 @@
#define ARM_FFA_SVC_H_

#define ARM_SVC_ID_FFA_VERSION_AARCH32 0x84000063
+#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH32 0x8400006F
+#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH32 0x84000070
#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64 0xC400006F
#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64 0xC4000070

+/* Generic IDs when using AArch32 or AArch64 execution state */
+#ifdef MDE_CPU_AARCH64
+#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64
+#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64
+#endif
+#ifdef MDE_CPU_ARM
+#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH32
+#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH32
+#endif
+
#define SPM_MAJOR_VERSION_FFA 1
#define SPM_MINOR_VERSION_FFA 0

diff --git a/ArmPkg/Include/IndustryStandard/ArmMmSvc.h b/ArmPkg/Include/IndustryStandard/ArmMmSvc.h
index 33d60ccf17..deb3bc99d2 100644
--- a/ArmPkg/Include/IndustryStandard/ArmMmSvc.h
+++ b/ArmPkg/Include/IndustryStandard/ArmMmSvc.h
@@ -15,10 +15,25 @@
* privileged operations on its behalf.
*/
#define ARM_SVC_ID_SPM_VERSION_AARCH32 0x84000060
+#define ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH32 0x84000061
+#define ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH32 0x84000064
+#define ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH32 0x84000065
#define ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64 0xC4000061
#define ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64 0xC4000064
#define ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64 0xC4000065

+/* Generic IDs when using AArch32 or AArch64 execution state */
+#ifdef MDE_CPU_AARCH64
+#define ARM_SVC_ID_SP_EVENT_COMPLETE ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64
+#define ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64
+#define ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64
+#endif
+#ifdef MDE_CPU_ARM
+#define ARM_SVC_ID_SP_EVENT_COMPLETE ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH32
+#define ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH32
+#define ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH32
+#endif
+
#define SET_MEM_ATTR_DATA_PERM_MASK 0x3
#define SET_MEM_ATTR_DATA_PERM_SHIFT 0
#define SET_MEM_ATTR_DATA_PERM_NO_ACCESS 0
diff --git a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
index 67afb0ea2d..9116a291da 100644
--- a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
+++ b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
@@ -49,6 +49,14 @@
#define ARM_SMC_ID_MM_COMMUNICATE_AARCH32 0x84000041
#define ARM_SMC_ID_MM_COMMUNICATE_AARCH64 0xC4000041

+/* Generic ID when using AArch32 or AArch64 execution state */
+#ifdef MDE_CPU_AARCH64
+#define ARM_SMC_ID_MM_COMMUNICATE ARM_SMC_ID_MM_COMMUNICATE_AARCH64
+#endif
+#ifdef MDE_CPU_ARM
+#define ARM_SMC_ID_MM_COMMUNICATE ARM_SMC_ID_MM_COMMUNICATE_AARCH32
+#endif
+
/* MM return error codes */
#define ARM_SMC_MM_RET_SUCCESS 0
#define ARM_SMC_MM_RET_NOT_SUPPORTED -1
--
2.17.1


回复: [edk2-devel] [PATCH v2 06/13] MdePkg/Register/Amd: define GHCB macros for SNP AP creation

gaoliming
 

Laszlo:
Thanks for your detail review. I have no comments for the changes in this patch set. Reviewed-by: Liming Gao <gaoliming@...>

Thanks
Liming

-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Laszlo Ersek
发送时间: 2021年5月17日 11:09
收件人: devel@edk2.groups.io; brijesh.singh@...
抄送: Tom Lendacky <thomas.lendacky@...>; James Bottomley
<jejb@...>; Min Xu <min.m.xu@...>; Jiewen Yao
<jiewen.yao@...>; Jordan Justen <jordan.l.justen@...>; Ard
Biesheuvel <ardb+tianocore@...>; Erdem Aktas
<erdemaktas@...>; Michael D Kinney
<michael.d.kinney@...>; Liming Gao <gaoliming@...>;
Zhiguang Liu <zhiguang.liu@...>
主题: Re: [edk2-devel] [PATCH v2 06/13] MdePkg/Register/Amd: define GHCB
macros for SNP AP creation

Patches v2 01-05 look good to me, thanks for the updates. Now on to this
one:

On 05/13/21 01:46, Brijesh Singh wrote:
From: Tom Lendacky <thomas.lendacky@...>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3275
(1) The "3D" seems like a typo in the bug ticket URL. (This crept into
v2 somehow; v1 didn't have it.)


Version 2 of GHCB introduces NAE for creating AP when SEV-SNP is enabled
in the guest VM. See the GHCB specification, Table 5 "List of Supported
Non-Automatic Events" and sections 4.1.9 and 4.3.2, for further details.

While at it, define the VMSA state save area that is required for creating
the AP. The save area format is defined in AMD APM volume 2, Table B-4
(there is a mistake in the table that defines the size of the reserved
area at offset 0xc8 as a dword, when it is actually a word). The format of
the save area segment registers is further defined in AMD APM volume 2,
sections 10 and 15.5.

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Reviewed-by: Liming Gao <gaoliming@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
MdePkg/Include/Register/Amd/Ghcb.h | 76
++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)

diff --git a/MdePkg/Include/Register/Amd/Ghcb.h
b/MdePkg/Include/Register/Amd/Ghcb.h
index 029904b1c63a..4d1ee29e0a5e 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -55,6 +55,7 @@
#define SVM_EXIT_AP_RESET_HOLD
0x80000004ULL
#define SVM_EXIT_AP_JUMP_TABLE
0x80000005ULL
#define SVM_EXIT_SNP_PAGE_STATE_CHANGE
0x80000010ULL
+#define SVM_EXIT_SNP_AP_CREATION
0x80000013ULL
#define SVM_EXIT_HYPERVISOR_FEATURES
0x8000FFFDULL
#define SVM_EXIT_UNSUPPORTED
0x8000FFFFULL

@@ -83,6 +84,12 @@
#define IOIO_SEG_ES 0
#define IOIO_SEG_DS (BIT11 | BIT10)

+//
+// AP Creation Information
+//
+#define SVM_VMGEXIT_SNP_AP_CREATE_ON_INIT 0
+#define SVM_VMGEXIT_SNP_AP_CREATE 1
+#define SVM_VMGEXIT_SNP_AP_DESTROY 2

typedef PACKED struct {
UINT8 Reserved1[203];
@@ -195,4 +202,73 @@ typedef struct {
SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY];
} SNP_PAGE_STATE_CHANGE_INFO;

+//
+// SEV-ES save area mapping structures used for SEV-SNP AP Creation.
+// Only the fields required to be set to a non-zero value are defined.
+//
+#define SEV_ES_RESET_CODE_SEGMENT_TYPE 0xA
+#define SEV_ES_RESET_DATA_SEGMENT_TYPE 0x2
+
+#define SEV_ES_RESET_LDT_TYPE 0x2
+#define SEV_ES_RESET_TSS_TYPE 0x3
+
+#pragma pack (1)
+typedef union {
+ struct {
+ UINT16 Type:4;
+ UINT16 Sbit:1;
+ UINT16 Dpl:2;
+ UINT16 Present:1;
+ UINT16 Avl:1;
+ UINT16 Reserved1:1;
+ UINT16 Db:1;
+ UINT16 Granularity:1;
+ } Bits;
+ UINT16 Uint16;
+} SEV_ES_SEGMENT_REGISTER_ATTRIBUTES;
+
+typedef struct {
+ UINT16 Selector;
+ SEV_ES_SEGMENT_REGISTER_ATTRIBUTES Attributes;
+ UINT32 Limit;
+ UINT64 Base;
+} SEV_ES_SEGMENT_REGISTER;
+
I'm not saying anything is incorrect about this, but I *am* going to
rant about the APM.

It's simply impenetrable. I've been staring at it for ~50 minutes now,
and I still cannot fully connect it to your code.

[1] In sections "4.8.1 Code-Segment Descriptors" and "4.8.2 Data-Segment
Descriptors", the reader is introduced to the "normal" (not SEV-ES, not
virtualized, not SMM) segment descriptors. Why *these* are relevant
*here* is nothing short of mind-boggling, but please bear with me.

[2] In section "10.2.3 SMRAM State-Save Area", "Table 10-1. AMD64
Architecture SMM State-Save Area", the reader is introduced to the
2+2+4+8 segment register representation. The table only lists "Selector,
Attributes, Limit, Base" as fields, and nothing about the actual
contents. Way too little information. I guess this is covered by the
commit message reference "section 10".

[3] In section "15.5 VMRUN Instruction", "15.5.1 Basic Operation",
paragraph "Segment State in the VMCB", we're given a long-winded,
*textual* only -- no diagram! -- and *differential* (relative)
explanation, on top of the two, above-quoted, locations of the spec. I'm
sorry but this is just impossible to follow. Would it have been a
unaffordable to insert a self-contained diagram here, with
self-contained, absolute explanation?

So let me quote:

The segment registers are stored in the VMCB in a format similar to
that for SMM: both base and limit are fully expanded; segment
attributes are stored as 12-bit values formed by the concatenation
of bits 55:52 and 47:40 from the original 64-bit (in-memory) segment
descriptors; the descriptor “P” bit is used to signal NULL segments
(P=0) where permissible and/or relevant.

So, if we apply this to [1] and [2], the "Selector", "Limit" and "Base"
fields of the SMM and VMCB segment register representation are
explained. Further, we get the following for the Attributes field, by
manual reconstruction:

55 54 53 52 47 46 45 44 43 42 41 40

G D L AVL P [DPL] 1 1 C R A Code Segment Descriptor
* * * * * * ignored bits in 64-bit
mode

G D/B - AVL P [DPL] 1 0 E W A Data Segment Descriptor
* * * * * * * * * * ignored bits in 64-bit
mode

In other words, in the code segment descriptor, D, L, P, DPL, and C
matter. In the data segment descriptor, only P matters.

In particular, what [3] says, quoted above, about the "P" bit, seems
sensible -- "P" is indeed *not* ignored for either segment descriptor
type (code or data).

But then we continure reading [3], and we find (quote again):

The loading of segment attributes from the VMCB (which may have been
overwritten by software) may result in attribute bit values that are
otherwise not allowed. However, only some of the attribute bits are
actually observed by hardware, depending on the segment register in
question:
* CS—D, L, P, and R.
* SS—B, P, E, W, and Code/Data
* DS, ES, FS, GS —D, P, DPL, E, W, and Code/Data.
* LDTR—P, S, and Type (LDT)
* TR—P, S, and Type (32- or 16-bit TSS)

I'm going to ignore SS, LDTR, and TR, but let's check CS and DS.

For CS, the spec says, "D, L, P, and R" are observed by the hardware.
But we've just shown that R is ignored *in general* for code segments in
64-bit mode! In other words, { D, L, P, R } is *not a subset* of { D, L,
P, DPL, C }.

For DS, the spec says here, "D, P, DPL, E, W, and Code/Data" are
observed. I'm going to give "Code/Data" a pass (bit 43 in the original
representation), but the rest is {D, P, DPL, E, W}, which is *not a
subset* of { P }.

Again, from [1], section 4.8.2 specifically, E (expand-down) and W
(writeable) are ignored, DPL is ignored, and D isn't even called D but
"D/B", and it is ignored. So how can the spec say in [3] that the
hardware observes { D, DPL, E, W } when all those are ignored per prior
definition [1]?

- And then I see no reference that SEV-ES uses the same
(circumstantially-defined) segment register format.


So anyway, I'll just accept that I don't understand the spec -- I think
it has inconsistencies. Let's look at the code:

- Bits 43:40 are packed into the "Type" bit-field. That means [1,C,R,A]
for the code segment descriptor, and [0,E,W,A] for data segment descriptors

SEV_ES_RESET_CODE_SEGMENT_TYPE has value 0xA (binary 1010), which
maps
to: 1=1, C=0, R=1, A=0. Problem: per [1], the R bit is ignored, so I
have no clue why we set it.

(2) Can you please explain that? Just in this discussion thread, no need
ot change the code or the commit message.

The C ("conforming") bit actually matters. It is documented in section
"4.7.2 Code-Segment Descriptors" (Code-Segment Descriptor—Legacy Mode).
It seems like "non-conforming" is not a problem here, as long as we
don't use multiple privilege levels, which I think we don't, in
firmware-land. OK.

Then, on to SEV_ES_RESET_DATA_SEGMENT_TYPE. Value 0x2 (binary 0010).
Maps to [0,E,W,A], meaning 0=0, E=0, W=1, A=0.

(3) Why is W (writeable) set to 1, when, according to [1], it is ignored
in 64-bit mode?


- "Sbit" seems to stand for bit 44 from the original representation --
constant 1. OK I think.

- "Dpl", "Present" and "Avl" look OK to me.

- Should "Reserved1" really be called that? It seems to map to bit 53 in
the original representation, and the L (long mode) bit actually matters
for the code segment. (It indeed appears undefined / reserved for data
segments.)

Am I *totally* mistaken here and we're not even talking long mode?

- "Db" and "Granularity" look OK.

- SEV_ES_RESET_LDT_TYPE (value 2) matches "64-bit LDT" in "4.8.3 System
Descriptors", "Table 4-6. System-Segment Descriptor Types—Long Mode". OK.

- SEV_ES_RESET_TSS_TYPE (value 3) seems wrong. In Table 4-6, value 3 is
associated with "Reserved (Illegal)". And, according to "12.2.2 TSS
Descriptor", "The TSS descriptor is a system-segment descriptor", which
makes me think that I'm looking at value 3 in the proper table (Table 4-6).


(4) Can you please explain why SEV_ES_RESET_TSS_TYPE is 3, and not (say)
0x9 ("Available 64-bit TSS") or 0xB ("Busy 64-bit TSS")?

(Please note that this is only superficial pattern matching from my side
("TSS"); I don't know the first thing about "hardware task management".)


+typedef struct {
+ SEV_ES_SEGMENT_REGISTER Es;
+ SEV_ES_SEGMENT_REGISTER Cs;
+ SEV_ES_SEGMENT_REGISTER Ss;
+ SEV_ES_SEGMENT_REGISTER Ds;
+ SEV_ES_SEGMENT_REGISTER Fs;
+ SEV_ES_SEGMENT_REGISTER Gs;
+ SEV_ES_SEGMENT_REGISTER Gdtr;
+ SEV_ES_SEGMENT_REGISTER Ldtr;
+ SEV_ES_SEGMENT_REGISTER Idtr;
+ SEV_ES_SEGMENT_REGISTER Tr;
+ UINT8 Reserved1[42];
+ UINT8 Vmpl;
+ UINT8 Reserved2[5];
+ UINT64 Efer;
+ UINT8 Reserved3[112];
+ UINT64 Cr4;
+ UINT8 Reserved4[8];
+ UINT64 Cr0;
+ UINT64 Dr7;
+ UINT64 Dr6;
+ UINT64 Rflags;
+ UINT64 Rip;
+ UINT8 Reserved5[232];
+ UINT64 GPat;
+ UINT8 Reserved6[320];
+ UINT64 SevFeatures;
+ UINT8 Reserved7[48];
+ UINT64 XCr0;
+ UINT8 Reserved8[24];
+ UINT32 Mxcsr;
+ UINT16 X87Ftw;
+ UINT8 Reserved9[2];
+ UINT16 X87Fcw;
+} SEV_ES_SAVE_AREA;
+#pragma pack ()
+
#endif
This part looks good to me.

(I spent almost two hours reviewing this patch.)

Thanks!
Laszlo





Re: [PATCH v2 3/5] GenFv: Arm: support images entered in Thumb mode

Etienne Carriere
 

On Mon, 17 May 2021 at 09:24, gaoliming <gaoliming@...> wrote:

Acked-by: Liming Gao <gaoliming@...>

-----邮件原件-----
发件人: Etienne Carriere <etienne.carriere@...>
发送时间: 2021年5月17日 13:49
收件人: devel@edk2.groups.io
抄送: Achin Gupta <achin.gupta@...>; Ard Biesheuvel
<ardb+tianocore@...>; Jiewen Yao <jiewen.yao@...>; Leif
Lindholm <leif@...>; Sami Mujawar <sami.mujawar@...>;
Sughosh Ganu <sughosh.ganu@...>; Etienne Carriere
<etienne.carriere@...>; Bob Feng <bob.c.feng@...>; Liming
Gao <gaoliming@...>
主题: [PATCH v2 3/5] GenFv: Arm: support images entered in Thumb mode

Change GenFv for Arm architecture to generate a specific jump
instruction as image entry instruction, when the target entry label
is assembled with Thumb instruction set. This is possible since
SecCoreEntryAddress value fetched from the PE32 has its LSBit set when
the entry instruction executes in Thumb mode.

Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Cc: Achin Gupta <achin.gupta@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Leif Lindholm <leif@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
Changes since v1:
- Fix typos in commit log and inline comments
- Change if() test operand to be an explicit boolean
---
BaseTools/Source/C/GenFv/GenFvInternalLib.c | 38 +++++++++++++++-----
1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index 6e296b8ad6..5f3fd4f808 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -34,9 +34,27 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "FvLib.h"
#include "PeCoffLib.h"

-#define ARMT_UNCONDITIONAL_JUMP_INSTRUCTION
0xEB000000
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION
0x14000000

+/*
+ * Arm instruction to jump to Fv entry instruction in Arm or Thumb mode.
+ * From ARM Arch Ref Manual versions b/c/d, section A8.8.25 BL, BLX
(immediate)
+ * BLX (encoding A2) branches to offset in Thumb instruction set mode.
+ * BL (encoding A1) branches to offset in Arm instruction set mode.
+ */
+#define ARM_JUMP_OFFSET_MAX 0xffffff
+#define ARM_JUMP_TO_ARM(Offset) (0xeb000000 | ((Offset - 8) >> 2))
+
+#define _ARM_JUMP_TO_THUMB(Imm32) (0xfa000000 | \
+ (((Imm32) & (1 << 1)) << (24 - 1))
| \
+ (((Imm32) >> 2) & 0x7fffff))
+#define ARM_JUMP_TO_THUMB(Offset)
_ARM_JUMP_TO_THUMB((Offset) - 8)
+
+/*
+ * Arm instruction to retrun from exception (MOVS PC, LR)
+ */
+#define ARM_RETURN_FROM_EXCEPTION 0xE1B0F07E
+
BOOLEAN mArm = FALSE;
BOOLEAN mRiscV = FALSE;
STATIC UINT32 MaxFfsAlignment = 0;
@@ -2203,23 +2221,25 @@ Returns:
// if we found an SEC core entry point then generate a branch
instruction
// to it and populate a debugger SWI entry as well
if (UpdateVectorSec) {
+ UINT32 EntryOffset;

VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM SEC
vector");

- // B SecEntryPoint - signed_immed_24 part +/-32MB offset
- // on ARM, the PC is always 8 ahead, so we're not really jumping
from
the base address, but from base address + 8
- ResetVector[0] = (INT32)(SecCoreEntryAddress -
FvInfo->BaseAddress - 8) >> 2;
+ EntryOffset = (INT32)(SecCoreEntryAddress - FvInfo->BaseAddress);

- if (ResetVector[0] > 0x00FFFFFF) {
- Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within
32MB of the start of the FV");
+ if (EntryOffset > ARM_JUMP_OFFSET_MAX) {
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point offset above
1MB of the start of the FV");
return EFI_ABORTED;
}

- // Add opcode for an unconditional branch with no link. i.e.: " B
SecEntryPoint"
- ResetVector[0] |= ARMT_UNCONDITIONAL_JUMP_INSTRUCTION;
+ if (SecCoreEntryAddress & 1 != 0) {
Sorry, I missed this one.
This needs extra parantheses.

I'll sent a v3. My apologies...

etienne

+ ResetVector[0] = ARM_JUMP_TO_THUMB(EntryOffset);
+ } else {
+ ResetVector[0] = ARM_JUMP_TO_ARM(EntryOffset);
+ }

// SWI handler movs pc,lr. Just in case a debugger uses SWI
- ResetVector[2] = 0xE1B0F07E;
+ ResetVector[2] = ARM_RETURN_FROM_EXCEPTION;

// Place holder to support a common interrupt handler from ROM.
// Currently not supported. For this to be used the reset vector
would
not be in this FV
--
2.17.1


回复: [PATCH v2 3/5] GenFv: Arm: support images entered in Thumb mode

gaoliming
 

Acked-by: Liming Gao <gaoliming@...>

-----邮件原件-----
发件人: Etienne Carriere <etienne.carriere@...>
发送时间: 2021年5月17日 13:49
收件人: devel@edk2.groups.io
抄送: Achin Gupta <achin.gupta@...>; Ard Biesheuvel
<ardb+tianocore@...>; Jiewen Yao <jiewen.yao@...>; Leif
Lindholm <leif@...>; Sami Mujawar <sami.mujawar@...>;
Sughosh Ganu <sughosh.ganu@...>; Etienne Carriere
<etienne.carriere@...>; Bob Feng <bob.c.feng@...>; Liming
Gao <gaoliming@...>
主题: [PATCH v2 3/5] GenFv: Arm: support images entered in Thumb mode

Change GenFv for Arm architecture to generate a specific jump
instruction as image entry instruction, when the target entry label
is assembled with Thumb instruction set. This is possible since
SecCoreEntryAddress value fetched from the PE32 has its LSBit set when
the entry instruction executes in Thumb mode.

Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Cc: Achin Gupta <achin.gupta@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Leif Lindholm <leif@...>
Cc: Sughosh Ganu <sughosh.ganu@...>
Signed-off-by: Etienne Carriere <etienne.carriere@...>
---
Changes since v1:
- Fix typos in commit log and inline comments
- Change if() test operand to be an explicit boolean
---
BaseTools/Source/C/GenFv/GenFvInternalLib.c | 38 +++++++++++++++-----
1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index 6e296b8ad6..5f3fd4f808 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -34,9 +34,27 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "FvLib.h"
#include "PeCoffLib.h"

-#define ARMT_UNCONDITIONAL_JUMP_INSTRUCTION
0xEB000000
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION
0x14000000

+/*
+ * Arm instruction to jump to Fv entry instruction in Arm or Thumb mode.
+ * From ARM Arch Ref Manual versions b/c/d, section A8.8.25 BL, BLX
(immediate)
+ * BLX (encoding A2) branches to offset in Thumb instruction set mode.
+ * BL (encoding A1) branches to offset in Arm instruction set mode.
+ */
+#define ARM_JUMP_OFFSET_MAX 0xffffff
+#define ARM_JUMP_TO_ARM(Offset) (0xeb000000 | ((Offset - 8) >> 2))
+
+#define _ARM_JUMP_TO_THUMB(Imm32) (0xfa000000 | \
+ (((Imm32) & (1 << 1)) << (24 - 1))
| \
+ (((Imm32) >> 2) & 0x7fffff))
+#define ARM_JUMP_TO_THUMB(Offset)
_ARM_JUMP_TO_THUMB((Offset) - 8)
+
+/*
+ * Arm instruction to retrun from exception (MOVS PC, LR)
+ */
+#define ARM_RETURN_FROM_EXCEPTION 0xE1B0F07E
+
BOOLEAN mArm = FALSE;
BOOLEAN mRiscV = FALSE;
STATIC UINT32 MaxFfsAlignment = 0;
@@ -2203,23 +2221,25 @@ Returns:
// if we found an SEC core entry point then generate a branch
instruction
// to it and populate a debugger SWI entry as well
if (UpdateVectorSec) {
+ UINT32 EntryOffset;

VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM SEC
vector");

- // B SecEntryPoint - signed_immed_24 part +/-32MB offset
- // on ARM, the PC is always 8 ahead, so we're not really jumping
from
the base address, but from base address + 8
- ResetVector[0] = (INT32)(SecCoreEntryAddress -
FvInfo->BaseAddress - 8) >> 2;
+ EntryOffset = (INT32)(SecCoreEntryAddress - FvInfo->BaseAddress);

- if (ResetVector[0] > 0x00FFFFFF) {
- Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within
32MB of the start of the FV");
+ if (EntryOffset > ARM_JUMP_OFFSET_MAX) {
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point offset above
1MB of the start of the FV");
return EFI_ABORTED;
}

- // Add opcode for an unconditional branch with no link. i.e.: " B
SecEntryPoint"
- ResetVector[0] |= ARMT_UNCONDITIONAL_JUMP_INSTRUCTION;
+ if (SecCoreEntryAddress & 1 != 0) {
+ ResetVector[0] = ARM_JUMP_TO_THUMB(EntryOffset);
+ } else {
+ ResetVector[0] = ARM_JUMP_TO_ARM(EntryOffset);
+ }

// SWI handler movs pc,lr. Just in case a debugger uses SWI
- ResetVector[2] = 0xE1B0F07E;
+ ResetVector[2] = ARM_RETURN_FROM_EXCEPTION;

// Place holder to support a common interrupt handler from ROM.
// Currently not supported. For this to be used the reset vector
would
not be in this FV
--
2.17.1


[PATCH v2 5/5] Maintainers: update Maintainers file as new files/folders created

Jianyong Wu
 

Create new entry for Cloud Hypervisor and assign reviewer to Sami
Mujawar.

Cc: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Jianyong Wu <jianyong.wu@...>
---
Maintainers.txt | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/Maintainers.txt b/Maintainers.txt
index cafe6b1ab85d..f8fae067c656 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -167,6 +167,13 @@ F: ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/
F: ArmVirtPkg/Library/NorFlashKvmtoolLib/
R: Sami Mujawar <sami.mujawar@...>

+ArmVirtPkg: Cloud Hypervisor emulated platform support
+F: ArmVirtPkg/ArmVirtCloudHv*
+F: ArmVirtPkg/CloudHvAcpiPlatformDxe/
+F: ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/
+F: ArmVirtPkg/Library/CloudHvVirtMemInfoLib/
+R: Sami Mujawar <sami.mujawar@...>
+
BaseTools
F: BaseTools/
W: https://github.com/tianocore/tianocore.github.io/wiki/BaseTools
--
2.17.1


[PATCH v2 4/5] ArmVirtPkg: Introduce Cloud Hypervisor to edk2 family

Jianyong Wu
 

Cloud Hypervisor is kvm based VMM and is implemented in rust. Just like
other VMMs it need UEFI support to let ACPI work. That's why
Cloud Hypervisor is introduced here.

Cc: Laszlo Ersek <lersek@...>
Cc: Leif Lindholm <leif@...>
Cc:
Signed-off-by: Jianyong Wu <jianyong.wu@...>
---
ArmVirtPkg/ArmVirtCloudHv.dsc | 455 ++++++++++++++++++++++++
ArmVirtPkg/ArmVirtCloudHv.fdf | 292 +++++++++++++++
ArmVirtPkg/ArmVirtCloudHvFvMain.fdf.inc | 169 +++++++++
3 files changed, 916 insertions(+)
create mode 100644 ArmVirtPkg/ArmVirtCloudHv.dsc
create mode 100644 ArmVirtPkg/ArmVirtCloudHv.fdf
create mode 100644 ArmVirtPkg/ArmVirtCloudHvFvMain.fdf.inc

diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc
new file mode 100644
index 000000000000..bf1f8c5a75ae
--- /dev/null
+++ b/ArmVirtPkg/ArmVirtCloudHv.dsc
@@ -0,0 +1,455 @@
+#
+# Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+# Copyright (c) 2014, Linaro Limited. All rights reserved.
+# Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = ArmVirtCloudHv
+ PLATFORM_GUID = DFFED32B-DFFE-D32B-DFFE-D32BDFFED32B
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/ArmVirtCloudHv-$(ARCH)
+ SUPPORTED_ARCHITECTURES = AARCH64|ARM
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = ArmVirtPkg/ArmVirtCloudHv.fdf
+
+ #
+ # Defines for default states. These can be changed on the command line.
+ # -D FLAG=VALUE
+ #
+ DEFINE TTY_TERMINAL = FALSE
+ DEFINE SECURE_BOOT_ENABLE = FALSE
+ DEFINE TPM2_ENABLE = FALSE
+ DEFINE TPM2_CONFIG_ENABLE = FALSE
+
+!include ArmVirtPkg/ArmVirt.dsc.inc
+
+[LibraryClasses.common]
+ ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+ ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+
+ # Virtio Support
+ VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
+ VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
+ QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+ QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
+ QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
+ QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
+
+ ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
+
+ TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+ BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+ PlatformBootManagerLib|ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+ PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf
+ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+ FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+ QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+ PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+ PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+ PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
+ PciHostBridgeUtilityLib|OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf
+
+!if $(TPM2_ENABLE) == TRUE
+ Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+ Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf
+ TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+!else
+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+!endif
+
+!include MdePkg/MdeLibs.dsc.inc
+
+[LibraryClasses.common.PEIM]
+ ArmVirtMemInfoLib|ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoPeiLib.inf
+
+!if $(TPM2_ENABLE) == TRUE
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+ ResetSystemLib|MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf
+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
+!endif
+
+[LibraryClasses.common.DXE_DRIVER]
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+
+!if $(TPM2_ENABLE) == TRUE
+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
+!endif
+
+[LibraryClasses.common.UEFI_DRIVER]
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+
+[BuildOptions]
+!include NetworkPkg/NetworkBuildOptions.dsc.inc
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|TRUE
+
+ ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+ # It could be set FALSE to save size.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+ gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|$(TPM2_ENABLE)
+
+[PcdsFixedAtBuild.common]
+!if $(ARCH) == AARCH64
+ gArmTokenSpaceGuid.PcdVFPEnabled|1
+!endif
+
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x4007c000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+ gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+
+ # Rsdp base address in Cloud Hypervisor
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiRsdpBaseAddress|0x40200000
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x4000000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x40000
+!if $(NETWORK_TLS_ENABLE) == TRUE
+ #
+ # The cumulative and individual VOLATILE variable size limits should be set
+ # high enough for accommodating several and/or large CA certificates.
+ #
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
+!endif
+
+ # Size of the region used by UEFI in permanent memory (Reserved 64MB)
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
+
+ #
+ # ARM PrimeCell
+ #
+
+ ## PL011 - Serial Terminal
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|38400
+
+ ## Default Terminal Type
+ ## 0-PCANSI, 1-VT100, 2-VT00+, 3-UTF8, 4-TTYTERM
+!if $(TTY_TERMINAL) == TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
+ # Set terminal type to TtyTerm, the value encoded is EFI_TTY_TERM_GUID
+ gArmVirtTokenSpaceGuid.PcdTerminalTypeGuidBuffer|{0x80, 0x6d, 0x91, 0x7d, 0xb1, 0x5b, 0x8c, 0x45, 0xa4, 0x8f, 0xe2, 0x5f, 0xdd, 0x51, 0xef, 0x94}
+!else
+ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|1
+!endif
+
+ # System Memory Base -- fixed at 0x4000_0000
+ gArmTokenSpaceGuid.PcdSystemMemoryBase|0x40000000
+
+ # initial location of the device tree blob passed by Cloud Hypervisor -- base of DRAM
+ gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress|0x40000000
+
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+ #
+ # The maximum physical I/O addressability of the processor, set with
+ # BuildCpuHob().
+ #
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
+
+ #
+ # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
+ #
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
+ gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
+ gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
+ gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
+!endif
+
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3
+ gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000
+
+[PcdsFixedAtBuild.AARCH64]
+ # Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point,
+ # if the entry point version is >= 3.0. AARCH64 OSes cannot assume the
+ # presence of the 32-bit entry point anyway (because many AARCH64 systems
+ # don't have 32-bit addressable physical RAM), and the additional allocations
+ # below 4 GB needlessly fragment the memory map. So expose the 64-bit entry
+ # point only, for entry point versions >= 3.0.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
+
+[PcdsDynamicDefault.common]
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
+
+ ## If TRUE, OvmfPkg/AcpiPlatformDxe will not wait for PCI
+ # enumeration to complete before installing ACPI tables.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
+
+ # System Memory Size -- 1 MB initially, actual size will be fetched from DT
+ gArmTokenSpaceGuid.PcdSystemMemorySize|0x00100000
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
+
+ gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|0x0
+ gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x0
+ gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x0
+ gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|0x0
+
+ #
+ # ARM General Interrupt Controller
+ #
+ gArmTokenSpaceGuid.PcdGicDistributorBase|0x0
+ gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x0
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x0
+
+ ## PL031 RealTimeClock
+ gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0x0
+
+ # set PcdPciExpressBaseAddress to MAX_UINT64, which signifies that this
+ # PCD and PcdPciDisableBusEnumeration above have not been assigned yet
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xFFFFFFFFFFFFFFFF
+
+ gArmTokenSpaceGuid.PcdPciIoTranslation|0
+# gArmTokenSpaceGuid.PcdPciIoTranslation|0x50000000
+
+ #
+ # TPM2 support
+ #
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
+!if $(TPM2_ENABLE) == TRUE
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0
+!endif
+
+[PcdsDynamicHii]
+ gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
+
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+ gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x8|3|NV,BS
+!endif
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+ #
+ # PEI Phase modules
+ #
+ ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
+ MdeModulePkg/Core/Pei/PeiMain.inf
+ MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+ ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
+ ArmPkg/Drivers/CpuPei/CpuPei.inf
+
+ MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+!if $(TPM2_ENABLE) == TRUE
+ MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf {
+ <LibraryClasses>
+ ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf
+ }
+ OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+ SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
+ <LibraryClasses>
+ HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
+ }
+!endif
+
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+
+ #
+ # DXE
+ #
+ MdeModulePkg/Core/Dxe/DxeMain.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ }
+ MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+
+ #
+ # Architectural Protocols
+ #
+ ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+ # don't use unaligned CopyMem () on the UEFI varstore NOR flash region
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ }
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+ <LibraryClasses>
+ NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!if $(TPM2_ENABLE) == TRUE
+ NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
+!endif
+ }
+ SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+ OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
+!else
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+!endif
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+ EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf {
+ <LibraryClasses>
+ NULL|ArmVirtPkg/Library/ArmVirtPL031FdtClientLib/ArmVirtPL031FdtClientLib.inf
+ }
+ EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ ArmPkg/Drivers/TimerDxe/TimerDxe.inf {
+ <LibraryClasses>
+ NULL|ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf
+ }
+ MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+ #
+ # Status Code Routing
+ #
+ MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+
+ #
+ # Platform Driver
+ #
+ ArmVirtPkg/VirtioFdtDxe/VirtioFdtDxe.inf
+ ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
+ ArmVirtPkg/HighMemDxe/HighMemDxe.inf
+ OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+ OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+ OvmfPkg/VirtioNetDxe/VirtioNet.inf
+ OvmfPkg/VirtioRngDxe/VirtioRng.inf
+
+ #
+ # FAT filesystem + GPT/MBR partitioning + UDF filesystem + virtio-fs
+ #
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ FatPkg/EnhancedFatDxe/Fat.inf
+ MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+ OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
+
+ #
+ # Bds
+ #
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
+ <LibraryClasses>
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+ MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+ MdeModulePkg/Logo/LogoDxe.inf
+ MdeModulePkg/Application/UiApp/UiApp.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+ }
+ OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
+
+ #
+ # SCSI Bus and Disk Driver
+ #
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+ #
+ # PCI support
+ #
+ ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf {
+ <LibraryClasses>
+ NULL|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+ }
+ MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
+ <LibraryClasses>
+ NULL|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+ }
+ OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+ OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
+ OvmfPkg/Virtio10Dxe/Virtio10.inf
+
+ #
+ # TPM2 support
+ #
+!if $(TPM2_ENABLE) == TRUE
+ SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf {
+ <LibraryClasses>
+ HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf
+ NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
+ }
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
+!endif
+!endif
+
+ #
+ # ACPI Support
+ #
+ ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf
+[Components.AARCH64]
+ MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+ ArmVirtPkg/CloudHvAcpiPlatformDxe/CloudHvAcpiPlatformDxe.inf {
+ <LibraryClasses>
+ NULL|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+ }
diff --git a/ArmVirtPkg/ArmVirtCloudHv.fdf b/ArmVirtPkg/ArmVirtCloudHv.fdf
new file mode 100644
index 000000000000..3619a09ba8c5
--- /dev/null
+++ b/ArmVirtPkg/ArmVirtCloudHv.fdf
@@ -0,0 +1,292 @@
+#
+# Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+# Copyright (c) 2014, Linaro Limited. All rights reserved.
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into the Flash Device Image. Each FD section
+# defines one flash "device" image. A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash" image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[Defines]
+!if $(FD_SIZE_IN_MB) == 2
+ DEFINE FVMAIN_COMPACT_SIZE = 0x1ff000
+!endif
+!if $(FD_SIZE_IN_MB) == 3
+ DEFINE FVMAIN_COMPACT_SIZE = 0x2ff000
+!endif
+
+[FD.CLOUDHV_EFI]
+BaseAddress = 0x00000000|gArmTokenSpaceGuid.PcdFdBaseAddress # cloud-hypervisor assigns 0 - 0x8000000 for a BootROM
+Size = $(FD_SIZE)|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize = 0x00001000
+NumBlocks = $(FD_NUM_BLOCKS)
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+#
+# UEFI has trouble dealing with FVs that reside at physical address 0x0.
+# So instead, put a hardcoded 'jump to 0x1000' at offset 0x0, and put the
+# real FV at offset 0x1000
+#
+0x00000000|0x00001000
+DATA = {
+!if $(ARCH) == AARCH64
+ 0x00, 0x04, 0x00, 0x14 # 'b 0x1000' in AArch64 ASM
+!else
+ 0xfe, 0x03, 0x00, 0xea # 'b 0x1000' in AArch32 ASM
+!endif
+}
+
+0x00001000|$(FVMAIN_COMPACT_SIZE)
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+!include VarStore.fdf.inc
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file. This section also defines order the components and modules are positioned
+# within the image. The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+#!include ArmVirtCloudHvFvMain.fdf.inc
+
+
+
+[FV.FvMain]
+FvNameGuid = 2A88A00E-E267-C8BF-0E80-AE1BD504ED90
+BlockSize = 0x40
+NumBlocks = 0 # This FV gets compressed so make it just big enough
+FvAlignment = 16 # FV alignment and FV attributes setting.
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+ INF MdeModulePkg/Core/Dxe/DxeMain.inf
+ INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+ INF ArmVirtPkg/VirtioFdtDxe/VirtioFdtDxe.inf
+ INF ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
+ INF ArmVirtPkg/HighMemDxe/HighMemDxe.inf
+
+ #
+ # PI DXE Drivers producing Architectural Protocols (EFI Services)
+ #
+ INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+ INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+ INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+ INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ #
+ # Multiple Console IO support
+ #
+ INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+ INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+ #
+ # FAT filesystem + GPT/MBR partitioning + UDF filesystem + virtio-fs
+ #
+ INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ INF FatPkg/EnhancedFatDxe/Fat.inf
+ INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+ INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
+
+ #
+ # Status Code Routing
+ #
+ INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+
+ #
+ # Platform Driver
+ #
+ INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+ INF OvmfPkg/VirtioNetDxe/VirtioNet.inf
+ INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+ INF OvmfPkg/VirtioRngDxe/VirtioRng.inf
+
+ #
+ # UEFI application (Shell Embedded Boot Loader)
+ #
+ INF ShellPkg/Application/Shell/Shell.inf
+ INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+ INF ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
+ INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
+
+ #
+ # Bds
+ #
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+ INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+ INF MdeModulePkg/Application/UiApp/UiApp.inf
+ INF OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
+
+ #
+ # SCSI Bus and Disk Driver
+ #
+ INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+ #
+ # ACPI Support
+ #
+ INF ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf
+!if $(ARCH) == AARCH64
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+ INF ArmVirtPkg/CloudHvAcpiPlatformDxe/CloudHvAcpiPlatformDxe.inf
+
+ #
+ # EBC support
+ #
+ INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+!endif
+
+ #
+ # PCI support
+ #
+ INF ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
+ INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+ INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+ INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+ INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
+ INF OvmfPkg/Virtio10Dxe/Virtio10.inf
+
+ #
+ # TPM2 support
+ #
+!if $(TPM2_ENABLE) == TRUE
+ INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+ INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
+!endif
+!endif
+
+ #
+ # TianoCore logo (splash screen)
+ #
+ INF MdeModulePkg/Logo/LogoDxe.inf
+
+ #
+ # Ramdisk support
+ #
+ INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+
+
+
+
+
+
+
+
+
+
+
+
+[FV.FVMAIN_COMPACT]
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+ INF ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
+ INF MdeModulePkg/Core/Pei/PeiMain.inf
+ INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+ INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
+ INF ArmPkg/Drivers/CpuPei/CpuPei.inf
+ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+ INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+!if $(TPM2_ENABLE) == TRUE
+ INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf
+ INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+ INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
+!endif
+
+ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ SECTION FV_IMAGE = FVMAIN
+ }
+ }
+
+!include ArmVirtRules.fdf.inc
diff --git a/ArmVirtPkg/ArmVirtCloudHvFvMain.fdf.inc b/ArmVirtPkg/ArmVirtCloudHvFvMain.fdf.inc
new file mode 100644
index 000000000000..51041e889ef4
--- /dev/null
+++ b/ArmVirtPkg/ArmVirtCloudHvFvMain.fdf.inc
@@ -0,0 +1,169 @@
+#
+# Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+# Copyright (c) 2014-2016, Linaro Limited. All rights reserved.
+# Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file. This section also defines order the components and modules are positioned
+# within the image. The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FvMain]
+FvNameGuid = 2A88A00E-E267-C8BF-0E80-AE1BD504ED90
+BlockSize = 0x40
+NumBlocks = 0 # This FV gets compressed so make it just big enough
+FvAlignment = 16 # FV alignment and FV attributes setting.
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+ INF MdeModulePkg/Core/Dxe/DxeMain.inf
+ INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+ INF ArmVirtPkg/VirtioFdtDxe/VirtioFdtDxe.inf
+ INF ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
+ INF ArmVirtPkg/HighMemDxe/HighMemDxe.inf
+
+ #
+ # PI DXE Drivers producing Architectural Protocols (EFI Services)
+ #
+ INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+ INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+ INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+ INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ #
+ # Multiple Console IO support
+ #
+ INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+ INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+ #
+ # FAT filesystem + GPT/MBR partitioning + UDF filesystem + virtio-fs
+ #
+ INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ INF FatPkg/EnhancedFatDxe/Fat.inf
+ INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+ INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
+
+ #
+ # Status Code Routing
+ #
+ INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+
+ #
+ # Platform Driver
+ #
+ INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+ INF OvmfPkg/VirtioNetDxe/VirtioNet.inf
+ INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+ INF OvmfPkg/VirtioRngDxe/VirtioRng.inf
+
+ #
+ # UEFI application (Shell Embedded Boot Loader)
+ #
+ INF ShellPkg/Application/Shell/Shell.inf
+ INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+ INF ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
+ INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
+
+ #
+ # Bds
+ #
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+ INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+ INF MdeModulePkg/Application/UiApp/UiApp.inf
+ INF OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
+
+ #
+ # SCSI Bus and Disk Driver
+ #
+ INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+ #
+ # ACPI Support
+ #
+ INF ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf
+!if $(ARCH) == AARCH64
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+ INF ArmVirtPkg/CloudHvAcpiPlatformDxe/CloudHvAcpiPlatformDxe.inf
+
+ #
+ # EBC support
+ #
+ INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+!endif
+
+ #
+ # PCI support
+ #
+ INF ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf
+ INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+ INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+ INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+ INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
+ INF OvmfPkg/Virtio10Dxe/Virtio10.inf
+
+ #
+ # TPM2 support
+ #
+!if $(TPM2_ENABLE) == TRUE
+ INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+ INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
+!endif
+!endif
+
+ #
+ # TianoCore logo (splash screen)
+ #
+ INF MdeModulePkg/Logo/LogoDxe.inf
+
+ #
+ # Ramdisk support
+ #
+ INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
--
2.17.1

17181 - 17200 of 92312