mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-12-10 07:14:36 +01:00
* Update config-extraction scripts to work with multiple chips * Standardise wording between common options * Various config-related fixes * Update pico_rand to use correct busctrl_hw struct-name * Don't start config descriptions with "The ..."
217 lines
9.6 KiB
C
217 lines
9.6 KiB
C
/*
|
|
* Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#ifndef _PICO_RAND_H
|
|
#define _PICO_RAND_H
|
|
|
|
#include "pico.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** \file pico/rand.h
|
|
* \defgroup pico_rand pico_rand
|
|
*
|
|
* \brief Random Number Generator API
|
|
*
|
|
* This module generates random numbers at runtime utilizing a number of possible entropy
|
|
* sources and uses those sources to modify the state of a 128-bit 'Pseudo
|
|
* Random Number Generator' implemented in software.
|
|
*
|
|
* The random numbers (32 to 128 bit) to be supplied are read from the PRNG which is used
|
|
* to help provide a large number space.
|
|
*
|
|
* The following (multiple) sources of entropy are available (of varying quality), each enabled by a #define:
|
|
*
|
|
* - The Ring Oscillator (ROSC) (\ref PICO_RAND_ENTROPY_SRC_ROSC == 1):
|
|
* \ref PICO_RAND_ROSC_BIT_SAMPLE_COUNT bits are gathered from the ring oscillator "random bit" and mixed in each
|
|
* time. This should not be used if the ROSC is off, or the processor is running from
|
|
* the ROSC.
|
|
* \note the maximum throughput of ROSC bit sampling is controlled by PICO_RAND_MIN_ROSC_BIT_SAMPLE_TIME_US which defaults
|
|
* to 10us, i.e. 100,000 bits per second.
|
|
* - Time (\ref PICO_RAND_ENTROPY_SRC_TIME == 1): The 64-bit microsecond timer is mixed in each time.
|
|
* - Bus Performance Counter (\ref PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER == 1): One of the bus fabric's performance
|
|
* counters is mixed in each time.
|
|
*
|
|
* \note All entropy sources are hashed before application to the PRNG state machine.
|
|
*
|
|
* The \em first time a random number is requested, the 128-bit PRNG state
|
|
* must be seeded. Multiple entropy sources are also available for the seeding operation:
|
|
*
|
|
* - The Ring Oscillator (ROSC) (\ref PICO_RAND_SEED_ENTROPY_SRC_ROSC == 1):
|
|
* 64 bits are gathered from the ring oscillator "random bit" and mixed into the seed.
|
|
* - Time (\ref PICO_RAND_SEED_ENTROPY_SRC_TIME == 1): The 64-bit microsecond timer is mixed into the seed.
|
|
* - Board Identifier (PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID == 1): The board id via \ref pico_get_unique_board_id
|
|
* is mixed into the seed.
|
|
* - RAM hash (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH): The hashed contents of a
|
|
* subset of RAM are mixed in. Initial RAM contents are undefined on power up, so provide a reasonable source of entropy.
|
|
* By default the last 1K of RAM (which usually contains the core 0 stack) is hashed, which may also provide for differences
|
|
* after each warm reset.
|
|
*
|
|
* With default settings, the seed generation takes approximately 1 millisecond while
|
|
* subsequent random numbers generally take between 10 and 20 microseconds to generate.
|
|
*
|
|
* pico_rand methods may be safely called from either core or from an IRQ, but be careful in the latter case as
|
|
* the calls may block for a number of microseconds waiting on more entropy.
|
|
*/
|
|
|
|
// ---------------
|
|
// ENTROPY SOURCES
|
|
// ---------------
|
|
|
|
// PICO_CONFIG: PICO_RAND_ENTROPY_SRC_ROSC, Enable/disable use of ROSC as an entropy source, type=bool, default=1 if no hardware TRNG, group=pico_rand
|
|
#ifndef PICO_RAND_ENTROPY_SRC_ROSC
|
|
#if !HAS_RP2350_TRNG
|
|
#define PICO_RAND_ENTROPY_SRC_ROSC 1
|
|
#endif
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_ENTROPY_SRC_TRNG, Enable/disable use of hardware TRNG as an entropy source, type=bool, default=1 if hardware TRNG, group=pico_rand
|
|
#ifndef PICO_RAND_ENTROPY_SRC_TRNG
|
|
#if HAS_RP2350_TRNG
|
|
#define PICO_RAND_ENTROPY_SRC_TRNG 1
|
|
#endif
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_ENTROPY_SRC_TIME, Enable/disable use of hardware timestamp as an entropy source, type=bool, default=1, group=pico_rand
|
|
#ifndef PICO_RAND_ENTROPY_SRC_TIME
|
|
#define PICO_RAND_ENTROPY_SRC_TIME 1
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER, Enable/disable use of a bus performance counter as an entropy source, type=bool, default=1 if no hardware TRNG, group=pico_rand
|
|
#ifndef PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER
|
|
#if !HAS_RP2350_TRNG
|
|
#define PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER 1
|
|
#endif
|
|
#endif
|
|
|
|
// --------------------
|
|
// SEED ENTROPY SOURCES
|
|
// --------------------
|
|
|
|
// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_ROSC, Enable/disable use of ROSC as an entropy source for the random seed, type=bool, default=PICO_RAND_ENTROPY_SRC_ROSC, group=pico_rand
|
|
#ifndef PICO_RAND_SEED_ENTROPY_SRC_ROSC
|
|
#define PICO_RAND_SEED_ENTROPY_SRC_ROSC PICO_RAND_ENTROPY_SRC_ROSC
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_TRNG, Enable/disable use of hardware TRNG as an entropy source for the random seed, type=bool, default=PICO_RAND_ENTROPY_SRC_TRNG, group=pico_rand
|
|
#if !defined(PICO_RAND_SEED_ENTROPY_SRC_TRNG) && HAS_RP2350_TRNG
|
|
#define PICO_RAND_SEED_ENTROPY_SRC_TRNG PICO_RAND_ENTROPY_SRC_TRNG
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_TIME, Enable/disable use of hardware timestamp as an entropy source for the random seed, type=bool, default=PICO_RAND_ENTROPY_SRC_TIME, group=pico_rand
|
|
#ifndef PICO_RAND_SEED_ENTROPY_SRC_TIME
|
|
#define PICO_RAND_SEED_ENTROPY_SRC_TIME PICO_RAND_ENTROPY_SRC_TIME
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_BUS_PERF_COUNTER, Enable/disable use of a bus performance counter as an entropy source for the random seed, type=bool, default=PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER, group=pico_rand
|
|
#ifndef PICO_RAND_SEED_ENTROPY_SRC_BUS_PERF_COUNTER
|
|
#define PICO_RAND_SEED_ENTROPY_SRC_BUS_PERF_COUNTER PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_BOOT_RANDOM, Enable/disable use of the per boot random number as an entropy source for the random seed, type=bool, default=0 on RP2040 which has none, group=pico_rand
|
|
#ifndef PICO_RAND_SEED_ENTROPY_SRC_BOOT_RANDOM
|
|
#if !PICO_RP2040
|
|
#define PICO_RAND_SEED_ENTROPY_SRC_BOOT_RANDOM 1
|
|
#endif
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID, Enable/disable use of board id as part of the random seed, type=bool, default=not PICO_RAND_SEED_ENTROPY_SRC_BOOT_RANDOM, group=pico_rand
|
|
#ifndef PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID
|
|
#define PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID (!PICO_RAND_SEED_ENTROPY_SRC_BOOT_RANDOM)
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH, Enable/disable use of a RAM hash as an entropy source for the random seed, type=bool, default=1 if no hardware TRNG, group=pico_rand
|
|
#ifndef PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH
|
|
#if !HAS_RP2350_TRNG
|
|
#define PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH 1
|
|
#endif
|
|
#endif
|
|
|
|
// ---------------------------------
|
|
// PICO_RAND_ENTROPY_SRC_ROSC CONFIG
|
|
// ---------------------------------
|
|
|
|
// PICO_CONFIG: PICO_RAND_ROSC_BIT_SAMPLE_COUNT, Number of samples to take of the ROSC random bit per random number generation , min=1, max=64, default=1, group=pico_rand
|
|
#ifndef PICO_RAND_ROSC_BIT_SAMPLE_COUNT
|
|
#define PICO_RAND_ROSC_BIT_SAMPLE_COUNT 1
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_MIN_ROSC_BIT_SAMPLE_TIME_US, Define a default minimum time between sampling the ROSC random bit, min=5, max=20, default=10, group=pico_rand
|
|
#ifndef PICO_RAND_MIN_ROSC_BIT_SAMPLE_TIME_US
|
|
// (Arbitrary / tested) minimum time between sampling the ROSC random bit
|
|
#define PICO_RAND_MIN_ROSC_BIT_SAMPLE_TIME_US 10u
|
|
#endif
|
|
|
|
// ---------------------------------------------
|
|
// PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER CONFIG
|
|
// ---------------------------------------------
|
|
|
|
// PICO_CONFIG: PICO_RAND_BUS_PERF_COUNTER_INDEX, Bus performance counter index to use for sourcing entropy, min=0, max=3, default=Undefined meaning pick one that is not counting any valid event already, group=pico_rand
|
|
// this is deliberately undefined by default, meaning the code will pick that appears unused
|
|
#if 0 // make tooling checks happy
|
|
#define PICO_RAND_BUS_PERF_COUNTER_INDEX 0
|
|
#endif
|
|
|
|
// PICO_CONFIG: PICO_RAND_BUS_PERF_COUNTER_EVENT, Bus performance counter event to use for sourcing entropy, default=arbiter_sram5_perf_event_access, group=pico_rand
|
|
#ifndef PICO_RAND_BUS_PERF_COUNTER_EVENT
|
|
#define PICO_RAND_BUS_PERF_COUNTER_EVENT arbiter_sram5_perf_event_access
|
|
#endif
|
|
|
|
// ------------------------------------------
|
|
// PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH CONFIG
|
|
// ------------------------------------------
|
|
|
|
// PICO_CONFIG: PICO_RAND_RAM_HASH_END, End of address in RAM (non-inclusive) to hash during pico_rand seed initialization, default=SRAM_END, group=pico_rand
|
|
#ifndef PICO_RAND_RAM_HASH_END
|
|
#define PICO_RAND_RAM_HASH_END SRAM_END
|
|
#endif
|
|
// PICO_CONFIG: PICO_RAND_RAM_HASH_START, Start of address in RAM (inclusive) to hash during pico_rand seed initialization, default=PICO_RAND_RAM_HASH_END - 1024, group=pico_rand
|
|
#ifndef PICO_RAND_RAM_HASH_START
|
|
#define PICO_RAND_RAM_HASH_START (PICO_RAND_RAM_HASH_END - 1024u)
|
|
#endif
|
|
|
|
// We provide a maximum of 128 bits entropy in one go
|
|
typedef struct rng_128 {
|
|
uint64_t r[2];
|
|
} rng_128_t;
|
|
|
|
/*! \brief Get 128-bit random number
|
|
* \ingroup pico_rand
|
|
*
|
|
* This method may be safely called from either core or from an IRQ, but be careful in the latter case as
|
|
* the call may block for a number of microseconds waiting on more entropy.
|
|
*
|
|
* \param rand128 Pointer to storage to accept a 128-bit random number
|
|
*/
|
|
void get_rand_128(rng_128_t *rand128);
|
|
|
|
/*! \brief Get 64-bit random number
|
|
* \ingroup pico_rand
|
|
*
|
|
* This method may be safely called from either core or from an IRQ, but be careful in the latter case as
|
|
* the call may block for a number of microseconds waiting on more entropy.
|
|
*
|
|
* \return 64-bit random number
|
|
*/
|
|
uint64_t get_rand_64(void);
|
|
|
|
/*! \brief Get 32-bit random number
|
|
* \ingroup pico_rand
|
|
*
|
|
* This method may be safely called from either core or from an IRQ, but be careful in the latter case as
|
|
* the call may block for a number of microseconds waiting on more entropy.
|
|
*
|
|
* \return 32-bit random number
|
|
*/
|
|
uint32_t get_rand_32(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|