| // 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_ |