Merge pull request #2260 from KeystoneHQ/replace-lvgl-rand
What changed, and why it matters
This commit replaces the on-screen keyboard shuffle and a word-list randomizer so they use the device's true random-number generator (TRNG) instead of LVGL's weaker pseudo-random function. The change is defensive: it removes a source of predictable randomness that could, in theory, make shuffled PIN layouts or recovery-phrase ordering easier to guess or reproduce.
Treat as a security-hardening fix. Verify that `TrngGet()` is properly seeded/initialized and that its output is suitable for cryptographic use. Audit other callers of `lv_rand()` for similar bias or predictability issues, and consider adding unit tests for shuffle uniformity and TRNG failure handling.
Security signals we found
Replaced pseudo-random generator with hardware TRNG in security-sensitive shuffle operations
Removed fixed-range modulo reduction bias source (`lv_rand(0, 2048) % n`)
Changed include from LVGL UI library to device TRNG driver in utility code
Targets PIN keypad layout randomization and mnemonic/seed word ordering
Evidence from the diff
The patch swaps lv_rand(0, 2048) for TrngGet() in two places: (1) gui_keyboard.c ShuffleNumKeyBoardMap(), which shuffles the numeric PIN keypad layout, and (2) user_utils.c ArrayRandom(), which appears to shuffle an array of strings (likely BIP39 seed words). The old code used a small, fixed-range PRNG output and reduced it modulo the array length, which can introduce bias and, depending on LVGL’s seeding, may be predictable. The new code reads hardware-backed random bytes from the TRNG driver. The commit does not disclose a specific vulnerability or incident; it reads as a hardening change.
Changed components
src/ui/gui_components/gui_keyboard.csrc/utils/user_utils.cOn-screen numeric PIN keyboard shuffleSeed-word/recovery-phrase array randomizerInspect captured patch +8 / −3
### src/ui/gui_components/gui_keyboard.c
@@ -12,6 +12,7 @@
#include "gui_hintbox.h"
#include "gui_button.h"
#include "device_setting.h"
+#include "drv_trng.h"
#pragma GCC optimize ("O0")
@@ -488,7 +489,9 @@ static void ShuffleNumKeyBoardMap(const char **map)
for (int i = 0; i < n; i++) digits[i] = map[digitIdx[i]];
for (int i = n - 1; i > 0; i--) {
- uint32_t r = lv_rand(0, 2048) % (i + 1);
+ uint32_t random;
+ TrngGet(&random, sizeof(random));
+ uint32_t r = random % (i + 1);
const char *tmp = digits[i];
digits[i] = digits[r];
digits[r] = tmp;
### src/utils/user_utils.c
@@ -1,6 +1,6 @@
#include "user_utils.h"
#include "define.h"
-#include "lvgl.h"
+#include "drv_trng.h"
#include "user_memory.h"
#define HEX_STRING_MAX_LENGTH 4096
@@ -167,7 +167,9 @@ void ArrayRandom(char *words, char *out, int count)
}
for (int i = 0; i < count - 1; ++i) {
- int num = i + lv_rand(0, 2048) % (count - i);
+ uint32_t random;
+ TrngGet(&random, sizeof(random));
+ int num = i + random % (count - i);
char *temp = pointerList[i];
pointerList[i] = pointerList[num];
pointerList[num] = temp;Why this scored 59/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.