Exemplo n.º 1
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", "english")

        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="english",
                )
            )
Exemplo n.º 2
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
def reset(client, strength=128):
    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
                mnemonic = yield from read_and_confirm_mnemonic(client.debug)
                all_mnemonics.append(mnemonic)

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

        # safety warning
        br = yield
        assert br.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(
            [
                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),  # 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),
            ]
            + [
                # individual mnemonic
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.Success),
            ]
            * (5 * 5)  # groups * shares
            + [
                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="en-US",
            backup_type=BackupType.Slip39_Advanced,
        )

    # 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
Exemplo n.º 4
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)
Exemplo n.º 5
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
def reset(client: Client, strength=128):
    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 _ in range(5):
            # mnemonic phrases
            mnemonic = yield from read_and_confirm_mnemonic(client.debug)
            all_mnemonics.append(mnemonic)

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

        # safety warning
        br = yield
        assert br.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),
            ]
            + [
                # individual mnemonic
                messages.ButtonRequest(code=B.ResetDevice),
                messages.ButtonRequest(code=B.Success),
            ]
            * 5  # number of shares
            + [
                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="en-US",
            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
Exemplo n.º 7
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
    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)
Exemplo n.º 9
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
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
    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
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 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([
            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),  # 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,
        ])
        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_Advanced,
        )

    # 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
def reset(client, strength=128, skip_backup=False):
    mnemonic = None
    word_count = strength // 32 * 3

    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=word_count)

        # 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.EntropyRequest(),
            messages.ButtonRequest(code=B.ResetDevice),
            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)

        os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
        with mock.patch("os.urandom", os_urandom), client:
            # 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.Bip39,
            )

    # 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 mnemonic
Exemplo n.º 14
0
def test_reset_failed_check(client: Client):
    mnemonic = None
    strength = 256  # 24 words

    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, wrong answer
        mnemonic = yield from read_and_confirm_mnemonic(client.debug,
                                                        choose_wrong=True)

        # warning screen
        br = yield
        assert br.code == B.ResetDevice
        client.debug.press_yes()

        # mnemonic phrases
        mnemonic = yield from read_and_confirm_mnemonic(client.debug)

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

        # confirm success
        br = yield
        assert br.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([
            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.Success),
            messages.ButtonRequest(code=B.Success),
            messages.Success,
            messages.Features,
        ])
        client.set_input_flow(input_flow)

        # PIN, passphrase, 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(messages.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 messages.BackupType.Bip39