| // Copyright lowRISC contributors. | 
 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
 | // SPDX-License-Identifier: Apache-2.0 | 
 |  | 
 | #ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_RAND_TESTUTILS_H_ | 
 | #define OPENTITAN_SW_DEVICE_LIB_TESTING_RAND_TESTUTILS_H_ | 
 |  | 
 | #include <stdint.h> | 
 |  | 
 | #include "sw/device/lib/testing/rv_core_ibex_testutils.h" | 
 |  | 
 | /** | 
 |  * A random number generator testutil type. | 
 |  * | 
 |  * Provides ability to control and maintain a random number generator. A random | 
 |  * number is produced via a mix of hardware-based (using on-device entropy | 
 |  * from rv_core_ibex random registers) and software-based (an LFSR-based PRNG) | 
 |  * approaches. The initial seed value for the PRNG is fetched from the | 
 |  * hardware. Following that, the PRNG kicks in and supplies random values | 
 |  * sought by the test. After a number of PRNG cycles, the LFSR can be freshly | 
 |  * reseeded from the hardware. If this frequency is set to 0, then the PRNG is | 
 |  * rendered disabled and random data is always fetched from the hardware. | 
 |  * | 
 |  * The software PRNG is faster because it consumes very few cycles compared to | 
 |  * the hardware - it helps improve the simulation time. | 
 |  */ | 
 | typedef struct rand_testutils_rng { | 
 |   /** | 
 |    * An rv_core_ibex DIF handle. | 
 |    */ | 
 |   dif_rv_core_ibex_t *rv_core_ibex; | 
 |   /** | 
 |    * The timeout in microseconds for fetching data from the hardware. | 
 |    */ | 
 |   uint32_t entropy_fetch_timeout_usec; | 
 |   /** | 
 |    * The PRNG LFSR. | 
 |    */ | 
 |   uint32_t lfsr; | 
 |   /** | 
 |    * The PRNG polynomial co-efficients. | 
 |    */ | 
 |   uint32_t polynomial_coefficients; | 
 |   /** | 
 |    * The PRNG LFSR reseed frequency. | 
 |    */ | 
 |   uint32_t reseed_frequency; | 
 |   /** | 
 |    * The LFSR operation counter. Resets on every reseed. | 
 |    */ | 
 |   uint32_t op_counter; | 
 | } rand_testutils_rng_t; | 
 |  | 
 | /** | 
 |  * A global random number generator testutil handle. | 
 |  */ | 
 | extern rand_testutils_rng_t rand_testutils_rng_ctx; | 
 |  | 
 | /** | 
 |  * Initializes and returns a random number generator testutil handle. | 
 |  * | 
 |  * @param rv_core_ibex An rv_core_ibex DIF handle. | 
 |  * @return The initialized timeout value. | 
 |  */ | 
 | rand_testutils_rng_t rand_testutils_init(dif_rv_core_ibex_t *rv_core_ibex); | 
 |  | 
 | /** | 
 |  * Reseeds the PRNG LFSR. | 
 |  * | 
 |  * The LFSR value is updated later, when the caller fetches the next random | 
 |  * data. | 
 |  * | 
 |  * Uses the global random number generator testutil handle | 
 |  * `rand_testutils_rng_ctx` which is initialized in ottf_main(). | 
 |  */ | 
 | inline void rand_testutils_reseed(void) { | 
 |   rand_testutils_rng_ctx.op_counter = UINT32_MAX; | 
 | } | 
 |  | 
 | /** | 
 |  * Returns a random unsigned integer. | 
 |  * | 
 |  * The random number is sourced either from the LFSR-based PRNG or from the | 
 |  * hardware, depending on the lobal random number generator testutil context | 
 |  * settings. | 
 |  * @return A pseudo-random 32-bit value. | 
 |  */ | 
 | uint32_t rand_testutils_gen32(void); | 
 |  | 
 | /** | 
 |  * Returns a random unsigned integer within a given range. | 
 |  * | 
 |  * This function invokes `rand_testutils_gen32()` and restricts the returned | 
 |  * value to be within the supplied range, inclusive of the range limits. Note | 
 |  * that a uniform distribution of values within the given range is not | 
 |  * guaranteed. | 
 |  * @param min The lower limit of the range. | 
 |  * @param max The upper limit of the range. | 
 |  * @return The computed random value within the supplied range. | 
 |  */ | 
 | uint32_t rand_testutils_gen32_range(uint32_t min, uint32_t max); | 
 |  | 
 | /** Shuffles an arbitrary array of elements. | 
 |  * | 
 |  * The shuffling occurs in-place. The reseeding of the LFSR is temporarily | 
 |  * turned off to allow faster runtime performance. | 
 |  * @param array Pointer to the array being shuffled. | 
 |  * @param size The size of each element in the array. | 
 |  * @param length The number of elements in the array. | 
 |  */ | 
 | void rand_testutils_shuffle(void *array, size_t size, size_t length); | 
 |  | 
 | #endif  // OPENTITAN_SW_DEVICE_LIB_TESTING_RAND_TESTUTILS_H_ |