/** @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>

#define DEFAULT_DELAY_TIME_IN_MICROSECONDS  10

/**
 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 DEFAULT_DELAY_TIME_IN_MICROSECONDS;
  }

  // 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 < sizeof (UINT16); 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 < sizeof (UINT32); 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 < sizeof (UINT64); 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);
}
