Matthew:

> -----邮件原件-----
> 发件人: [email protected]
> <[email protected]> 代表 Matthew
> Carlson
> 发送时间: 2020年8月27日 4:55
> 收件人: [email protected]
> 抄送: Ard Biesheuvel <[email protected]>; Michael D Kinney
> <[email protected]>; Liming Gao <[email protected]>;
> Zhiguang Liu <[email protected]>; Matthew Carlson
> <[email protected]>
> 主题: [edk2-devel] [PATCH v9 1/5] MdePkg: TimerRngLib: Added RngLib that
> uses TimerLib
> 
> From: Matthew Carlson <[email protected]>
> 
> Added a new RngLib that provides random numbers from the TimerLib
> using the performance counter. This is meant to be used for OpenSSL
> to replicate past behavior. This should not be used in production as
> a real source of entropy.
> 
> Ref: https://github.com/tianocore/edk2/pull/845
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> 
> Cc: Ard Biesheuvel <[email protected]>
> Cc: Michael D Kinney <[email protected]>
> Cc: Liming Gao <[email protected]>
> Cc: Zhiguang Liu <[email protected]>
> Signed-off-by: Matthew Carlson <[email protected]>
> ---
>  MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c          | 187
> ++++++++++++++++++++
>  MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf |  36 ++++
>  MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni |  15 ++
>  MdePkg/MdePkg.dsc                                        |
> 3 +-
>  4 files changed, 240 insertions(+), 1 deletion(-)
> 
> diff --git a/MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c
> b/MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c
> new file mode 100644
> index 000000000000..aecaa427bb3f
> --- /dev/null
> +++ b/MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c
> @@ -0,0 +1,187 @@
> +/** @file
> 
> +  BaseRng Library that uses the TimerLib to provide reasonably random
> numbers.
> 
> +  Do not use this on a production system.
> 
> +
> 
> +  Copyright (c) Microsoft Corporation.
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +**/
> 
> +
> 
> +#include <Base.h>
> 
> +#include <Library/BaseLib.h>
> 
> +#include <Library/DebugLib.h>
> 
> +#include <Library/TimerLib.h>
> 
> +
> 
> +/**
> 
> + Using the TimerLib GetPerformanceCounterProperties() we delay
> 
> + for enough time for the PerformanceCounter to increment.
> 
> +
> 
> + If the return value from GetPerformanceCounterProperties (TimerLib)
> 
> + is zero, this function will return 10 and attempt to assert.
> 
> + **/
> 
> +STATIC
> 
> +UINT32
> 
> +CalculateMinimumDecentDelayInMicroseconds (
> 
> +  VOID
> 
> +  )
> 
> +{
> 
> +  UINT64 CounterHz;
> 
> +
> 
> +  // Get the counter properties
> 
> +  CounterHz = GetPerformanceCounterProperties (NULL, NULL);
> 
> +  // Make sure we won't divide by zero
> 
> +  if (CounterHz == 0) {
> 
> +    ASSERT(CounterHz != 0); // Assert so the developer knows something is
> wrong
> 
> +    return 10; // return 10 microseconds by default
> 

How about define one macro for the default value?


> +  }
> 
> +  // Calculate the minimum delay based on 1.5 microseconds divided by the
> hertz.
> 
> +  // We calculate the length of a cycle (1/CounterHz) and multiply it by
1.5
> microseconds
> 
> +  // This ensures that the performance counter has increased by at least
> one
> 
> +  return (UINT32)(MAX (DivU64x64Remainder (1500000,CounterHz, NULL),
> 1));
> 
> +}
> 
> +
> 
> +
> 
> +/**
> 
> +  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;
> 
> +  UINT8  *RandPtr;
> 
> +  UINT32  DelayInMicroSeconds;
> 
> +
> 
> +  ASSERT (Rand != NULL);
> 
> +
> 
> +  if (Rand == NULL) {
> 
> +    return FALSE;
> 
> +  }
> 
> +  DelayInMicroSeconds = CalculateMinimumDecentDelayInMicroseconds ();
> 
> +  RandPtr = (UINT8*)Rand;
> 
> +  // Get 2 bytes of random ish data
> 
> +  for (Index = 0; Index < 2; Index ++) {
> 
> +    *RandPtr = (UINT8)(GetPerformanceCounter () & 0xFF);
> 
> +    // Delay to give the performance counter a chance to change
> 
> +    MicroSecondDelay (DelayInMicroSeconds);
> 
> +    RandPtr++;
> 
> +  }
> 
> +  return TRUE;
> 
> +}
> 
> +
> 
> +/**
> 
> +  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;
> 
> +  UINT8  *RandPtr;
> 
> +  UINT32  DelayInMicroSeconds;
> 
> +
> 
> +  ASSERT (Rand != NULL);
> 
> +
> 
> +  if (NULL == Rand) {
> 
> +    return FALSE;
> 
> +  }
> 
> +
> 
> +  RandPtr = (UINT8 *) Rand;
> 
> +  DelayInMicroSeconds = CalculateMinimumDecentDelayInMicroseconds ();
> 
> +  // Get 4 bytes of random ish data
> 
> +  for (Index = 0; Index < 4; Index ++) {
> 
> +    *RandPtr = (UINT8)(GetPerformanceCounter () & 0xFF);
> 
> +    // Delay to give the performance counter a chance to change
> 
> +    MicroSecondDelay (DelayInMicroSeconds);
> 
> +    RandPtr++;
> 
> +  }
> 
> +  return TRUE;
> 
> +}
> 
> +
> 
> +/**
> 
> +  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;
> 
> +  UINT8  *RandPtr;
> 
> +  UINT32  DelayInMicroSeconds;
> 
> +
> 
> +  ASSERT (Rand != NULL);
> 
> +
> 
> +  if (NULL == Rand) {
> 
> +    return FALSE;
> 
> +  }
> 
> +
> 
> +  RandPtr = (UINT8 *)Rand;
> 
> +  DelayInMicroSeconds = CalculateMinimumDecentDelayInMicroseconds ();
> 
> +  // Get 8 bytes of random ish data
> 
> +  for (Index = 0; Index < 8; Index ++) {
> 
> +    *RandPtr = (UINT8)(GetPerformanceCounter () & 0xFF);
> 
> +    // Delay to give the performance counter a chance to change
> 
> +    MicroSecondDelay (DelayInMicroSeconds);
> 
> +    RandPtr++;
> 
> +  }
> 
> +
> 
> +  return TRUE;
> 
> +}
> 
> +
> 
> +/**
> 
> +  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);
> 
> +  // This should take around 80ms
> 
> +
> 
> +  // Read first 64 bits
> 
> +  if (!GetRandomNumber64 (Rand)) {
> 
> +    return FALSE;
> 
> +  }
> 
> +
> 
> +  // Read second 64 bits
> 
> +  return GetRandomNumber64 (++Rand);
> 
> +}
> 
> diff --git a/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
> b/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
> new file mode 100644
> index 000000000000..c499e5327351
> --- /dev/null
> +++ b/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> 
> +#  Instance of RNG (Random Number Generator) Library.
> 
> +#
> 
> +#  BaseRng Library that uses the TimerLib to provide reasonably random
> numbers.
> 
> +#  Do NOT use this on a production system as this uses the system
> performance
> 
> +#  counter rather than a true source of random in addition to having a
weak
> 
> +#  random algorithm. This is provided primarily as a source of entropy
for
> 
> +#  OpenSSL for platforms that do not have a good built in RngLib as this
> 
> +#  emulates what was done before (though it isn't perfect).
> 
> +#
> 
> +#  Copyright (c) Microsoft Corporation. All rights reserved.<BR>
> 
> +#
> 
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +#
> 
> +#
> 
> +##
> 
> +
> 
> +[Defines]
> 
> +  INF_VERSION                    = 1.27
> 
> +  BASE_NAME                      = BaseRngLibTimerLib
> 
> +  MODULE_UNI_FILE                = BaseRngLibTimerLib.uni
> 
> +  FILE_GUID                      =
> 74950C45-10FC-4AB5-B114-49C87C17409B
> 
> +  MODULE_TYPE                    = BASE
> 
> +  VERSION_STRING                 = 1.0
> 
> +  LIBRARY_CLASS                  = RngLib
> 
> +  CONSTRUCTOR                    = BaseRngLibConstructor
> 
Please remove CONSTRUCTOR, this library instance has no constructor. 

> +
> 
> +[Sources]
> 
> +  RngLibTimer.c
> 
> +
> 
> +[Packages]
> 
> +  MdePkg/MdePkg.dec
> 
> +
> 
> +[LibraryClasses]
> 
> +  BaseLib
> 
> +  TimerLib
> 

Please add DebugLib here, this library instance also depends on DebugLib.

Thanks
Liming

> diff --git a/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni
> b/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni
> new file mode 100644
> index 000000000000..fde24b9f0107
> --- /dev/null
> +++ b/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni
> @@ -0,0 +1,15 @@
> +// @file
> 
> +// Instance of RNG (Random Number Generator) Library.
> 
> +//
> 
> +// RngLib that uses TimerLib's performance counter to provide random
> numbers.
> 
> +//
> 
> +// Copyright (c) Microsoft Corporation.
> 
> +//
> 
> +// 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 "BaseRng Library
> that uses the TimerLib to provide low-entropy random numbers"
> 
> +
> 
> diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
> index 472fa3777412..d7ba3a730909 100644
> --- a/MdePkg/MdePkg.dsc
> +++ b/MdePkg/MdePkg.dsc
> @@ -62,6 +62,8 @@
>    MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.inf
> 
>    MdePkg/Library/BasePrintLib/BasePrintLib.inf
> 
> 
> MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull
> .inf
> 
> +  MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
> 
> +  MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
> 
>    MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
> 
>    MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> 
> 
> MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
> 
> @@ -69,7 +71,6 @@
> 
> MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressL
> ib.inf
> 
>    MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
> 
>    MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
> 
> -  MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
> 
> 
> 
>    MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> 
>    MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> 
> --
> 2.28.0.windows.1
> 
> 
> -=-=-=-=-=-=
> Groups.io Links: You receive all messages sent to this group.
> 
> View/Reply Online (#64653): https://edk2.groups.io/g/devel/message/64653
> Mute This Topic: https://groups.io/mt/76437900/4905953
> Group Owner: [email protected]
> Unsubscribe: https://edk2.groups.io/g/devel/unsub
> [[email protected]]
> -=-=-=-=-=-=




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#64667): https://edk2.groups.io/g/devel/message/64667
Mute This Topic: https://groups.io/mt/76442516/21656
Group Owner: [email protected]
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to