async def bootscreen() -> None: ui.display.orientation(storage.device.get_rotation()) while True: try: if storage.sd_salt.is_enabled() or config.has_pin(): await lockscreen() salt = await request_sd_salt() if not config.has_pin(): config.unlock(pin_to_int(""), salt) storage.init_unlocked() return label = "Enter your PIN" while True: pin = await request_pin(label, config.get_pin_rem()) if config.unlock(pin_to_int(pin), salt): storage.init_unlocked() return else: label = "Wrong PIN, enter again" except (OSError, PinCancelled, SdCardUnavailable) as e: if __debug__: log.exception(__name__, e) except BaseException as e: if __debug__: log.exception(__name__, e) utils.halt(e.__class__.__name__)
async def verify_user_pin(prompt: str = "Enter your PIN", allow_cancel: bool = True, retry: bool = True) -> None: if config.has_pin(): pin = await request_pin(prompt, config.get_pin_rem(), allow_cancel) config.ensure_not_wipe_code(pin_to_int(pin)) else: pin = "" try: salt = await request_sd_salt() except SdCardUnavailable: raise PinCancelled if config.unlock(pin_to_int(pin), salt): return elif not config.has_pin(): raise RuntimeError while retry: pin = await request_pin("Wrong PIN, enter again", config.get_pin_rem(), allow_cancel) if config.unlock(pin_to_int(pin), salt): return raise PinInvalid
async def bootscreen() -> None: ui.display.orientation(storage_device.get_rotation()) salt_auth_key = storage_device.get_sd_salt_auth_key() while True: try: if salt_auth_key is not None or config.has_pin(): await lockscreen() if salt_auth_key is not None: salt = await request_sd_salt(None, salt_auth_key ) # type: Optional[bytearray] else: salt = None if not config.has_pin(): config.unlock(pin_to_int(""), salt) storage.init_unlocked() return label = "Enter your PIN" while True: pin = await request_pin(label, config.get_pin_rem()) if config.unlock(pin_to_int(pin), salt): storage.init_unlocked() return else: label = "Wrong PIN, enter again" except (OSError, PinCancelled, SdProtectCancelled) as e: if __debug__: log.exception(__name__, e) except BaseException as e: utils.halt(e.__class__.__name__)
async def bootscreen(): while True: try: if not config.has_pin(): config.unlock(pin_to_int(''), show_pin_timeout) return await lockscreen() while True: pin = await request_pin() if config.unlock(pin_to_int(pin), show_pin_timeout): return except: pass
async def bootscreen(): while True: try: if not config.has_pin(): config.unlock(pin_to_int(''), show_pin_timeout) return await lockscreen() label = None while True: pin = await request_pin(label) if config.unlock(pin_to_int(pin), show_pin_timeout): return else: label = 'Wrong PIN, enter again' except: # noqa: E722 pass
async def get_owner_key(ctx, msg): if not config.has_pin(): return Failure(message='PIN is not set') label = "Enter your PIN" while True: try: pin = await ctx.wait(request_pin(label)) if config.unlock(pin_to_int(pin)): break else: label = "Wrong PIN, enter again" except PinCancelled: raise wire.ActionCancelled("Cancelled") export_warning_msg = 'Exposing the key to a third party allows them to see your balance.' await beam_confirm_message(ctx, 'Owner key', export_warning_msg, False) wait_warning_msg = 'Please wait few seconds until exporting is done' await beam_confirm_message(ctx, 'Owner key', wait_warning_msg, False) pin = pin.encode() owner_key = generate_owner_key(pin) if msg.show_display: await beam_confirm_message(ctx, 'Owner key', owner_key, True) return BeamOwnerKey(key=owner_key)
def test_set_get(self): config.init() config.wipe() self.assertEqual(config.unlock('', None), True) for _ in range(32): appid, key = random_entry() value = random.bytes(128) config.set(appid, key, value) value2 = config.get(appid, key) self.assertEqual(value, value2) # Test value deletion. self.assertTrue(config.delete(appid, key)) self.assertIsNone(config.get(appid, key)) self.assertFalse(config.delete(appid, key)) # Test get/set for APP out ouf range. with self.assertRaises(ValueError): config.set(0, 1, b'test') with self.assertRaises(ValueError): config.get(0, 1) with self.assertRaises(ValueError): config.set(192, 1, b'test') with self.assertRaises(ValueError): config.get(192, 1)
def test_public(self): config.init() config.wipe() self.assertEqual(config.unlock(pin_to_int('')), True) appid, key = random_entry() value32 = random.bytes(32) config.set(appid, key, value32) value16 = random.bytes(16) config.set(appid, key, value16, True) v1 = config.get(appid, key) v2 = config.get(appid, key, True) self.assertNotEqual(v1, v2) self.assertEqual(v1, value32) self.assertEqual(v2, value16) config.init() v1 = config.get(appid, key) v2 = config.get(appid, key, True) self.assertNotEqual(v1, v2) self.assertEqual(v1, None) self.assertEqual(v2, value16)
def test_get_default(self): config.init() config.wipe() self.assertEqual(config.unlock(pin_to_int(''), None), True) for _ in range(128): appid, key = random_entry() value = config.get(appid, key) self.assertEqual(value, bytes())
async def bootscreen(): while True: try: if not config.has_pin(): config.unlock(pin_to_int(""), show_pin_timeout) return await lockscreen() label = None while True: pin = await request_pin(label) if config.unlock(pin_to_int(pin), show_pin_timeout): return else: label = "Wrong PIN, enter again" except Exception as e: if __debug__: log.exception(__name__, e)
async def verify_user_pin( ctx: wire.GenericContext = wire.DUMMY_CONTEXT, prompt: str = "Enter your PIN", allow_cancel: bool = True, retry: bool = True, cache_time_ms: int = 0, ) -> None: last_unlock = _get_last_unlock_time() if ( cache_time_ms and last_unlock and utime.ticks_ms() - last_unlock <= cache_time_ms and config.is_unlocked() ): return if config.has_pin(): from trezor.ui.layouts import request_pin_on_device pin = await request_pin_on_device( ctx, prompt, config.get_pin_rem(), allow_cancel ) config.ensure_not_wipe_code(pin) else: pin = "" try: salt = await request_sd_salt(ctx) except SdCardUnavailable: raise wire.PinCancelled("SD salt is unavailable") if config.unlock(pin, salt): _set_last_unlock_time() return elif not config.has_pin(): raise RuntimeError while retry: pin = await request_pin_on_device( ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel ) if config.unlock(pin, salt): _set_last_unlock_time() return raise wire.PinInvalid
def test_change_pin(self): config.init() config.wipe() self.assertTrue(config.unlock('', None)) config.set(1, 1, b'value') PINS = ('123', '123', 'Trezor T', '3141592653589793238462643383279502884197', '') old_pin = '' for new_pin in PINS: self.assertTrue(config.unlock(old_pin, None)) # The APP namespace which is reserved for storage related values is inaccessible even # when unlocked. with self.assertRaises(ValueError): config.set(PINAPP, PINKEY, b'value') self.assertTrue(config.change_pin(old_pin, new_pin, None, None)) # Old PIN cannot be used to change the current PIN. if old_pin != new_pin: self.assertFalse(config.change_pin(old_pin, '666', None, None)) # Storage remains unlocked. self.assertEqual(config.get(1, 1), b'value') # The APP namespace which is reserved for storage related values is inaccessible even # when unlocked. with self.assertRaises(ValueError): config.get(PINAPP, PINKEY) # Old PIN cannot be used to unlock storage. if old_pin != new_pin: config.init() self.assertFalse(config.unlock(old_pin, None)) self.assertEqual(config.get(1, 1), None) with self.assertRaises(RuntimeError): config.set(1, 1, b'new value') # New PIN unlocks the storage. self.assertTrue(config.unlock(new_pin, None)) self.assertEqual(config.get(1, 1), b'value') # Lock the storage. config.init() old_pin = new_pin
def test_change_pin(self): config.init() config.wipe() self.assertEqual(config.unlock(pin_to_int('')), True) with self.assertRaises(RuntimeError): config.set(PINAPP, PINKEY, b'value') self.assertEqual( config.change_pin(pin_to_int('000'), pin_to_int('666')), False) self.assertEqual(config.change_pin(pin_to_int(''), pin_to_int('000')), True) self.assertEqual(config.get(PINAPP, PINKEY), None) config.set(1, 1, b'value') config.init() self.assertEqual(config.unlock(pin_to_int('000')), True) config.change_pin(pin_to_int('000'), pin_to_int('')) config.init() self.assertEqual(config.unlock(pin_to_int('000')), False) self.assertEqual(config.unlock(pin_to_int('')), True) self.assertEqual(config.get(1, 1), b'value')
async def unlock_layout(): while True: if config.has_pin(): pin = await request_pin() else: pin = '' if config.unlock(pin_to_int(pin), show_pin_timeout): return else: await unlock_failed()
async def bootscreen(): while True: try: if not config.has_pin(): config.unlock(pin_to_int("")) storage.init_unlocked() return await lockscreen() label = None while True: pin = await request_pin(label, config.get_pin_rem()) if config.unlock(pin_to_int(pin)): storage.init_unlocked() return else: label = "Wrong PIN, enter again" except Exception as e: if __debug__: log.exception(__name__, e)
def test_compact(self): config.init() config.wipe() self.assertEqual(config.unlock(pin_to_int(''), None), True) appid, key = 1, 1 for _ in range(259): value = random.bytes(259) config.set(appid, key, value) value2 = config.get(appid, key) self.assertEqual(value, value2)
def test_set_get(self): config.init() config.wipe() self.assertEqual(config.unlock(pin_to_int(''), None), True) for _ in range(32): appid, key = random_entry() value = random.bytes(128) config.set(appid, key, value) value2 = config.get(appid, key) self.assertEqual(value, value2)
def test_change_sd_salt(self): salt1 = b"0123456789abcdef0123456789abcdef" salt2 = b"0123456789ABCDEF0123456789ABCDEF" # Enable PIN and SD salt. config.init() config.wipe() self.assertTrue(config.unlock('', None)) config.set(1, 1, b'value') self.assertFalse(config.change_pin('', '', salt1, None)) self.assertTrue(config.change_pin('', '000', None, salt1)) self.assertEqual(config.get(1, 1), b'value') # Disable PIN and change SD salt. config.init() self.assertFalse(config.unlock('000', None)) self.assertIsNone(config.get(1, 1)) self.assertTrue(config.unlock('000', salt1)) self.assertTrue(config.change_pin('000', '', salt1, salt2)) self.assertEqual(config.get(1, 1), b'value') # Disable SD salt. config.init() self.assertFalse(config.unlock('000', salt2)) self.assertIsNone(config.get(1, 1)) self.assertTrue(config.unlock('', salt2)) self.assertTrue(config.change_pin('', '', salt2, None)) self.assertEqual(config.get(1, 1), b'value') # Check that PIN and SD salt are disabled. config.init() self.assertTrue(config.unlock('', None)) self.assertEqual(config.get(1, 1), b'value')
def test_lock(self): for _ in range(128): config.init() config.wipe() self.assertEqual(config.unlock(pin_to_int('')), True) appid, key = random_entry() value = random.bytes(16) config.set(appid, key, value) config.init() self.assertEqual(config.get(appid, key), None) with self.assertRaises(RuntimeError): config.set(appid, key, bytes()) config.init() config.wipe()
def test_wipe(self): config.init() config.wipe() self.assertEqual(config.unlock(pin_to_int(''), None), True) config.set(1, 1, b'hello') config.set(1, 2, b'world') v0 = config.get(1, 1) v1 = config.get(1, 2) self.assertEqual(v0, b'hello') self.assertEqual(v1, b'world') config.wipe() v0 = config.get(1, 1) v1 = config.get(1, 2) self.assertEqual(v0, bytes()) self.assertEqual(v1, bytes())
def test_counter(self): config.init() config.wipe() # Test writable_locked when storage is locked. config.lock() with self.assertRaises(RuntimeError): config.set_counter(1, 2, 0, False) with self.assertRaises(RuntimeError): config.next_counter(1, 2, False) config.set_counter(1, 2, 100, True) for i in range(100, 200): self.assertEqual(config.next_counter(1, 2, True), i + 1) # Test increment with storage unlocked. self.assertEqual(config.unlock('', None), True) for i in range(200, 300): self.assertEqual(config.next_counter(1, 2, True), i + 1) # Test counter deletion. config.delete(1, 2, True, True) self.assertEqual(config.next_counter(1, 2, True), 0) # Test overflow protection. with self.assertRaises(RuntimeError): config.set_counter(1, 2, 0x1_0000_0000, True) start = 0xFFFF_FFFF - 100 config.set_counter(1, 2, start, True) for i in range(start, 0xFFFF_FFFF): self.assertEqual(config.next_counter(1, 2, True), i + 1)
def test_sign_transaction(self): test_datasets = ( ( # Inputs: [ # KIDV: # idx, type, sub_idx, value [1, 1, 1, 2], [2, 2, 2, 5], ], # Outputs: [ # KIDV: # idx, type, sub_idx, value [3, 3, 3, 3], ], # Nonce slot: 2, # Kernel params: # fee, min_height, max_height, # commitment_x, commitment_y, # multisig_nonce_x, multisig_nonce_y, # offset_sk # expected_signature, expected_is_signed 1, 1, 5, "0x12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef", 0, "0x12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef", 0, "0x12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef", "614856ca69245fd9c6e8db15a256c050ca078e79a6f49e61e24688fdcad73bf6", True), ([ [1, 0, 1, 8], [2, 0, 0, 5], ], [ [1, 0, 1, 4], ], 2, 1, 1, 5, "0x12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef", 0, "0x12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef", 0, "0x12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef", "7c4fe694451b28159e5407714072acd1eae4da18aef1dfd42bb165405f529a04", True), ([ [0, 0, 0, 40], ], [ [0, 0, 0, 16], [0, 0, 0, 24], ], 1, 0, 25000, 27500, "0x12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef", 0, "0x12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef", 0, "0x12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef12abcdef", "60e3e9d87bd264bdcac4518284bd4f850561c3bb251bd758bb1349a44188a28c", True), ) config.init() config.wipe() config.unlock(pin_to_int('')) create_master_nonce(self.seed) for test_params in test_datasets: inputs = create_kidv_list_from(test_params[0]) outputs = create_kidv_list_from(test_params[1]) nonce_slot = test_params[2] fee = test_params[3] min_height = test_params[4] max_height = test_params[5] commitment_x = test_params[6] commitment_y = test_params[7] multisig_nonce_x = test_params[8] multisig_nonce_y = test_params[9] offset_sk = test_params[10] expected_signature = test_params[11] expected_is_signed = test_params[12] tm = beam.TransactionMaker() sk_total, value_transferred = sign_tx_part_1( tm, self.mnemonic, inputs, outputs, fee, min_height, max_height, commitment_x, commitment_y, multisig_nonce_x, multisig_nonce_y, nonce_slot, offset_sk) signature, is_signed = sign_tx_part_2(tm, sk_total, nonce_slot) self.assertEqual(bin_to_str(signature), expected_signature) self.assertEqual(is_signed, expected_is_signed)
usb.bus.open() import trezorio as io from trezorui import Display import storage import storage.resident_credentials from trezor import config d = Display() d.clear() d.backlight(255) config.init(False) salt = None config.unlock(1, salt) storage.init_unlocked() storage.cache.start_session() print("is_initialized: ", storage.device.is_initialized()) print("version: ", storage.device.is_version_stored()) print("version: ", storage.device.get_version()) print("needs backup: ", storage.device.needs_backup()) storage.device.set_backed_up() print("needs backup: ", storage.device.needs_backup()) flags = storage.device.get_flags() print("flags", flags) storage.device.set_flags(0x200) print("flags", storage.device.get_flags()) secret = "0" * 32 backup_type = 0