Q becomes calculator rather than e-waste
This commit is contained in:
parent
038199a3e2
commit
4457576ad4
@ -44,6 +44,8 @@ Spending policies for "Single Signers" adds new spending policy options:
|
||||
|
||||
## 1.3.4Q - 2025-09-2x
|
||||
|
||||
- Enhancement: Enter "forever calculator" mode when Q would otherwise be e-waste: after 13
|
||||
PIN failures, when device is bricked.
|
||||
- Bugfix: Correct line positioning when 24 seed words displayed.
|
||||
|
||||
|
||||
|
||||
@ -8,8 +8,9 @@ import utime, ngu, re
|
||||
from utils import B2A, word_wrap
|
||||
from ux_q1 import ux_input_text
|
||||
|
||||
async def login_repl(allow_login=True):
|
||||
async def login_repl():
|
||||
from glob import dis
|
||||
from pincodes import pa
|
||||
|
||||
NUM_LINES = 7 # 10 - title - 2 for prompt
|
||||
|
||||
@ -64,12 +65,11 @@ Example Commands:
|
||||
elif ln in ('help', 'cls', 'rand'):
|
||||
# no need for () for these commands
|
||||
ans = state[ln]()
|
||||
elif allow_login and re_pin.match(ln) and (len(ln) <= 13):
|
||||
elif pa.attempts_left and re_pin.match(ln) and (len(ln) <= 13):
|
||||
# try login
|
||||
m = re_pin.match(ln)
|
||||
ln = m.group(1)+ '-' + m.group(2)
|
||||
print(ln)
|
||||
from pincodes import pa
|
||||
|
||||
try:
|
||||
pa.setup(ln)
|
||||
ok = pa.login()
|
||||
@ -83,7 +83,7 @@ Example Commands:
|
||||
else:
|
||||
ans = 'Error: ' + repr(exc.args)
|
||||
|
||||
elif allow_login and re_prefix.match(ln) and (len(ln) <= 7):
|
||||
elif re_prefix.match(ln) and (len(ln) <= 7):
|
||||
# show words
|
||||
from pincodes import pa
|
||||
ans = pa.prefix_words(ln[:-1].encode())
|
||||
|
||||
@ -181,14 +181,22 @@ class LoginUX:
|
||||
async def we_are_ewaste(self, num_fails):
|
||||
msg = '''After %d failed PIN attempts this Coldcard is locked forever. \
|
||||
By design, there is no way to reset or recover the secure element, and its contents \
|
||||
are now forever inaccessible.
|
||||
are now forever inaccessible.\n\n''' % num_fails
|
||||
|
||||
Restore your seed words onto a new Coldcard.''' % num_fails
|
||||
if has_qwerty:
|
||||
msg += 'Calculator mode starts now.'
|
||||
else:
|
||||
msg += 'Restore your seed words onto a new Coldcard.'
|
||||
|
||||
while 1:
|
||||
ch = await ux_show_story(msg, title='I Am Brick!', escape='6')
|
||||
if ch == '6': break
|
||||
|
||||
if has_qwerty:
|
||||
from calc import login_repl
|
||||
await login_repl()
|
||||
|
||||
|
||||
async def confirm_attempt(self, attempts_left, value):
|
||||
|
||||
ch = await ux_show_story('''You have %d attempts left before this Coldcard BRICKS \
|
||||
|
||||
@ -90,7 +90,7 @@ async def more_setup():
|
||||
from pincodes import pa
|
||||
# check for bricked system early
|
||||
# bricked CC not going past this point
|
||||
pa.enforce_brick()
|
||||
await pa.enforce_brick()
|
||||
|
||||
pa.setup(b'') # just to see where we stand.
|
||||
is_blank = pa.is_blank()
|
||||
|
||||
@ -130,9 +130,10 @@ class PinAttempt:
|
||||
# seed, we are not going to let them see it, nor sign things we dont like, etc.
|
||||
self.hobbled_mode = False
|
||||
|
||||
assert MAX_PIN_LEN == 32 # update FMT otherwise
|
||||
assert ustruct.calcsize(PIN_ATTEMPT_FMT_V1) == PIN_ATTEMPT_SIZE_V1
|
||||
assert ustruct.calcsize(PIN_ATTEMPT_FMT_V2_ADDITIONS) == PIN_ATTEMPT_SIZE - PIN_ATTEMPT_SIZE_V1
|
||||
#assert MAX_PIN_LEN == 32 # update FMT otherwise
|
||||
#assert ustruct.calcsize(PIN_ATTEMPT_FMT_V1) == PIN_ATTEMPT_SIZE_V1
|
||||
#assert ustruct.calcsize(PIN_ATTEMPT_FMT_V2_ADDITIONS) \
|
||||
# == PIN_ATTEMPT_SIZE - PIN_ATTEMPT_SIZE_V1
|
||||
|
||||
def __repr__(self):
|
||||
return '<PinAttempt: fails/left=%d/%d tc_flag/arg=0x%x/0x%x>' % (
|
||||
@ -535,11 +536,10 @@ class PinAttempt:
|
||||
# check for bricked system early
|
||||
if get_is_bricked():
|
||||
try:
|
||||
# regardless of settings.calc forever calculator after brickage
|
||||
# for Q models fom version 5.X.X
|
||||
if version.has_qwerty:
|
||||
# regardless of settings, become a forever calculator after brickage.
|
||||
while version.has_qwerty:
|
||||
from calc import login_repl
|
||||
await login_repl(allow_login=False)
|
||||
await login_repl()
|
||||
finally:
|
||||
# die right away if it's not going to work
|
||||
enter_dfu(3)
|
||||
|
||||
@ -53,7 +53,7 @@ wallet (on testnet, always with the same seed). But there are other options:
|
||||
- `--deriv` => go to the Derive Entropy menu inside settings, also loads XPRV from BIP
|
||||
- `--secret 01abababab...` => directly set contents of SE secret, see SecretStash.encode()
|
||||
- `--eject` => pretend no (simulated) SD Card is inserted
|
||||
- `--eff` => (mk4) wipe setttings at startup, use simulator defaults
|
||||
- `--eff` => wipe setttings at startup, use simulator defaults, save nothing.
|
||||
- `--seq 1234yx34` => after start, enter those keypresses to get you to some submenu
|
||||
- `--seq 2ENTER` => (Q) press 2 then ENTER, does QR at startup
|
||||
- `--bootup-movie` => begin a movie on startup, to capture boot sequence
|
||||
@ -61,6 +61,8 @@ wallet (on testnet, always with the same seed). But there are other options:
|
||||
- `--battery` => (Q) assume the USB cable is NOT connected (ie. on battery power)
|
||||
- `--early-usb` => start simulated USB interface even before user is login (useful for login testing)
|
||||
- `--segregate` => scroll down to `Running simulators in parallel` section
|
||||
- `--bricked` => simulate a system w/ bricked SE1: no more pin tries, etc.
|
||||
- `--fails N` => simulate N wrong PIN attempts before login, where (1 <= N <= 13)
|
||||
|
||||
See `variant/sim_settings.py` for the details of settings-related options.
|
||||
|
||||
|
||||
@ -98,6 +98,9 @@ def gate(method, buf_io, arg2):
|
||||
|
||||
if method == 5:
|
||||
# are we a brick? No.
|
||||
if '--bricked' in sys.argv:
|
||||
# if SE1 has pairing secret rotated; wont be able to do much
|
||||
return 1
|
||||
return 0
|
||||
|
||||
if method == 6:
|
||||
|
||||
@ -155,6 +155,7 @@ if '--enter' in sys.argv:
|
||||
# keep at end of file: extra enter to confirm something from above
|
||||
numpad.inject('y')
|
||||
|
||||
|
||||
# not best place for this
|
||||
import hsm
|
||||
hsm.POLICY_FNAME = hsm.POLICY_FNAME.replace('/flash/', '')
|
||||
|
||||
@ -144,6 +144,13 @@ if '-g' in sys.argv:
|
||||
# do login.. but does not work if _skip_pin got saved into settings already
|
||||
sim_defaults.pop('_skip_pin', 0)
|
||||
|
||||
if '--fails' in sys.argv:
|
||||
# fast-forward as if N PIN failures have already happened.
|
||||
count = int(sys.argv[sys.argv.index('--fails') + 1])
|
||||
import ckcc
|
||||
ckcc.SE_STATE.force_fails(count)
|
||||
sim_defaults.pop('_skip_pin', 0)
|
||||
|
||||
if '--nick' in sys.argv:
|
||||
nick = sys.argv[sys.argv.index('--nick') + 1]
|
||||
sim_defaults['nick'] = nick
|
||||
|
||||
Loading…
Reference in New Issue
Block a user