Date   

[edk2-platforms] [PATCH V1 00/13] SecFspWrapperPlatformSecLib Cleanup

Nate DeSimone
 

This patch series cleans up two outstanding problems with=0D
SecFspWrapperPlatformSecLib:=0D
=0D
1. There are several copies of SecFspWrapperPlatformSecLib=0D
thoughout the codebase, this patch series consolidates=0D
the various implementations down to a single implementation=0D
contained in MinPlatformPkg.=0D
=0D
The WhiskeylakeOpenBoardPkg implementation of=0D
SecFspWrapperPlatformSecLib diverged from MinPlatformPkg by=0D
halting the TCO watch dog timer early in SEC instead of=0D
early in PEI. Analysis of this change has shown that it is=0D
unnessesary, so this patch series move that code back to PEI.=0D
=0D
The KabylakeOpenBoardPkg implementation of=0D
SecFspWrapperPlatformSecLib contains support for FSP dispatch=0D
mode. This was integrated into MinPlatformPkg, eliminating the=0D
need for KabylakeOpenBoardPkg version.=0D
=0D
2. Due to EFI_PEI_TEMPORARY_RAM_DONE_PPI being implemented=0D
by SecMain, the BoardInitLib event callbacks for=0D
BeforeTempRamExit() and AfterTempRamExit() are currently=0D
linked by PlatformSecLib. Linking BoardInitLib in SEC=0D
phase places a lot of restrictions on how BoardInitLib=0D
is implemented. To mitigate this, the BoardInitLib calls=0D
have been moved to a PlatformInitPreMem.=0D
PlatformInitPreMem is invoked by PlatformSecLib using the=0D
new PLATFORM_INIT_TEMP_RAM_EXIT_PPI, which then invokes=0D
the BoardInitLib event callbacks.
=0D
This patch series also includes some general cleanup.=0D
=0D
Cc: Chasel Chiu <chasel.chiu@...>=0D
Cc: Michael Kubacki <michael.a.kubacki@...>=0D
Cc: Sai Chaganty <rangasai.v.chaganty@...>=0D
Cc: Liming Gao <liming.gao@...>=0D
Cc: Isaac W Oram <isaac.w.oram@...>=0D
Cc: Jeremy Soller <jeremy@...>=0D
Signed-off-by: Nate DeSimone <@natedesimone>=0D

Nate DeSimone (13):
KabylakeSiliconPkg: Change MODULE_TYPE of SiliconInitLib to PEIM
KabylakeOpenBoardPkg: Update location of SiliconInitLib
KabylakeSiliconPkg: Cleanup old comments
CoffeeLakeSiliconPkg: Move TcoWdtHob.h
CoffeelakeSiliconPkg: Add SiliconInitLib
WhiskeylakeOpenBoardPkg: Add SiliconInitLib APIs to BoardInitLib
WhiskeylakeOpenBoardPkg: Whitespace cleanup in BoardInitLib
WhiskeylakeOpenBoardPkg: Remove SecFspWrapperPlatformSecLib override
MinPlatformPkg: FSP Dispatch Mode Support for PlatformSecLib
MinPlatformPkg: Coding style cleanups in MinPlatformPkg.dec
KabylakeOpenBoardPkg: Add support for PcdFspDispatchModeUseFspPeiMain
KabylakeOpenBoardPkg: Remove SecFspWrapperPlatformSecLib override
MinPlatformPkg: Remove BoardInitLib dependency from PlatformSecLib

.../FspWrapperPlatformSecLib.c | 186 ---------
.../SecFspWrapperPlatformSecLib/FsptCoreUpd.h | 40 --
.../SecFspWrapperPlatformSecLib/Ia32/Fsp.h | 42 --
.../Ia32/PeiCoreEntry.nasm | 130 -------
.../Ia32/SecEntry.nasm | 361 ------------------
.../Ia32/Stack.nasm | 72 ----
.../PlatformInit.c | 47 ---
.../SecFspWrapperPlatformSecLib.inf | 97 -----
.../SecGetPerformance.c | 89 -----
.../SecPlatformInformation.c | 78 ----
.../SecRamInitData.c | 36 --
.../SecTempRamDone.c | 73 ----
.../GalagoPro3/OpenBoardPkg.dsc | 4 +-
.../KabylakeRvp3/OpenBoardPkg.dsc | 4 +-
.../KabylakeRvp3/OpenBoardPkg.fdf | 5 +-
.../KabylakeRvp3/OpenBoardPkgPcd.dsc | 20 +
.../FspWrapperPlatformSecLib.c | 34 +-
.../SecFspWrapperPlatformSecLib.inf | 8 +-
.../SecTempRamDone.c | 72 +++-
.../Include/Ppi/PlatformInitTempRamExitPpi.h | 55 +++
.../Intel/MinPlatformPkg/MinPlatformPkg.dec | 311 ++++++++-------
.../PlatformInitPei/PlatformInitPreMem.c | 76 +++-
.../PlatformInitPei/PlatformInitPreMem.inf | 1 +
.../FspWrapperPlatformSecLib.c | 163 --------
.../SecFspWrapperPlatformSecLib/FsptCoreUpd.h | 40 --
.../SecFspWrapperPlatformSecLib/Ia32/Fsp.h | 43 ---
.../Ia32/PeiCoreEntry.nasm | 130 -------
.../Ia32/SecEntry.nasm | 361 ------------------
.../Ia32/Stack.nasm | 72 ----
.../PlatformInit.c | 54 ---
.../SecFspWrapperPlatformSecLib.inf | 97 -----
.../SecGetPerformance.c | 90 -----
.../SecPlatformInformation.c | 79 ----
.../SecRamInitData.c | 37 --
.../SecTempRamDone.c | 48 ---
.../BoardInitLib/PeiBoardInitPostMemLib.inf | 1 +
.../BoardInitLib/PeiBoardInitPreMemLib.inf | 1 +
.../PeiMultiBoardInitPostMemLib.inf | 1 +
.../PeiMultiBoardInitPreMemLib.inf | 2 +-
.../PeiWhiskeylakeURvpInitPostMemLib.c | 191 +++++----
.../PeiWhiskeylakeURvpInitPreMemLib.c | 346 +++++++----------
.../BoardInitLib/WhiskeylakeURvpInit.h | 1 +
.../WhiskeylakeURvp/OpenBoardPkg.dsc | 7 +-
.../Include/Guid/TcoWdtHob.h | 0
.../Include/Library/SiliconInitLib.h | 28 ++
.../PeiSiliconInitLib/PeiSiliconInitLib.inf | 46 +++
.../Library/PeiSiliconInitLib/SiliconInit.c | 19 +
.../PeiSiliconInitLib/SiliconInitPreMem.c | 109 ++++++
.../PeiSiliconInitLib.inf} | 3 +-
.../SiliconInit.c | 0
.../SiliconInitPreMem.c | 4 +-
51 files changed, 863 insertions(+), 2951 deletions(-)
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/FsptCoreUpd.h
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/Ia32/Fsp.h
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/Ia32/Stack.nasm
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/PlatformInit.c
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/SecGetPerformance.c
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/SecPlatformInformation.c
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/SecRamInitData.c
delete mode 100644 Platform/Intel/KabylakeOpenBoardPkg/FspWrapper/Library/=
SecFspWrapperPlatformSecLib/SecTempRamDone.c
create mode 100644 Platform/Intel/MinPlatformPkg/Include/Ppi/PlatformInitT=
empRamExitPpi.h
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/FsptCoreUpd.h
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/Ia32/Fsp.h
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/PlatformInit.c
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/SecGetPerformance.c
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/SecPlatformInformation.c
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/SecRamInitData.c
delete mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Libra=
ry/SecFspWrapperPlatformSecLib/SecTempRamDone.c
rename {Platform/Intel/WhiskeylakeOpenBoardPkg =3D> Silicon/Intel/Coffeela=
keSiliconPkg}/Include/Guid/TcoWdtHob.h (100%)
create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/Sili=
conInitLib.h
create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiliconIn=
itLib/PeiSiliconInitLib.inf
create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiliconIn=
itLib/SiliconInit.c
create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiliconIn=
itLib/SiliconInitPreMem.c
rename Silicon/Intel/KabylakeSiliconPkg/Library/{SiliconInitLib/SiliconIni=
tLib.inf =3D> PeiSiliconInitLib/PeiSiliconInitLib.inf} (91%)
rename Silicon/Intel/KabylakeSiliconPkg/Library/{SiliconInitLib =3D> PeiSi=
liconInitLib}/SiliconInit.c (100%)
rename Silicon/Intel/KabylakeSiliconPkg/Library/{SiliconInitLib =3D> PeiSi=
liconInitLib}/SiliconInitPreMem.c (95%)

--=20
2.23.0.windows.1


Re: [[PATCH 1/1]] EmulatorPkg using CpuBreakPoint

Kilian Kegel
 

Hi Ray,

 

[Ray] 1. Can you remove “if(1)”?:

                DONE

Please define it in the begin of the function, and use edk2 data type and coding style, such as UINTN Index.

DONE

[Ray] 2. strncmp assumes user may input “/debugxxxxx”. Is that a valid assumption? I thought we only accept “/debug” the whole word as input parameter to trigger debugging.

I have no preference at all here. We can also consider to use a stricmp() to be case-in-sensitive…

[Ray] 3. I prefer to break the long string to multiple lines of SecPrint() call as what the code does in below.

Removed the entire string, that came in per accident and was a comment only “//”

 

Thanks,

Kilian

 

diff --git a/EmulatorPkg/Win/Host/WinHost.c b/EmulatorPkg/Win/Host/WinHost.c

index 62a89f7617..0eeb5979ff 100644

--- a/EmulatorPkg/Win/Host/WinHost.c

+++ b/EmulatorPkg/Win/Host/WinHost.c

@@ -394,6 +394,7 @@ Returns:

   UINTN                 ProcessAffinityMask;

   UINTN                 SystemAffinityMask;

   INT32                 LowBit;

+  INT32                 i;

   //

   // Enable the privilege so that RTC driver can successfully run SetTime()

@@ -410,6 +411,26 @@ Returns:

   SecPrint ("\n\rEDK II WIN Host Emulation Environment from http://www.tianocore.org/edk2/\n\r");

+  SecPrint ("######################################################################################################\n");

+  SecPrint ("add \"/debug\" command line switch, to connect to the debugger at the very beginning of POST emulation\n");

+  SecPrint ("######################################################################################################\n");

+  if (Argc > 1) {

+    for (i = 1; i < Argc; i++) {

+      if (0 == strcmp("/debug", Argv[i])) {

+          SecPrint("\t1. start your debug engine\n");

+          SecPrint("\t2. attach to process WinHost.exe\n");

+          SecPrint("\t4. SET A SOFTWARE BREAKPOINT (F9) in line 431\n");

+          SecPrint("\t5. and press ENTER in the WinHost command box\n");

+          SecPrint("\t6. go back to the debug engine and RUN/SINGLE STEP the application\n");

+          SecPrint("\t7. otherwise press enter to continue...\n");

+

+          getchar();    //wait for keyboard input

+

+          SecPrint("");//now you can single step the entire boot/emulation process, good luck...

+      }

+    }

+  }

+

   //

   // Determine the first thread available to this process.

   //

From: Ni, Ray
Sent: Wednesday, November 13, 2019 03:27 AM
To: devel@edk2.groups.io; Gao, Liming; KILIAN_KEGEL@...
Cc: Richardson, Brian; Kinney, Michael D
Subject: RE: [edk2-devel] [[PATCH 1/1]] EmulatorPkg using CpuBreakPoint

 

Kilian,

Thank you very much for enabling the better VS debugging experience.

 

Minor comments below.

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Liming Gao
Sent: Wednesday, November 13, 2019 9:07 AM
To: devel@edk2.groups.io; KILIAN_KEGEL@...
Cc: Richardson, Brian <brian.richardson@...>; Kinney, Michael D <michael.d.kinney@...>; Gao, Liming <liming.gao@...>
Subject: Re: [edk2-devel] [[PATCH 1/1]] EmulatorPkg using CpuBreakPoint

 

Kilian:

  Can you create the patch with the commit message?

 

  For the patch, I add my comments.

 

 

From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of Kilian Kegel
Sent: Wednesday, November 06, 2019 1:36 AM
To: Gao, Liming <liming.gao@...>
Cc: devel@edk2.groups.io; Richardson, Brian <brian.richardson@...>; Kinney, Michael D <michael.d.kinney@...>
Subject: [edk2-devel] [[PATCH 1/1]] EmulatorPkg using CpuBreakPoint

 

Hi Liming,

>Kilian: can you send the patch to edk2 mail list for code review?

Regards,

Kilian

 

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

 

diff --git a/EmulatorPkg/Win/Host/WinHost.c b/EmulatorPkg/Win/Host/WinHost.c

index 62a89f7617..53cda86f9a 100644

--- a/EmulatorPkg/Win/Host/WinHost.c

+++ b/EmulatorPkg/Win/Host/WinHost.c

@@ -409,7 +409,30 @@ Returns:

   FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume);

   SecPrint ("\n\rEDK II WIN Host Emulation Environment from http://www.tianocore.org/edk2/\n\r");

-

+  if (1) {

Please use TRUE instead of 1

[Ray] 1. Can you remove “if(1)”?

 

+    int i;

Please define it in the begin of the function, and use edk2 data type and coding style, such as UINTN Index.

 

+    SecPrint ("######################################################################################################\n");

+    SecPrint ("add \"/debug\" command line switch, to connect to the debugger at the very beginning of POST emulation\n");

+    SecPrint ("######################################################################################################\n");

+    if (Argc > 1) {

+      for (i = 1; i < Argc; i++) {

+        if (0 == strcmp("/debug", Argv[i])) {

How about use strncmp?

[Ray] 2. strncmp assumes user may input “/debugxxxxx”. Is that a valid assumption? I thought we only accept “/debug” the whole word as input parameter to trigger debugging.

 

Thanks

Liming

+          //SecPrint("IF YOU WANT TO DEBUG from the very beginning of the EMULATION:\n\t1. start the TASKMGR\n\t2. connect WinHost.exe to the debugger\n\t3. and press ENTER in this command box\nOR\n");

[Ray] 3. I prefer to break the long string to multiple lines of SecPrint() call as what the code does in below.

 

+          SecPrint("\t1. start your debug engine\n");

+          SecPrint("\t2. attache to process WinHost.exe\n");

+          SecPrint("\t4. SET A SOFTWARE BREAKPOINT (F9) in line 431\n");

+          SecPrint("\t5. and press ENTER in the WinHost command box\n");

+          SecPrint("\t6. go back to the debug engine and RUN/SINGLE STEP the application\n");

+          SecPrint("\t7. otherwise press enter to continue...\n");

+

+          getchar();    //wait for keyboard input

+

+          SecPrint("");//now you can single step the entire boot/emulation process, good luck...

+        }

+      }

+    }

+  }

   //

   // Determine the first thread available to this process.

   //

 

From: Kilian Kegel <kilian_kegel@...>
Sent: Monday, October 28, 2019 2:01:23 PM
To: liming.gao@... <liming.gao@...>
Cc: devel@edk2.groups.io <devel@edk2.groups.io>; Richardson, Brian <brian.richardson@...>; Kinney, Michael D <michael.d.kinney@...>
Subject: [edk2-devel] [edk2] [EmulatorPkg] using __debugbreak()

 

Hi Liming,

 

If have observed in newer Windows 10 versions, when using __debugbreak()in any

application that Windows just terminates the app, instead offering to debug it.

So in WinHost.exe too.

 

That’s why I usually insert the code snippet below to run into getchar()

when the program was started with the /debug command line switch.

As long as the App waits for the next keystroke, I can start the debugger (VS2019)

and connect to WinHost.exe process for debugging.

 

Do you have a better solution without modifying the source code?

 

Thanks,

Kilian

    if(1){

        int i;

 

        SecPrint ("######################################################################################################\n");

        SecPrint ("add \"/debug\" command line switch, to connect to the debugger at the very beginning of POST emulation\n");

        SecPrint ("######################################################################################################\n");

 

        if(Argc > 1){

            for(i = 1 ; i < Argc ; i++){

                if(0 == strcmp("/debug", Argv[i])){

                        //SecPrint("IF YOU WANT TO DEBUG from the very beginning of the EMULATION:\n\t1. start the TASKMGR\n\t2. connect WinHost.exe to the debugger\n\t3. and press ENTER in this command box\nOR\n");

                        SecPrint("\t1. start Visual Studio\n");

                        SecPrint("\t2. DEBUG->ATTACH TO PROCESS (CTRL + ALT + P) --> WinHost.exe\n");

                        SecPrint("\t3. Break All  (CTRL + ALT + Break) --> WinHost.exe\n");

                        SecPrint("\t4. SET A SOFTWARE BREAKPOINT (F9) in line 445\n");

                        SecPrint("\t5. and press ENTER in this command box\n");

                        SecPrint("\t6. go back to Visual Studio an RUN/SINGLE STEP the application\n");

                        SecPrint("\t7. otherwise press enter to continue...\n");

                        getchar();

                        //

                        // 1. SET A SOFTWARE BREAKPOINT TO THE NEXT LINE of code below -->> SecPrint("");

                        // 2. switch to the command box and press ENTER

                        // 3. start single stepping the entire boot/emulation process, good luck...

                        //

                        SecPrint("");//now you can single step the entire boot/emulation process, good luck...

                   }

            }

        }

    }

 


Re: [PATCH 00/11] Use proper entropy sources

Wang, Jian J
 

Hi Mike,

Here're some suggestions:
- If OpensslLib library is used, RngLib instance must be specified along
with it.
- For package dsc, BaseLibRngNull can be used because their main
purpose is just for build.
- For platforms which don't need random number at all, BaseLibRngNull
is recommended.
- If drivers HddPasswordDxe/TlsDxe (TlsLib) and/or crypto algorithm like
AES/RSA-OAEP/RSA-PK1 are used in a platform, BaseLibRngNull must
*not* be used. This rule might change due to the future code base
change.
- For IA32/X64 platforms, BaseLibRng is recommended as the default
library instance to avoid unknown uses of RNG. But the users can
choose
- RngLibRdSeed, if rdseed is supported for sure and high quality
of entropy source is needed; or
- DxeRngLibRngProtocol, if EFI_RNG_PROTOCOL is implemented in
the platform and only DXE drivers or applications use RNG, or
arch independent is more important.
- For OVMF, there's already a driver implemented EFI_RNG_PROTOCOL.
DxeRngLibRngProtocol is always recommended.
- For other ARCH platforms, I don't see implementation of RngLib nor
EFI_RNG_PROTOCOL. They have to use BaseRngLibNull or implement
their own version of RngLib. There's an ARCH independent solution
called CPU Jitter RNG, which has been adopted by Linux. But there's
concern that it won't work well in BIOS environment.
(see https://www.chronox.de/jent/doc/CPU-Jitter-NPTRNG.html)
- If BaseLibRngNull ASSERTs at boot time, there must be some use cases
missed. Use a full implementation of RngLib instead.

Regards,
Jian

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@...>
Sent: Thursday, November 14, 2019 12:21 PM
To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@...>; Kinney,
Michael D <michael.d.kinney@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>; Bret Barkelew
<bret.barkelew@...>; Zhang, Chao B <chao.b.zhang@...>;
Wu, Jiaxin <jiaxin.wu@...>; Yao, Jiewen <jiewen.yao@...>; Justen,
Jordan L <jordan.l.justen@...>; Laszlo Ersek <lersek@...>; Leif
Lindholm <leif.lindholm@...>; Gao, Liming <liming.gao@...>;
Rabeda, Maciej <maciej.rabeda@...>; Matthew Carlson
<macarl@...>; Ni, Ray <ray.ni@...>; Sean Brogan
<sean.brogan@...>; Fu, Siyuan <@sfu5>; Lu, XiaoyuX
<xiaoyux.lu@...>
Subject: RE: [edk2-devel] [PATCH 00/11] Use proper entropy sources

Jian,

In this patch series I see mixed use of different RngLib instances.

How does a platform developer working on their DSC file know if the
BaseCryptLib services they are using require a Null or a complete
implementation of the RngLib? How does a platform developer know
if they made the wrong choice.

Thanks,

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On
Behalf Of Wang, Jian J
Sent: Wednesday, November 13, 2019 6:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ard.biesheuvel@...>; Bret
Barkelew <bret.barkelew@...>; Zhang, Chao B
<chao.b.zhang@...>; Wu, Jiaxin
<jiaxin.wu@...>; Yao, Jiewen
<jiewen.yao@...>; Justen, Jordan L
<jordan.l.justen@...>; Laszlo Ersek
<lersek@...>; Leif Lindholm
<leif.lindholm@...>; Gao, Liming
<liming.gao@...>; Rabeda, Maciej
<maciej.rabeda@...>; Matthew Carlson
<macarl@...>; Kinney, Michael D
<michael.d.kinney@...>; Ni, Ray
<ray.ni@...>; Sean Brogan
<sean.brogan@...>; Fu, Siyuan
<@sfu5>; Lu, XiaoyuX
<xiaoyux.lu@...>
Subject: [edk2-devel] [PATCH 00/11] Use proper entropy
sources

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

Patch series summary:
- Add BaseRngLibNull to package dsc
- Add DxeRngLibRngProtocol to make use
EFI_RNG_PROTOCOL
- Add RdSeed interface and RngLibRdSeed for IA32/X64
arch
- Remove following files
rand_pool_noise.h
rand_pool_noise_tsc.c
rand_pool_noise.c
- Update rand_pool.c to use RngLib interface directly
and the drop the TimerLib depenency from OpensslLib
- Update OVMF platform dsc to use DxeRngLibRngProtocol
when necessary

Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Bret Barkelew <bret.barkelew@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Jiaxin Wu <jiaxin.wu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Leif Lindholm <leif.lindholm@...>
Cc: Liming Gao <liming.gao@...>
Cc: Maciej Rabeda <maciej.rabeda@...>
Cc: Matthew Carlson <macarl@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Ray Ni <ray.ni@...>
Cc: Sean Brogan <sean.brogan@...>
Cc: Siyuan Fu <@sfu5>
Cc: Xiaoyu Lu <xiaoyux.lu@...>

Jian J Wang (11):
NetworkPkg/NetworkPkg.dsc: specify RngLib instance
for build
SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib
instances
FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib
instances in dsc files
MdePkg/BaseLib: add interface to wrap rdseed IA
instruction
SecurityPkg/RngLibRdSeed: add an instance of RngLib
to make use rdseed
SecurityPkg/DxeRngLibRngProtocol: add RNG protocol
version of RngLib
SecurityPkg/SecurityPkg.dsc: add new RngLib instances
for build
OvmfPkg: specify RngLib instances in dsc files
ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances
in dsc files
CryptoPkg/OpensslLib: use RngLib to get high quality
random entropy
FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib
instance

ArmVirtPkg/ArmVirt.dsc.inc | 2 +
CryptoPkg/CryptoPkg.dsc | 1 +
CryptoPkg/Library/OpensslLib/OpensslLib.inf | 15 +-
.../Library/OpensslLib/OpensslLibCrypto.inf | 15 +-
CryptoPkg/Library/OpensslLib/rand_pool.c | 253
++----------------
.../Library/OpensslLib/rand_pool_noise.c | 29 --
.../Library/OpensslLib/rand_pool_noise.h | 29 --
.../Library/OpensslLib/rand_pool_noise_tsc.c | 43 --
-
FmpDevicePkg/FmpDevicePkg.dsc | 2 +-
MdePkg/Include/Library/BaseLib.h | 51
++++
MdePkg/Library/BaseLib/BaseLib.inf | 4 +
MdePkg/Library/BaseLib/BaseLibInternals.h | 46
++++
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm | 87
++++++
MdePkg/Library/BaseLib/X64/RdSeed.nasm | 80
++++++
MdePkg/Library/BaseLib/X86RdSeed.c | 73
+++++
NetworkPkg/NetworkPkg.dsc | 1 +
OvmfPkg/OvmfPkgIa32.dsc | 5 +
OvmfPkg/OvmfPkgIa32X64.dsc | 5 +
OvmfPkg/OvmfPkgX64.dsc | 5 +
OvmfPkg/OvmfXen.dsc | 5 +
.../DxeRngLibRngProtocol.c | 200
++++++++++++++
.../DxeRngLibRngProtocol.inf | 42
+++
.../DxeRngLibRngProtocol.uni | 14 +
.../RngLibRdSeed/RngLibRdSeed.inf | 37
+++
.../RngLibRdSeed/RngLibRdSeed.uni | 18 ++
.../RngLibRdSeed/RngRdSeed.c | 189
+++++++++++++
SecurityPkg/SecurityPkg.dsc | 6 +
SignedCapsulePkg/SignedCapsulePkg.dsc | 6 +
28 files changed, 909 insertions(+), 354 deletions(-)
delete mode 100644
CryptoPkg/Library/OpensslLib/rand_pool_noise.c
delete mode 100644
CryptoPkg/Library/OpensslLib/rand_pool_noise.h
delete mode 100644
CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
create mode 100644
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
create mode 100644
MdePkg/Library/BaseLib/X64/RdSeed.nasm
create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c
create mode 100644
SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
DxeRngLibRngProtocol.c
create mode 100644
SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
DxeRngLibRngProtocol.inf
create mode 100644
SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
DxeRngLibRngProtocol.uni
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
Seed.inf
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
Seed.uni
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
d.c

--
2.17.1.windows.2



[PATCH v1] MdeModulePkg/NvmExpressDxe: Fix wrong queue size for async IO queues

Wu, Hao A
 

From: Sean Brogan <sean.brogan@...>

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

When a packet is queued/completed for the asynchronous IO queue, the logic
to roll over to the front of the queue doesn't account for actual size of
the IO Submission/Completion queue.

This causes a device to hang due to doorbell being outside of visible
queue. An example would be if an NVMe drive only supported a queue size of
128 while the driver supports 256.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Sean Brogan <sean.brogan@...>
Signed-off-by: Hao A Wu <hao.a.wu@...>
---
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c | 2 +-
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
index 3bde96bc95..62886d5c91 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
@@ -672,7 +672,7 @@ ProcessAsyncTaskList (
}

Private->CqHdbl[QueueId].Cqh++;
- if (Private->CqHdbl[QueueId].Cqh > NVME_ASYNC_CCQ_SIZE) {
+ if (Private->CqHdbl[QueueId].Cqh > MIN (NVME_ASYNC_CCQ_SIZE, Private->Cap.Mqes)) {
Private->CqHdbl[QueueId].Cqh = 0;
Private->Pt[QueueId] ^= 1;
}
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
index 8e72137946..e9357b1239 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
@@ -452,6 +452,7 @@ NvmExpressPassThru (
NVME_SQ *Sq;
NVME_CQ *Cq;
UINT16 QueueId;
+ UINT16 QueueSize;
UINT32 Bytes;
UINT16 Offset;
EFI_EVENT TimerEvent;
@@ -540,6 +541,7 @@ NvmExpressPassThru (
Prp = NULL;
TimerEvent = NULL;
Status = EFI_SUCCESS;
+ QueueSize = MIN (NVME_ASYNC_CSQ_SIZE, Private->Cap.Mqes) + 1;

if (Packet->QueueType == NVME_ADMIN_QUEUE) {
QueueId = 0;
@@ -552,7 +554,7 @@ NvmExpressPassThru (
//
// Submission queue full check.
//
- if ((Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1) ==
+ if ((Private->SqTdbl[QueueId].Sqt + 1) % QueueSize ==
Private->AsyncSqHead) {
return EFI_NOT_READY;
}
@@ -701,7 +703,7 @@ NvmExpressPassThru (
//
if ((Event != NULL) && (QueueId != 0)) {
Private->SqTdbl[QueueId].Sqt =
- (Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1);
+ (Private->SqTdbl[QueueId].Sqt + 1) % QueueSize;
} else {
Private->SqTdbl[QueueId].Sqt ^= 1;
}
--
2.12.0.windows.1


Re: [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction

Wang, Jian J
 

Mike,

Thanks for finding it. I'll update the code in v2.

Regards,
Jian

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@...>
Sent: Thursday, November 14, 2019 12:17 PM
To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@...>; Kinney,
Michael D <michael.d.kinney@...>
Cc: Gao, Liming <liming.gao@...>; Ni, Ray <ray.ni@...>
Subject: RE: [edk2-devel] [PATCH 04/11] MdePkg/BaseLib: add interface to wrap
rdseed IA instruction

Jian,

According to the NASM docuimentation, the rdseed instruction
has been supported since 2.10.02.

https://www.nasm.us/xdoc/2.10.09/html/nasmdocc.html

Please use rdseed instead of db bytes.

Thanks,

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On
Behalf Of Wang, Jian J
Sent: Wednesday, November 13, 2019 6:18 PM
To: devel@edk2.groups.io
Cc: Kinney, Michael D <michael.d.kinney@...>;
Gao, Liming <liming.gao@...>; Ni, Ray
<ray.ni@...>
Subject: [edk2-devel] [PATCH 04/11] MdePkg/BaseLib: add
interface to wrap rdseed IA instruction

BaseRngLib uses rdrand instruction to get random number
from DRNG in the processor, which is not a good
candidate for seeding openssl rand interface.

rdseed in x86 cpu provides non-deterministic random
number (NRBG) which meets NIST SP 800-90B and NIST
SP800-90C standards and can be used as seed for other
software DRNG. This patch adds a C interface
AsmRdSeed() to wrap it in BaseLib so that we can add a
new RngLib for users to choose in their platform, if
their processor support rdseed instruction.

Ref:
https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
MdePkg/Include/Library/BaseLib.h | 51
+++++++++++++
MdePkg/Library/BaseLib/BaseLib.inf | 4 ++
MdePkg/Library/BaseLib/BaseLibInternals.h | 46
++++++++++++
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm | 87
+++++++++++++++++++++++
MdePkg/Library/BaseLib/X64/RdSeed.nasm | 80
+++++++++++++++++++++
MdePkg/Library/BaseLib/X86RdSeed.c | 73
+++++++++++++++++++
6 files changed, 341 insertions(+)
create mode 100644
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
create mode 100644
MdePkg/Library/BaseLib/X64/RdSeed.nasm
create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c

diff --git a/MdePkg/Include/Library/BaseLib.h
b/MdePkg/Include/Library/BaseLib.h
index 2a75bc023f..e2f9bf121e 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7856,6 +7856,57 @@ AsmRdRand64 (
OUT UINT64 *Rand
);

+/**
+ Generates a 16-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdSeed16 (
+ OUT UINT16 *Seed
+ );
+
+/**
+ Generates a 32-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed32 (
+ OUT UINT32 *Seed
+ );
+
+/**
+ Generates a 64-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed64 (
+ OUT UINT64 *Seed
+ );
+
/**
Load given selector into TR register.

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
b/MdePkg/Library/BaseLib/BaseLib.inf
index 3586beb0ab..5e12093ba3 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -181,6 +181,7 @@
Ia32/EnableCache.nasm| GCC
Ia32/DisableCache.nasm| GCC
Ia32/RdRand.nasm
+ Ia32/RdSeed.nasm

Ia32/DivS64x64Remainder.c
Ia32/InternalSwitchStack.c | MSFT
@@ -202,6 +203,7 @@
X86DisablePaging64.c
X86DisablePaging32.c
X86RdRand.c
+ X86RdSeed.c
X86PatchInstruction.c
X86SpeculationBarrier.c

@@ -306,12 +308,14 @@
X86DisablePaging64.c
X86DisablePaging32.c
X86RdRand.c
+ X86RdSeed.c
X86PatchInstruction.c
X86SpeculationBarrier.c
X64/GccInline.c | GCC
X64/EnableDisableInterrupts.nasm
X64/DisablePaging64.nasm
X64/RdRand.nasm
+ X64/RdSeed.nasm
ChkStkGcc.c | GCC

[Sources.EBC]
diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h
b/MdePkg/Library/BaseLib/BaseLibInternals.h
index 6837d67d90..7b18b192c9 100644
--- a/MdePkg/Library/BaseLib/BaseLibInternals.h
+++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
@@ -862,6 +862,52 @@ InternalX86RdRand64 (
OUT UINT64 *Rand
);

+/**
+ Generates a 16-bit random seed through RDSEED
instruction.
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed16 (
+ OUT UINT16 *Seed
+ );
+
+/**
+ Generates a 32-bit random seed through RDSEED
instruction.
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed32 (
+ OUT UINT32 *Seed
+ );
+
+/**
+ Generates a 64-bit random seed through RDSEED
instruction.
+
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed64 (
+ OUT UINT64 *Seed
+ );
+
#else

#endif
diff --git a/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
new file mode 100644
index 0000000000..0a4de30db6
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
@@ -0,0 +1,87 @@
+;-----------------------------------------------------
-----------------
+--------
+;
+; Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR> ;
+SPDX-License-Identifier: BSD-2-Clause-Patent ; ;
Module Name:
+;
+; RdSeed.nasm
+;
+; Abstract:
+;
+; Generates random seed through CPU RdSeed
instruction under 32-bit platform.
+;
+; Notes:
+;
+;-----------------------------------------------------
-----------------
+--------
+
+SECTION .text
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 16 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed16)
+ASM_PFX(InternalX86RdSeed16):
+ ; rdseed ax ; generate a 16 bit
RN into ax
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r16: "0f
c7 /7 ModRM:r/m(w)"
+ jc rn16_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn16_ok:
+ mov edx, dword [esp + 4]
+ mov [edx], ax
+ mov eax, 1
+ ret
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 32 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed32)
+ASM_PFX(InternalX86RdSeed32):
+ ; rdseed eax ; generate a 32 bit
RN into eax
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r32: "0f
c7 /7 ModRM:r/m(w)"
+ jc rn32_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn32_ok:
+ mov edx, dword [esp + 4]
+ mov [edx], eax
+ mov eax, 1
+ ret
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 64 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed64)
+ASM_PFX(InternalX86RdSeed64):
+ ; rdseed eax ; generate a 32 bit
RN into eax
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r32: "0f
c7 /7 ModRM:r/m(w)"
+ jnc rn64_ret ; jmp if CF=0
+ mov edx, dword [esp + 4]
+ mov [edx], eax
+
+ db 0xf, 0xc7, 0xf0 ; generate another
32 bit RN
+ jnc rn64_ret ; jmp if CF=0
+ mov [edx + 4], eax
+
+ mov eax, 1
+ ret
+rn64_ret:
+ xor eax, eax
+ pause
+ ret ; return with
failure status
+
diff --git a/MdePkg/Library/BaseLib/X64/RdSeed.nasm
b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
new file mode 100644
index 0000000000..a60acfeace
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
@@ -0,0 +1,80 @@
+;-----------------------------------------------------
-----------------
+--------
+;
+; Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR> ;
+SPDX-License-Identifier: BSD-2-Clause-Patent ; ;
Module Name:
+;
+; RdSeed.nasm
+;
+; Abstract:
+;
+; Generates random seed through CPU RdSeed
instruction under 64-bit platform.
+;
+; Notes:
+;
+;-----------------------------------------------------
-----------------
+--------
+
+ DEFAULT REL
+ SECTION .text
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 16 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed16)
+ASM_PFX(InternalX86RdSeed16):
+ ; rdseed ax ; generate a 16 bit
RN into eax,
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r16: "0f
c7 /7 ModRM:r/m(w)"
+ jc rn16_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn16_ok:
+ mov [rcx], ax
+ mov rax, 1
+ ret
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 32 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed32)
+ASM_PFX(InternalX86RdSeed32):
+ ; rdseed eax ; generate a 32 bit
RN into eax,
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r32: "0f
c7 /7 ModRM:r/m(w)"
+ jc rn32_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn32_ok:
+ mov [rcx], eax
+ mov rax, 1
+ ret
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 64 bit random seed through one
RDSEED
+instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed64)
+ASM_PFX(InternalX86RdSeed64):
+ ; rdseed rax ; generate a 64 bit
RN into rax,
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0x48, 0xf, 0xc7, 0xf8 ; rdseed r64:
"REX.W + 0f c7 /7 ModRM:r/m(w)"
+ jc rn64_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn64_ok:
+ mov [rcx], rax
+ mov rax, 1
+ ret
+
diff --git a/MdePkg/Library/BaseLib/X86RdSeed.c
b/MdePkg/Library/BaseLib/X86RdSeed.c
new file mode 100644
index 0000000000..9fa7948ff1
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X86RdSeed.c
@@ -0,0 +1,73 @@
+/** @file
+ IA-32/x64 AsmRdSeedxx()
+ Generates random seed through CPU RdSeed
instruction.
+
+ Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BaseLibInternals.h"
+
+/**
+ Generates a 16-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdSeed16 (
+ OUT UINT16 *Seed
+ )
+{
+ ASSERT (Seed != NULL);
+ return InternalX86RdSeed16 (Seed);
+}
+
+/**
+ Generates a 32-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed32 (
+ OUT UINT32 *Seed
+ )
+{
+ ASSERT (Seed != NULL);
+ return InternalX86RdSeed32 (Seed);
+}
+
+/**
+ Generates a 64-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed64 (
+ OUT UINT64 *Seed
+ )
+{
+ ASSERT (Seed != NULL);
+ return InternalX86RdSeed64 (Seed);
+}
--
2.17.1.windows.2



Re: [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed

Wang, Jian J
 

Mike,

I figured that rdseed is only needed in cases demanding highest entropy,
like seeding other pseudo-RNG. It's not for general purpose randomness.
Then I put it in SecurityPkg. But I'm ok to put it into MdePkg. I have no
strong opinion for this.

Regards,
Jian

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@...>
Sent: Thursday, November 14, 2019 12:25 PM
To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@...>; Kinney,
Michael D <michael.d.kinney@...>
Cc: Yao, Jiewen <jiewen.yao@...>; Zhang, Chao B
<chao.b.zhang@...>; Gao, Liming <liming.gao@...>; Ni, Ray
<ray.ni@...>
Subject: RE: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an
instance of RngLib to make use rdseed

Jian,

Why is this lib instance in the SecurityPkg? It only depends
on the MdePkg. Can't non security feature related modules
that want to a random number use this lib without using the
SecurityPkg? Could this lib instance be added to MdePkg?

Thanks,

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On
Behalf Of Wang, Jian J
Sent: Wednesday, November 13, 2019 6:18 PM
To: devel@edk2.groups.io
Cc: Yao, Jiewen <jiewen.yao@...>; Zhang, Chao B
<chao.b.zhang@...>; Kinney, Michael D
<michael.d.kinney@...>; Gao, Liming
<liming.gao@...>; Ni, Ray <ray.ni@...>
Subject: [edk2-devel] [PATCH 05/11]
SecurityPkg/RngLibRdSeed: add an instance of RngLib to
make use rdseed

This version of RngLib makes use of AsmRdSeed to get
non-deterministic random number, which can be used for
seeding other software DRNG like rand interface in
openssl. It can be used only on IA32/X64 processors
which supports rdseed instruction.

Ref:
https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
.../RngLibRdSeed/RngLibRdSeed.inf | 37
++++
.../RngLibRdSeed/RngLibRdSeed.uni | 18 ++
.../RngLibRdSeed/RngRdSeed.c | 189
++++++++++++++++++
3 files changed, 244 insertions(+)
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
Seed.inf
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
Seed.uni
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
d.c

diff --git
a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.inf
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.inf
new file mode 100644
index 0000000000..8162408775
--- /dev/null
+++
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.inf
@@ -0,0 +1,37 @@
+## @file
+# Instance of RNG (Random Number Generator) Library.
+#
+# Rng RdSeed Library that uses CPU RdSeed instruction
access to
+provide # non-deterministic random number which can
be used as seed
+for other # software deterministic RNGs.
+#
+# Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # # ##
+
+[Defines]
+ INF_VERSION = 0x00010029
+ BASE_NAME = RngLibRdSeed
+ MODULE_UNI_FILE = RngLibRdSeed.uni
+ FILE_GUID = 8B613B2E-B944-40F9-
B979-1B60D7CAA73C
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RngLib
+ CONSTRUCTOR =
RngLibRdSeedConstructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.Ia32, Sources.X64]
+ RngRdSeed.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
diff --git
a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.uni
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.uni
new file mode 100644
index 0000000000..051a3019bc
--- /dev/null
+++
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.uni
@@ -0,0 +1,18 @@
+// /** @file
+// Instance of RNG (Random Number Generator) Library.
+//
+// Rng RdSeed Library that uses CPU RdSeed instruction
access to
+provide // non-deterministic random number which can
be used as seed
+for other // software deterministic RNGs.
+//
+// Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR> //
+// SPDX-License-Identifier: BSD-2-Clause-Patent // //
**/
+
+
+#string STR_MODULE_ABSTRACT #language en-
US "Instance of RNG Library"
+
+#string STR_MODULE_DESCRIPTION #language en-
US "RngRdSeed Library that uses CPU RdSeed instruction
access to provide non-deterministic random numbers."
+
diff --git
a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
eed.c
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
eed.c
new file mode 100644
index 0000000000..0036faa050
--- /dev/null
+++
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
eed.c
@@ -0,0 +1,189 @@
+/** @file
+ Random number generator services that uses RdSeed
instruction access
+ to provide non-deterministic random numbers, which
are usually used
+ for seeding other pseudo-random number generators.
+
+Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
+
+//
+// Bit mask used to determine if RdSeed instruction is
supported.
+//
+#define RDSEED_MASK BIT18
+
+//
+// Limited retry number when valid random data is
returned.
+// It varies between 1 and 100 according to "Intel(R)
DRGN Software
+Implementation // Guide". Let's use the same value as
RDRAND in BaseRngLib.
+//
+#define RDSEED_RETRY_LIMIT 10
+
+/**
+ The constructor function checks whether or not
RDSEED instruction is
+supported
+ by the host hardware.
+
+ The constructor function checks whether or not
RDSEED instruction is supported.
+ It will ASSERT() if RDSEED instruction is not
supported.
+
+ @retval RETURN_SUCCESS The processor supports
RDSEED instruction.
+ @retval RETURN_UNSUPPORTED RDSEED instruction is
not supported.
+
+**/
+RETURN_STATUS
+EFIAPI
+RngLibRdSeedConstructor (
+ VOID
+ )
+{
+ UINT32 RegEbx;
+
+ //
+ // Determine RDSEED support by examining bit 18 of
the EBX register
+ returned by // CPUID(EAX=7, ECX=0). BIT18 of EBX
indicates that
+ processor support RDSEED // instruction.
+ //
+ AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL); if
((RegEbx &
+ RDSEED_MASK) != RDSEED_MASK) {
+ ASSERT ((RegEbx & RDSEED_MASK) == RDSEED_MASK);
+ return RETURN_UNSUPPORTED;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Generates a 16-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 16-
bit random value.
+
+ @retval TRUE Random number generated
successfully.
+ @retval FALSE Failed to generate the random
number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ UINT32 Index;
+
+ ASSERT (Rand != NULL);
+
+ //
+ // A loop to fetch a 16 bit random value with a
retry count limit.
+ //
+ for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
{
+ if (AsmRdSeed16 (Rand)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 32-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 32-
bit random value.
+
+ @retval TRUE Random number generated
successfully.
+ @retval FALSE Failed to generate the random
number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ UINT32 Index;
+
+ ASSERT (Rand != NULL);
+
+ //
+ // A loop to fetch a 32 bit random value with a
retry count limit.
+ //
+ for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
{
+ if (AsmRdSeed32 (Rand)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 64-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 64-
bit random value.
+
+ @retval TRUE Random number generated
successfully.
+ @retval FALSE Failed to generate the random
number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ UINT32 Index;
+
+ ASSERT (Rand != NULL);
+
+ //
+ // A loop to fetch a 64 bit random value with a
retry count limit.
+ //
+ for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
{
+ if (AsmRdSeed64 (Rand)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 128-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the
128-bit random value.
+
+ @retval TRUE Random number generated
successfully.
+ @retval FALSE Failed to generate the random
number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber128 (
+ OUT UINT64 *Rand
+ )
+{
+ ASSERT (Rand != NULL);
+
+ //
+ // Read first 64 bits
+ //
+ if (!GetRandomNumber64 (Rand)) {
+ return FALSE;
+ }
+
+ //
+ // Read second 64 bits
+ //
+ return GetRandomNumber64 (++Rand);
+}
--
2.17.1.windows.2



Re: [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed

Michael D Kinney
 

Jian,

Why is this lib instance in the SecurityPkg? It only depends
on the MdePkg. Can't non security feature related modules
that want to a random number use this lib without using the
SecurityPkg? Could this lib instance be added to MdePkg?

Thanks,

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On
Behalf Of Wang, Jian J
Sent: Wednesday, November 13, 2019 6:18 PM
To: devel@edk2.groups.io
Cc: Yao, Jiewen <jiewen.yao@...>; Zhang, Chao B
<chao.b.zhang@...>; Kinney, Michael D
<michael.d.kinney@...>; Gao, Liming
<liming.gao@...>; Ni, Ray <ray.ni@...>
Subject: [edk2-devel] [PATCH 05/11]
SecurityPkg/RngLibRdSeed: add an instance of RngLib to
make use rdseed

This version of RngLib makes use of AsmRdSeed to get
non-deterministic random number, which can be used for
seeding other software DRNG like rand interface in
openssl. It can be used only on IA32/X64 processors
which supports rdseed instruction.

Ref:
https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
.../RngLibRdSeed/RngLibRdSeed.inf | 37
++++
.../RngLibRdSeed/RngLibRdSeed.uni | 18 ++
.../RngLibRdSeed/RngRdSeed.c | 189
++++++++++++++++++
3 files changed, 244 insertions(+)
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
Seed.inf
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
Seed.uni
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
d.c

diff --git
a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.inf
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.inf
new file mode 100644
index 0000000000..8162408775
--- /dev/null
+++
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.inf
@@ -0,0 +1,37 @@
+## @file
+# Instance of RNG (Random Number Generator) Library.
+#
+# Rng RdSeed Library that uses CPU RdSeed instruction
access to
+provide # non-deterministic random number which can
be used as seed
+for other # software deterministic RNGs.
+#
+# Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # # ##
+
+[Defines]
+ INF_VERSION = 0x00010029
+ BASE_NAME = RngLibRdSeed
+ MODULE_UNI_FILE = RngLibRdSeed.uni
+ FILE_GUID = 8B613B2E-B944-40F9-
B979-1B60D7CAA73C
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RngLib
+ CONSTRUCTOR =
RngLibRdSeedConstructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.Ia32, Sources.X64]
+ RngRdSeed.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
diff --git
a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.uni
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.uni
new file mode 100644
index 0000000000..051a3019bc
--- /dev/null
+++
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
RdSeed.uni
@@ -0,0 +1,18 @@
+// /** @file
+// Instance of RNG (Random Number Generator) Library.
+//
+// Rng RdSeed Library that uses CPU RdSeed instruction
access to
+provide // non-deterministic random number which can
be used as seed
+for other // software deterministic RNGs.
+//
+// Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR> //
+// SPDX-License-Identifier: BSD-2-Clause-Patent // //
**/
+
+
+#string STR_MODULE_ABSTRACT #language en-
US "Instance of RNG Library"
+
+#string STR_MODULE_DESCRIPTION #language en-
US "RngRdSeed Library that uses CPU RdSeed instruction
access to provide non-deterministic random numbers."
+
diff --git
a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
eed.c
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
eed.c
new file mode 100644
index 0000000000..0036faa050
--- /dev/null
+++
b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
eed.c
@@ -0,0 +1,189 @@
+/** @file
+ Random number generator services that uses RdSeed
instruction access
+ to provide non-deterministic random numbers, which
are usually used
+ for seeding other pseudo-random number generators.
+
+Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
+
+//
+// Bit mask used to determine if RdSeed instruction is
supported.
+//
+#define RDSEED_MASK BIT18
+
+//
+// Limited retry number when valid random data is
returned.
+// It varies between 1 and 100 according to "Intel(R)
DRGN Software
+Implementation // Guide". Let's use the same value as
RDRAND in BaseRngLib.
+//
+#define RDSEED_RETRY_LIMIT 10
+
+/**
+ The constructor function checks whether or not
RDSEED instruction is
+supported
+ by the host hardware.
+
+ The constructor function checks whether or not
RDSEED instruction is supported.
+ It will ASSERT() if RDSEED instruction is not
supported.
+
+ @retval RETURN_SUCCESS The processor supports
RDSEED instruction.
+ @retval RETURN_UNSUPPORTED RDSEED instruction is
not supported.
+
+**/
+RETURN_STATUS
+EFIAPI
+RngLibRdSeedConstructor (
+ VOID
+ )
+{
+ UINT32 RegEbx;
+
+ //
+ // Determine RDSEED support by examining bit 18 of
the EBX register
+ returned by // CPUID(EAX=7, ECX=0). BIT18 of EBX
indicates that
+ processor support RDSEED // instruction.
+ //
+ AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL); if
((RegEbx &
+ RDSEED_MASK) != RDSEED_MASK) {
+ ASSERT ((RegEbx & RDSEED_MASK) == RDSEED_MASK);
+ return RETURN_UNSUPPORTED;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Generates a 16-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 16-
bit random value.
+
+ @retval TRUE Random number generated
successfully.
+ @retval FALSE Failed to generate the random
number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ UINT32 Index;
+
+ ASSERT (Rand != NULL);
+
+ //
+ // A loop to fetch a 16 bit random value with a
retry count limit.
+ //
+ for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
{
+ if (AsmRdSeed16 (Rand)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 32-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 32-
bit random value.
+
+ @retval TRUE Random number generated
successfully.
+ @retval FALSE Failed to generate the random
number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ UINT32 Index;
+
+ ASSERT (Rand != NULL);
+
+ //
+ // A loop to fetch a 32 bit random value with a
retry count limit.
+ //
+ for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
{
+ if (AsmRdSeed32 (Rand)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 64-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 64-
bit random value.
+
+ @retval TRUE Random number generated
successfully.
+ @retval FALSE Failed to generate the random
number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ UINT32 Index;
+
+ ASSERT (Rand != NULL);
+
+ //
+ // A loop to fetch a 64 bit random value with a
retry count limit.
+ //
+ for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
{
+ if (AsmRdSeed64 (Rand)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 128-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the
128-bit random value.
+
+ @retval TRUE Random number generated
successfully.
+ @retval FALSE Failed to generate the random
number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber128 (
+ OUT UINT64 *Rand
+ )
+{
+ ASSERT (Rand != NULL);
+
+ //
+ // Read first 64 bits
+ //
+ if (!GetRandomNumber64 (Rand)) {
+ return FALSE;
+ }
+
+ //
+ // Read second 64 bits
+ //
+ return GetRandomNumber64 (++Rand);
+}
--
2.17.1.windows.2



Re: [PATCH 00/11] Use proper entropy sources

Michael D Kinney
 

Jian,

In this patch series I see mixed use of different RngLib instances.

How does a platform developer working on their DSC file know if the
BaseCryptLib services they are using require a Null or a complete
implementation of the RngLib? How does a platform developer know
if they made the wrong choice.

Thanks,

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On
Behalf Of Wang, Jian J
Sent: Wednesday, November 13, 2019 6:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ard.biesheuvel@...>; Bret
Barkelew <bret.barkelew@...>; Zhang, Chao B
<chao.b.zhang@...>; Wu, Jiaxin
<jiaxin.wu@...>; Yao, Jiewen
<jiewen.yao@...>; Justen, Jordan L
<jordan.l.justen@...>; Laszlo Ersek
<lersek@...>; Leif Lindholm
<leif.lindholm@...>; Gao, Liming
<liming.gao@...>; Rabeda, Maciej
<maciej.rabeda@...>; Matthew Carlson
<macarl@...>; Kinney, Michael D
<michael.d.kinney@...>; Ni, Ray
<ray.ni@...>; Sean Brogan
<sean.brogan@...>; Fu, Siyuan
<@sfu5>; Lu, XiaoyuX
<xiaoyux.lu@...>
Subject: [edk2-devel] [PATCH 00/11] Use proper entropy
sources

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

Patch series summary:
- Add BaseRngLibNull to package dsc
- Add DxeRngLibRngProtocol to make use
EFI_RNG_PROTOCOL
- Add RdSeed interface and RngLibRdSeed for IA32/X64
arch
- Remove following files
rand_pool_noise.h
rand_pool_noise_tsc.c
rand_pool_noise.c
- Update rand_pool.c to use RngLib interface directly
and the drop the TimerLib depenency from OpensslLib
- Update OVMF platform dsc to use DxeRngLibRngProtocol
when necessary

Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Bret Barkelew <bret.barkelew@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Jiaxin Wu <jiaxin.wu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Leif Lindholm <leif.lindholm@...>
Cc: Liming Gao <liming.gao@...>
Cc: Maciej Rabeda <maciej.rabeda@...>
Cc: Matthew Carlson <macarl@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Ray Ni <ray.ni@...>
Cc: Sean Brogan <sean.brogan@...>
Cc: Siyuan Fu <@sfu5>
Cc: Xiaoyu Lu <xiaoyux.lu@...>

Jian J Wang (11):
NetworkPkg/NetworkPkg.dsc: specify RngLib instance
for build
SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib
instances
FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib
instances in dsc files
MdePkg/BaseLib: add interface to wrap rdseed IA
instruction
SecurityPkg/RngLibRdSeed: add an instance of RngLib
to make use rdseed
SecurityPkg/DxeRngLibRngProtocol: add RNG protocol
version of RngLib
SecurityPkg/SecurityPkg.dsc: add new RngLib instances
for build
OvmfPkg: specify RngLib instances in dsc files
ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances
in dsc files
CryptoPkg/OpensslLib: use RngLib to get high quality
random entropy
FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib
instance

ArmVirtPkg/ArmVirt.dsc.inc | 2 +
CryptoPkg/CryptoPkg.dsc | 1 +
CryptoPkg/Library/OpensslLib/OpensslLib.inf | 15 +-
.../Library/OpensslLib/OpensslLibCrypto.inf | 15 +-
CryptoPkg/Library/OpensslLib/rand_pool.c | 253
++----------------
.../Library/OpensslLib/rand_pool_noise.c | 29 --
.../Library/OpensslLib/rand_pool_noise.h | 29 --
.../Library/OpensslLib/rand_pool_noise_tsc.c | 43 --
-
FmpDevicePkg/FmpDevicePkg.dsc | 2 +-
MdePkg/Include/Library/BaseLib.h | 51
++++
MdePkg/Library/BaseLib/BaseLib.inf | 4 +
MdePkg/Library/BaseLib/BaseLibInternals.h | 46
++++
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm | 87
++++++
MdePkg/Library/BaseLib/X64/RdSeed.nasm | 80
++++++
MdePkg/Library/BaseLib/X86RdSeed.c | 73
+++++
NetworkPkg/NetworkPkg.dsc | 1 +
OvmfPkg/OvmfPkgIa32.dsc | 5 +
OvmfPkg/OvmfPkgIa32X64.dsc | 5 +
OvmfPkg/OvmfPkgX64.dsc | 5 +
OvmfPkg/OvmfXen.dsc | 5 +
.../DxeRngLibRngProtocol.c | 200
++++++++++++++
.../DxeRngLibRngProtocol.inf | 42
+++
.../DxeRngLibRngProtocol.uni | 14 +
.../RngLibRdSeed/RngLibRdSeed.inf | 37
+++
.../RngLibRdSeed/RngLibRdSeed.uni | 18 ++
.../RngLibRdSeed/RngRdSeed.c | 189
+++++++++++++
SecurityPkg/SecurityPkg.dsc | 6 +
SignedCapsulePkg/SignedCapsulePkg.dsc | 6 +
28 files changed, 909 insertions(+), 354 deletions(-)
delete mode 100644
CryptoPkg/Library/OpensslLib/rand_pool_noise.c
delete mode 100644
CryptoPkg/Library/OpensslLib/rand_pool_noise.h
delete mode 100644
CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
create mode 100644
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
create mode 100644
MdePkg/Library/BaseLib/X64/RdSeed.nasm
create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c
create mode 100644
SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
DxeRngLibRngProtocol.c
create mode 100644
SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
DxeRngLibRngProtocol.inf
create mode 100644
SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
DxeRngLibRngProtocol.uni
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
Seed.inf
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
Seed.uni
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
d.c

--
2.17.1.windows.2



Re: [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction

Michael D Kinney
 

Jian,

According to the NASM docuimentation, the rdseed instruction
has been supported since 2.10.02.

https://www.nasm.us/xdoc/2.10.09/html/nasmdocc.html

Please use rdseed instead of db bytes.

Thanks,

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On
Behalf Of Wang, Jian J
Sent: Wednesday, November 13, 2019 6:18 PM
To: devel@edk2.groups.io
Cc: Kinney, Michael D <michael.d.kinney@...>;
Gao, Liming <liming.gao@...>; Ni, Ray
<ray.ni@...>
Subject: [edk2-devel] [PATCH 04/11] MdePkg/BaseLib: add
interface to wrap rdseed IA instruction

BaseRngLib uses rdrand instruction to get random number
from DRNG in the processor, which is not a good
candidate for seeding openssl rand interface.

rdseed in x86 cpu provides non-deterministic random
number (NRBG) which meets NIST SP 800-90B and NIST
SP800-90C standards and can be used as seed for other
software DRNG. This patch adds a C interface
AsmRdSeed() to wrap it in BaseLib so that we can add a
new RngLib for users to choose in their platform, if
their processor support rdseed instruction.

Ref:
https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
MdePkg/Include/Library/BaseLib.h | 51
+++++++++++++
MdePkg/Library/BaseLib/BaseLib.inf | 4 ++
MdePkg/Library/BaseLib/BaseLibInternals.h | 46
++++++++++++
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm | 87
+++++++++++++++++++++++
MdePkg/Library/BaseLib/X64/RdSeed.nasm | 80
+++++++++++++++++++++
MdePkg/Library/BaseLib/X86RdSeed.c | 73
+++++++++++++++++++
6 files changed, 341 insertions(+)
create mode 100644
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
create mode 100644
MdePkg/Library/BaseLib/X64/RdSeed.nasm
create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c

diff --git a/MdePkg/Include/Library/BaseLib.h
b/MdePkg/Include/Library/BaseLib.h
index 2a75bc023f..e2f9bf121e 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7856,6 +7856,57 @@ AsmRdRand64 (
OUT UINT64 *Rand
);

+/**
+ Generates a 16-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdSeed16 (
+ OUT UINT16 *Seed
+ );
+
+/**
+ Generates a 32-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed32 (
+ OUT UINT32 *Seed
+ );
+
+/**
+ Generates a 64-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed64 (
+ OUT UINT64 *Seed
+ );
+
/**
Load given selector into TR register.

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
b/MdePkg/Library/BaseLib/BaseLib.inf
index 3586beb0ab..5e12093ba3 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -181,6 +181,7 @@
Ia32/EnableCache.nasm| GCC
Ia32/DisableCache.nasm| GCC
Ia32/RdRand.nasm
+ Ia32/RdSeed.nasm

Ia32/DivS64x64Remainder.c
Ia32/InternalSwitchStack.c | MSFT
@@ -202,6 +203,7 @@
X86DisablePaging64.c
X86DisablePaging32.c
X86RdRand.c
+ X86RdSeed.c
X86PatchInstruction.c
X86SpeculationBarrier.c

@@ -306,12 +308,14 @@
X86DisablePaging64.c
X86DisablePaging32.c
X86RdRand.c
+ X86RdSeed.c
X86PatchInstruction.c
X86SpeculationBarrier.c
X64/GccInline.c | GCC
X64/EnableDisableInterrupts.nasm
X64/DisablePaging64.nasm
X64/RdRand.nasm
+ X64/RdSeed.nasm
ChkStkGcc.c | GCC

[Sources.EBC]
diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h
b/MdePkg/Library/BaseLib/BaseLibInternals.h
index 6837d67d90..7b18b192c9 100644
--- a/MdePkg/Library/BaseLib/BaseLibInternals.h
+++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
@@ -862,6 +862,52 @@ InternalX86RdRand64 (
OUT UINT64 *Rand
);

+/**
+ Generates a 16-bit random seed through RDSEED
instruction.
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed16 (
+ OUT UINT16 *Seed
+ );
+
+/**
+ Generates a 32-bit random seed through RDSEED
instruction.
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed32 (
+ OUT UINT32 *Seed
+ );
+
+/**
+ Generates a 64-bit random seed through RDSEED
instruction.
+
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed64 (
+ OUT UINT64 *Seed
+ );
+
#else

#endif
diff --git a/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
new file mode 100644
index 0000000000..0a4de30db6
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
@@ -0,0 +1,87 @@
+;-----------------------------------------------------
-----------------
+--------
+;
+; Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR> ;
+SPDX-License-Identifier: BSD-2-Clause-Patent ; ;
Module Name:
+;
+; RdSeed.nasm
+;
+; Abstract:
+;
+; Generates random seed through CPU RdSeed
instruction under 32-bit platform.
+;
+; Notes:
+;
+;-----------------------------------------------------
-----------------
+--------
+
+SECTION .text
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 16 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed16)
+ASM_PFX(InternalX86RdSeed16):
+ ; rdseed ax ; generate a 16 bit
RN into ax
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r16: "0f
c7 /7 ModRM:r/m(w)"
+ jc rn16_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn16_ok:
+ mov edx, dword [esp + 4]
+ mov [edx], ax
+ mov eax, 1
+ ret
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 32 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed32)
+ASM_PFX(InternalX86RdSeed32):
+ ; rdseed eax ; generate a 32 bit
RN into eax
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r32: "0f
c7 /7 ModRM:r/m(w)"
+ jc rn32_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn32_ok:
+ mov edx, dword [esp + 4]
+ mov [edx], eax
+ mov eax, 1
+ ret
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 64 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed64)
+ASM_PFX(InternalX86RdSeed64):
+ ; rdseed eax ; generate a 32 bit
RN into eax
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r32: "0f
c7 /7 ModRM:r/m(w)"
+ jnc rn64_ret ; jmp if CF=0
+ mov edx, dword [esp + 4]
+ mov [edx], eax
+
+ db 0xf, 0xc7, 0xf0 ; generate another
32 bit RN
+ jnc rn64_ret ; jmp if CF=0
+ mov [edx + 4], eax
+
+ mov eax, 1
+ ret
+rn64_ret:
+ xor eax, eax
+ pause
+ ret ; return with
failure status
+
diff --git a/MdePkg/Library/BaseLib/X64/RdSeed.nasm
b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
new file mode 100644
index 0000000000..a60acfeace
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
@@ -0,0 +1,80 @@
+;-----------------------------------------------------
-----------------
+--------
+;
+; Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR> ;
+SPDX-License-Identifier: BSD-2-Clause-Patent ; ;
Module Name:
+;
+; RdSeed.nasm
+;
+; Abstract:
+;
+; Generates random seed through CPU RdSeed
instruction under 64-bit platform.
+;
+; Notes:
+;
+;-----------------------------------------------------
-----------------
+--------
+
+ DEFAULT REL
+ SECTION .text
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 16 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed16)
+ASM_PFX(InternalX86RdSeed16):
+ ; rdseed ax ; generate a 16 bit
RN into eax,
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r16: "0f
c7 /7 ModRM:r/m(w)"
+ jc rn16_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn16_ok:
+ mov [rcx], ax
+ mov rax, 1
+ ret
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 32 bit random seed through
RDSEED instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed32)
+ASM_PFX(InternalX86RdSeed32):
+ ; rdseed eax ; generate a 32 bit
RN into eax,
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r32: "0f
c7 /7 ModRM:r/m(w)"
+ jc rn32_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn32_ok:
+ mov [rcx], eax
+ mov rax, 1
+ ret
+
+;-----------------------------------------------------
-----------------
+-------- ; Generates a 64 bit random seed through one
RDSEED
+instruction.
+; Return TRUE if Seed generated successfully, or
FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
+;-----------------------------------------------------
-----------------
+--------
+global ASM_PFX(InternalX86RdSeed64)
+ASM_PFX(InternalX86RdSeed64):
+ ; rdseed rax ; generate a 64 bit
RN into rax,
+ ; CF=1 if RN
generated ok, otherwise CF=0
+ db 0x48, 0xf, 0xc7, 0xf8 ; rdseed r64:
"REX.W + 0f c7 /7 ModRM:r/m(w)"
+ jc rn64_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ pause
+ ret ; return with
failure status
+rn64_ok:
+ mov [rcx], rax
+ mov rax, 1
+ ret
+
diff --git a/MdePkg/Library/BaseLib/X86RdSeed.c
b/MdePkg/Library/BaseLib/X86RdSeed.c
new file mode 100644
index 0000000000..9fa7948ff1
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X86RdSeed.c
@@ -0,0 +1,73 @@
+/** @file
+ IA-32/x64 AsmRdSeedxx()
+ Generates random seed through CPU RdSeed
instruction.
+
+ Copyright (c) 2019, Intel Corporation. All rights
reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BaseLibInternals.h"
+
+/**
+ Generates a 16-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdSeed16 (
+ OUT UINT16 *Seed
+ )
+{
+ ASSERT (Seed != NULL);
+ return InternalX86RdSeed16 (Seed);
+}
+
+/**
+ Generates a 32-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed32 (
+ OUT UINT32 *Seed
+ )
+{
+ ASSERT (Seed != NULL);
+ return InternalX86RdSeed32 (Seed);
+}
+
+/**
+ Generates a 64-bit random seed through RDSEED
instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the
seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call
RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed64 (
+ OUT UINT64 *Seed
+ )
+{
+ ASSERT (Seed != NULL);
+ return InternalX86RdSeed64 (Seed);
+}
--
2.17.1.windows.2



Re: [PATCH V2] BaseTools:Add [packages] section in dsc file

Bob Feng
 

This patch looks good.

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

-----Original Message-----
From: Fan, ZhijuX
Sent: Thursday, November 14, 2019 9:28 AM
To: devel@edk2.groups.io
Cc: Gao, Liming <liming.gao@...>; Feng, Bob C <bob.c.feng@...>
Subject: [PATCH V2] BaseTools:Add [packages] section in dsc file

BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=2270

Currently a PCD (e.g. FeaturePCD) cannot be used in a conditional statement in a DSC/FDF file without a module in the build referencing the PCD package DEC file.

An example implementation that to support this is to allow a [Packages] section in the DSC file to list additional package dependencies for PCD references in the package DSC/FDF files.

this patch is going to add the ability to have the [packages] section defined in the DSC file

Cc: Liming Gao <liming.gao@...>
Cc: Bob Feng <bob.c.feng@...>
Signed-off-by: Zhiju.Fan <zhijux.fan@...>
---
BaseTools/Source/Python/AutoGen/ModuleAutoGen.py | 29 +++++++++++++++++-----
BaseTools/Source/Python/AutoGen/PlatformAutoGen.py | 1 +
.../Source/Python/AutoGen/WorkspaceAutoGen.py | 1 +
BaseTools/Source/Python/Common/DataType.py | 1 +
BaseTools/Source/Python/Workspace/DscBuildData.py | 23 ++++++++++++++++-
.../Source/Python/Workspace/MetaFileParser.py | 14 +++++++++++
.../Source/Python/Workspace/WorkspaceCommon.py | 2 ++
.../Source/Python/Workspace/WorkspaceDatabase.py | 4 +++
8 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
index f0812b6887..e6d6c43810 100755
--- a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
@@ -462,14 +462,31 @@ class ModuleAutoGen(AutoGen):
def BuildCommand(self):
return self.PlatformInfo.BuildCommand

- ## Get object list of all packages the module and its dependent libraries belong to
+ ## Get Module package and Platform package
+ #
+ # @retval list The list of package object
+ #
+ @cached_property
+ def PackageList(self):
+ PkagList = []
+ if self.Module.Packages:
+ PkagList.extend(self.Module.Packages)
+ Platform = self.BuildDatabase[self.PlatformInfo.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
+ for Package in Platform.Packages:
+ if Package in PkagList:
+ continue
+ PkagList.append(Package)
+ return PkagList
+
+ ## Get object list of all packages the module and its dependent
+ libraries belong to and the Platform depends on
#
# @retval list The list of package object
#
@cached_property
def DerivedPackageList(self):
PackageList = []
- for M in [self.Module] + self.DependentLibraryList:
+ PackageList.extend(self.PackageList)
+ for M in self.DependentLibraryList:
for Package in M.Packages:
if Package in PackageList:
continue
@@ -938,13 +955,13 @@ class ModuleAutoGen(AutoGen):
self.Targets
return self._FileTypes

- ## Get the list of package object the module depends on
+ ## Get the list of package object the module depends on and the
+ Platform depends on
#
# @retval list The package object list
#
@cached_property
def DependentPackageList(self):
- return self.Module.Packages
+ return self.PackageList

## Return the list of auto-generated code file
#
@@ -1101,7 +1118,7 @@ class ModuleAutoGen(AutoGen):
RetVal.append(self.MetaFile.Dir)
RetVal.append(self.DebugDir)

- for Package in self.Module.Packages:
+ for Package in self.PackageList:
PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)
if PackageDir not in RetVal:
RetVal.append(PackageDir) @@ -1125,7 +1142,7 @@ class ModuleAutoGen(AutoGen):
@cached_property
def PackageIncludePathList(self):
IncludesList = []
- for Package in self.Module.Packages:
+ for Package in self.PackageList:
PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)
IncludesList = Package.Includes
if Package._PrivateIncludes:
diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
index debeb46f58..4c3cdf82d5 100644
--- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
@@ -975,6 +975,7 @@ class PlatformAutoGen(AutoGen):
continue
ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain]
RetVal.update(ModuleData.Packages)
+ RetVal.update(self.Platform.Packages)
return list(RetVal)

@cached_property
diff --git a/BaseTools/Source/Python/AutoGen/WorkspaceAutoGen.py b/BaseTools/Source/Python/AutoGen/WorkspaceAutoGen.py
index 9d8040905e..fde48b4b27 100644
--- a/BaseTools/Source/Python/AutoGen/WorkspaceAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/WorkspaceAutoGen.py
@@ -420,6 +420,7 @@ class WorkspaceAutoGen(AutoGen):
continue
ModuleData = self.BuildDatabase[ModuleFile, Arch, self.BuildTarget, self.ToolChain]
PkgSet.update(ModuleData.Packages)
+ PkgSet.update(Platform.Packages)
Pkgs[Arch] = list(PkgSet)
return Pkgs

diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py
index 5d49afb0a9..8d80b41089 100644
--- a/BaseTools/Source/Python/Common/DataType.py
+++ b/BaseTools/Source/Python/Common/DataType.py
@@ -519,6 +519,7 @@ SECTIONS_HAVE_ITEM_AFTER_ARCH_SET = {TAB_LIBRARY_CLASSES.upper(), TAB_DEPEX.uppe
PCDS_DYNAMICEX_VPD.upper(),
PCDS_DYNAMICEX_HII.upper(),
TAB_BUILD_OPTIONS.upper(),
+ TAB_PACKAGES.upper(),
TAB_INCLUDES.upper()}

#
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 9192077f90..03a15bbf3e 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -719,6 +719,24 @@ class DscBuildData(PlatformBuildClassObject):
self._RawData.DisableOverrideComponent(Components[(file_guid_str,str(ModuleFile))])
Components[(file_guid_str,str(ModuleFile))] = ModuleId
self._RawData._PostProcessed = False
+
+ ## Retrieve packages this Platform depends on
+ @cached_property
+ def Packages(self):
+ RetVal = set()
+ RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch]
+ Macros = self._Macros
+ for Record in RecordList:
+ File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate('.dec')
+ if ErrorCode != 0:
+ LineNo = Record[-1]
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
+ # parse this package now. we need it to get protocol/ppi/guid value
+ RetVal.add(self._Bdb[File, self._Arch, self._Target, self._Toolchain])
+ return RetVal
+
## Retrieve [Components] section information
@property
def Modules(self):
@@ -896,7 +914,8 @@ class DscBuildData(PlatformBuildClassObject):
continue
ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
PkgSet.update(ModuleData.Packages)
-
+ if self.Packages:
+ PkgSet.update(self.Packages)
self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
self._GuidDict.update(GlobalData.gPlatformPcds)

@@ -3320,6 +3339,8 @@ class DscBuildData(PlatformBuildClassObject):
continue
ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
PkgSet.update(ModuleData.Packages)
+ if self.Packages:
+ PkgSet.update(self.Packages)
self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
self._GuidDict.update(GlobalData.gPlatformPcds)
return self._DecPcds
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index 806fc322c5..3f96ce0564 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -160,6 +160,7 @@ class MetaFileParser(object):
self.MetaFile = FilePath
self._FileDir = self.MetaFile.Dir
self._Defines = {}
+ self._Packages = []
self._FileLocalMacros = {}
self._SectionsMacroDict = defaultdict(dict)

@@ -351,6 +352,13 @@ class MetaFileParser(object):
# If the section information is needed later, it should be stored in database
self._ValueList[0] = self._SectionName

+ ## [packages] section parser
+ @ParseMacro
+ def _PackageParser(self):
+ self._CurrentLine = CleanString(self._CurrentLine)
+ self._Packages.append(self._CurrentLine)
+ self._ValueList[0] = self._CurrentLine
+
## [defines] section parser
@ParseMacro
def _DefineParser(self):
@@ -848,6 +856,7 @@ class DscParser(MetaFileParser):
TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
+ TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,
TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
@@ -1339,6 +1348,7 @@ class DscParser(MetaFileParser):
MODEL_META_DATA_DEFINE : self.__ProcessDefine,
MODEL_META_DATA_GLOBAL_DEFINE : self.__ProcessDefine,
MODEL_META_DATA_INCLUDE : self.__ProcessDirective,
+ MODEL_META_DATA_PACKAGE : self.__ProcessPackages,
MODEL_META_DATA_CONDITIONAL_STATEMENT_IF : self.__ProcessDirective,
MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE : self.__ProcessDirective,
MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF : self.__ProcessDirective,
@@ -1642,6 +1652,9 @@ class DscParser(MetaFileParser):
self._ValueList = None
self._ContentIndex -= 1

+ def __ProcessPackages(self):
+ self._ValueList[0] = ReplaceMacro(self._ValueList[0],
+ self._Macros)
+
def __ProcessSkuId(self):
self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True)
for Value in self._ValueList] @@ -1720,6 +1733,7 @@ class DscParser(MetaFileParser):
MODEL_META_DATA_COMPONENT : _ComponentParser,
MODEL_META_DATA_BUILD_OPTION : _BuildOptionParser,
MODEL_UNKNOWN : MetaFileParser._Skip,
+ MODEL_META_DATA_PACKAGE : MetaFileParser._PackageParser,
MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
MODEL_META_DATA_SECTION_HEADER : MetaFileParser._SectionHeaderParser,
MODEL_META_DATA_SUBSECTION_HEADER : _SubsectionHeaderParser,
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
index 0b11ec2d59..913e710fd9 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
@@ -37,6 +37,8 @@ class OrderedListDict(OrderedDict):
#
def GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain):
PkgSet = set()
+ if Platform.Packages:
+ PkgSet.update(Platform.Packages)
for ModuleFile in Platform.Modules:
Data = BuildDatabase[ModuleFile, Arch, Target, Toolchain]
PkgSet.update(Data.Packages)
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
index ab7b4506c1..9420eaa608 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
@@ -186,6 +186,10 @@ class WorkspaceDatabase(object):
for Package in LibObj.Packages:
if Package not in PackageList:
PackageList.append(Package)
+ for Package in Pa.Packages:
+ if Package in PackageList:
+ continue
+ PackageList.append(Package)

return PackageList

--
2.14.1.windows.1


Re: [PATCH 00/11] Use proper entropy sources

Wang, Jian J
 

The patches can also be found at in my fork in github

https://github.com/jwang36/edk2/tree/fix-bz1871-use-proper-entropy-sources-v1

Regards,
Jian

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Wang, Jian
J
Sent: Thursday, November 14, 2019 10:18 AM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ard.biesheuvel@...>; Bret Barkelew
<bret.barkelew@...>; Zhang, Chao B <chao.b.zhang@...>;
Wu, Jiaxin <jiaxin.wu@...>; Yao, Jiewen <jiewen.yao@...>; Justen,
Jordan L <jordan.l.justen@...>; Laszlo Ersek <lersek@...>; Leif
Lindholm <leif.lindholm@...>; Gao, Liming <liming.gao@...>;
Rabeda, Maciej <maciej.rabeda@...>; Matthew Carlson
<macarl@...>; Kinney, Michael D <michael.d.kinney@...>; Ni,
Ray <ray.ni@...>; Sean Brogan <sean.brogan@...>; Fu,
Siyuan <@sfu5>; Lu, XiaoyuX <xiaoyux.lu@...>
Subject: [edk2-devel] [PATCH 00/11] Use proper entropy sources

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

Patch series summary:
- Add BaseRngLibNull to package dsc
- Add DxeRngLibRngProtocol to make use EFI_RNG_PROTOCOL
- Add RdSeed interface and RngLibRdSeed for IA32/X64 arch
- Remove following files
rand_pool_noise.h
rand_pool_noise_tsc.c
rand_pool_noise.c
- Update rand_pool.c to use RngLib interface directly
and the drop the TimerLib depenency from OpensslLib
- Update OVMF platform dsc to use DxeRngLibRngProtocol
when necessary

Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Bret Barkelew <bret.barkelew@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Jiaxin Wu <jiaxin.wu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Leif Lindholm <leif.lindholm@...>
Cc: Liming Gao <liming.gao@...>
Cc: Maciej Rabeda <maciej.rabeda@...>
Cc: Matthew Carlson <macarl@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Ray Ni <ray.ni@...>
Cc: Sean Brogan <sean.brogan@...>
Cc: Siyuan Fu <@sfu5>
Cc: Xiaoyu Lu <xiaoyux.lu@...>

Jian J Wang (11):
NetworkPkg/NetworkPkg.dsc: specify RngLib instance for build
SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib instances
FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib instances in dsc files
MdePkg/BaseLib: add interface to wrap rdseed IA instruction
SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib
SecurityPkg/SecurityPkg.dsc: add new RngLib instances for build
OvmfPkg: specify RngLib instances in dsc files
ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files
CryptoPkg/OpensslLib: use RngLib to get high quality random entropy
FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib instance

ArmVirtPkg/ArmVirt.dsc.inc | 2 +
CryptoPkg/CryptoPkg.dsc | 1 +
CryptoPkg/Library/OpensslLib/OpensslLib.inf | 15 +-
.../Library/OpensslLib/OpensslLibCrypto.inf | 15 +-
CryptoPkg/Library/OpensslLib/rand_pool.c | 253 ++----------------
.../Library/OpensslLib/rand_pool_noise.c | 29 --
.../Library/OpensslLib/rand_pool_noise.h | 29 --
.../Library/OpensslLib/rand_pool_noise_tsc.c | 43 ---
FmpDevicePkg/FmpDevicePkg.dsc | 2 +-
MdePkg/Include/Library/BaseLib.h | 51 ++++
MdePkg/Library/BaseLib/BaseLib.inf | 4 +
MdePkg/Library/BaseLib/BaseLibInternals.h | 46 ++++
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm | 87 ++++++
MdePkg/Library/BaseLib/X64/RdSeed.nasm | 80 ++++++
MdePkg/Library/BaseLib/X86RdSeed.c | 73 +++++
NetworkPkg/NetworkPkg.dsc | 1 +
OvmfPkg/OvmfPkgIa32.dsc | 5 +
OvmfPkg/OvmfPkgIa32X64.dsc | 5 +
OvmfPkg/OvmfPkgX64.dsc | 5 +
OvmfPkg/OvmfXen.dsc | 5 +
.../DxeRngLibRngProtocol.c | 200 ++++++++++++++
.../DxeRngLibRngProtocol.inf | 42 +++
.../DxeRngLibRngProtocol.uni | 14 +
.../RngLibRdSeed/RngLibRdSeed.inf | 37 +++
.../RngLibRdSeed/RngLibRdSeed.uni | 18 ++
.../RngLibRdSeed/RngRdSeed.c | 189 +++++++++++++
SecurityPkg/SecurityPkg.dsc | 6 +
SignedCapsulePkg/SignedCapsulePkg.dsc | 6 +
28 files changed, 909 insertions(+), 354 deletions(-)
delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.c
delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.h
delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
create mode 100644 MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
create mode 100644 MdePkg/Library/BaseLib/X64/RdSeed.nasm
create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c
create mode 100644
SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngPr
otocol.c
create mode 100644
SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngPr
otocol.inf
create mode 100644
SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngPr
otocol.uni
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni
create mode 100644
SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c

--
2.17.1.windows.2



[PATCH 11/11] FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib instance

Wang, Jian J
 

TimerLib instance was added for openssl1.1.1b upgrade due to rand
interface implementation based on TimerLib. Since RngLib is now
used instead, TimerLib is not needed any more.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Liming Gao <liming.gao@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
FmpDevicePkg/FmpDevicePkg.dsc | 1 -
1 file changed, 1 deletion(-)

diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index 201ea00f63..2fd7cf4d88 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -60,7 +60,6 @@
CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
FmpDeviceLib|FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf
- TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf

[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
--
2.17.1.windows.2


[PATCH 10/11] CryptoPkg/OpensslLib: use RngLib to get high quality random entropy

Wang, Jian J
 

Per BZ1871, OpensslLib should use RngLib to get high quality of random
entropy. This patch remove all code depending on TimerLib for this job,
and add RngLib interface to implement the rand interface required by
openssl.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Xiaoyu Lu <xiaoyux.lu@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
CryptoPkg/CryptoPkg.dsc | 1 +
CryptoPkg/Library/OpensslLib/OpensslLib.inf | 15 +-
.../Library/OpensslLib/OpensslLibCrypto.inf | 15 +-
CryptoPkg/Library/OpensslLib/rand_pool.c | 253 ++----------------
.../Library/OpensslLib/rand_pool_noise.c | 29 --
.../Library/OpensslLib/rand_pool_noise.h | 29 --
.../Library/OpensslLib/rand_pool_noise_tsc.c | 43 ---
7 files changed, 32 insertions(+), 353 deletions(-)
delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.c
delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.h
delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c

diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index ec43c1f0a4..54f892996a 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -44,6 +44,7 @@

IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+ RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf

[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
index b28dd9e480..4c535dc1e6 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
@@ -23,7 +23,6 @@

[Sources]
buildinf.h
- rand_pool_noise.h
$(OPENSSL_PATH)/e_os.h
# Autogenerated files list starts here
$(OPENSSL_PATH)/crypto/aes/aes_cbc.c
@@ -602,18 +601,6 @@
ossl_store.c
rand_pool.c

-[Sources.Ia32]
- rand_pool_noise_tsc.c
-
-[Sources.X64]
- rand_pool_noise_tsc.c
-
-[Sources.ARM]
- rand_pool_noise.c
-
-[Sources.AARCH64]
- rand_pool_noise.c
-
[Packages]
MdePkg/MdePkg.dec
CryptoPkg/CryptoPkg.dec
@@ -621,7 +608,7 @@
[LibraryClasses]
BaseLib
DebugLib
- TimerLib
+ RngLib
PrintLib

[LibraryClasses.ARM]
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
index 1b6ff5ed54..51159a6f2d 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
@@ -547,22 +547,9 @@
$(OPENSSL_PATH)/crypto/objects/obj_xref.h
# Autogenerated files list ends here
buildinf.h
- rand_pool_noise.h
ossl_store.c
rand_pool.c

-[Sources.Ia32]
- rand_pool_noise_tsc.c
-
-[Sources.X64]
- rand_pool_noise_tsc.c
-
-[Sources.ARM]
- rand_pool_noise.c
-
-[Sources.AARCH64]
- rand_pool_noise.c
-
[Packages]
MdePkg/MdePkg.dec
CryptoPkg/CryptoPkg.dec
@@ -570,7 +557,7 @@
[LibraryClasses]
BaseLib
DebugLib
- TimerLib
+ RngLib
PrintLib

[LibraryClasses.ARM]
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool.c b/CryptoPkg/Library/OpensslLib/rand_pool.c
index 9d2a4ad138..f57c238fc4 100644
--- a/CryptoPkg/Library/OpensslLib/rand_pool.c
+++ b/CryptoPkg/Library/OpensslLib/rand_pool.c
@@ -11,213 +11,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <openssl/aes.h>

#include <Uefi.h>
-#include <Library/TimerLib.h>
-
-#include "rand_pool_noise.h"
-
-/**
- Get some randomness from low-order bits of GetPerformanceCounter results.
- And combine them to the 64-bit value
-
- @param[out] Rand Buffer pointer to store the 64-bit random value.
-
- @retval TRUE Random number generated successfully.
- @retval FALSE Failed to generate.
-**/
-STATIC
-BOOLEAN
-EFIAPI
-GetRandNoise64FromPerformanceCounter(
- OUT UINT64 *Rand
- )
-{
- UINT32 Index;
- UINT32 *RandPtr;
-
- if (NULL == Rand) {
- return FALSE;
- }
-
- RandPtr = (UINT32 *) Rand;
-
- for (Index = 0; Index < 2; Index ++) {
- *RandPtr = (UINT32) (GetPerformanceCounter () & 0xFF);
- MicroSecondDelay (10);
- RandPtr++;
- }
-
- return TRUE;
-}
-
-/**
- Calls RandomNumber64 to fill
- a buffer of arbitrary size with random bytes.
-
- @param[in] Length Size of the buffer, in bytes, to fill with.
- @param[out] RandBuffer Pointer to the buffer to store the random result.
-
- @retval EFI_SUCCESS Random bytes generation succeeded.
- @retval EFI_NOT_READY Failed to request random bytes.
-
-**/
-STATIC
-BOOLEAN
-EFIAPI
-RandGetBytes (
- IN UINTN Length,
- OUT UINT8 *RandBuffer
- )
-{
- BOOLEAN Ret;
- UINT64 TempRand;
-
- Ret = FALSE;
-
- while (Length > 0) {
- //
- // Get random noise from platform.
- // If it failed, fallback to PerformanceCounter
- // If you really care about security, you must override
- // GetRandomNoise64FromPlatform.
- //
- Ret = GetRandomNoise64 (&TempRand);
- if (Ret == FALSE) {
- Ret = GetRandNoise64FromPerformanceCounter (&TempRand);
- }
- if (!Ret) {
- return Ret;
- }
- if (Length >= sizeof (TempRand)) {
- *((UINT64*) RandBuffer) = TempRand;
- RandBuffer += sizeof (UINT64);
- Length -= sizeof (TempRand);
- } else {
- CopyMem (RandBuffer, &TempRand, Length);
- Length = 0;
- }
- }
-
- return Ret;
-}
-
-/**
- Creates a 128bit random value that is fully forward and backward prediction resistant,
- suitable for seeding a NIST SP800-90 Compliant.
- This function takes multiple random numbers from PerformanceCounter to ensure reseeding
- and performs AES-CBC-MAC over the data to compute the seed value.
-
- @param[out] SeedBuffer Pointer to a 128bit buffer to store the random seed.
-
- @retval TRUE Random seed generation succeeded.
- @retval FALSE Failed to request random bytes.
-
-**/
-STATIC
-BOOLEAN
-EFIAPI
-RandGetSeed128 (
- OUT UINT8 *SeedBuffer
- )
-{
- BOOLEAN Ret;
- UINT8 RandByte[16];
- UINT8 Key[16];
- UINT8 Ffv[16];
- UINT8 Xored[16];
- UINT32 Index;
- UINT32 Index2;
- AES_KEY AESKey;
-
- //
- // Chose an arbitary key and zero the feed_forward_value (FFV)
- //
- for (Index = 0; Index < 16; Index++) {
- Key[Index] = (UINT8) Index;
- Ffv[Index] = 0;
- }
-
- AES_set_encrypt_key (Key, 16 * 8, &AESKey);
-
- //
- // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 bit value
- // The 10us gaps will ensure multiple reseeds within the system time with a large
- // design margin.
- //
- for (Index = 0; Index < 32; Index++) {
- MicroSecondDelay (10);
- Ret = RandGetBytes (16, RandByte);
- if (!Ret) {
- return Ret;
- }
-
- //
- // Perform XOR operations on two 128-bit value.
- //
- for (Index2 = 0; Index2 < 16; Index2++) {
- Xored[Index2] = RandByte[Index2] ^ Ffv[Index2];
- }
-
- AES_encrypt (Xored, Ffv, &AESKey);
- }
-
- for (Index = 0; Index < 16; Index++) {
- SeedBuffer[Index] = Ffv[Index];
- }
-
- return Ret;
-}
-
-/**
- Generate high-quality entropy source.
-
- @param[in] Length Size of the buffer, in bytes, to fill with.
- @param[out] Entropy Pointer to the buffer to store the entropy data.
-
- @retval EFI_SUCCESS Entropy generation succeeded.
- @retval EFI_NOT_READY Failed to request random data.
-
-**/
-STATIC
-BOOLEAN
-EFIAPI
-RandGenerateEntropy (
- IN UINTN Length,
- OUT UINT8 *Entropy
- )
-{
- BOOLEAN Ret;
- UINTN BlockCount;
- UINT8 Seed[16];
- UINT8 *Ptr;
-
- BlockCount = Length / 16;
- Ptr = (UINT8 *) Entropy;
-
- //
- // Generate high-quality seed for DRBG Entropy
- //
- while (BlockCount > 0) {
- Ret = RandGetSeed128 (Seed);
- if (!Ret) {
- return Ret;
- }
- CopyMem (Ptr, Seed, 16);
-
- BlockCount--;
- Ptr = Ptr + 16;
- }
-
- //
- // Populate the remained data as request.
- //
- Ret = RandGetSeed128 (Seed);
- if (!Ret) {
- return Ret;
- }
- CopyMem (Ptr, Seed, (Length % 16));
-
- return Ret;
-}
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>

/*
* Add random bytes to the pool to acquire requested amount of entropy
@@ -229,17 +25,30 @@ RandGenerateEntropy (
*/
size_t rand_pool_acquire_entropy(RAND_POOL *pool)
{
- BOOLEAN Ret;
- size_t bytes_needed;
- unsigned char * buffer;
+ BOOLEAN ret;
+ size_t bytes_needed;
+ size_t len;
+ unsigned char *buffer;
+ UINT64 data[2];

bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
if (bytes_needed > 0) {
buffer = rand_pool_add_begin(pool, bytes_needed);

if (buffer != NULL) {
- Ret = RandGenerateEntropy(bytes_needed, buffer);
- if (FALSE == Ret) {
+ ret = TRUE;
+ while (bytes_needed > 0 && ret) {
+ ret = GetRandomNumber128 (data);
+ if (ret) {
+ len = MIN (bytes_needed, sizeof(data));
+ CopyMem (buffer, data, len);
+
+ bytes_needed -= len;
+ buffer += len;
+ }
+ }
+
+ if (FALSE == ret) {
rand_pool_add_end(pool, 0, 0);
} else {
rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
@@ -257,13 +66,11 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
*/
int rand_pool_add_nonce_data(RAND_POOL *pool)
{
- struct {
- UINT64 Rand;
- UINT64 TimerValue;
- } data = { 0 };
+ UINT64 data[2];

- RandGetBytes(8, (UINT8 *)&(data.Rand));
- data.TimerValue = GetPerformanceCounter();
+ if (!GetRandomNumber128 (data)) {
+ return 0;
+ }

return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);
}
@@ -275,13 +82,11 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
*/
int rand_pool_add_additional_data(RAND_POOL *pool)
{
- struct {
- UINT64 Rand;
- UINT64 TimerValue;
- } data = { 0 };
+ UINT64 data[2];

- RandGetBytes(8, (UINT8 *)&(data.Rand));
- data.TimerValue = GetPerformanceCounter();
+ if (!GetRandomNumber128 (data)) {
+ return 0;
+ }

return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);
}
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c b/CryptoPkg/Library/OpensslLib/rand_pool_noise.c
deleted file mode 100644
index c16ed8b454..0000000000
--- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/** @file
- Provide rand noise source.
-
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/BaseLib.h>
-
-/**
- Get 64-bit noise source
-
- @param[out] Rand Buffer pointer to store 64-bit noise source
-
- @retval FALSE Failed to generate
-**/
-BOOLEAN
-EFIAPI
-GetRandomNoise64 (
- OUT UINT64 *Rand
- )
-{
- //
- // Return FALSE will fallback to use PerformaceCounter to
- // generate noise.
- //
- return FALSE;
-}
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h b/CryptoPkg/Library/OpensslLib/rand_pool_noise.h
deleted file mode 100644
index 75acc686a9..0000000000
--- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/** @file
- Provide rand noise source.
-
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __RAND_POOL_NOISE_H__
-#define __RAND_POOL_NOISE_H__
-
-#include <Uefi/UefiBaseType.h>
-
-/**
- Get 64-bit noise source.
-
- @param[out] Rand Buffer pointer to store 64-bit noise source
-
- @retval TRUE Get randomness successfully.
- @retval FALSE Failed to generate
-**/
-BOOLEAN
-EFIAPI
-GetRandomNoise64 (
- OUT UINT64 *Rand
- );
-
-
-#endif // __RAND_POOL_NOISE_H__
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c b/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
deleted file mode 100644
index 4158106231..0000000000
--- a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/** @file
- Provide rand noise source.
-
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/TimerLib.h>
-
-/**
- Get 64-bit noise source
-
- @param[out] Rand Buffer pointer to store 64-bit noise source
-
- @retval TRUE Get randomness successfully.
- @retval FALSE Failed to generate
-**/
-BOOLEAN
-EFIAPI
-GetRandomNoise64 (
- OUT UINT64 *Rand
- )
-{
- UINT32 Index;
- UINT32 *RandPtr;
-
- if (NULL == Rand) {
- return FALSE;
- }
-
- RandPtr = (UINT32 *)Rand;
-
- for (Index = 0; Index < 2; Index ++) {
- *RandPtr = (UINT32) ((AsmReadTsc ()) & 0xFF);
- RandPtr++;
- MicroSecondDelay (10);
- }
-
- return TRUE;
-}
--
2.17.1.windows.2


[PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files

Wang, Jian J
 

Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib. Update
ArmVirt.dsc.inc file to accommodate the coming changes. It's supposed
that only TlsDxe needs random number. The RngDxeLib is added for it. For
all other drivers, RngLibNull is used by default.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Leif Lindholm <leif.lindholm@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
ArmVirtPkg/ArmVirt.dsc.inc | 2 ++
1 file changed, 2 insertions(+)

diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 10037c938e..10e0890699 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -156,8 +156,10 @@
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
!if $(NETWORK_TLS_ENABLE) == TRUE
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+ RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
!else
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+ RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
!endif
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf

--
2.17.1.windows.2


[PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files

Wang, Jian J
 

Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib.
Update OVMF dsc files to accommodate the coming changes. It's supposed
that only TlsDxe needs random number. The DxeRngLibRngProtocol is added
for it. For all other drivers, BaseRngLibNull is used by default.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
OvmfPkg/OvmfPkgIa32.dsc | 5 +++++
OvmfPkg/OvmfPkgIa32X64.dsc | 5 +++++
OvmfPkg/OvmfPkgX64.dsc | 5 +++++
OvmfPkg/OvmfXen.dsc | 5 +++++
4 files changed, 20 insertions(+)

diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index d350b75630..5a709a95b2 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -217,6 +217,7 @@

[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf

[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
@@ -786,6 +787,10 @@
<LibraryClasses>
NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
}
+ NetworkPkg/TlsDxe/TlsDxe.inf {
+ <LibraryClasses>
+ RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+ }
!endif
OvmfPkg/VirtioNetDxe/VirtioNet.inf

diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 1ef82cafe4..16ff25fd2c 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -222,6 +222,7 @@

[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf

[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
@@ -799,6 +800,10 @@
<LibraryClasses>
NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
}
+ NetworkPkg/TlsDxe/TlsDxe.inf {
+ <LibraryClasses>
+ RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+ }
!endif
OvmfPkg/VirtioNetDxe/VirtioNet.inf

diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 232815c08e..c9c2af740f 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -222,6 +222,7 @@

[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf

[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
@@ -797,6 +798,10 @@
<LibraryClasses>
NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
}
+ NetworkPkg/TlsDxe/TlsDxe.inf {
+ <LibraryClasses>
+ RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+ }
!endif
OvmfPkg/VirtioNetDxe/VirtioNet.inf

diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 8c11efe9b7..557dff7744 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -204,6 +204,7 @@

[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf

[LibraryClasses.common.SEC]
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
@@ -666,6 +667,10 @@
<LibraryClasses>
NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
}
+ NetworkPkg/TlsDxe/TlsDxe.inf {
+ <LibraryClasses>
+ RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+ }
!endif

#
--
2.17.1.windows.2


[PATCH 07/11] SecurityPkg/SecurityPkg.dsc: add new RngLib instances for build

Wang, Jian J
 

Add new libraries DxeRngLibRngProtocol and RngLibRdSeed into
SecurityPkg.dsc.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
SecurityPkg/SecurityPkg.dsc | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index a2eeadda7a..21b454f80d 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -231,6 +231,11 @@
SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
SecurityPkg/Library/TcgPpVendorLibNull/TcgPpVendorLibNull.inf

+ #
+ # General Random Number Generator
+ #
+ SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+
[Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf

@@ -309,6 +314,7 @@
# Random Number Generator
#
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+ SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf

#
# Opal Password solution
--
2.17.1.windows.2


[PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib

Wang, Jian J
 

From: Matthew Carlson <macarl@...>

This version of RngLib makes use of EFI_RNG_PROTOCOL to provide random
number. According to UEFI spec, EFI_RNG_PROTOCOL should meet NIST SP
800-90 and/or ANSI X9.31 standards.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Matthew Carlson <macarl@...>
Cc: Sean Brogan <sean.brogan@...>
Cc: Bret Barkelew <bret.barkelew@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
.../DxeRngLibRngProtocol.c | 200 ++++++++++++++++++
.../DxeRngLibRngProtocol.inf | 42 ++++
.../DxeRngLibRngProtocol.uni | 14 ++
3 files changed, 256 insertions(+)
create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni

diff --git a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
new file mode 100644
index 0000000000..8ce4a7050d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
@@ -0,0 +1,200 @@
+/** @file
+ Provides an implementation of the library class RngLib that uses the Rng protocol.
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+Copyright (c) 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
+#include <Protocol/Rng.h>
+
+/**
+ Generates a random number via the NIST 800-9A algorithm. Refer to
+ http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf
+ for more information.
+
+ @param[out] Buffer Buffer to receive the random number.
+ @param[in] BufferSize Number of bytes in Buffer.
+
+ @retval EFI_SUCCESS Random data generated successfully.
+ @retval Others Failed to generate the random number.
+
+**/
+STATIC
+EFI_STATUS
+GenerateRandomNumberViaNist800Algorithm(
+ OUT UINT8* Buffer,
+ IN UINTN BufferSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_RNG_PROTOCOL* RngProtocol;
+
+ Status = EFI_UNSUPPORTED;
+ RngProtocol = NULL;
+
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "[%a] Buffer == NULL.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (gBS == NULL) {
+ DEBUG ((DEBUG_ERROR, "[%a] GenerateRandomNumber, gBS == NULL. Called too soon.\n", __FUNCTION__));
+ return EFI_LOAD_ERROR;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&RngProtocol);
+ if (EFI_ERROR (Status) || RngProtocol == NULL) {
+ DEBUG ((DEBUG_ERROR, "[%a] Could not locate RNG prototocol, Status = %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Ctr256Guid, BufferSize, Buffer);
+ DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm CTR-256 - Status = %r\n", __FUNCTION__, Status));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hmac256Guid, BufferSize, Buffer);
+ DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm HMAC-256 - Status = %r\n", __FUNCTION__, Status));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hash256Guid, BufferSize, Buffer);
+ DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm Hash-256 - Status = %r\n", __FUNCTION__, Status));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // If we get to this point, we have failed
+ //
+ DEBUG((DEBUG_ERROR, "[%a] GetRNG() failed, staus = %r\n", __FUNCTION__, Status));
+
+ return Status;
+}
+
+
+/**
+ Generates a 16-bit random number.
+
+ if Rand is NULL, return FALSE.
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ EFI_STATUS Status;
+
+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 2);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ Generates a 32-bit random number.
+
+ if Rand is NULL, return FALSE.
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ EFI_STATUS Status;
+
+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 4);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ Generates a 64-bit random number.
+
+ if Rand is NULL, return FALSE.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ EFI_STATUS Status;
+
+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 8);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ Generates a 128-bit random number.
+
+ if Rand is NULL, return FALSE.
+
+ @param[out] Rand Buffer pointer to store the 128-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber128 (
+ OUT UINT64 *Rand
+ )
+{
+ EFI_STATUS Status;
+
+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 16);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
new file mode 100644
index 0000000000..d47fe3be53
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
@@ -0,0 +1,42 @@
+# @file
+# Provides implementation of the library class RngLib that uses the RngProtocol
+#
+# @copyright
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010029
+ BASE_NAME = DxeRngLibRngProtocol
+ MODULE_UNI_FILE = DxeRngLibRngProtocol.uni
+ FILE_GUID = FF9F84C5-A33E-44E3-9BB5-0D654B2D4149
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RngLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64
+#
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[Sources]
+ DxeRngLibRngProtocol.c
+
+[LibraryClasses]
+ DebugLib
+ UefiBootServicesTableLib
+
+[Protocols]
+ gEfiRngProtocolGuid ## CONSUMES
+
+[Depex]
+ gEfiRngProtocolGuid
+
+[Guids]
+ gEfiRngAlgorithmSp80090Ctr256Guid ## CONSUMES
+ gEfiRngAlgorithmSp80090Hash256Guid ## CONSUMES
+ gEfiRngAlgorithmSp80090Hmac256Guid ## CONSUMES
diff --git a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni
new file mode 100644
index 0000000000..09af056bd3
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Instance of RNG (Random Number Generator) Library Based on EFI_RNG_PROTOCOL.
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Instance of RNG Library Based on EFI_RNG_PROTOCOL."
+
+#string STR_MODULE_DESCRIPTION #language en-US "This version of RNG library makes use of EFI_RNG_PROTOCOL to generate random number compliant with NIST 800-9A."
+
--
2.17.1.windows.2


[PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed

Wang, Jian J
 

This version of RngLib makes use of AsmRdSeed to get non-deterministic
random number, which can be used for seeding other software DRNG like
rand interface in openssl. It can be used only on IA32/X64 processors
which supports rdseed instruction.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
.../RngLibRdSeed/RngLibRdSeed.inf | 37 ++++
.../RngLibRdSeed/RngLibRdSeed.uni | 18 ++
.../RngLibRdSeed/RngRdSeed.c | 189 ++++++++++++++++++
3 files changed, 244 insertions(+)
create mode 100644 SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf
create mode 100644 SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni
create mode 100644 SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c

diff --git a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf
new file mode 100644
index 0000000000..8162408775
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf
@@ -0,0 +1,37 @@
+## @file
+# Instance of RNG (Random Number Generator) Library.
+#
+# Rng RdSeed Library that uses CPU RdSeed instruction access to provide
+# non-deterministic random number which can be used as seed for other
+# software deterministic RNGs.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010029
+ BASE_NAME = RngLibRdSeed
+ MODULE_UNI_FILE = RngLibRdSeed.uni
+ FILE_GUID = 8B613B2E-B944-40F9-B979-1B60D7CAA73C
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RngLib
+ CONSTRUCTOR = RngLibRdSeedConstructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.Ia32, Sources.X64]
+ RngRdSeed.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
diff --git a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni
new file mode 100644
index 0000000000..051a3019bc
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni
@@ -0,0 +1,18 @@
+// /** @file
+// Instance of RNG (Random Number Generator) Library.
+//
+// Rng RdSeed Library that uses CPU RdSeed instruction access to provide
+// non-deterministic random number which can be used as seed for other
+// software deterministic RNGs.
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Instance of RNG Library"
+
+#string STR_MODULE_DESCRIPTION #language en-US "RngRdSeed Library that uses CPU RdSeed instruction access to provide non-deterministic random numbers."
+
diff --git a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c
new file mode 100644
index 0000000000..0036faa050
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c
@@ -0,0 +1,189 @@
+/** @file
+ Random number generator services that uses RdSeed instruction access
+ to provide non-deterministic random numbers, which are usually used
+ for seeding other pseudo-random number generators.
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
+
+//
+// Bit mask used to determine if RdSeed instruction is supported.
+//
+#define RDSEED_MASK BIT18
+
+//
+// Limited retry number when valid random data is returned.
+// It varies between 1 and 100 according to "Intel(R) DRGN Software Implementation
+// Guide". Let's use the same value as RDRAND in BaseRngLib.
+//
+#define RDSEED_RETRY_LIMIT 10
+
+/**
+ The constructor function checks whether or not RDSEED instruction is supported
+ by the host hardware.
+
+ The constructor function checks whether or not RDSEED instruction is supported.
+ It will ASSERT() if RDSEED instruction is not supported.
+
+ @retval RETURN_SUCCESS The processor supports RDSEED instruction.
+ @retval RETURN_UNSUPPORTED RDSEED instruction is not supported.
+
+**/
+RETURN_STATUS
+EFIAPI
+RngLibRdSeedConstructor (
+ VOID
+ )
+{
+ UINT32 RegEbx;
+
+ //
+ // Determine RDSEED support by examining bit 18 of the EBX register returned by
+ // CPUID(EAX=7, ECX=0). BIT18 of EBX indicates that processor support RDSEED
+ // instruction.
+ //
+ AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL);
+ if ((RegEbx & RDSEED_MASK) != RDSEED_MASK) {
+ ASSERT ((RegEbx & RDSEED_MASK) == RDSEED_MASK);
+ return RETURN_UNSUPPORTED;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Generates a 16-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ UINT32 Index;
+
+ ASSERT (Rand != NULL);
+
+ //
+ // A loop to fetch a 16 bit random value with a retry count limit.
+ //
+ for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++) {
+ if (AsmRdSeed16 (Rand)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 32-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ UINT32 Index;
+
+ ASSERT (Rand != NULL);
+
+ //
+ // A loop to fetch a 32 bit random value with a retry count limit.
+ //
+ for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++) {
+ if (AsmRdSeed32 (Rand)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 64-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ UINT32 Index;
+
+ ASSERT (Rand != NULL);
+
+ //
+ // A loop to fetch a 64 bit random value with a retry count limit.
+ //
+ for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++) {
+ if (AsmRdSeed64 (Rand)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 128-bit random number.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the 128-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber128 (
+ OUT UINT64 *Rand
+ )
+{
+ ASSERT (Rand != NULL);
+
+ //
+ // Read first 64 bits
+ //
+ if (!GetRandomNumber64 (Rand)) {
+ return FALSE;
+ }
+
+ //
+ // Read second 64 bits
+ //
+ return GetRandomNumber64 (++Rand);
+}
--
2.17.1.windows.2


[PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction

Wang, Jian J
 

BaseRngLib uses rdrand instruction to get random number from DRNG in the
processor, which is not a good candidate for seeding openssl rand
interface.

rdseed in x86 cpu provides non-deterministic random number (NRBG) which
meets NIST SP 800-90B and NIST SP800-90C standards and can be used as
seed for other software DRNG. This patch adds a C interface AsmRdSeed()
to wrap it in BaseLib so that we can add a new RngLib for users to choose
in their platform, if their processor support rdseed instruction.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
MdePkg/Include/Library/BaseLib.h | 51 +++++++++++++
MdePkg/Library/BaseLib/BaseLib.inf | 4 ++
MdePkg/Library/BaseLib/BaseLibInternals.h | 46 ++++++++++++
MdePkg/Library/BaseLib/Ia32/RdSeed.nasm | 87 +++++++++++++++++++++++
MdePkg/Library/BaseLib/X64/RdSeed.nasm | 80 +++++++++++++++++++++
MdePkg/Library/BaseLib/X86RdSeed.c | 73 +++++++++++++++++++
6 files changed, 341 insertions(+)
create mode 100644 MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
create mode 100644 MdePkg/Library/BaseLib/X64/RdSeed.nasm
create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c

diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 2a75bc023f..e2f9bf121e 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7856,6 +7856,57 @@ AsmRdRand64 (
OUT UINT64 *Rand
);

+/**
+ Generates a 16-bit random seed through RDSEED instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdSeed16 (
+ OUT UINT16 *Seed
+ );
+
+/**
+ Generates a 32-bit random seed through RDSEED instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed32 (
+ OUT UINT32 *Seed
+ );
+
+/**
+ Generates a 64-bit random seed through RDSEED instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed64 (
+ OUT UINT64 *Seed
+ );
+
/**
Load given selector into TR register.

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 3586beb0ab..5e12093ba3 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -181,6 +181,7 @@
Ia32/EnableCache.nasm| GCC
Ia32/DisableCache.nasm| GCC
Ia32/RdRand.nasm
+ Ia32/RdSeed.nasm

Ia32/DivS64x64Remainder.c
Ia32/InternalSwitchStack.c | MSFT
@@ -202,6 +203,7 @@
X86DisablePaging64.c
X86DisablePaging32.c
X86RdRand.c
+ X86RdSeed.c
X86PatchInstruction.c
X86SpeculationBarrier.c

@@ -306,12 +308,14 @@
X86DisablePaging64.c
X86DisablePaging32.c
X86RdRand.c
+ X86RdSeed.c
X86PatchInstruction.c
X86SpeculationBarrier.c
X64/GccInline.c | GCC
X64/EnableDisableInterrupts.nasm
X64/DisablePaging64.nasm
X64/RdRand.nasm
+ X64/RdSeed.nasm
ChkStkGcc.c | GCC

[Sources.EBC]
diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h b/MdePkg/Library/BaseLib/BaseLibInternals.h
index 6837d67d90..7b18b192c9 100644
--- a/MdePkg/Library/BaseLib/BaseLibInternals.h
+++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
@@ -862,6 +862,52 @@ InternalX86RdRand64 (
OUT UINT64 *Rand
);

+/**
+ Generates a 16-bit random seed through RDSEED instruction.
+
+ @param[out] Seed Buffer pointer to store the seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed16 (
+ OUT UINT16 *Seed
+ );
+
+/**
+ Generates a 32-bit random seed through RDSEED instruction.
+
+ @param[out] Seed Buffer pointer to store the seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed32 (
+ OUT UINT32 *Seed
+ );
+
+/**
+ Generates a 64-bit random seed through RDSEED instruction.
+
+
+ @param[out] Seed Buffer pointer to store the seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed64 (
+ OUT UINT64 *Seed
+ );
+
#else

#endif
diff --git a/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
new file mode 100644
index 0000000000..0a4de30db6
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
@@ -0,0 +1,87 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; RdSeed.nasm
+;
+; Abstract:
+;
+; Generates random seed through CPU RdSeed instruction under 32-bit platform.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+;------------------------------------------------------------------------------
+; Generates a 16 bit random seed through RDSEED instruction.
+; Return TRUE if Seed generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed16)
+ASM_PFX(InternalX86RdSeed16):
+ ; rdseed ax ; generate a 16 bit RN into ax
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r16: "0f c7 /7 ModRM:r/m(w)"
+ jc rn16_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ pause
+ ret ; return with failure status
+rn16_ok:
+ mov edx, dword [esp + 4]
+ mov [edx], ax
+ mov eax, 1
+ ret
+
+;------------------------------------------------------------------------------
+; Generates a 32 bit random seed through RDSEED instruction.
+; Return TRUE if Seed generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed32)
+ASM_PFX(InternalX86RdSeed32):
+ ; rdseed eax ; generate a 32 bit RN into eax
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r32: "0f c7 /7 ModRM:r/m(w)"
+ jc rn32_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ pause
+ ret ; return with failure status
+rn32_ok:
+ mov edx, dword [esp + 4]
+ mov [edx], eax
+ mov eax, 1
+ ret
+
+;------------------------------------------------------------------------------
+; Generates a 64 bit random seed through RDSEED instruction.
+; Return TRUE if Seed generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed64)
+ASM_PFX(InternalX86RdSeed64):
+ ; rdseed eax ; generate a 32 bit RN into eax
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r32: "0f c7 /7 ModRM:r/m(w)"
+ jnc rn64_ret ; jmp if CF=0
+ mov edx, dword [esp + 4]
+ mov [edx], eax
+
+ db 0xf, 0xc7, 0xf0 ; generate another 32 bit RN
+ jnc rn64_ret ; jmp if CF=0
+ mov [edx + 4], eax
+
+ mov eax, 1
+ ret
+rn64_ret:
+ xor eax, eax
+ pause
+ ret ; return with failure status
+
diff --git a/MdePkg/Library/BaseLib/X64/RdSeed.nasm b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
new file mode 100644
index 0000000000..a60acfeace
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
@@ -0,0 +1,80 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; RdSeed.nasm
+;
+; Abstract:
+;
+; Generates random seed through CPU RdSeed instruction under 64-bit platform.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; Generates a 16 bit random seed through RDSEED instruction.
+; Return TRUE if Seed generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed16)
+ASM_PFX(InternalX86RdSeed16):
+ ; rdseed ax ; generate a 16 bit RN into eax,
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r16: "0f c7 /7 ModRM:r/m(w)"
+ jc rn16_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ pause
+ ret ; return with failure status
+rn16_ok:
+ mov [rcx], ax
+ mov rax, 1
+ ret
+
+;------------------------------------------------------------------------------
+; Generates a 32 bit random seed through RDSEED instruction.
+; Return TRUE if Seed generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed32)
+ASM_PFX(InternalX86RdSeed32):
+ ; rdseed eax ; generate a 32 bit RN into eax,
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0xf, 0xc7, 0xf8 ; rdseed r32: "0f c7 /7 ModRM:r/m(w)"
+ jc rn32_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ pause
+ ret ; return with failure status
+rn32_ok:
+ mov [rcx], eax
+ mov rax, 1
+ ret
+
+;------------------------------------------------------------------------------
+; Generates a 64 bit random seed through one RDSEED instruction.
+; Return TRUE if Seed generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed64)
+ASM_PFX(InternalX86RdSeed64):
+ ; rdseed rax ; generate a 64 bit RN into rax,
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0x48, 0xf, 0xc7, 0xf8 ; rdseed r64: "REX.W + 0f c7 /7 ModRM:r/m(w)"
+ jc rn64_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ pause
+ ret ; return with failure status
+rn64_ok:
+ mov [rcx], rax
+ mov rax, 1
+ ret
+
diff --git a/MdePkg/Library/BaseLib/X86RdSeed.c b/MdePkg/Library/BaseLib/X86RdSeed.c
new file mode 100644
index 0000000000..9fa7948ff1
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X86RdSeed.c
@@ -0,0 +1,73 @@
+/** @file
+ IA-32/x64 AsmRdSeedxx()
+ Generates random seed through CPU RdSeed instruction.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BaseLibInternals.h"
+
+/**
+ Generates a 16-bit random seed through RDSEED instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdSeed16 (
+ OUT UINT16 *Seed
+ )
+{
+ ASSERT (Seed != NULL);
+ return InternalX86RdSeed16 (Seed);
+}
+
+/**
+ Generates a 32-bit random seed through RDSEED instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed32 (
+ OUT UINT32 *Seed
+ )
+{
+ ASSERT (Seed != NULL);
+ return InternalX86RdSeed32 (Seed);
+}
+
+/**
+ Generates a 64-bit random seed through RDSEED instruction.
+
+ if Seed is NULL, then ASSERT().
+
+ @param[out] Seed Buffer pointer to store the seed data.
+
+ @retval TRUE RDSEED call was successful.
+ @retval FALSE Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed64 (
+ OUT UINT64 *Seed
+ )
+{
+ ASSERT (Seed != NULL);
+ return InternalX86RdSeed64 (Seed);
+}
--
2.17.1.windows.2


[PATCH 03/11] FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib instances in dsc files

Wang, Jian J
 

Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib.
RngLibNull is used by default. TimerLib will be removed once its
dependency is removed.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Liming Gao <liming.gao@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Jian J Wang <jian.j.wang@...>
---
FmpDevicePkg/FmpDevicePkg.dsc | 1 +
1 file changed, 1 insertion(+)

diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index f4093d3837..201ea00f63 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -53,6 +53,7 @@
!else
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+ RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
!endif
FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
--
2.17.1.windows.2