You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Boot-time unlock loop never calls reset_activity — device flickers Enter-PIN/Locked forever and needs two unlocks (#713 fixed in only one of two paths) #728
Observed on pq1 silicon (sealed EVT unit, interactive ui-lcd image, 2026-09-22): a device left at the boot PIN prompt flickers between "Enter PIN / to unlock" and "Locked" indefinitely, and the operator has to enter the PIN twice before reaching the main screen.
Operator, verbatim:
"now it flickers between enter pin and something else in a loop"
"I unlocked the first time, and then less than a second later it asked me again to unlock. Only then it went on the main screen."
No PIN attempts are consumed — GET_STATUS read locked=0 remaining=10 afterwards. The loop never submits a PIN, so it does not walk toward the 10-attempt wipe. That is the one piece of good news.
Cause
There are two unlock loops. #713's fix landed in one of them.
loop{
ui::show_status("Enter PIN","to unlock");// no reset_activityletmut pin = matchenter_pin(){PinEntryResult::Cancelled | PinEntryResult::IdleWipe => {
ui::show_status("Locked","");continue;// re-prompt, timer STILL expired}
ui::pin_entry::enter_pin (pin_entry.rs:102) samples timeout::is_idle()before waiting and calls reset_activity() only after a button event (pin_entry.rs:112). So once the idle deadline has passed, wait_button returns None immediately, enter_pin returns IdleWipe, the loop shows "Locked" and re-prompts — forever, with nothing ever resetting the timer.
grep -rn 'timeout::reset_activity()' secure/src/ --include=*.rs (excluding tests) confirms the production call sites are main.rs:4297, main.rs:4323, pin_entry.rs:112 and the seed wizard. Nothing in the 3938 loop.
Why the operator sees a "double unlock"
The first entry is consumed by an idle cycle; once a button press lands, pin_entry.rs:112 resets the timer and the next entry succeeds. From the outside that reads as "it asked me twice".
Impact
Any user who does not enter the PIN promptly on a cold boot sees a device apparently looping, and must enter the PIN twice.
It is the first thing a user does with the device, on the trusted display, so it is squarely a shipping-quality defect.
Call timeout::reset_activity() immediately before enter_pin() in the boot-time loop, matching 4297. Consider instead moving the reset insideenter_pin() at entry, so no future call site can reintroduce the asymmetry — the two loops have now diverged once already.
Whatever the fix, it wants a test that asserts BOTH loops reset activity, not just the one that was reported.
Summary
Observed on pq1 silicon (sealed EVT unit, interactive
ui-lcdimage, 2026-09-22): a device left at the boot PIN prompt flickers between "Enter PIN / to unlock" and "Locked" indefinitely, and the operator has to enter the PIN twice before reaching the main screen.Operator, verbatim:
No PIN attempts are consumed —
GET_STATUSreadlocked=0 remaining=10afterwards. The loop never submits a PIN, so it does not walk toward the 10-attempt wipe. That is the one piece of good news.Cause
There are two unlock loops. #713's fix landed in one of them.
secure/src/main.rs:4295— PendSV re-unlock, correct:secure/src/main.rs:3938— boot-time unlock, missing it:ui::pin_entry::enter_pin(pin_entry.rs:102) samplestimeout::is_idle()before waiting and callsreset_activity()only after a button event (pin_entry.rs:112). So once the idle deadline has passed,wait_buttonreturnsNoneimmediately,enter_pinreturnsIdleWipe, the loop shows "Locked" and re-prompts — forever, with nothing ever resetting the timer.grep -rn 'timeout::reset_activity()' secure/src/ --include=*.rs(excluding tests) confirms the production call sites aremain.rs:4297,main.rs:4323,pin_entry.rs:112and the seed wizard. Nothing in the 3938 loop.Why the operator sees a "double unlock"
The first entry is consumed by an idle cycle; once a button press lands,
pin_entry.rs:112resets the timer and the next entry succeeds. From the outside that reads as "it asked me twice".Impact
CMD_LOCK→REQUEST_UNLOCKstranding, fixed in the PendSV path, and that fix is confirmed still working (a re-unlock after an idle wipe succeeded in 28 s this session).Fix
Call
timeout::reset_activity()immediately beforeenter_pin()in the boot-time loop, matching 4297. Consider instead moving the reset insideenter_pin()at entry, so no future call site can reintroduce the asymmetry — the two loops have now diverged once already.Whatever the fix, it wants a test that asserts BOTH loops reset activity, not just the one that was reported.
Evidence
003B0022 30465002 2033314C, non-e2e-testimagedual-se,dev-testkey,ui-lcd,stm32u585,usb,board-pq1.GET_STATUSafter the episode:locked=0 remaining=10.