What changed, and why it matters
This commit adds a shuffled numeric keypad for PIN entry on a hardware wallet. Instead of always showing 0-9 in the same order, the digits now appear in a random order each time. This is a defensive measure to make it harder for someone watching or recording the screen to learn your PIN based on where you tap.
No action required; this is a defensive hardening change. If desired, verify that lv_rand() is seeded from an entropy source and that the shuffle is applied consistently across all PIN-entry flows. Consider documenting the security rationale in code comments.
Security signals we found
Adds randomized on-screen keypad layout for PIN entry
Uses non-cryptographic PRNG (lv_rand) for UI shuffle
Targets shoulder-surfing / video side-channel mitigation
No bounds-checking issues or memory safety defects visible in diff
Evidence from the diff
The patch introduces ShuffleNumKeyBoardMap(), which extracts the digit entries from the numeric button-matrix map and performs a Fisher-Yates shuffle using lv_rand(). The shuffled map is then applied to the PIN-entry numeric keyboard (NUM_KEYBOARD_PIN). The randomness source is lv_rand(0, 2048) % (i + 1), which is a non-cryptographic PRNG and introduces a small modulo bias, but for UI layout randomization this is generally acceptable. No vulnerability is introduced; the change improves side-channel resistance against shoulder-surfing and video-based PIN reconstruction.
Changed components
src/ui/gui_components/gui_keyboard.cNUM_KEYBOARD_PIN keypadInspect captured patch +19 / −0
diff --git a/src/ui/gui_components/gui_keyboard.c b/src/ui/gui_components/gui_keyboard.c
index 98d9a20..74bf3be 100644
--- a/src/ui/gui_components/gui_keyboard.c
+++ b/src/ui/gui_components/gui_keyboard.c
@@ -470,6 +470,24 @@ void *GuiCreateEmojiKeyBoard(lv_obj_t *parent, lv_obj_t *icon)
return hintbox;
}
+static void ShuffleNumKeyBoardMap(const char **map)
+{
+ int digitIdx[] = {0, 1, 2, 4, 5, 6, 8, 9, 10, 13};
+ const int n = NUMBER_OF_ARRAYS(digitIdx);
+
+ const char *digits[10];
+ 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);
+ const char *tmp = digits[i];
+ digits[i] = digits[r];
+ digits[r] = tmp;
+ }
+
+ for (int i = 0; i < n; i++) map[digitIdx[i]] = digits[i];
+}
+
void *GuiCreateNumKeyboard(lv_obj_t *parent, lv_event_cb_t cb, NUM_KEYBOARD_ENUM numMode, void *param)
{
uint16_t kbHeight = 310;
@@ -478,6 +496,7 @@ void *GuiCreateNumKeyboard(lv_obj_t *parent, lv_event_cb_t cb, NUM_KEYBOARD_ENUM
switch (numMode) {
case NUM_KEYBOARD_PIN:
lv_obj_add_style(btnm, &g_numBtnmStyle, LV_PART_ITEMS);
+ ShuffleNumKeyBoardMap((const char **)g_numBtnmMap);
lv_btnmatrix_set_map(btnm, (const char **)g_numBtnmMap);
lv_obj_align(btnm, LV_ALIGN_TOP_MID, 0, 490 - GUI_MAIN_AREA_OFFSET);
lv_obj_set_style_bg_color(btnm, DARK_BG_COLOR, LV_PART_MAIN);
Why this scored 42/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.