From 255c8e22a5171fc52d0e7c297b2267e83d48bd5c Mon Sep 17 00:00:00 2001 From: Qin Long Date: Mon, 21 Sep 2015 05:54:03 +0000 Subject: [PATCH] MdePkg: Add RngLib into MdePkg 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. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Qin Long Reviewed-by: Michael Kinney Reviewed-by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18519 6f19259b-4bc3-4df7-8a09-765794883524 --- MdePkg/Include/Library/RngLib.h | 69 ++++++++++ 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 + 6 files changed, 272 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 0000000000..157a93139c --- /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.
+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/BaseRngLib/BaseRng.c b/MdePkg/Library/BaseRngLib/BaseRng.c new file mode 100644 index 0000000000..279df3013c --- /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.
+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 +#include + +// +// 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 0000000000..05a5b77dc3 --- /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.
+# +# 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+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#tbiepq0P kajio8cSzOe9vC$P-HO}$(Eb_e|M1t3++X0||Mr2mAF7cjiU0rr literal 0 HcmV?d00001 diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 60549afaaa..337059a6a6 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 00c46d44fe..4ea367ccc0 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.39.2