def test_sdcard_read(self):
     sd = io.SDCard()
     x = bytearray(8 * 512)
     sd.power(True)
     assert sd.read(0, x) is True
     sd.power(False)
     assert sd.read(0, x) is False
Exemple #2
0
async def set_sd_salt(
    ctx: Optional[wire.Context], salt: bytes, salt_tag: bytes, new: bool = False
) -> None:
    salt_path = _get_salt_path(new)

    while True:
        sd = io.SDCard()
        while not sd.power(True):
            await _insert_card_dialog(ctx)

        try:
            fs = io.FatFS()
            fs.mount()
            fs.mkdir("/trezor", True)
            fs.mkdir(_get_device_dir(), True)
            with fs.open(salt_path, "w") as f:
                f.write(salt)
                f.write(salt_tag)
            break
        except Exception:
            fs.unmount()
            sd.power(False)
            await _write_failed_dialog(ctx)

    fs.unmount()
    sd.power(False)
Exemple #3
0
async def set_sd_salt(ctx: Optional[wire.Context],
                      salt: bytes,
                      salt_tag: bytes,
                      filename: str = "salt") -> None:
    device_dir = "/trezor/device_%s" % storage.device.get_device_id()
    salt_path = "%s/%s" % (device_dir, filename)

    sd = io.SDCard()
    fs = io.FatFS()
    if not sd.power(True):
        await insert_card_dialog(ctx)
        raise SdProtectCancelled

    try:
        fs.mount()

        try:
            fs.mkdir("/trezor")
        except OSError:
            # Directory already exists.
            pass

        try:
            fs.mkdir(device_dir)
        except OSError:
            # Directory already exists.
            pass

        with fs.open(salt_path, "w") as f:
            f.write(salt)
            f.write(salt_tag)
    finally:
        fs.unmount()
        sd.power(False)
Exemple #4
0
 def test_read(self):
     sd = io.SDCard()
     x = bytearray(8 * 512)
     sd.power(True)
     sd.read(0, x)
     sd.power(False)
     with self.assertRaises(OSError):
         sd.read(0, x)
Exemple #5
0
def get_features() -> Features:
    f = Features()
    f.vendor = "trezor.io"
    f.language = "en-US"
    f.major_version = utils.VERSION_MAJOR
    f.minor_version = utils.VERSION_MINOR
    f.patch_version = utils.VERSION_PATCH
    f.revision = utils.GITREV.encode()
    f.model = utils.MODEL
    f.device_id = storage.device.get_device_id()
    f.label = storage.device.get_label()
    f.initialized = storage.is_initialized()
    f.pin_protection = config.has_pin()
    f.pin_cached = config.has_pin()
    f.passphrase_protection = storage.device.is_passphrase_enabled()
    f.needs_backup = storage.device.needs_backup()
    f.unfinished_backup = storage.device.unfinished_backup()
    f.no_backup = storage.device.no_backup()
    f.flags = storage.device.get_flags()
    f.recovery_mode = storage.recovery.is_in_progress()
    f.backup_type = mnemonic.get_type()
    if utils.BITCOIN_ONLY:
        f.capabilities = [
            Capability.Bitcoin,
            Capability.Crypto,
            Capability.Shamir,
            Capability.ShamirGroups,
            Capability.PassphraseEntry,
        ]
    else:
        f.capabilities = [
            Capability.Bitcoin,
            Capability.Bitcoin_like,
            Capability.Binance,
            Capability.Cardano,
            Capability.Crypto,
            Capability.EOS,
            Capability.Ethereum,
            Capability.Lisk,
            Capability.Monero,
            Capability.NEM,
            Capability.Ripple,
            Capability.Stellar,
            Capability.Tezos,
            Capability.U2F,
            Capability.Shamir,
            Capability.ShamirGroups,
            Capability.PassphraseEntry,
        ]
    f.sd_card_present = io.SDCard().present()
    f.sd_protection = storage.sd_salt.is_enabled()
    f.wipe_code_protection = config.has_wipe_code()
    f.session_id = cache.get_session_id()
    f.passphrase_always_on_device = storage.device.get_passphrase_always_on_device(
    )
    return f
 def test_sdcard_power(self):
     sd = io.SDCard()
     x = bytearray(8 * 512)
     assert sd.capacity() == 0
     assert sd.read(0, x) is False
     sd.power(True)
     assert sd.capacity() > 0
     assert sd.read(0, x) is True
     sd.power(False)
     assert sd.capacity() == 0
     assert sd.read(0, x) is False
 def test_sdcard_read_write(self):
     sd = io.SDCard()
     r = bytearray(8 * 512)
     w0 = bytearray(b'0' * (8 * 512))
     w1 = bytearray(b'1' * (8 * 512))
     sd.power(True)
     assert sd.write(0, w0) is True
     assert sd.read(0, r) is True
     assert r == w0
     assert sd.write(0, w1) is True
     assert sd.read(0, r) is True
     assert r == w1
     sd.power(False)
Exemple #8
0
 def test_power(self):
     sd = io.SDCard()
     x = bytearray(8 * 512)
     self.assertEqual(sd.capacity(), 0)
     with self.assertRaises(OSError):
         sd.read(0, x)
     sd.power(True)
     self.assertTrue(sd.capacity() > 0)
     sd.read(0, x)
     sd.power(False)
     self.assertEqual(sd.capacity(), 0)
     with self.assertRaises(OSError):
         sd.read(0, x)
Exemple #9
0
 def test_read_write(self):
     sd = io.SDCard()
     r = bytearray(8 * 512)
     w0 = bytearray(b'0' * (8 * 512))
     w1 = bytearray(b'1' * (8 * 512))
     sd.power(True)
     sd.write(0, w0)
     sd.read(0, r)
     self.assertEqual(r, w0)
     sd.write(0, w1)
     sd.read(0, r)
     self.assertEqual(r, w1)
     sd.power(False)
Exemple #10
0
async def remove_sd_salt(ctx: Optional[wire.Context]) -> None:
    salt_path = _get_salt_path()

    sd = io.SDCard()
    fs = io.FatFS()
    if not sd.power(True):
        raise OSError

    try:
        fs.mount()
        # TODO Possibly overwrite salt file with random data.
        fs.unlink(salt_path)
    finally:
        fs.unmount()
        sd.power(False)
Exemple #11
0
async def remove_sd_salt(ctx: Optional[wire.Context]) -> None:
    salt_path = _get_salt_path()

    sd = io.SDCard()
    fs = io.FatFS()
    if not sd.power(True):
        await _insert_card_dialog(ctx)
        raise SdProtectCancelled

    try:
        fs.mount()
        # TODO Possibly overwrite salt file with random data.
        fs.unlink(salt_path)
    finally:
        fs.unmount()
        sd.power(False)
Exemple #12
0
async def remove_sd_salt(ctx: Optional[wire.Context]) -> None:
    device_dir = "/trezor/device_%s" % storage.device.get_device_id()
    salt_path = "%s/salt" % device_dir

    sd = io.SDCard()
    fs = io.FatFS()
    if not sd.power(True):
        await insert_card_dialog(ctx)
        raise SdProtectCancelled

    try:
        fs.mount()
        # TODO Possibly overwrite salt file with random data.
        fs.unlink(salt_path)
    finally:
        fs.unmount()
        sd.power(False)
Exemple #13
0
async def request_sd_salt(
    ctx: Optional[wire.Context], salt_auth_key: bytes
) -> bytearray:
    salt_path = _get_salt_path()
    new_salt_path = _get_salt_path(True)

    while True:
        sd = io.SDCard()
        fs = io.FatFS()
        while not sd.power(True):
            await _insert_card_dialog(ctx)

        try:
            fs.mount()
            salt = _load_salt(fs, salt_auth_key, salt_path)
            if salt is not None:
                return salt

            # Check if there is a new salt.
            salt = _load_salt(fs, salt_auth_key, new_salt_path)
            if salt is not None:
                # SD salt regeneration was interrupted earlier. Bring into consistent state.
                # TODO Possibly overwrite salt file with random data.
                try:
                    fs.unlink(salt_path)
                except OSError:
                    pass

                try:
                    fs.rename(new_salt_path, salt_path)
                except OSError:
                    error_dialog = _write_failed_dialog(ctx)
                else:
                    return salt
            else:
                # No valid salt file on this SD card.
                error_dialog = _wrong_card_dialog(ctx)
        finally:
            fs.unmount()
            sd.power(False)

        await error_dialog
Exemple #14
0
async def commit_sd_salt(ctx: Optional[wire.Context]) -> None:
    salt_path = _get_salt_path()
    new_salt_path = _get_salt_path(True)

    sd = io.SDCard()
    fs = io.FatFS()
    if not sd.power(True):
        raise OSError

    try:
        fs.mount()
        # TODO Possibly overwrite salt file with random data.
        try:
            fs.unlink(salt_path)
        except OSError:
            pass
        fs.rename(new_salt_path, salt_path)
    finally:
        fs.unmount()
        sd.power(False)
    def wrapped_func(*args, **kwargs):  # type: ignore
        global _ensure_filesystem_nesting_counter

        sd = io.SDCard()
        if _ensure_filesystem_nesting_counter == 0:
            if not sd.power(True):
                raise OSError

        try:
            _ensure_filesystem_nesting_counter += 1
            fs = io.FatFS()
            fs.mount()
            # XXX do we need to differentiate failure types?
            # If yes, can the problem be derived from the type of OSError raised?
            return func(*args, **kwargs)
        finally:
            _ensure_filesystem_nesting_counter -= 1
            assert _ensure_filesystem_nesting_counter >= 0
            if _ensure_filesystem_nesting_counter == 0:
                fs.unmount()
                sd.power(False)
Exemple #16
0
async def set_sd_salt(ctx: Optional[wire.Context],
                      salt: bytes,
                      salt_tag: bytes,
                      new: bool = False) -> None:
    salt_path = _get_salt_path(new)

    sd = io.SDCard()
    if not sd.power(True):
        await _insert_card_dialog(ctx)
        raise SdProtectCancelled

    fs = io.FatFS()

    try:
        fs.mount()
        fs.mkdir("/trezor", True)
        fs.mkdir(_get_device_dir(), True)
        with fs.open(salt_path, "w") as f:
            f.write(salt)
            f.write(salt_tag)
    finally:
        fs.unmount()
        sd.power(False)
Exemple #17
0
    ui.display.bar_radius(42, 102, 156, 36, ui.BG, ui.TITLE_GREY, 4)
    ui.display.text_center(ui.WIDTH // 2, 128, "Locked", ui.BOLD,
                           ui.TITLE_GREY, ui.BG)

    ui.display.text_center(ui.WIDTH // 2 + 10, 220, "Tap to unlock", ui.BOLD,
                           ui.TITLE_GREY, ui.BG)
    ui.display.icon(45, 202, res.load(ui.ICON_CLICK), ui.TITLE_GREY, ui.BG)

    ui.backlight_fade(ui.BACKLIGHT_NORMAL)

    await ui.click()


if utils.EMULATOR:
    # Ensure the emulated SD card is FAT32 formatted.
    sd = io.SDCard()
    sd.power(True)
    fs = io.FatFS()
    try:
        fs.mount()
    except OSError:
        fs.mkfs()
    else:
        fs.unmount()
    sd.power(False)

ui.display.backlight(ui.BACKLIGHT_NONE)
ui.backlight_fade(ui.BACKLIGHT_NORMAL)
config.init(show_pin_timeout)
loop.schedule(bootscreen())
loop.run()
Exemple #18
0
 def test_sdcard(self):
     sd = io.SDCard()
     sd.present()
Exemple #19
0
async def request_sd_salt(ctx: Optional[wire.Context],
                          salt_auth_key: bytes) -> bytearray:
    salt_path = _get_salt_path()
    new_salt_path = _get_salt_path(True)

    sd = io.SDCard()
    fs = io.FatFS()
    if not sd.power(True):
        await _insert_card_dialog(ctx)
        raise SdProtectCancelled

    try:
        fs.mount()

        # Load salt if it exists.
        try:
            with fs.open(salt_path, "r") as f:
                salt = bytearray(
                    SD_SALT_LEN_BYTES)  # type: Optional[bytearray]
                salt_tag = bytearray(SD_SALT_AUTH_TAG_LEN_BYTES)
                f.read(salt)
                f.read(salt_tag)
        except OSError:
            salt = None

        if salt is not None and consteq(
                hmac.new(salt_auth_key, salt,
                         sha256).digest()[:SD_SALT_AUTH_TAG_LEN_BYTES],
                salt_tag,
        ):
            return salt

        # Load salt.new if it exists.
        try:
            with fs.open(new_salt_path, "r") as f:
                new_salt = bytearray(
                    SD_SALT_LEN_BYTES)  # type: Optional[bytearray]
                new_salt_tag = bytearray(SD_SALT_AUTH_TAG_LEN_BYTES)
                f.read(new_salt)
                f.read(new_salt_tag)
        except OSError:
            new_salt = None

        if new_salt is not None and consteq(
                hmac.new(salt_auth_key, new_salt,
                         sha256).digest()[:SD_SALT_AUTH_TAG_LEN_BYTES],
                new_salt_tag,
        ):
            # SD salt regeneration was interrupted earlier. Bring into consistent state.
            # TODO Possibly overwrite salt file with random data.
            try:
                fs.unlink(salt_path)
            except OSError:
                pass
            fs.rename(new_salt_path, salt_path)
            return new_salt
    finally:
        fs.unmount()
        sd.power(False)

    await _wrong_card_dialog(ctx)
    raise SdProtectCancelled
 def setUp(self):
     self.sd = io.SDCard()
     self.sd.power(True)
     self.fs = io.FatFS()
     self.fs.mkfs()
     self.fs.mount()
 def test_sdcard_start(self):
     sd = io.SDCard()
     assert sd.present() is True
Exemple #22
0
 def test_start(self):
     sd = io.SDCard()
     self.assertTrue(sd.present())
async def ensure_sd_card(ctx: wire.GenericContext) -> None:
    sd = io.SDCard()
    while not sd.present():
        if not await insert_card_dialog(ctx):
            raise SdProtectCancelled("SD card required.")