1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-29 02:48:18 +00:00

tests: test reset device also with another strengths

This commit is contained in:
Tomas Susanka 2020-03-13 09:50:20 +00:00
parent 0f95eff4ff
commit ad25096f90
4 changed files with 252 additions and 225 deletions

View File

@ -22,79 +22,86 @@ from trezorlib import device, messages as proto
from ..common import generate_entropy
def reset_device(client, strength):
# No PIN, no passphrase
external_entropy = b"zlutoucky kun upel divoke ody" * 2
ret = client.call_raw(
proto.ResetDevice(
display_random=False,
strength=strength,
passphrase_protection=False,
pin_protection=False,
language="en-US",
label="test",
)
)
assert isinstance(ret, proto.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(proto.ButtonAck())
# Provide entropy
assert isinstance(ret, proto.EntropyRequest)
internal_entropy = client.debug.read_reset_entropy()
ret = client.call_raw(proto.EntropyAck(entropy=external_entropy))
# Generate mnemonic locally
entropy = generate_entropy(strength, internal_entropy, external_entropy)
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
mnemonic = []
for _ in range(strength // 32 * 3):
assert isinstance(ret, proto.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
client.call_raw(proto.ButtonAck())
mnemonic = " ".join(mnemonic)
# Compare that device generated proper mnemonic for given entropies
assert mnemonic == expected_mnemonic
mnemonic = []
for _ in range(strength // 32 * 3):
assert isinstance(ret, proto.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
resp = client.call_raw(proto.ButtonAck())
assert isinstance(resp, proto.Success)
mnemonic = " ".join(mnemonic)
# Compare that second pass printed out the same mnemonic once again
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
# Do pin & passphrase-protected action, PassphraseRequest should NOT be raised
resp = client.call_raw(proto.GetAddress())
assert isinstance(resp, proto.Address)
@pytest.mark.skip_t2
class TestMsgResetDevice:
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device(self, client):
# No PIN, no passphrase
external_entropy = b"zlutoucky kun upel divoke ody" * 2
strength = 128
ret = client.call_raw(
proto.ResetDevice(
display_random=False,
strength=strength,
passphrase_protection=False,
pin_protection=False,
language="en-US",
label="test",
)
)
assert isinstance(ret, proto.ButtonRequest)
client.debug.press_yes()
ret = client.call_raw(proto.ButtonAck())
# Provide entropy
assert isinstance(ret, proto.EntropyRequest)
internal_entropy = client.debug.read_reset_entropy()
ret = client.call_raw(proto.EntropyAck(entropy=external_entropy))
# Generate mnemonic locally
entropy = generate_entropy(strength, internal_entropy, external_entropy)
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
mnemonic = []
for _ in range(strength // 32 * 3):
assert isinstance(ret, proto.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
client.call_raw(proto.ButtonAck())
mnemonic = " ".join(mnemonic)
# Compare that device generated proper mnemonic for given entropies
assert mnemonic == expected_mnemonic
mnemonic = []
for _ in range(strength // 32 * 3):
assert isinstance(ret, proto.ButtonRequest)
mnemonic.append(client.debug.read_reset_word())
client.debug.press_yes()
resp = client.call_raw(proto.ButtonAck())
assert isinstance(resp, proto.Success)
mnemonic = " ".join(mnemonic)
# Compare that second pass printed out the same mnemonic once again
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
# Do pin & passphrase-protected action, PassphraseRequest should NOT be raised
resp = client.call_raw(proto.GetAddress())
assert isinstance(resp, proto.Address)
def test_reset_device_128(self, client):
reset_device(client, 128)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_pin(self, client):
def test_reset_device_192(self, client):
reset_device(client, 192)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_256_pin(self, client):
external_entropy = b"zlutoucky kun upel divoke ody" * 2
strength = 128
strength = 256
ret = client.call_raw(
proto.ResetDevice(

View File

@ -31,89 +31,98 @@ from ..common import (
)
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
STRENGTH_TO_WORDS = {128: 12, 192: 18, 256: 24}
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)
@pytest.mark.skip_t1
class TestMsgResetDeviceT2:
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device(self, client):
mnemonic = None
strength = 128
reset_device(client, 128) # 12 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
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()
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)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_192(self, client):
reset_device(client, 192) # 18 words
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_pin(self, client):
mnemonic = None
strength = 128
strength = 256 # 24 words
def input_flow():
nonlocal mnemonic
@ -149,7 +158,7 @@ class TestMsgResetDeviceT2:
# mnemonic phrases
btn_code = yield
assert btn_code == B.ResetDevice
mnemonic = read_and_confirm_mnemonic(client.debug, words=12)
mnemonic = read_and_confirm_mnemonic(client.debug, words=24)
# confirm recovery seed check
btn_code = yield

View File

@ -32,104 +32,113 @@ from ..common import (
read_and_confirm_mnemonic,
)
STRENGTH_TO_WORDS = {128: 20, 256: 33}
@pytest.mark.skip_t1
class TestMsgResetDeviceT2:
# TODO: test with different options
@pytest.mark.setup_client(uninitialized=True)
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)
def reset_device(client, strength):
words = STRENGTH_TO_WORDS[strength]
member_threshold = 3
all_mnemonics = []
# 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)
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)
# Confirm continue to next share
btn_code = yield
assert btn_code == B.Success
client.debug.press_yes()
# 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=words)
all_mnemonics.append(mnemonic)
# safety warning
# Confirm continue to next share
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)
# safety warning
btn_code = yield
assert btn_code == B.Success
client.debug.press_yes()
# 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,
)
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)
# generate secret locally
internal_entropy = client.debug.state().reset_entropy
secret = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
# 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,
)
# validate that all combinations will result in the correct master secret
validate_mnemonics(all_mnemonics, member_threshold, secret)
# generate secret locally
internal_entropy = client.debug.state().reset_entropy
secret = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
# 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
# validate that all combinations will result in the correct master secret
validate_mnemonics(all_mnemonics, member_threshold, secret)
# backup attempt fails because backup was done in reset
with pytest.raises(TrezorFailure, match="ProcessError: Seed already backed up"):
device.backup(client)
# 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)
@pytest.mark.skip_t1
class TestMsgResetDeviceT2:
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_slip39_basic(self, client):
reset_device(client, 128)
@pytest.mark.setup_client(uninitialized=True)
def test_reset_device_slip39_basic_256(self, client):
reset_device(client, 256)
def validate_mnemonics(mnemonics, threshold, expected_ems):

View File

@ -220,9 +220,11 @@
"test_msg_resetdevice_bip39_t2.py-test_already_initialized": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_resetdevice_bip39_t2.py-test_failed_pin": "f284b630fef6ae437c9726cd0ee0d1728a77f677f37cd5f88aabb21e596f589e",
"test_msg_resetdevice_bip39_t2.py-test_reset_device": "aaa37f33897fbdf33858a9cbb8982be1b1c1d1e2cbff83ebfd4c49fa8fc4b342",
"test_msg_resetdevice_bip39_t2.py-test_reset_device_pin": "8cf79b65a37d6680f351a203f32f49b41425531be77ddcc8db894959aada7cd9",
"test_msg_resetdevice_bip39_t2.py-test_reset_device_192": "febbacc3370cf9219faa49bbc542a7aa1280d9fc3e6e9776dacbcd2f09231636",
"test_msg_resetdevice_bip39_t2.py-test_reset_device_pin": "dd95b1f1e7b496828314a4baf77f5f9f3aa54fc11754236e35f7519da9fd44c8",
"test_msg_resetdevice_slip39_advanced.py-test_reset_device_slip39_advanced": "b1ca19a20f4d2be96847c8d2373921a68c5c9bd1292790229c64f93a0319cb69",
"test_msg_resetdevice_slip39_basic.py-test_reset_device_slip39_basic": "77e9d45a9fb16a8759478ac1d433bb86ce58c01fa135bc4524596955de20552d",
"test_msg_resetdevice_slip39_basic.py-test_reset_device_slip39_basic_256": "5f21f628ada58d9b519aec96f99a087df1098825de33421ddb36777dc4f578f1",
"test_msg_ripple_get_address.py-test_ripple_get_address": "2bb7d7bf48f1218530b4d7045d48480cad6411e110df537551b2f80b342007f2",
"test_msg_ripple_get_address.py-test_ripple_get_address_other": "2bb7d7bf48f1218530b4d7045d48480cad6411e110df537551b2f80b342007f2",
"test_msg_ripple_sign_tx.py-test_ripple_sign_invalid_fee": "1c0ca08b857da6121f43cfb1632c7f7e1d189ef1fdb665db7ba2cdfa7a59ea7c",