From 62e7dcc66a645876d5a62dd4c35ad1e0244357ed Mon Sep 17 00:00:00 2001 From: Giovanni Bajo Date: Tue, 31 Dec 2024 03:17:39 +0100 Subject: [PATCH] joypad: feed user inputs into the getentropy() pool This makes things more random under emulators where user input is basically the only source of non determinism. --- src/joypad.c | 4 ++++ src/system.c | 55 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/joypad.c b/src/joypad.c index e0c61e297..364a4b4a8 100644 --- a/src/joypad.c +++ b/src/joypad.c @@ -469,6 +469,10 @@ static void joypad_read_callback(uint64_t *out_dwords, void *ctx) { memcpy((void *)joypad_read_output, out_dwords, JOYBUS_BLOCK_SIZE); joypad_read_pending = false; + + // Use some bytes from the joypad inputs to feed the entropy pool + extern void __entropy_add(uint64_t); + __entropy_add(out_dwords[0]); } /** diff --git a/src/system.c b/src/system.c index e019fdc1f..6e6a6e099 100644 --- a/src/system.c +++ b/src/system.c @@ -1334,6 +1334,44 @@ int truncate( const char *path, off_t length ) return ret; } +/** + * @brief Add some non-deterministic data to the entropy pool. + * + * This is an internal function that can be used by libdragon libraries to add + * some non-deterministic data to the entropy pool. One example of such data + * would be the joypad inputs at any given point. + * + * The entropy pool is then used t + * + * @param k Non-deterministic data (up to 64 bits) + */ +void __entropy_add(uint64_t k) { + // This is half of MurMurHash3-128. + k *= __entropy_K[0]; + k = k<<31 | k>>33; + k *= __entropy_K[1]; + disable_interrupts(); + __entropy_state ^= k; + __entropy_state = __entropy_state<<27 | __entropy_state>>37; + __entropy_state = __entropy_state * 5 + 0x52dce729; + enable_interrupts(); +} + +// Extract data from the entropy pool. This is kept here for symmetry with +// __entropy_add, but it is not an API; the API to use to extract entropy is +// #getentropy. +static uint64_t __entropy_get(void) { + disable_interrupts(); + uint64_t h = __entropy_state; + enable_interrupts(); + h ^= h >> 33; + h *= __entropy_K[2]; + h ^= h >> 33; + h *= __entropy_K[3]; + h ^= h >> 33; + return h; +} + /** * @brief Generate an array of unpredictable random numbers * @@ -1367,24 +1405,13 @@ int getentropy(uint8_t *buf, size_t buflen) // Mix in some hardware state / counters that are likely to be random // at the point of sampling, especially during hardware activity. - // This is half of MurMurHash3-128. for (int i=0; i>33; - k *= __entropy_K[1]; - __entropy_state ^= k; - __entropy_state = __entropy_state<<27 | __entropy_state>>37; - __entropy_state = __entropy_state * 5 + 0x52dce729; + __entropy_add(k); } - // Extract the current hash value - uint64_t h = __entropy_state; - h ^= h >> 33; - h *= __entropy_K[2]; - h ^= h >> 33; - h *= __entropy_K[3]; - h ^= h >> 33; + // Extract the current entropy value + uint64_t h = __entropy_get(); // Generate output buffer typedef uint64_t u_uint64_t __attribute__((aligned(1)));