mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
105 lines
2.4 KiB
C
105 lines
2.4 KiB
C
/**
|
|
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
|
* 2019 Freie Universität Berlin
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup sys_random
|
|
* @{
|
|
* @file
|
|
*
|
|
* @brief PRNG seeding
|
|
*
|
|
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
* @}
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <assert.h>
|
|
|
|
#include "log.h"
|
|
#include "random.h"
|
|
#include "bitarithm.h"
|
|
|
|
#ifdef MODULE_PUF_SRAM
|
|
#include "puf_sram.h"
|
|
#endif
|
|
#ifdef MODULE_PERIPH_HWRNG
|
|
#include "periph/hwrng.h"
|
|
#endif
|
|
#ifdef MODULE_PERIPH_CPUID
|
|
#include "luid.h"
|
|
#endif
|
|
|
|
#define ENABLE_DEBUG 0
|
|
#include "debug.h"
|
|
|
|
void auto_init_random(void)
|
|
{
|
|
uint32_t seed;
|
|
#ifdef MODULE_PUF_SRAM
|
|
/* TODO: hand state to application? */
|
|
if (puf_sram_state) {
|
|
LOG_WARNING("random: PUF SEED not fresh\n");
|
|
}
|
|
seed = puf_sram_seed;
|
|
#elif defined (MODULE_PERIPH_HWRNG)
|
|
hwrng_read(&seed, 4);
|
|
#elif defined (MODULE_PERIPH_CPUID)
|
|
luid_get(&seed, 4);
|
|
#else
|
|
LOG_WARNING("random: NO SEED AVAILABLE!\n");
|
|
seed = RANDOM_SEED_DEFAULT;
|
|
#endif
|
|
DEBUG("random: using seed value %u\n", (unsigned)seed);
|
|
random_init(seed);
|
|
}
|
|
|
|
void random_bytes(void *target, size_t n)
|
|
{
|
|
uint32_t random;
|
|
uint8_t *dst = target;
|
|
uint8_t *random_pos = (uint8_t*)&random;
|
|
unsigned _n = 0;
|
|
|
|
while (n--) {
|
|
if (! (_n++ & 0x3)) {
|
|
random = random_uint32();
|
|
random_pos = (uint8_t *) &random;
|
|
}
|
|
*dst++ = *random_pos++;
|
|
}
|
|
}
|
|
|
|
uint32_t random_uint32_range(uint32_t a, uint32_t b)
|
|
{
|
|
assert(a < b);
|
|
|
|
uint32_t divisor, rand_val, range = b - a;
|
|
uint8_t range_msb = bitarithm_msb(range);
|
|
|
|
/* check if range is a power of two */
|
|
if (!(range & (range - 1))) {
|
|
divisor = (1 << range_msb) - 1;
|
|
}
|
|
else if (range_msb < 31) {
|
|
/* leftshift for next power of two interval */
|
|
divisor = (1 << (range_msb + 1)) -1;
|
|
}
|
|
else {
|
|
/* disable modulo operation in loop below */
|
|
divisor = UINT32_MAX;
|
|
}
|
|
/* get random numbers until value is smaller than range */
|
|
do {
|
|
rand_val = (random_uint32() & divisor);
|
|
} while (rand_val >= range);
|
|
/* return random in range [a,b] */
|
|
return (rand_val + a);
|
|
}
|