diff --git a/sys/include/random.h b/sys/include/random.h index 85eb4bb13c..e61f3d69af 100644 --- a/sys/include/random.h +++ b/sys/include/random.h @@ -27,6 +27,7 @@ #define RANDOM_H #include +#include #ifdef __cplusplus extern "C" { @@ -67,6 +68,11 @@ void random_init_by_array(uint32_t init_key[], int key_length); */ uint32_t random_uint32(void); +/** + * @brief writes random bytes in the [0,0xff]-interval to memory + */ +void random_bytes(uint8_t *buf, size_t size); + /** * @brief generates a random number r with a <= r < b. * diff --git a/sys/random/tinymt32.c b/sys/random/tinymt32.c index d40e9b6e45..8442457e96 100644 --- a/sys/random/tinymt32.c +++ b/sys/random/tinymt32.c @@ -6,7 +6,7 @@ * directory for more details. */ - /** +/** * @ingroup sys_random * @{ * @file @@ -20,9 +20,18 @@ */ #include +#include #include "tinymt32/tinymt32.h" +#define _ALIGNMENT_MASK (sizeof(uint32_t) - 1) + +/* fits size to byte alignment */ +static inline uint8_t *_align(uint8_t *buf) +{ + return (uint8_t *)(((size_t) buf + _ALIGNMENT_MASK) & ~(_ALIGNMENT_MASK)); +} + static tinymt32_t _random; void random_init(uint32_t seed) @@ -35,6 +44,36 @@ uint32_t random_uint32(void) return tinymt32_generate_uint32(&_random); } +void random_bytes(uint8_t *buf, size_t size) +{ + size_t iter = size; + size_t diff = _align(buf) - buf; + uint32_t tmp; + + /* Fill first <4 unaligned bytes */ + if (diff) { + tmp = tinymt32_generate_uint32(&_random); + if (diff > size) { + diff = size; + } + memcpy(buf, &tmp, diff); + iter -= diff; + } + + /* Fill aligned bytes */ + while (iter >= sizeof(uint32_t)) { + *((uint32_t *) buf) = tinymt32_generate_uint32(&_random); + buf += sizeof(uint32_t); + iter -= sizeof(uint32_t); + } + + /* Fill last bytes */ + if (iter) { + tmp = tinymt32_generate_uint32(&_random); + memcpy(buf, &tmp, iter); + } +} + void random_init_by_array(uint32_t init_key[], int key_length) { tinymt32_init_by_array(&_random, init_key, key_length);