Exemple #1
0
def load_settings(
    label: str = None,
    use_passphrase: bool = None,
    homescreen: bytes = None,
    passphrase_source: int = None,
    display_rotation: int = None,
) -> None:
    if label is not None:
        config.set(_APP, _LABEL, label.encode(), True)  # public
    if use_passphrase is not None:
        _set_bool(_APP, _USE_PASSPHRASE, use_passphrase)
    if homescreen is not None:
        if homescreen[:8] == b"TOIf\x90\x00\x90\x00":
            if len(homescreen) <= HOMESCREEN_MAXSIZE:
                config.set(_APP, _HOMESCREEN, homescreen, True)  # public
        else:
            config.set(_APP, _HOMESCREEN, b"", True)  # public
    if passphrase_source is not None:
        if passphrase_source in (0, 1, 2):
            config.set(_APP, _PASSPHRASE_SOURCE, bytes([passphrase_source]))
    if display_rotation is not None:
        if display_rotation not in (0, 90, 180, 270):
            raise ValueError("Unsupported display rotation degrees: %d" %
                             display_rotation)
        else:
            config.set(_APP, _ROTATION, display_rotation.to_bytes(2, "big"),
                       True)  # public
Exemple #2
0
    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_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_set_get(self):
     config.wipe()
     for _ in range(64):
         appid, key = random.uniform(256), random.uniform(256)
         value = random.bytes(128)
         config.set(appid, key, value)
         value2 = config.get(appid, key)
         self.assertEqual(value, value2)
Exemple #5
0
def store_mnemonic(
    secret: bytes,
    mnemonic_type: int,
    needs_backup: bool = False,
    no_backup: bool = False,
) -> None:
    config.set(_APP, _MNEMONIC_SECRET, secret)
    _set_uint8(_APP, _MNEMONIC_TYPE, mnemonic_type)
    _init(needs_backup, no_backup)
Exemple #6
0
def set_flags(flags: int) -> None:
    b = config.get(_APP, _FLAGS)
    if b is None:
        b = 0
    else:
        b = int.from_bytes(b, "big")
    flags = (flags | b) & 0xFFFFFFFF
    if flags != b:
        config.set(_APP, _FLAGS, flags.to_bytes(4, "big"))
Exemple #7
0
def store_mnemonic(
    secret: bytes, mnemonic_type: int, needs_backup: bool, no_backup: bool
) -> None:
    config.set(_APP, _MNEMONIC_SECRET, secret)
    _set_uint8(_APP, _MNEMONIC_TYPE, mnemonic_type)
    config.set(_APP, _VERSION, _STORAGE_VERSION)
    _set_bool(_APP, _NO_BACKUP, no_backup)
    if not no_backup:
        _set_bool(_APP, _NEEDS_BACKUP, needs_backup)
Exemple #8
0
def create_nonce(idx):
    if idx != get_master_nonce_idx():
        old_nonce = config.get(beam_app_id(), idx)
        new_nonce = bytearray(32)
        if old_nonce:
                new_nonce = bytearray(old_nonce)
        master_nonce = config.get(beam_app_id(), get_master_nonce_idx())
        beam.create_derived_nonce(master_nonce, idx, new_nonce)
        config.set(beam_app_id(), idx, new_nonce)
        return old_nonce, new_nonce
 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)
Exemple #11
0
def init_unlocked():
    # Check for storage version upgrade.
    version = config.get(_APP, _VERSION)
    if version == b"\x01":
        # Make the U2F counter public and writable even when storage is locked.
        counter = config.get(_APP, _U2F_COUNTER)
        if counter is not None:
            config.set_counter(_APP, _U2F_COUNTER, counter,
                               True)  # writable when locked
            config.delete(_APP, _U2F_COUNTER)
        config.set(_APP, _VERSION, _STORAGE_VERSION)
Exemple #12
0
def load_settings(label: str=None, use_passphrase: bool=None, homescreen: bytes=None) -> None:
    if label is not None:
        config.set(_APP, _LABEL, label.encode(), True)  # public
    if use_passphrase is True:
        config.set(_APP, _USE_PASSPHRASE, b'\x01')
    if use_passphrase is False:
        config.set(_APP, _USE_PASSPHRASE, b'')
    if homescreen is not None:
        if homescreen[:8] == b'TOIf\x90\x00\x90\x00':
            config.set(_APP, _HOMESCREEN, homescreen, True)  # public
        else:
            config.set(_APP, _HOMESCREEN, b'', True)  # public
 def test_wipe(self):
     config.wipe()
     config.set(0, 0, b'hello')
     config.set(1, 1, b'world')
     v0 = config.get(0, 0)
     v1 = config.get(1, 1)
     self.assertEqual(v0, b'hello')
     self.assertEqual(v1, b'world')
     config.wipe()
     v0 = config.get(0, 0)
     v1 = config.get(1, 1)
     self.assertEqual(v0, bytes())
     self.assertEqual(v1, bytes())
 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()
Exemple #15
0
def load_mnemonic(mnemonic: str, needs_backup: bool) -> None:
    config.set(_APP, _MNEMONIC, mnemonic.encode())
    config.set(_APP, _VERSION, _STORAGE_VERSION)
    if needs_backup:
        config.set(_APP, _NEEDS_BACKUP, b'\x01')
    else:
        config.set(_APP, _NEEDS_BACKUP, b'')
 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_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')
Exemple #18
0
    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)
Exemple #19
0
def load_settings(
    label: str = None,
    use_passphrase: bool = None,
    homescreen: bytes = None,
    passphrase_source: int = None,
) -> None:
    if label is not None:
        config.set(_APP, _LABEL, label.encode(), True)  # public
    if use_passphrase is not None:
        _set_bool(_APP, _USE_PASSPHRASE, use_passphrase)
    if homescreen is not None:
        if homescreen[:8] == b"TOIf\x90\x00\x90\x00":
            if len(homescreen) <= HOMESCREEN_MAXSIZE:
                config.set(_APP, _HOMESCREEN, homescreen, True)  # public
        else:
            config.set(_APP, _HOMESCREEN, b"", True)  # public
    if passphrase_source is not None:
        if passphrase_source in [0, 1, 2]:
            config.set(_APP, _PASSPHRASE_SOURCE, bytes([passphrase_source]))
Exemple #20
0
    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
Exemple #21
0
def get_device_id() -> str:
    dev_id = config.get(_APP, _DEVICE_ID, True).decode()  # public
    if not dev_id:
        dev_id = _new_device_id()
        config.set(_APP, _DEVICE_ID, dev_id.encode(), True)  # public
    return dev_id
Exemple #22
0
def set_u2f_counter(cntr: int):
    config.set(_APP, _U2F_COUNTER, cntr.to_bytes(4, "big"))
Exemple #23
0
def set_autolock_delay_ms(delay_ms: int) -> None:
    if delay_ms < 60 * 1000:
        delay_ms = 60 * 1000
    config.set(_APP, _AUTOLOCK_DELAY_MS, delay_ms.to_bytes(4, "big"))
Exemple #24
0
def _set_bool(app: int, key: int, value: bool, public: bool = False) -> None:
    if value:
        config.set(app, key, _TRUE_BYTE, public)
    else:
        config.set(app, key, _FALSE_BYTE, public)
Exemple #25
0
def _set_uint16(app: int, key: int, val: int):
    config.set(app, key, val.to_bytes(2, "big"))
Exemple #26
0
def set_backed_up() -> None:
    config.set(_APP, _NEEDS_BACKUP, b"")
Exemple #27
0
def set_slip39_mnemonic(index: int, mnemonic: str):
    config.set(_SLIP39_MNEMONICS, index, mnemonic.encode())
Exemple #28
0
def set(app: int, key: int, data: bytes, public: bool = False) -> None:
    config.set(app, key, data, public)
Exemple #29
0
def set_unfinished_backup(state: bool) -> None:
    if state:
        config.set(_APP, _UNFINISHED_BACKUP, b"\x01")
    else:
        config.set(_APP, _UNFINISHED_BACKUP, b"")
Exemple #30
0
def _init(needs_backup=False, no_backup=False):
    config.set(_APP, _VERSION, _STORAGE_VERSION)
    _set_bool(_APP, _NO_BACKUP, no_backup)
    if not no_backup:
        _set_bool(_APP, _NEEDS_BACKUP, needs_backup)