Add one library class (RngLib.h) with three GetRandomNumber16/32/64
APIs to provide random number generator services, and one library
instance (BaseRngLib), based on Intel RdRand instruction access,
to provide high-quality random numbers generator.

Signed-off-by: Qin Long <[email protected]>
Reviewed-by: Michael Kinney <[email protected]>
---
 MdePkg/Include/Library/RngLib.h          |  69 ++++++++++++++
 MdePkg/Library/BaseLib/BaseLib.inf       |   6 ++
 MdePkg/Library/BaseRngLib/BaseRng.c      | 157 +++++++++++++++++++++++++++++++
 MdePkg/Library/BaseRngLib/BaseRngLib.inf |  41 ++++++++
 MdePkg/Library/BaseRngLib/BaseRngLib.uni | Bin 0 -> 1878 bytes
 MdePkg/MdePkg.dec                        |   4 +
 MdePkg/MdePkg.dsc                        |   1 +
 7 files changed, 278 insertions(+)
 create mode 100644 MdePkg/Include/Library/RngLib.h
 create mode 100644 MdePkg/Library/BaseRngLib/BaseRng.c
 create mode 100644 MdePkg/Library/BaseRngLib/BaseRngLib.inf
 create mode 100644 MdePkg/Library/BaseRngLib/BaseRngLib.uni

diff --git a/MdePkg/Include/Library/RngLib.h b/MdePkg/Include/Library/RngLib.h
new file mode 100644
index 0000000..157a931
--- /dev/null
+++ b/MdePkg/Include/Library/RngLib.h
@@ -0,0 +1,69 @@
+/** @file
+  Provides random number generator services.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __RNG_LIB_H__
+#define __RNG_LIB_H__
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+#endif  // __RNG_LIB_H__
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf 
b/MdePkg/Library/BaseLib/BaseLib.inf
index 4a37e60..4cc86d7 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -159,6 +159,7 @@
   Ia32/EnablePaging64.asm | MSFT
   Ia32/EnableCache.c | MSFT
   Ia32/DisableCache.c | MSFT
+  Ia32/RdRand.asm | MSFT
 
   Ia32/Wbinvd.asm | INTEL 
   Ia32/WriteMm7.asm | INTEL 
@@ -252,6 +253,7 @@
   Ia32/EnablePaging64.asm | INTEL
   Ia32/EnableCache.asm | INTEL
   Ia32/DisableCache.asm | INTEL
+  Ia32/RdRand.asm | INTEL
 
   Ia32/GccInline.c | GCC
   Ia32/Thunk16.nasm | GCC 
@@ -279,6 +281,7 @@
   Ia32/LShiftU64.S | GCC 
   Ia32/EnableCache.S | GCC
   Ia32/DisableCache.S | GCC
+  Ia32/RdRand.S | GCC
 
   Ia32/DivS64x64Remainder.c
   Ia32/InternalSwitchStack.c | MSFT
@@ -383,10 +386,12 @@
   X64/CpuBreakpoint.c | MSFT 
   X64/WriteMsr64.c | MSFT 
   X64/ReadMsr64.c | MSFT 
+  X64/RdRand.asm | MSFT
 
   X64/CpuBreakpoint.asm | INTEL 
   X64/WriteMsr64.asm | INTEL 
   X64/ReadMsr64.asm | INTEL 
+  X64/RdRand.asm | INTEL
 
   X64/Non-existing.c
   Math64.c
@@ -417,6 +422,7 @@
   X64/CpuIdEx.S | GCC 
   X64/EnableCache.S | GCC
   X64/DisableCache.S | GCC
+  X64/RdRand.S | GCC
   ChkStkGcc.c  | GCC 
 
 [Sources.IPF]
diff --git a/MdePkg/Library/BaseRngLib/BaseRng.c 
b/MdePkg/Library/BaseRngLib/BaseRng.c
new file mode 100644
index 0000000..279df30
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/BaseRng.c
@@ -0,0 +1,157 @@
+/** @file
+  Random number generator services that uses RdRand instruction access
+  to provide high-quality random numbers.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+//
+// Bit mask used to determine if RdRand instruction is supported.
+//
+#define RDRAND_MASK                  BIT30
+
+//
+// Limited retry number when valid random data is returned.
+// Uses the recommended value defined in Section 7.3.17 of "Intel 64 and IA-32
+// Architectures Software Developer's Mannual".
+//
+#define RDRAND_RETRY_LIMIT           10
+
+/**
+  The constructor function checks whether or not RDRAND instruction is 
supported
+  by the host hardware.
+
+  The constructor function checks whether or not RDRAND instruction is 
supported.
+  It will ASSERT() if RDRAND instruction is not supported.
+  It will always return RETURN_SUCCESS.
+
+  @retval RETURN_SUCCESS   The constructor always returns EFI_SUCCESS.
+
+**/
+RETURN_STATUS
+EFIAPI
+BaseRngLibConstructor (
+  VOID
+  )
+{
+  UINT32  RegEcx;
+
+  //
+  // Determine RDRAND support by examining bit 30 of the ECX register returned 
by
+  // CPUID. A value of 1 indicates that processor support RDRAND instruction.
+  //
+  AsmCpuid (1, 0, 0, &RegEcx, 0);
+  ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
+
+  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 < RDRAND_RETRY_LIMIT; Index++) {
+    if (AsmRdRand16 (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 < RDRAND_RETRY_LIMIT; Index++) {
+    if (AsmRdRand32 (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 < RDRAND_RETRY_LIMIT; Index++) {
+    if (AsmRdRand64 (Rand)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.inf 
b/MdePkg/Library/BaseRngLib/BaseRngLib.inf
new file mode 100644
index 0000000..05a5b77
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/BaseRngLib.inf
@@ -0,0 +1,41 @@
+## @file
+#  Instance of RNG (Random Number Generator) Library.
+#
+#  BaseRng Library that uses CPU RdRand instruction access to provide
+#  high-quality random numbers.
+#
+#  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD 
License
+#  which accompanies this distribution. The full text of the license may be 
found at
+#  http://opensource.org/licenses/bsd-license.php.
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BaseRngLib
+  MODULE_UNI_FILE                = BaseRngLib.uni
+  FILE_GUID                      = 626440D8-1971-41D9-9AB2-FB25F4AE79BC
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RngLib
+  CONSTRUCTOR                    = BaseRngLibConstructor
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources.Ia32, Sources.X64]
+  BaseRng.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.uni 
b/MdePkg/Library/BaseRngLib/BaseRngLib.uni
new file mode 100644
index 
0000000000000000000000000000000000000000..3d6e905d79a40b0c90329a576bcdb193cee6cf06
GIT binary patch
literal 1878
zcmd6nU2hUW6o${WiT`0kZ>niQO}sJ2Sjt+7TF3&aUNs9?*n|S^QYwF5ecl;%2W<Vi
zGn?I+IiK%&&zb%Htziv|cpvjb_S&v2vzdLihxP!ebZwhkVJk~nM`$8jU=>+n=XS<=
z$WFR3@@vlLcEdWvGUs&0I(Pe&7z<>NkiI9&kbTO#v3iv)WNo4=@JsNX-0_HrHN|3u
z=Em6->`tv~1J(pAC8mf>9)FJI2#*XDbF5NMs;A&lyanGScow$CW{f7FnIf5x@z}l)
zC5533j}0EGA=EzKslB+ju2bSK@yxdoRly-R#L6>!Vo&Y49kCbdD=^I1%O}T6U)Ag@
zsG~VSFN+XOwdAfU@xNv_2FFWl!pN(tqEK0%sxrrbuYKZjsE@ub&$PPk`BIOUPPf6&
z_vYH6QofAcjA$XgIxKH7CbrcJVG8l(Ew&|D^J@N5rbAPx?uuPMOX|5~;w1-%YAsQY
zU`Lkfi|0pLKdGf((|XoIs_6?@0@ho{#fb0SYBO^BIVt&4F5L@NJp^Z&SA7wyLVAVV
zcSxAOV)HYmeO@A}O5I%P{>Xo^Wk85lJG@Rgt?0xHcS|)>o?F@HuDZILmkIj)90igg
z$j40czNSu;DQ~!ss^qQ3An7tc9d2{N%zfb8hRX;xwf2#=nXm!7*fBidFVJG2U{gj2
z?6;Zd7>k~Z++n9l*0;v0xQbe1ZMw5gM?1A&pjXt6%NW@OR*6G)j=W7&#pt-~2`6Ef
zOga15%0^ke)f;S;{S)guG(xT$7;m%qDq{Os#R<{daM5L+l(V(NTbL>RR~rtyWO@&(
zsqweR^LI(44lxEqi|rCb;!Dh)z*ZkTzj_YnqHe*2&Zm4eH=2cGVhL#tbie<D>pq0P
kajio8cSzOe9vC$P-HO}$(Eb_e|M1t3++X0||Mr2mAF7cjiU0rr

literal 0
HcmV?d00001

diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 60549af..337059a 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -249,6 +249,10 @@
   #
   SmmPeriodicSmiLib|Include/Library/SmmPeriodicSmiLib.h
 
+  ##  @libraryclass  Provides services to generate random number.
+  #
+  RngLib|Include/Library/RngLib.h
+
 [LibraryClasses.IPF]
   ##  @libraryclass  The SAL Library provides a service to make a SAL CALL.
   SalLib|Include/Library/SalLib.h
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index 00c46d4..4ea367c 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -152,6 +152,7 @@
   MdePkg/Library/BaseS3SmbusLib/BaseS3SmbusLib.inf
   MdePkg/Library/BaseS3StallLib/BaseS3StallLib.inf
   MdePkg/Library/SmmMemLib/SmmMemLib.inf
+  MdePkg/Library/BaseRngLib/BaseRngLib.inf
 
 [Components.IPF]
   MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
-- 
2.5.1.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to