fix the verifying ps hang on wrong password in btc only multi-sig
What changed, and why it matters
This commit fixes a user-interface bug in the Bitcoin-only multi-sig wallet screens of the Keystone 3 hardware wallet firmware. If a user entered the wrong device-unlock password while the lock screen was shown over these multi-sig views, the lock screen would get stuck showing 'Verifying' instead of returning to the password entry and showing the failed-attempt count. The fix makes the wrong-password result update the lock screen, matching the correct-password path. It is a denial-of-usability issue, not a theft-of-funds vulnerability.
No urgent security action required. Treat as a normal firmware bug-fix release. Users who experienced the lock screen hang can update when convenient. If a security advisory is published, it should clarify this is a usability issue, not a cryptographic or asset-loss vulnerability.
Security signals we found
UI lock-up / denial of usability on wrong password
Incorrect routing of password verification result between overlapping views
Missing handling for SIG_LOCK_VIEW_SCREEN_GO_HOME_PASS in password error path
Fix mirrors existing PASS case, indicating a previously incomplete error branch
Evidence from the diff
In two BTC-only multi-sig view event handlers (import wallet info and manage wallet), the SIG_VERIFY_PASSWORD event handler did not distinguish whether the password verification result came from the device lock screen’s GO_HOME_PASS flow. When the lock screen was on top of these views and the password was wrong, the result was routed to the view’s own password-error handler instead of the lock screen’s, leaving the lock screen’s ‘Verifying’ spinner active and preventing further interaction. The patch adds a check for SIG_LOCK_VIEW_SCREEN_GO_HOME_PASS and calls GuiLockScreenPassCode(false) and GuiLockScreenErrorCount(param) to dismiss the spinner and update the lock screen’s attempt count, mirroring the existing PASS branch.
Changed components
src/ui/gui_views/btc_only/multi_sig/gui_import_multisig_wallet_info_view.csrc/ui/gui_views/btc_only/multi_sig/gui_manage_multisig_wallet_view.cKeystone 3 firmware Bitcoin-only multi-sig UIInspect captured patch +20 / −0
diff --git a/src/ui/gui_views/btc_only/multi_sig/gui_import_multisig_wallet_info_view.c b/src/ui/gui_views/btc_only/multi_sig/gui_import_multisig_wallet_info_view.c
index cdc6851..846e5da 100644
--- a/src/ui/gui_views/btc_only/multi_sig/gui_import_multisig_wallet_info_view.c
+++ b/src/ui/gui_views/btc_only/multi_sig/gui_import_multisig_wallet_info_view.c
@@ -3,6 +3,7 @@
#include "gui_views.h"
#include "gui_status_bar.h"
#include "gui_lock_widgets.h"
+#include "gui_model.h"
#include "gui_import_multisig_wallet_info_widgets.h"
int32_t GuiImportMultisigWalletInfoViewEventProcess(void *self, uint16_t usEvent, void *param, uint16_t usLen)
@@ -30,6 +31,15 @@ int32_t GuiImportMultisigWalletInfoViewEventProcess(void *self, uint16_t usEvent
if (param == NULL) {
return ERR_GUI_ERROR;
}
+ // When the lock screen is shown on top of this view (device-lock hintbox -> unlock), a wrong
+ // password comes back here with the GO_HOME_PASS purpose. Dismiss the lock screen's "Verifying"
+ // loading and show the attempts on the lock screen instead of this view's (hidden) keyboard —
+ // otherwise the lock screen stays stuck on "Verifying". Mirrors the PASS case above.
+ if (*(uint16_t *)((PasswordVerifyResult_t *)param)->signal == SIG_LOCK_VIEW_SCREEN_GO_HOME_PASS) {
+ GuiLockScreenPassCode(false);
+ GuiLockScreenErrorCount(param);
+ break;
+ }
GuiImportMultisigPasswordErrorCount(param);
break;
default:
diff --git a/src/ui/gui_views/btc_only/multi_sig/gui_manage_multisig_wallet_view.c b/src/ui/gui_views/btc_only/multi_sig/gui_manage_multisig_wallet_view.c
index 7ed911a..3a16176 100644
--- a/src/ui/gui_views/btc_only/multi_sig/gui_manage_multisig_wallet_view.c
+++ b/src/ui/gui_views/btc_only/multi_sig/gui_manage_multisig_wallet_view.c
@@ -2,6 +2,7 @@
#include "gui_views.h"
#include "gui_manage_multisig_wallet_widgets.h"
#include "gui_lock_widgets.h"
+#include "gui_model.h"
int32_t GuiManageMultiViewEventProcess(void *self, uint16_t usEvent, void *param, uint16_t usLen)
{
@@ -40,6 +41,15 @@ int32_t GuiManageMultiViewEventProcess(void *self, uint16_t usEvent, void *param
if (param == NULL) {
return ERR_GUI_ERROR;
}
+ // When the lock screen is shown on top of this view (device-lock hintbox -> unlock), a wrong
+ // password comes back here with the GO_HOME_PASS purpose. Dismiss the lock screen's "Verifying"
+ // loading and show the attempts on the lock screen instead of this view's (hidden) keyboard —
+ // otherwise the lock screen stays stuck on "Verifying". Mirrors the PASS case above.
+ if (*(uint16_t *)((PasswordVerifyResult_t *)param)->signal == SIG_LOCK_VIEW_SCREEN_GO_HOME_PASS) {
+ GuiLockScreenPassCode(false);
+ GuiLockScreenErrorCount(param);
+ break;
+ }
GuiManageMultisigPasswordErrorCount(param);
break;
default:
Why this scored 30/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.