コード例 #1
0
    def test_apply_settings(self):
        self.setup_mnemonic_pin_passphrase()
        assert self.client.features.label == "test"

        with self.client:
            self.client.set_expected_responses([
                proto.PinMatrixRequest(),
                proto.ButtonRequest(),
                proto.Success(),
                proto.Features(),
            ])
            if self.client.features.major_version >= 2:
                self.client.expected_responses.pop(0)  # skip PinMatrixRequest
            device.apply_settings(self.client, label="new label")

        assert self.client.features.label == "new label"
コード例 #2
0
def test_set_pin_to_wipe_code(client):
    # Set wipe code.
    with client:
        client.set_expected_responses(
            [messages.ButtonRequest()] * 4 +
            [messages.Success(), messages.Features()])
        client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4])
        device.change_wipe_code(client)

    # Try to set the PIN to the current wipe code value.
    with client, pytest.raises(TrezorFailure):
        client.set_expected_responses(
            [messages.ButtonRequest()] * 4 +
            [messages.Failure(code=messages.FailureType.PinInvalid)])
        client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4])
        device.change_pin(client)
コード例 #3
0
def test_skip_backup_manual(client, backup_type, backup_flow):
    def reset_skip_input_flow():
        yield  # Confirm Recovery
        client.debug.press_yes()

        yield  # Skip Backup
        client.debug.press_no()

        yield  # Confirm skip backup
        client.debug.press_no()

    os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
    with mock.patch("os.urandom", os_urandom), client:
        client.set_input_flow(reset_skip_input_flow)
        client.set_expected_responses([
            messages.ButtonRequest(code=B.ResetDevice),
            messages.EntropyRequest(),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.Success(),
            messages.Features(),
        ])
        device.reset(
            client,
            pin_protection=False,
            passphrase_protection=False,
            backup_type=backup_type,
        )

    assert client.features.initialized is True
    assert client.features.needs_backup is True
    assert client.features.unfinished_backup is False
    assert client.features.no_backup is False
    assert client.features.backup_type is backup_type

    secret = backup_flow(client)

    client.init_device()
    assert client.features.initialized is True
    assert client.features.needs_backup is False
    assert client.features.unfinished_backup is False
    assert client.features.backup_type is backup_type

    assert secret is not None
    state = client.debug.state()
    assert state.mnemonic_type is backup_type
    assert state.mnemonic_secret == secret
コード例 #4
0
def test_set_pin(client):
    assert client.features.pin_protection is False

    # Check that there's no PIN protection
    _check_no_pin(client)

    # Let's set new PIN
    with client:
        client.use_pin_sequence([PIN6, PIN6])
        client.set_expected_responses(
            [messages.ButtonRequest()] * 4 +
            [messages.Success(), messages.Features()])
        device.change_pin(client)

    client.init_device()
    assert client.features.pin_protection is True
    _check_pin(client, PIN6)
コード例 #5
0
def backup_flow_slip39_basic(client):
    mnemonics = []

    def input_flow():
        # 1. Checklist
        # 2. Number of shares (5)
        # 3. Checklist
        # 4. Threshold (3)
        # 5. Checklist
        # 6. Confirm show seeds
        yield from click_through(client.debug, screens=6, code=B.ResetDevice)

        # Mnemonic phrases
        for _ in range(5):
            yield  # Phrase screen
            mnemonic = read_and_confirm_mnemonic(client.debug, words=20)
            mnemonics.append(mnemonic)
            yield  # Confirm continue to next
            client.debug.press_yes()

        # Confirm backup
        yield
        client.debug.press_yes()

    with client:
        client.set_input_flow(input_flow)
        client.set_expected_responses(
            [messages.ButtonRequest(code=B.ResetDevice)] * 6  # intro screens
            + [
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.Success),
            ] * 5  # individual shares
            + [
                messages.ButtonRequest(code=B.Success),
                messages.Success(),
                messages.Features(),
            ])
        device.backup(client)

    mnemonics = mnemonics[:3]
    ms = shamir.combine_mnemonics(mnemonics)
    identifier, iteration_exponent, _, _, _ = shamir._decode_mnemonics(
        mnemonics)
    secret = shamir._encrypt(ms, b"", iteration_exponent, identifier)
    return secret
コード例 #6
0
def test_remove_pin(client):
    assert client.features.pin_protection is True

    # Check current PIN value
    _check_pin(client, PIN4)

    # Let's remove PIN
    with client:
        client.use_pin_sequence([PIN4])
        client.set_expected_responses(
            [messages.ButtonRequest()] * 3 +
            [messages.Success(), messages.Features()])
        device.change_pin(client, remove=True)

    # Check that there's no PIN protection now
    client.init_device()
    assert client.features.pin_protection is False
    _check_no_pin(client)
コード例 #7
0
def test_change_pin(client):
    assert client.features.pin_protection is True

    # Check current PIN value
    _check_pin(client, PIN4)

    # Let's change PIN
    with client:
        client.use_pin_sequence([PIN4, PIN6, PIN6])
        client.set_expected_responses(
            [messages.ButtonRequest()] * 5 +
            [messages.Success(), messages.Features()])
        device.change_pin(client)

    # Check that there's still PIN protection now
    client.init_device()
    assert client.features.pin_protection is True
    # Check that the PIN is correct
    _check_pin(client, PIN6)
コード例 #8
0
    def test_reset_device(self, client):
        with client:
            client.set_expected_responses(
                [proto.ButtonRequest()] + [proto.EntropyRequest()] +
                [proto.ButtonRequest()] * 24 +
                [proto.Success(), proto.Features()])
            device.reset(client, False, 128, True, False, "label", "en-US")

        with pytest.raises(TrezorFailure):
            # This must fail, because device is already initialized
            # Using direct call because `device.reset` has its own check
            client.call(
                proto.ResetDevice(
                    display_random=False,
                    strength=128,
                    passphrase_protection=True,
                    pin_protection=False,
                    label="label",
                    language="en-US",
                ))
コード例 #9
0
def test_remove_pin(client):
    assert client.features.pin_protection is True
    # Check that there's PIN protection
    _check_pin(client, PIN4)

    # Let's remove PIN
    with client:
        client.use_pin_sequence([PIN4])
        client.set_expected_responses([
            messages.ButtonRequest(
                code=messages.ButtonRequestType.ProtectCall),
            messages.PinMatrixRequest(),
            messages.Success(),
            messages.Features(),
        ])
        device.change_pin(client, remove=True)

    # Check that there's no PIN protection now
    assert client.features.pin_protection is False
    _check_no_pin(client)
コード例 #10
0
    def test_apply_auto_lock_delay(self):
        self.setup_mnemonic_pin_passphrase()

        with self.client:
            self.client.set_expected_responses([proto.PinMatrixRequest(),
                                                proto.ButtonRequest(),
                                                proto.Success(),
                                                proto.Features()])
            self.client.apply_settings(auto_lock_delay_ms=int(10e3))  # 10 secs

        time.sleep(0.1)  # sleep less than auto-lock delay
        with self.client:
            # No PIN protection is required.
            self.client.set_expected_responses([proto.Success()])
            self.client.ping(msg='', pin_protection=True)

        time.sleep(10.1)  # sleep more than auto-lock delay
        with self.client:
            self.client.set_expected_responses([proto.PinMatrixRequest(),
                                                proto.Success()])
            self.client.ping(msg='', pin_protection=True)
コード例 #11
0
    def test_recovery_device(self, client):
        client.set_mnemonic(MNEMONIC12)
        with client:
            client.set_expected_responses(
                [proto.ButtonRequest()] + [proto.WordRequest()] * 24 +
                [proto.Success(), proto.Features()])

            device.recover(client, 12, False, False, "label", "en-US",
                           client.mnemonic_callback)

        with pytest.raises(TrezorFailure):
            # This must fail, because device is already initialized
            # Using direct call because `device.reset` has its own check
            client.call(
                proto.RecoveryDevice(
                    word_count=12,
                    passphrase_protection=False,
                    pin_protection=False,
                    label="label",
                    language="en-US",
                ))
コード例 #12
0
    def test_load_device(self):
        with self.client:
            self.client.set_expected_responses(
                [proto.ButtonRequest(),
                 proto.Success(),
                 proto.Features()])
            self.client.load_device_by_mnemonic('this is mnemonic',
                                                '1234',
                                                True,
                                                'label',
                                                'english',
                                                skip_checksum=True)

        # This must fail, because device is already initialized
        with pytest.raises(Exception):
            self.client.load_device_by_mnemonic('this is mnemonic',
                                                '1234',
                                                True,
                                                'label',
                                                'english',
                                                skip_checksum=True)
コード例 #13
0
def recover(client, mnemonic):
    debug = client.debug
    words = mnemonic.split(" ")

    def input_flow():
        yield  # Confirm recovery
        debug.press_yes()
        yield  # Homescreen
        debug.press_yes()

        yield  # Enter word count
        debug.input(str(len(words)))

        yield  # Homescreen
        debug.press_yes()
        yield  # Enter words
        for word in words:
            debug.input(word)

        yield  # confirm success
        debug.press_yes()

    with client:
        client.set_input_flow(input_flow)
        client.set_expected_responses([
            messages.ButtonRequest(code=B.ProtectCall),
            messages.ButtonRequest(code=B.RecoveryHomepage),
            messages.ButtonRequest(code=B.MnemonicWordCount),
            messages.ButtonRequest(code=B.RecoveryHomepage),
            messages.ButtonRequest(code=B.MnemonicInput),
            messages.ButtonRequest(code=B.Success),
            messages.Success(),
            messages.Features(),
        ])
        ret = device.recover(client, pin_protection=False, label="label")

    # Workflow successfully ended
    assert ret == messages.Success(message="Device recovered")
    assert client.features.pin_protection is False
    assert client.features.passphrase_protection is False
コード例 #14
0
def _set_wipe_code(client, pin, wipe_code):
    # Set/change wipe code.
    with client:
        if client.features.pin_protection:
            pins = [pin, wipe_code, wipe_code]
            pin_matrices = [
                messages.PinMatrixRequest(type=PinType.Current),
                messages.PinMatrixRequest(type=PinType.WipeCodeFirst),
                messages.PinMatrixRequest(type=PinType.WipeCodeSecond),
            ]
        else:
            pins = [wipe_code, wipe_code]
            pin_matrices = [
                messages.PinMatrixRequest(type=PinType.WipeCodeFirst),
                messages.PinMatrixRequest(type=PinType.WipeCodeSecond),
            ]

        client.use_pin_sequence(pins)
        client.set_expected_responses(
            [messages.ButtonRequest()] + pin_matrices +
            [messages.Success(), messages.Features()])
        device.change_wipe_code(client)
コード例 #15
0
def test_change_pin(client):
    assert client.features.pin_protection is True
    # Check that there's PIN protection
    _check_pin(client, PIN4)

    # Let's change PIN
    with client:
        client.use_pin_sequence([PIN4, PIN6, PIN6])
        client.set_expected_responses([
            messages.ButtonRequest(
                code=messages.ButtonRequestType.ProtectCall),
            messages.PinMatrixRequest(),
            messages.PinMatrixRequest(),
            messages.PinMatrixRequest(),
            messages.Success(),
            messages.Features(),
        ])
        device.change_pin(client)

    # Check that there's still PIN protection now
    assert client.features.pin_protection is True
    # Check that the PIN is correct
    _check_pin(client, PIN6)
def test_wipe_code_activate(client):
    import time

    device_id = client.features.device_id

    # Set wipe code.
    with client:
        client.set_expected_responses(
            [messages.ButtonRequest()] * 5 +
            [messages.Success(), messages.Features()])
        client.set_input_flow(
            _input_flow_set_wipe_code(client.debug, PIN4, WIPE_CODE4))

        device.change_wipe_code(client)

    # Try to change the PIN.
    ret = client.call_raw(messages.ChangePin(remove=False))

    # Confirm change PIN.
    assert isinstance(ret, messages.ButtonRequest)
    client.debug.press_yes()
    ret = client.call_raw(messages.ButtonAck())

    # Enter the wipe code instead of the current PIN
    assert ret == messages.ButtonRequest(code=messages.ButtonRequestType.Other)
    client.debug.input(WIPE_CODE4)
    client._raw_write(messages.ButtonAck())

    # Allow the device to display wipe code popup and restart.
    time.sleep(7)

    # Check that the device has been wiped.
    client.init_device()
    assert client.features.initialized is False
    assert client.features.pin_protection is False
    assert client.features.wipe_code_protection is False
    assert client.features.device_id != device_id
コード例 #17
0
def backup_flow_bip39(client):
    mnemonic = None

    def input_flow():
        nonlocal mnemonic

        # 1. Confirm Reset
        yield from click_through(client.debug, screens=1, code=B.ResetDevice)

        # mnemonic phrases
        btn_code = yield
        assert btn_code == B.ResetDevice
        mnemonic = read_and_confirm_mnemonic(client.debug, words=12)

        # confirm recovery seed check
        btn_code = yield
        assert btn_code == B.Success
        client.debug.press_yes()

        # confirm success
        btn_code = yield
        assert btn_code == B.Success
        client.debug.press_yes()

    with client:
        client.set_expected_responses([
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.Success),
            messages.Success(),
            messages.Features(),
        ])
        client.set_input_flow(input_flow)
        device.backup(client)

    return mnemonic.encode()
コード例 #18
0
def test_backup_bip39(client):
    assert client.features.needs_backup is True
    mnemonic = None

    def input_flow():
        nonlocal mnemonic
        yield  # Confirm Backup
        client.debug.press_yes()
        yield  # Mnemonic phrases
        mnemonic = read_and_confirm_mnemonic(client.debug, words=12)
        yield  # Confirm success
        client.debug.press_yes()
        yield  # Backup is done
        client.debug.press_yes()

    with client:
        client.set_input_flow(input_flow)
        client.set_expected_responses(
            [
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.Success),
                messages.ButtonRequest(code=B.Success),
                messages.Success(),
                messages.Features(),
            ]
        )
        device.backup(client)

    assert mnemonic == MNEMONIC12
    client.init_device()
    assert client.features.initialized is True
    assert client.features.needs_backup is False
    assert client.features.unfinished_backup is False
    assert client.features.no_backup is False
    assert client.features.backup_type is messages.BackupType.Bip39
コード例 #19
0
    def test_reset_device_shamir(self):
        strength = 128
        member_threshold = 3

        def input_flow():
            # Confirm Reset
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # Backup your seed
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # Confirm warning
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # shares info
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # Set & Confirm number of shares
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # threshold info
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # Set & confirm threshold value
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # Confirm show seeds
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # show & confirm shares
            all_mnemonics = []
            for h in range(5):
                words = []
                btn_code = yield
                assert btn_code == B.Other

                # mnemonic phrases
                # 20 word over 6 pages for strength 128, 33 words over 9 pages for strength 256
                for i in range(6):
                    words.extend(self.client.debug.read_reset_word().split())
                    if i < 5:
                        self.client.debug.swipe_down()
                    else:
                        # last page is confirmation
                        self.client.debug.press_yes()

                # check share
                for _ in range(3):
                    index = self.client.debug.read_reset_word_pos()
                    self.client.debug.input(words[index])

                all_mnemonics.extend([" ".join(words)])

                # Confirm continue to next share
                btn_code = yield
                assert btn_code == B.Success
                self.client.debug.press_yes()

            # generate secret locally
            internal_entropy = self.client.debug.state().reset_entropy
            secret = generate_entropy(strength, internal_entropy,
                                      EXTERNAL_ENTROPY)

            # validate that all combinations will result in the correct master secret
            validate_mnemonics(all_mnemonics, member_threshold, secret)

            # safety warning
            btn_code = yield
            assert btn_code == B.Success
            self.client.debug.press_yes()

        os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
        with mock.patch("os.urandom", os_urandom), self.client:
            self.client.set_expected_responses([
                proto.ButtonRequest(code=B.ResetDevice),
                proto.EntropyRequest(),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Other),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.Other),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.Other),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.Other),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.Other),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.Success),
                proto.Success(),
                proto.Features(),
            ])
            self.client.set_input_flow(input_flow)

            # No PIN, no passphrase, don't display random
            device.reset(
                self.client,
                display_random=False,
                strength=strength,
                passphrase_protection=False,
                pin_protection=False,
                label="test",
                language="english",
                backup_type=ResetDeviceBackupType.Slip39_Single_Group,
            )

        # Check if device is properly initialized
        resp = self.client.call_raw(proto.Initialize())
        assert resp.initialized is True
        assert resp.needs_backup is False
        assert resp.pin_protection is False
        assert resp.passphrase_protection is False
コード例 #20
0
 def test_initialize(self, client):
     with client:
         client.set_expected_responses([proto.Features()])
         client.init_device()
コード例 #21
0
def test_backup_slip39_advanced(client):
    assert client.features.needs_backup is True
    mnemonics = []

    def input_flow():
        # 1. Checklist
        # 2. Set and confirm group count
        # 3. Checklist
        # 4. Set and confirm group threshold
        # 5. Checklist
        # 6-15: for each of 5 groups:
        #   1. Set & Confirm number of shares
        #   2. Set & confirm share threshold value
        # 16. Confirm show seeds
        yield from click_through(client.debug, screens=16, code=B.ResetDevice)

        # Mnemonic phrases
        for _ in range(5):
            for _ in range(5):
                yield  # Phrase screen
                mnemonic = read_and_confirm_mnemonic(client.debug, words=20)
                mnemonics.append(mnemonic)
                yield  # Confirm continue to next
                client.debug.press_yes()

        # Confirm backup
        yield
        client.debug.press_yes()

    with client:
        client.set_input_flow(input_flow)
        client.set_expected_responses([
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),  # group #1 counts
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),  # group #2 counts
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),  # group #3 counts
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),  # group #4 counts
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),  # group #5 counts
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),  # show seeds
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),  # show seeds ends here
            messages.ButtonRequest(code=B.Success),
            messages.Success(),
            messages.Features(),
        ])
        device.backup(client)

    client.init_device()
    assert client.features.initialized is True
    assert client.features.needs_backup is False
    assert client.features.unfinished_backup is False
    assert client.features.no_backup is False
    assert client.features.backup_type is messages.BackupType.Slip39_Advanced

    expected_ms = shamir.combine_mnemonics(MNEMONIC_SLIP39_ADVANCED_20)
    actual_ms = shamir.combine_mnemonics(mnemonics[:3] + mnemonics[5:8] +
                                         mnemonics[10:13])
    assert expected_ms == actual_ms
コード例 #22
0
    def test_reset_device_pin(self, client):
        mnemonic = None
        strength = 256  # 24 words

        def input_flow():
            nonlocal mnemonic

            # Confirm Reset
            btn_code = yield
            assert btn_code == B.ResetDevice
            client.debug.press_yes()

            # Enter new PIN
            yield
            client.debug.input("654")

            # Confirm PIN
            yield
            client.debug.input("654")

            # Confirm entropy
            btn_code = yield
            assert btn_code == B.ResetDevice
            client.debug.press_yes()

            # Backup your seed
            btn_code = yield
            assert btn_code == B.ResetDevice
            client.debug.press_yes()

            # Confirm warning
            btn_code = yield
            assert btn_code == B.ResetDevice
            client.debug.press_yes()

            # mnemonic phrases
            btn_code = yield
            assert btn_code == B.ResetDevice
            mnemonic = read_and_confirm_mnemonic(client.debug, words=24)

            # confirm recovery seed check
            btn_code = yield
            assert btn_code == B.Success
            client.debug.press_yes()

            # confirm success
            btn_code = yield
            assert btn_code == B.Success
            client.debug.press_yes()

        os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
        with mock.patch("os.urandom", os_urandom), client:
            client.set_expected_responses([
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.PinEntry),
                proto.ButtonRequest(code=B.PinEntry),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.EntropyRequest(),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.Success),
                proto.Success(),
                proto.Features(),
            ])
            client.set_input_flow(input_flow)

            # PIN, passphrase, display random
            device.reset(
                client,
                display_random=True,
                strength=strength,
                passphrase_protection=True,
                pin_protection=True,
                label="test",
                language="en-US",
            )

        # generate mnemonic locally
        internal_entropy = client.debug.state().reset_entropy
        entropy = generate_entropy(strength, internal_entropy,
                                   EXTERNAL_ENTROPY)
        expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)

        # Compare that device generated proper mnemonic for given entropies
        assert mnemonic == expected_mnemonic

        # Check if device is properly initialized
        resp = client.call_raw(proto.Initialize())
        assert resp.initialized is True
        assert resp.needs_backup is False
        assert resp.pin_protection is True
        assert resp.passphrase_protection is True
コード例 #23
0
def reset_device(client, strength):
    words = STRENGTH_TO_WORDS[strength]
    mnemonic = None

    def input_flow():
        nonlocal mnemonic
        # 1. Confirm Reset
        # 2. Backup your seed
        # 3. Confirm warning
        yield from click_through(client.debug, screens=3, code=B.ResetDevice)

        # mnemonic phrases
        btn_code = yield
        assert btn_code == B.ResetDevice
        mnemonic = read_and_confirm_mnemonic(client.debug, words=words)

        # confirm recovery seed check
        btn_code = yield
        assert btn_code == B.Success
        client.debug.press_yes()

        # confirm success
        btn_code = yield
        assert btn_code == B.Success
        client.debug.press_yes()

    os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
    with mock.patch("os.urandom", os_urandom), client:
        client.set_expected_responses([
            proto.ButtonRequest(code=B.ResetDevice),
            proto.EntropyRequest(),
            proto.ButtonRequest(code=B.ResetDevice),
            proto.ButtonRequest(code=B.ResetDevice),
            proto.ButtonRequest(code=B.ResetDevice),
            proto.ButtonRequest(code=B.Success),
            proto.ButtonRequest(code=B.Success),
            proto.Success(),
            proto.Features(),
        ])
        client.set_input_flow(input_flow)

        # No PIN, no passphrase, don't display random
        device.reset(
            client,
            display_random=False,
            strength=strength,
            passphrase_protection=False,
            pin_protection=False,
            label="test",
            language="en-US",
        )

    # generate mnemonic locally
    internal_entropy = client.debug.state().reset_entropy
    entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
    expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)

    # Compare that device generated proper mnemonic for given entropies
    assert mnemonic == expected_mnemonic

    # Check if device is properly initialized
    resp = client.call_raw(proto.Initialize())
    assert resp.initialized is True
    assert resp.needs_backup is False
    assert resp.pin_protection is False
    assert resp.passphrase_protection is False
    assert resp.backup_type is proto.BackupType.Bip39

    # backup attempt fails because backup was done in reset
    with pytest.raises(TrezorFailure,
                       match="ProcessError: Seed already backed up"):
        device.backup(client)
コード例 #24
0
    def test_reset_device_slip39_basic(self, client):
        strength = 128
        member_threshold = 3
        all_mnemonics = []

        def input_flow():
            # 1. Confirm Reset
            # 2. Backup your seed
            # 3. Confirm warning
            # 4. shares info
            # 5. Set & Confirm number of shares
            # 6. threshold info
            # 7. Set & confirm threshold value
            # 8. Confirm show seeds
            yield from click_through(client.debug,
                                     screens=8,
                                     code=B.ResetDevice)

            # show & confirm shares
            for h in range(5):
                # mnemonic phrases
                btn_code = yield
                assert btn_code == B.ResetDevice
                mnemonic = read_and_confirm_mnemonic(client.debug, words=20)
                all_mnemonics.append(mnemonic)

                # Confirm continue to next share
                btn_code = yield
                assert btn_code == B.Success
                client.debug.press_yes()

            # safety warning
            btn_code = yield
            assert btn_code == B.Success
            client.debug.press_yes()

        os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
        with mock.patch("os.urandom", os_urandom), client:
            client.set_expected_responses([
                proto.ButtonRequest(code=B.ResetDevice),
                proto.EntropyRequest(),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.Success),
                proto.Success(),
                proto.Features(),
            ])
            client.set_input_flow(input_flow)

            # No PIN, no passphrase, don't display random
            device.reset(
                client,
                display_random=False,
                strength=strength,
                passphrase_protection=False,
                pin_protection=False,
                label="test",
                language="en-US",
                backup_type=BackupType.Slip39_Basic,
            )

        # generate secret locally
        internal_entropy = client.debug.state().reset_entropy
        secret = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)

        # validate that all combinations will result in the correct master secret
        validate_mnemonics(all_mnemonics, member_threshold, secret)

        # Check if device is properly initialized
        assert client.features.initialized is True
        assert client.features.needs_backup is False
        assert client.features.pin_protection is False
        assert client.features.passphrase_protection is False
        assert client.features.backup_type is BackupType.Slip39_Basic

        # backup attempt fails because backup was done in reset
        with pytest.raises(TrezorFailure,
                           match="ProcessError: Seed already backed up"):
            device.backup(client)
コード例 #25
0
    def test_reset_device(self):
        words = []
        strength = 128

        def input_flow():
            # Confirm Reset
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # Backup your seed
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # mnemonic phrases
            btn_code = yield
            assert btn_code == B.ResetDevice
            # 12 words, 3 pages
            for i in range(3):
                time.sleep(1)
                words.extend(self.client.debug.state().reset_word.split())
                if i < 2:
                    self.client.debug.swipe_down()
                else:
                    # last page is confirmation
                    self.client.debug.press_yes()

            # check backup words
            for _ in range(2):
                time.sleep(1)
                index = self.client.debug.state().reset_word_pos
                self.client.debug.input(words[index])

            # safety warning
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

        os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
        with mock.patch("os.urandom", os_urandom), self.client:
            self.client.set_expected_responses([
                proto.ButtonRequest(code=B.ResetDevice),
                proto.EntropyRequest(),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.Success(),
                proto.Features(),
            ])
            self.client.set_input_flow(input_flow)

            # No PIN, no passphrase, don't display random
            device.reset(
                self.client,
                display_random=False,
                strength=strength,
                passphrase_protection=False,
                pin_protection=False,
                label="test",
                language="english",
            )

        # generate mnemonic locally
        internal_entropy = self.client.debug.state().reset_entropy
        entropy = generate_entropy(strength, internal_entropy,
                                   EXTERNAL_ENTROPY)
        expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)

        # Compare that device generated proper mnemonic for given entropies
        assert " ".join(words) == expected_mnemonic

        # Check if device is properly initialized
        resp = self.client.call_raw(proto.Initialize())
        assert resp.initialized is True
        assert resp.needs_backup is False
        assert resp.pin_protection is False
        assert resp.passphrase_protection is False
コード例 #26
0
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.

import pytest

from trezorlib import device, messages as proto

EXPECTED_RESPONSES_NOPIN = [
    proto.ButtonRequest(),
    proto.Success(), proto.Features()
]
EXPECTED_RESPONSES_PIN_T1 = [proto.PinMatrixRequest()
                             ] + EXPECTED_RESPONSES_NOPIN
EXPECTED_RESPONSES_PIN_TT = [proto.ButtonRequest()] + EXPECTED_RESPONSES_NOPIN

PIN4 = "1234"


def _set_expected_responses(client):
    client.use_pin_sequence([PIN4])
    if client.features.model == "1":
        client.set_expected_responses(EXPECTED_RESPONSES_PIN_T1)
    else:
        client.set_expected_responses(EXPECTED_RESPONSES_PIN_TT)
コード例 #27
0
def reset(client, strength=128):
    all_mnemonics = []
    # per SLIP-39: strength in bits, rounded up to nearest multiple of 10, plus 70 bits
    # of metadata, split into 10-bit words
    word_count = ((strength + 9) // 10) + 7

    def input_flow():
        # 1. Confirm Reset
        # 2. Backup your seed
        # 3. Confirm warning
        # 4. shares info
        # 5. Set & Confirm number of shares
        # 6. threshold info
        # 7. Set & confirm threshold value
        # 8. Confirm show seeds
        yield from click_through(client.debug, screens=8, code=B.ResetDevice)

        # show & confirm shares
        for h in range(5):
            # mnemonic phrases
            btn_code = yield
            assert btn_code == B.ResetDevice
            mnemonic = read_and_confirm_mnemonic(client.debug,
                                                 words=word_count)
            all_mnemonics.append(mnemonic)

            # Confirm continue to next share
            btn_code = yield
            assert btn_code == B.Success
            client.debug.press_yes()

        # safety warning
        btn_code = yield
        assert btn_code == B.Success
        client.debug.press_yes()

    with client:
        client.set_expected_responses([
            messages.ButtonRequest(code=B.ResetDevice),
            messages.EntropyRequest(),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.ResetDevice),
            messages.ButtonRequest(code=B.Success),
            messages.ButtonRequest(code=B.Success),
            messages.Success(),
            messages.Features(),
        ])
        client.set_input_flow(input_flow)

        # No PIN, no passphrase, don't display random
        device.reset(
            client,
            display_random=False,
            strength=strength,
            passphrase_protection=False,
            pin_protection=False,
            label="test",
            language="english",
            backup_type=BackupType.Slip39_Basic,
        )

    # Check if device is properly initialized
    assert client.features.initialized is True
    assert client.features.needs_backup is False
    assert client.features.pin_protection is False
    assert client.features.passphrase_protection is False

    return all_mnemonics
コード例 #28
0
def reset(client, strength=128):
    all_mnemonics = []

    def input_flow():
        # Confirm Reset
        btn_code = yield
        assert btn_code == B.ResetDevice
        client.debug.press_yes()

        # Backup your seed
        btn_code = yield
        assert btn_code == B.ResetDevice
        client.debug.press_yes()

        # Confirm warning
        btn_code = yield
        assert btn_code == B.ResetDevice
        client.debug.press_yes()

        # shares info
        btn_code = yield
        assert btn_code == B.ResetDevice
        client.debug.press_yes()

        # Set & Confirm number of shares
        btn_code = yield
        assert btn_code == B.ResetDevice
        client.debug.press_yes()

        # threshold info
        btn_code = yield
        assert btn_code == B.ResetDevice
        client.debug.press_yes()

        # Set & confirm threshold value
        btn_code = yield
        assert btn_code == B.ResetDevice
        client.debug.press_yes()

        # Confirm show seeds
        btn_code = yield
        assert btn_code == B.ResetDevice
        client.debug.press_yes()

        # show & confirm shares
        for h in range(5):
            words = []
            btn_code = yield
            assert btn_code == B.Other

            # mnemonic phrases
            # 20 word over 6 pages for strength 128, 33 words over 9 pages for strength 256
            for i in range(6):
                words.extend(client.debug.read_reset_word().split())
                if i < 5:
                    client.debug.swipe_down()
                else:
                    # last page is confirmation
                    client.debug.press_yes()

            # check share
            for _ in range(3):
                index = client.debug.read_reset_word_pos()
                client.debug.input(words[index])

            all_mnemonics.extend([" ".join(words)])

            # Confirm continue to next share
            btn_code = yield
            assert btn_code == B.Success
            client.debug.press_yes()

        # safety warning
        btn_code = yield
        assert btn_code == B.Success
        client.debug.press_yes()

    with client:
        client.set_expected_responses(
            [
                messages.ButtonRequest(code=B.ResetDevice),
                messages.EntropyRequest(),
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.Other),
                messages.ButtonRequest(code=B.Success),
                messages.ButtonRequest(code=B.Other),
                messages.ButtonRequest(code=B.Success),
                messages.ButtonRequest(code=B.Other),
                messages.ButtonRequest(code=B.Success),
                messages.ButtonRequest(code=B.Other),
                messages.ButtonRequest(code=B.Success),
                messages.ButtonRequest(code=B.Other),
                messages.ButtonRequest(code=B.Success),
                messages.ButtonRequest(code=B.Success),
                messages.Success(),
                messages.Features(),
            ]
        )
        client.set_input_flow(input_flow)

        # No PIN, no passphrase, don't display random
        device.reset(
            client,
            display_random=False,
            strength=strength,
            passphrase_protection=False,
            pin_protection=False,
            label="test",
            language="english",
            backup_type=ResetDeviceBackupType.Slip39_Single_Group,
        )
    client.set_input_flow(None)

    # Check if device is properly initialized
    assert client.features.initialized is True
    assert client.features.needs_backup is False
    assert client.features.pin_protection is False
    assert client.features.passphrase_protection is False

    return all_mnemonics
コード例 #29
0
 def test_initialize(self):
     with self.client:
         self.setup_mnemonic_pin_passphrase()
         self.client.set_expected_responses([proto.Features()])
         self.client.init_device()
コード例 #30
0
    def test_reset_device_slip39_advanced(self, client):
        strength = 128
        word_count = 20
        member_threshold = 3
        all_mnemonics = []

        def input_flow():
            # 1. Confirm Reset
            # 2. Backup your seed
            # 3. Confirm warning
            # 4. shares info
            # 5. Set & Confirm number of groups
            # 6. threshold info
            # 7. Set & confirm group threshold value
            # 8-17: for each of 5 groups:
            #   1. Set & Confirm number of shares
            #   2. Set & confirm share threshold value
            # 18. Confirm show seeds
            yield from click_through(client.debug,
                                     screens=18,
                                     code=B.ResetDevice)

            # show & confirm shares for all groups
            for g in range(5):
                for h in range(5):
                    # mnemonic phrases
                    btn_code = yield
                    assert btn_code == B.ResetDevice
                    mnemonic = read_and_confirm_mnemonic(client.debug,
                                                         words=word_count)
                    all_mnemonics.append(mnemonic)

                    # Confirm continue to next share
                    btn_code = yield
                    assert btn_code == B.Success
                    client.debug.press_yes()

            # safety warning
            btn_code = yield
            assert btn_code == B.Success
            client.debug.press_yes()

        os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
        with mock.patch("os.urandom", os_urandom), client:
            client.set_expected_responses([
                proto.ButtonRequest(code=B.ResetDevice),
                proto.EntropyRequest(),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),  # group #1 counts
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),  # group #2 counts
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),  # group #3 counts
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),  # group #4 counts
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),  # group #5 counts
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),  # show seeds
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.Success),  # show seeds ends here
                proto.ButtonRequest(code=B.Success),
                proto.Success(),
                proto.Features(),
            ])
            client.set_input_flow(input_flow)

            # No PIN, no passphrase, don't display random
            device.reset(
                client,
                display_random=False,
                strength=strength,
                passphrase_protection=False,
                pin_protection=False,
                label="test",
                language="english",
                backup_type=BackupType.Slip39_Advanced,
            )

        # generate secret locally
        internal_entropy = client.debug.state().reset_entropy
        secret = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)

        # validate that all combinations will result in the correct master secret
        validate_mnemonics(all_mnemonics, member_threshold, secret)

        # Check if device is properly initialized
        assert client.features.initialized is True
        assert client.features.needs_backup is False
        assert client.features.pin_protection is False
        assert client.features.passphrase_protection is False
        assert client.features.backup_type is BackupType.Slip39_Advanced