What changed, and why it matters
This commit swaps out the LVGL graphics library's pseudo-random number generator for the device's hardware true random number generator (TRNG) in two places: shuffling the on-screen numeric keypad and shuffling recovery-word lists. The old code used lv_rand, which is not designed for cryptographic security and may be predictable. Using a predictable shuffle could let an attacker who can see or guess the random sequence reduce the number of possible keypad layouts or word orders they must try, weakening protections for PIN entry or seed-phrase backup verification. The patch itself is a clear improvement, but it is small and we cannot verify from the diff alone whether the TRNG driver is correctly implemented or whether other sensitive code still uses lv_rand.
Verify that TrngGet is a properly seeded and audited hardware TRNG with adequate entropy for each call. Audit all remaining lv_rand and similar non-cryptographic RNG uses across the firmware and replace them in security contexts. Consider adding a small bias-removal step (e.g., rejection sampling) for the modulo reduction when range sizes are not powers of two. Review whether the shuffle outputs are observable by side channels (timing, display refresh) that could leak the TRNG output or resulting permutation.
Security signals we found
Replacement of non-cryptographic PRNG with hardware TRNG in security-sensitive shuffle routines
Fisher-Yates shuffle of on-screen PIN keypad now uses TrngGet
Fisher-Yates shuffle of mnemonic word array now uses TrngGet
Removal of lv_rand dependency from user_utils.c
Evidence from the diff
The diff replaces lv_rand(0, 2048) % range calls with TrngGet(&random, sizeof(random)) % range in gui_keyboard.c (Fisher-Yates shuffle of a numeric PIN keypad) and user_utils.c (Fisher-Yates-style shuffle of an array of strings, likely BIP-39 seed words). lv_rand is LVGL’s internal RNG and is not a CSPRNG; its output can be deterministic or low-entropy depending on seeding. TrngGet is the board’s hardware TRNG driver. The change removes a source of deterministic randomness from two security-sensitive UI operations. However, the patch does not show the TrngGet implementation, error handling, entropy validation, or whether modulo bias is mitigated. It also does not show whether other lv_rand callers remain in the firmware.
Changed components
src/ui/gui_components/gui_keyboard.csrc/utils/user_utils.cOn-screen numeric/PIN keyboard shuffleRecovery phrase / mnemonic word shuffle utilityInspect captured patch +8 / −3
diff --git a/src/ui/gui_components/gui_keyboard.c b/src/ui/gui_components/gui_keyboard.c
index 59b0caa..2d29149 100644
--- a/src/ui/gui_components/gui_keyboard.c
+++ b/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;
diff --git a/src/utils/user_utils.c b/src/utils/user_utils.c
index 470f917..7c97d77 100644
--- a/src/utils/user_utils.c
+++ b/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.