remove version.has_fatram, add version.supports_hsm

This commit is contained in:
Peter D. Gray 2023-06-05 09:06:22 -04:00 committed by scgbckbone
parent 05b86b6375
commit c8adf9cefa
11 changed files with 95 additions and 87 deletions

View File

@ -901,17 +901,18 @@ async def start_login_sequence():
# If HSM policy file is available, offer to start that,
# **before** the USB is even enabled.
# do not offer HSM if wallet is blank -> HSM needs secret
if not pa.is_secret_blank():
try:
import hsm, hsm_ux
if version.supports_hsm:
# do not offer HSM if wallet is blank -> HSM needs secret
if not pa.is_secret_blank():
try:
import hsm, hsm_ux
if hsm.hsm_policy_available():
settings.put("hsmcmd", True)
ar = await hsm_ux.start_hsm_approval(usb_mode=False, startup_mode=True)
if ar:
await ar.interact()
except: pass
if hsm.hsm_policy_available():
settings.put("hsmcmd", True)
ar = await hsm_ux.start_hsm_approval(usb_mode=False, startup_mode=True)
if ar:
await ar.interact()
except: pass
if version.has_nfc and settings.get('nfc', 0):
# Maybe allow NFC now

View File

@ -19,9 +19,6 @@ from charcodes import KEY_QR, KEY_NFC, KEY_PAGE_UP, KEY_PAGE_DOWN, KEY_HOME
def truncate_address(addr):
# Truncates address to width of screen, replacing middle chars
# - 16 chars screen width
# - but 2 lost at left (menu arrow, corner arrow)
# - want to show not truncated on right side
if not version.has_qwerty:
# - 16 chars screen width
# - but 2 lost at left (menu arrow, corner arrow)

View File

@ -104,9 +104,10 @@ def render_backup_contents(bypass_tmp=False):
if k == 'seeds' and not v: continue
ADD('setting.' + k, v)
import hsm
if hsm.hsm_policy_available():
ADD('hsm_policy', hsm.capture_backup())
if version.supports_hsm:
import hsm
if hsm.hsm_policy_available():
ADD('hsm_policy', hsm.capture_backup())
rv.write('\n# EOF\n')
@ -218,7 +219,7 @@ def restore_from_dict_ll(vals):
# write out
settings.save()
if 'hsm_policy' in vals:
if version.supports_hsm and ('hsm_policy' in vals):
import hsm
hsm.restore_backup(vals['hsm_policy'])

View File

@ -22,6 +22,15 @@ from paper import make_paper_wallet
from trick_pins import TrickPinMenu
# Optional feature: HSM, depends on hardware
# - code for HSM support wont exist on other version, so dont call it
if version.supports_hsm:
from hsm import hsm_policy_available
hsm_feature = lambda: True
else:
hsm_policy_available = lambda: False
hsm_feature = lambda: False
trick_pin_menu = TrickPinMenu.make_menu
#
@ -272,8 +281,8 @@ AdvancedNormalMenu = [
MenuItem('Paper Wallets', f=make_paper_wallet, predicate=lambda: make_paper_wallet),
ToggleMenuItem('Enable HSM', 'hsmcmd', ['Default Off', 'Enable'],
story="Enable HSM? Enables all user management commands, and other HSM-only USB commands. \
By default these commands are disabled."),
MenuItem('User Management', menu=make_users_menu),
By default these commands are disabled.", predicate=hsm_feature),
MenuItem('User Management', menu=make_users_menu, predicate=hsm_feature),
MenuItem('NFC Tools', predicate=nfc_enabled, menu=NFCToolsMenu),
MenuItem("Danger Zone", menu=DangerZoneMenu),
]

View File

@ -22,8 +22,6 @@ freeze_as_mpy('', [
'ftux.py',
'glob.py',
'history.py',
'hsm.py',
'hsm_ux.py',
'imptask.py',
'login.py',
'main.py',
@ -47,7 +45,6 @@ freeze_as_mpy('', [
'ssd1306.py',
'stash.py',
'usb.py',
'users.py',
'utils.py',
'ux.py',
'version.py',

View File

@ -9,6 +9,9 @@ freeze_as_mpy('', [
'ndef.py',
'trick_pins.py',
'ux_mk4.py',
'hsm.py',
'hsm_ux.py',
'users.py',
], opt=0)
# Optimize data-like files, since no need to debug them.

View File

@ -297,11 +297,6 @@ async def make_paper_wallet(*a):
menu = MenuSystem([])
rv = PaperWalletMaker(menu)
# annoying?
# always have them pick the template, because that's mostly required
#if rv.can_do_qr():
# await rv.pick_template()
rv.update_menu()
return menu

View File

@ -10,7 +10,7 @@ from public_constants import STXN_FLAGS_MASK
from ustruct import pack, unpack_from
from ckcc import watchpoint, is_simulator
from utils import problem_file_line, call_later_ms
from version import is_devmode, MAX_TXN_LEN, MAX_UPLOAD_LEN
from version import supports_hsm, is_devmode, MAX_TXN_LEN, MAX_UPLOAD_LEN
from exceptions import FramingError, CCBusyError, HSMDenied, HSMCMDDisabled
# Unofficial, unpermissioned... numbers
@ -570,64 +570,65 @@ class USBHandler:
if cmd == 'bagi':
return self.handle_bag_number(args)
# HSM and user-related features only supported on larger-memory Mk3
if supports_hsm:
# HSM and user-related features only supported on Mk4
if cmd == 'hsms':
# HSM mode "start" -- requires user approval
if args:
file_len, file_sha = unpack_from('<I32s', args)
if file_sha != self.file_checksum.digest():
return b'err_Checksum'
assert 2 <= file_len <= (200*1000), "badlen"
else:
file_len = 0
if cmd == 'hsms':
# HSM mode "start" -- requires user approval
if args:
file_len, file_sha = unpack_from('<I32s', args)
if file_sha != self.file_checksum.digest():
return b'err_Checksum'
assert 2 <= file_len <= (200*1000), "badlen"
else:
file_len = 0
# Start an UX interaction but return (mostly) immediately here
from hsm_ux import start_hsm_approval
await start_hsm_approval(sf_len=file_len, usb_mode=True)
# Start an UX interaction but return (mostly) immediately here
from hsm_ux import start_hsm_approval
await start_hsm_approval(sf_len=file_len, usb_mode=True)
return None
if cmd == 'hsts':
# can always query HSM mode
from hsm import hsm_status_report
import ujson
return b'asci' + ujson.dumps(hsm_status_report())
if cmd == 'gslr':
# get the value held in the Storage Locker
assert hsm_active, 'need hsm'
return b'biny' + hsm_active.fetch_storage_locker()
# User Mgmt
if cmd == 'nwur': # new user
from users import Users
auth_mode, ul, sl = unpack_from('<BBB', args)
username = bytes(args[3:3+ul]).decode('ascii')
secret = bytes(args[3+ul:3+ul+sl])
return b'asci' + Users.create(username, auth_mode, secret).encode('ascii')
if cmd == 'rmur': # delete user
from users import Users
ul, = unpack_from('<B', args)
username = bytes(args[1:1+ul]).decode('ascii')
return Users.delete(username)
if cmd == 'user': # auth user (HSM mode)
from users import Users
totp_time, ul, tl = unpack_from('<IBB', args)
username = bytes(args[6:6+ul]).decode('ascii')
token = bytes(args[6+ul:6+ul+tl])
if hsm_active:
# just queues these details, can't be checked until PSBT on-hand
hsm_active.usb_auth_user(username, token, totp_time)
return None
else:
# dryrun/testing purposes: validate only, doesn't unlock nothing
return b'asci' + Users.auth_okay(username, token, totp_time).encode('ascii')
if cmd == 'hsts':
# can always query HSM mode
from hsm import hsm_status_report
import ujson
return b'asci' + ujson.dumps(hsm_status_report())
if cmd == 'gslr':
# get the value held in the Storage Locker
assert hsm_active, 'need hsm'
return b'biny' + hsm_active.fetch_storage_locker()
# User Mgmt
if cmd == 'nwur': # new user
from users import Users
auth_mode, ul, sl = unpack_from('<BBB', args)
username = bytes(args[3:3+ul]).decode('ascii')
secret = bytes(args[3+ul:3+ul+sl])
return b'asci' + Users.create(username, auth_mode, secret).encode('ascii')
if cmd == 'rmur': # delete user
from users import Users
ul, = unpack_from('<B', args)
username = bytes(args[1:1+ul]).decode('ascii')
return Users.delete(username)
if cmd == 'user': # auth user (HSM mode)
from users import Users
totp_time, ul, tl = unpack_from('<IBB', args)
username = bytes(args[6:6+ul]).decode('ascii')
token = bytes(args[6+ul:6+ul+tl])
if hsm_active:
# just queues these details, can't be checked until PSBT on-hand
hsm_active.usb_auth_user(username, token, totp_time)
return None
else:
# dryrun/testing purposes: validate only, doesn't unlock nothing
return b'asci' + Users.auth_okay(username, token, totp_time).encode('ascii')
#print("USB garbage: %s +[%d]" % (cmd, len(args)))

View File

@ -75,7 +75,7 @@ def serial_number():
def probe_system():
# run-once code to determine what hardware we are running on
global hw_label, has_608, has_fatram, is_factory_mode, is_devmode, has_psram, is_edge
global has_se2, mk_num, has_nfc, has_qr, num_sd_slots, has_qwerty, has_battery
global has_se2, mk_num, has_nfc, has_qr, num_sd_slots, has_qwerty, has_battery, supports_hsm
global MAX_UPLOAD_LEN, MAX_TXN_LEN
from sigheader import RAM_BOOT_FLAGS, RBF_FACTORY_MODE
@ -90,6 +90,7 @@ def probe_system():
has_battery = False
has_qwerty = False
is_edge = False
supports_hsm = False
cpuid = ckcc.get_cpu_id()
assert cpuid == 0x470 # STM32L4S5VI
@ -102,6 +103,7 @@ def probe_system():
hw_label = 'q1'
has_battery = True
has_qwerty = True
supports_hsm = False
# but, still mk_num = 4
except ValueError:
pass

1
testing/charcodes.py Symbolic link
View File

@ -0,0 +1 @@
../shared/charcodes.py

View File

@ -36,7 +36,7 @@ def get_header_value(fld_name):
hw_label = 'mk4'
has_608 = True
has_membrane = True
has_fatram = True
supports_hsm = True
has_se2 = True
has_psram = True
has_nfc = True
@ -51,26 +51,26 @@ if '--mk1' in sys.argv:
hw_label = 'mk1'
has_608 = False
has_membrane = False
has_fatram = False
has_se2 = False
has_psram = False
has_nfc = False
supports_hsm = False
if '--mk2' in sys.argv:
hw_label = 'mk2'
has_608 = False
has_fatram = False
has_se2 = False
has_psram = False
has_nfc = False
supports_hsm = False
if '--mk3' in sys.argv:
hw_label = 'mk3'
has_608 = True
has_fatram = True
has_se2 = False
has_psram = False
has_nfc = False
supports_hsm = False
mk_num = int(hw_label[2:])
@ -80,6 +80,7 @@ if '--q1' in sys.argv:
num_sd_slots = 2
has_battery = True
has_qwerty = True
supports_hsm = False
from public_constants import MAX_TXN_LEN, MAX_UPLOAD_LEN
from public_constants import MAX_TXN_LEN_MK4, MAX_UPLOAD_LEN_MK4