diff --git a/SConscript.unix b/SConscript.unix index 1e1f344e93..65bd40c0ee 100644 --- a/SConscript.unix +++ b/SConscript.unix @@ -223,6 +223,7 @@ SOURCE_UNIX = [ 'vendor/micropython/ports/unix/alloc.c', 'embed/unix/common.c', 'embed/unix/flash.c', + 'embed/unix/rng.c', 'embed/unix/sdcard.c', 'embed/unix/sbu.c', 'embed/unix/touch.c', diff --git a/embed/extmod/modtrezorcrypto/modtrezorcrypto-random.h b/embed/extmod/modtrezorcrypto/modtrezorcrypto-random.h index 646bde6541..f455bda83a 100644 --- a/embed/extmod/modtrezorcrypto/modtrezorcrypto-random.h +++ b/embed/extmod/modtrezorcrypto/modtrezorcrypto-random.h @@ -43,13 +43,23 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_bytes_obj, mod_trezorcr /// Shuffles items of given list (in-place). /// ''' STATIC mp_obj_t mod_trezorcrypto_random_shuffle(mp_obj_t data) { - size_t item_cnt; + size_t count; mp_obj_t *items; - mp_obj_get_array(data, &item_cnt, &items); - if (item_cnt > 256) { + mp_obj_get_array(data, &count, &items); + if (count > 256) { mp_raise_ValueError("Maximum list size is 256 items"); } - random_permute(items, sizeof(mp_obj_t *), item_cnt); + if (count <= 1) { + return mp_const_none; + } + // Fisher-Yates shuffle + mp_obj_t t; + for (size_t i = count - 1; i >= 1; i--) { + size_t j = random_uniform(i + 1); + t = items[i]; + items[i] = items[j]; + items[j] = t; + } return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_shuffle_obj, mod_trezorcrypto_random_shuffle); diff --git a/embed/extmod/modtrezorcrypto/rand.c b/embed/extmod/modtrezorcrypto/rand.c index 0f100e403b..f4a5a9ab5c 100644 --- a/embed/extmod/modtrezorcrypto/rand.c +++ b/embed/extmod/modtrezorcrypto/rand.c @@ -5,32 +5,12 @@ * see LICENSE file for details */ -#include #include "rand.h" - -#ifdef UNIX -#include -#include -static FILE *frand = NULL; -#else -uint32_t rng_get(void); -#endif +#include "rng.h" uint32_t random32(void) { -#ifdef UNIX - uint32_t r; - size_t len = sizeof(r); - if (!frand) { - frand = fopen("/dev/urandom", "r"); - } - size_t len_read = fread(&r, 1, len, frand); - (void)len_read; - assert(len_read == len); - return r; -#else return rng_get(); -#endif } uint32_t random_uniform(uint32_t n) @@ -42,36 +22,11 @@ uint32_t random_uniform(uint32_t n) void random_buffer(uint8_t *buf, size_t len) { -#ifdef UNIX - if (!frand) { - frand = fopen("/dev/urandom", "r"); - } - size_t len_read = fread(buf, 1, len, frand); - (void)len_read; - assert(len_read == len); -#else - size_t i; uint32_t r = 0; - for (i = 0; i < len; i++) { + for (size_t i = 0; i < len; i++) { if (i % 4 == 0) { r = random32(); } buf[i] = (r >> ((i % 4) * 8)) & 0xFF; } -#endif -} - -void random_permute(void *buf, size_t size, size_t count) -{ - if (count < 1 || size < 1) { - return; - } - uint8_t *d = (uint8_t *)buf; - uint8_t t[size]; - for (size_t i = count - 1; i >= 1; i--) { - size_t j = random_uniform(i + 1); - memcpy(t, d + j * size, size); - memcpy(d + j * size, d + i * size, size); - memcpy(d + i * size, t, size); - } } diff --git a/embed/extmod/modtrezorcrypto/rand.h b/embed/extmod/modtrezorcrypto/rand.h index d2624cec22..913e15852e 100644 --- a/embed/extmod/modtrezorcrypto/rand.h +++ b/embed/extmod/modtrezorcrypto/rand.h @@ -14,6 +14,5 @@ uint32_t random32(void); uint32_t random_uniform(uint32_t n); void random_buffer(uint8_t *buf, size_t len); -void random_permute(void *buf, size_t size, size_t count); #endif diff --git a/embed/trezorhal/rng.c b/embed/trezorhal/rng.c index bc383892d6..620c1c8af6 100644 --- a/embed/trezorhal/rng.c +++ b/embed/trezorhal/rng.c @@ -1,5 +1,7 @@ #include "rng.h" +#include STM32_HAL_H + #pragma GCC optimize("no-stack-protector") // applies to all functions in this file void rng_init(void) diff --git a/embed/trezorhal/rng.h b/embed/trezorhal/rng.h index 51c0802380..2e8eb9442e 100644 --- a/embed/trezorhal/rng.h +++ b/embed/trezorhal/rng.h @@ -1,7 +1,7 @@ #ifndef TREZORHAL_RNG_H #define TREZORHAL_RNG_H -#include STM32_HAL_H +#include void rng_init(void); uint32_t rng_read(const uint32_t previous, const uint32_t compare_previous); diff --git a/embed/unix/rng.c b/embed/unix/rng.c new file mode 100644 index 0000000000..513c075638 --- /dev/null +++ b/embed/unix/rng.c @@ -0,0 +1,17 @@ +#include +#include + +#include "common.h" +#include "rng.h" + +uint32_t rng_get(void) +{ + static FILE *frand = NULL; + if (!frand) { + frand = fopen("/dev/urandom", "r"); + } + ensure(sectrue * (frand != NULL), "fopen failed"); + uint32_t r; + ensure(sectrue * (sizeof(r) == fread(&r, 1, sizeof(r), frand)), "fread failed"); + return r; +} diff --git a/embed/unix/rng.h b/embed/unix/rng.h new file mode 120000 index 0000000000..917f74c3e7 --- /dev/null +++ b/embed/unix/rng.h @@ -0,0 +1 @@ +../trezorhal/rng.h \ No newline at end of file