From 8f5f5daaab8eecedcf71d8bd379f8f7644180f76 Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Fri, 14 Aug 2020 18:54:44 +0200 Subject: [PATCH] test(storage): Update tests to comply with new storage version and interface. --- storage/tests/c/storage.py | 15 ++++++--- storage/tests/c0/libtrezor-storage0.so | Bin 18032 -> 0 bytes storage/tests/c0/storage.py | 12 +++---- storage/tests/python/src/consts.py | 10 +++--- storage/tests/python/src/crypto.py | 6 ++-- storage/tests/python/src/storage.py | 25 ++++++--------- storage/tests/python/tests/test_pin.py | 18 +++++------ storage/tests/test.py | 4 +-- storage/tests/tests/common.py | 2 +- storage/tests/tests/storage_model.py | 8 ++--- storage/tests/tests/test_pin.py | 35 ++++++++++----------- storage/tests/tests/test_random.py | 7 +++-- storage/tests/tests/test_random_upgrade.py | 5 ++- storage/tests/tests/test_set_get.py | 10 +++--- storage/tests/tests/test_upgrade.py | 14 ++++----- 15 files changed, 87 insertions(+), 84 deletions(-) delete mode 100755 storage/tests/c0/libtrezor-storage0.so diff --git a/storage/tests/c/storage.py b/storage/tests/c/storage.py index 51ba594984..ee652ff994 100644 --- a/storage/tests/c/storage.py +++ b/storage/tests/c/storage.py @@ -21,10 +21,10 @@ class Storage: def wipe(self) -> None: self.lib.storage_wipe() - def unlock(self, pin: int, ext_salt: bytes = None) -> bool: + def unlock(self, pin: str, ext_salt: bytes = None) -> bool: if ext_salt is not None and len(ext_salt) != EXTERNAL_SALT_LEN: raise ValueError - return sectrue == self.lib.storage_unlock(c.c_uint32(pin), ext_salt) + return sectrue == self.lib.storage_unlock(pin.encode(), len(pin), ext_salt) def lock(self) -> None: self.lib.storage_lock() @@ -37,8 +37,8 @@ class Storage: def change_pin( self, - oldpin: int, - newpin: int, + oldpin: str, + newpin: str, old_ext_salt: bytes = None, new_ext_salt: bytes = None, ) -> bool: @@ -47,7 +47,12 @@ class Storage: if new_ext_salt is not None and len(new_ext_salt) != EXTERNAL_SALT_LEN: raise ValueError return sectrue == self.lib.storage_change_pin( - c.c_uint32(oldpin), c.c_uint32(newpin), old_ext_salt, new_ext_salt + oldpin.encode(), + len(oldpin), + newpin.encode(), + len(newpin), + old_ext_salt, + new_ext_salt, ) def get(self, key: int) -> bytes: diff --git a/storage/tests/c0/libtrezor-storage0.so b/storage/tests/c0/libtrezor-storage0.so deleted file mode 100755 index 3504b9d607d08069419942ee5235895e12995c26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18032 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 RCx7Rc1jmPpQ9`@?{{cchCT{=$ diff --git a/storage/tests/c0/storage.py b/storage/tests/c0/storage.py index 235695c63f..d7981fb1ec 100644 --- a/storage/tests/c0/storage.py +++ b/storage/tests/c0/storage.py @@ -20,18 +20,18 @@ class Storage: def wipe(self) -> None: self.lib.storage_wipe() - def check_pin(self, pin: int) -> bool: - return sectrue == self.lib.storage_check_pin(c.c_uint32(pin)) + def check_pin(self, pin: str) -> bool: + return sectrue == self.lib.storage_check_pin(c.c_uint32(int("1" + pin))) - def unlock(self, pin: int) -> bool: - return sectrue == self.lib.storage_unlock(c.c_uint32(pin)) + def unlock(self, pin: str) -> bool: + return sectrue == self.lib.storage_unlock(c.c_uint32(int("1" + pin))) def has_pin(self) -> bool: return sectrue == self.lib.storage_has_pin() - def change_pin(self, oldpin: int, newpin: int) -> bool: + def change_pin(self, oldpin: str, newpin: str) -> bool: return sectrue == self.lib.storage_change_pin( - c.c_uint32(oldpin), c.c_uint32(newpin) + c.c_uint32(int("1" + oldpin)), c.c_uint32(int("1" + newpin)) ) def get(self, key: int) -> bytes: diff --git a/storage/tests/python/src/consts.py b/storage/tests/python/src/consts.py index c70a1c97a0..349794deef 100644 --- a/storage/tests/python/src/consts.py +++ b/storage/tests/python/src/consts.py @@ -21,11 +21,11 @@ WIPE_CODE_DATA_KEY = (PIN_APP_ID << 8) | 0x06 # Norcow storage key of the storage upgrade flag. STORAGE_UPGRADED_KEY = (PIN_APP_ID << 8) | 0x07 -# The PIN value corresponding to an invalid PIN. -PIN_INVALID = 0 +# Norcow storage key of the unauthenticated storage version. +UNAUTH_VERSION_KEY = (PIN_APP_ID << 8) | 0x08 # The PIN value corresponding to an empty PIN. -PIN_EMPTY = 1 +PIN_EMPTY = "" # Maximum number of failed unlock attempts. PIN_MAX_TRIES = 16 @@ -64,7 +64,7 @@ WIPE_CODE_TAG_SIZE = 8 # The value corresponding to an unconfigured wipe code. # NOTE: This is intentionally different from PIN_EMPTY so that we don't need # special handling when both the PIN and wipe code are not set. -WIPE_CODE_EMPTY = 0 +WIPE_CODE_EMPTY = "\0\0\0\0" # Size of counter. 4B integer and 8B tail. COUNTER_TAIL = 12 @@ -128,7 +128,7 @@ NORCOW_SECTOR_SIZE = 64 * 1024 NORCOW_MAGIC = b"NRC2" # Norcow version, set in the storage header, but also as an encrypted item. -NORCOW_VERSION = b"\x02\x00\x00\x00" +NORCOW_VERSION = b"\x03\x00\x00\x00" # Norcow magic combined with the version, which is stored as its negation. NORCOW_MAGIC_AND_VERSION = NORCOW_MAGIC + bytes( diff --git a/storage/tests/python/src/crypto.py b/storage/tests/python/src/crypto.py index 037d82a0e5..30b1f851d2 100644 --- a/storage/tests/python/src/crypto.py +++ b/storage/tests/python/src/crypto.py @@ -7,7 +7,7 @@ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from . import consts, prng -def derive_kek_keiv(salt: bytes, pin: int) -> (bytes, bytes): +def derive_kek_keiv(salt: bytes, pin: str) -> (bytes, bytes): kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=consts.KEK_SIZE + consts.KEIV_SIZE, @@ -15,7 +15,7 @@ def derive_kek_keiv(salt: bytes, pin: int) -> (bytes, bytes): iterations=10000, backend=default_backend(), ) - pbkdf_output = kdf.derive(pin.to_bytes(4, "little")) + pbkdf_output = kdf.derive(pin.encode()) # the first 256b is Key Encryption Key kek = pbkdf_output[: consts.KEK_SIZE] # following with 96b of Initialization Vector @@ -42,7 +42,7 @@ def chacha_poly_decrypt( def decrypt_edek_esak( - pin: int, salt: bytes, edek_esak: bytes, pvc: bytes + pin: str, salt: bytes, edek_esak: bytes, pvc: bytes ) -> (bytes, bytes): """ Decrypts EDEK, ESAK to DEK, SAK and checks PIN in the process. diff --git a/storage/tests/python/src/storage.py b/storage/tests/python/src/storage.py index 65267244d4..538fa2be9f 100644 --- a/storage/tests/python/src/storage.py +++ b/storage/tests/python/src/storage.py @@ -38,14 +38,15 @@ class Storage: self.sak = prng.random_buffer(consts.SAK_SIZE) self.nc.set(consts.SAT_KEY, crypto.init_hmacs(self.sak)) - self._set_encrypt(consts.VERSION_KEY, b"\x02\x00\x00\x00") + self._set_encrypt(consts.VERSION_KEY, consts.NORCOW_VERSION) + self.nc.set(consts.UNAUTH_VERSION_KEY, consts.NORCOW_VERSION) self.nc.set(consts.STORAGE_UPGRADED_KEY, consts.FALSE_WORD) self.pin_log.init() self._set_wipe_code(consts.WIPE_CODE_EMPTY) self._set_pin(consts.PIN_EMPTY) self.unlocked = False - def _set_pin(self, pin: int): + def _set_pin(self, pin: str): random_salt = prng.random_buffer(consts.PIN_SALT_SIZE) salt = self.hw_salt_hash + random_salt kek, keiv = crypto.derive_kek_keiv(salt, pin) @@ -61,10 +62,10 @@ class Storage: else: self._set_bool(consts.PIN_NOT_SET_KEY, False) - def _set_wipe_code(self, wipe_code: int): + def _set_wipe_code(self, wipe_code: str): if wipe_code == consts.PIN_EMPTY: wipe_code = consts.WIPE_CODE_EMPTY - wipe_code_bytes = wipe_code.to_bytes(4, "little") + wipe_code_bytes = wipe_code.encode() salt = prng.random_buffer(consts.WIPE_CODE_SALT_SIZE) tag = crypto._hmac(salt, wipe_code_bytes)[: consts.WIPE_CODE_TAG_SIZE] self.nc.set(consts.WIPE_CODE_DATA_KEY, wipe_code_bytes + salt + tag) @@ -73,10 +74,7 @@ class Storage: self.nc.wipe() self._init_pin() - def check_pin(self, pin: int) -> bool: - if pin == 0: - return False - + def check_pin(self, pin: str) -> bool: self.pin_log.write_attempt() data = self.nc.get(consts.EDEK_ESEK_PVC_KEY) @@ -99,7 +97,7 @@ class Storage: def lock(self) -> None: self.unlocked = False - def unlock(self, pin: int) -> bool: + def unlock(self, pin: str) -> bool: if not self.initialized or not self.check_pin(pin): return False @@ -117,13 +115,8 @@ class Storage: def get_pin_rem(self) -> int: return consts.PIN_MAX_TRIES - self.pin_log.get_failures_count() - def change_pin(self, oldpin: int, newpin: int) -> bool: - if ( - not self.initialized - or not self.unlocked - or oldpin == consts.PIN_INVALID - or newpin == consts.PIN_INVALID - ): + def change_pin(self, oldpin: str, newpin: str) -> bool: + if not self.initialized or not self.unlocked: return False if not self.check_pin(oldpin): return False diff --git a/storage/tests/python/tests/test_pin.py b/storage/tests/python/tests/test_pin.py index a6f517922d..23527a8e00 100644 --- a/storage/tests/python/tests/test_pin.py +++ b/storage/tests/python/tests/test_pin.py @@ -5,24 +5,24 @@ def test_set_pin_success(): s = Storage() hw_salt = b"\x00\x00\x00\x00\x00\x00" s.init(hw_salt) - s._set_pin(1) - assert s.unlock(1) + s._set_pin("") + assert s.unlock("") s = Storage() s.init(hw_salt) - s._set_pin(229922) - assert s.unlock(229922) + s._set_pin("229922") + assert s.unlock("229922") def test_set_pin_failure(): s = Storage() hw_salt = b"\x00\x00\x00\x00\x00\x00" s.init(hw_salt) - s._set_pin(1) - assert s.unlock(1) - assert not s.unlock(1234) + s._set_pin("") + assert s.unlock("") + assert not s.unlock("1234") s = Storage() s.init(hw_salt) - s._set_pin(229922) - assert not s.unlock(1122992211) + s._set_pin("229922") + assert not s.unlock("1122992211") diff --git a/storage/tests/test.py b/storage/tests/test.py index 0ee5f4a0e4..97d365119d 100755 --- a/storage/tests/test.py +++ b/storage/tests/test.py @@ -28,8 +28,8 @@ a = [] for s in [sc, sp]: print(s.__class__) s.init(uid) - assert s.unlock(3) is False - assert s.unlock(1) is True + assert s.unlock("3") is False + assert s.unlock("") is True s.set(0xBEEF, b"hello") s.set(0x03FE, b"world!") s.set(0xBEEF, b"satoshi") diff --git a/storage/tests/tests/common.py b/storage/tests/tests/common.py index c66ea8091e..9a88a9c146 100644 --- a/storage/tests/tests/common.py +++ b/storage/tests/tests/common.py @@ -15,7 +15,7 @@ def init( for s in (sc, sp): s.init(uid) if unlock: - assert s.unlock(1) + assert s.unlock("") return sc, sp diff --git a/storage/tests/tests/storage_model.py b/storage/tests/tests/storage_model.py index 06eedc4600..f11f9b3e1d 100644 --- a/storage/tests/tests/storage_model.py +++ b/storage/tests/tests/storage_model.py @@ -2,7 +2,7 @@ class StorageModel: - _EMPTY_PIN = 1 + _EMPTY_PIN = "" _PIN_MAX_TRIES = 16 def __init__(self) -> None: @@ -13,14 +13,14 @@ class StorageModel: def wipe(self) -> None: self.unlocked = False - self.pin = 1 + self.pin = self._EMPTY_PIN self.pin_rem = self._PIN_MAX_TRIES self.dict = {} def lock(self) -> None: self.unlocked = False - def unlock(self, pin: int) -> bool: + def unlock(self, pin: str) -> bool: if pin == self.pin: self.pin_rem = self._PIN_MAX_TRIES self.unlocked = True @@ -37,7 +37,7 @@ class StorageModel: def get_pin_rem(self) -> int: return self.pin_rem - def change_pin(self, oldpin: int, newpin: int) -> bool: + def change_pin(self, oldpin: str, newpin: str) -> bool: if self.unlocked and self.unlock(oldpin): self.pin = newpin return True diff --git a/storage/tests/tests/test_pin.py b/storage/tests/tests/test_pin.py index efda1a3301..8e75de1c9a 100644 --- a/storage/tests/tests/test_pin.py +++ b/storage/tests/tests/test_pin.py @@ -16,15 +16,14 @@ def test_init_pin(): def test_change_pin(): sc, sp = common.init(unlock=True) for s in (sc, sp): - assert s.change_pin(1, 2221) - assert not s.change_pin(99991, 1) # invalid old PIN - assert not s.unlock(0) # invalid PIN - assert s.unlock(2221) - assert not s.change_pin(2221, 0) # invalid new PIN - assert s.change_pin(2221, 999991) - assert s.change_pin(999991, 991) - assert s.unlock(991) - assert not s.unlock(99991) # invalid PIN + assert s.change_pin("", "222") + assert not s.change_pin("9999", "") # invalid PIN + assert s.unlock("222") + assert s.change_pin("222", "99999") + assert s.change_pin("99999", "Trezor") + assert s.unlock("Trezor") + assert not s.unlock("9999") # invalid PIN + assert not s.unlock("99999") # invalid old PIN assert common.memory_equals(sc, sp) @@ -33,34 +32,34 @@ def test_has_pin(): sc, sp = common.init() for s in (sc, sp): assert not s.has_pin() - assert s.unlock(1) + assert s.unlock("") assert not s.has_pin() - assert s.change_pin(1, 221) + assert s.change_pin("", "22") assert s.has_pin() - assert s.change_pin(221, 1) + assert s.change_pin("22", "") assert not s.has_pin() def test_wipe_after_max_pin(): sc, sp = common.init(unlock=True) for s in (sc, sp): - assert s.change_pin(1, 2221) - assert s.unlock(2221) + assert s.change_pin("", "222") + assert s.unlock("222") s.set(0x0202, b"Hello") # try an invalid PIN MAX - 1 times for i in range(consts.PIN_MAX_TRIES - 1): - assert not s.unlock(99991) + assert not s.unlock("9999") # this should pass - assert s.unlock(2221) + assert s.unlock("222") assert s.get(0x0202) == b"Hello" # try an invalid PIN MAX times, the storage should get wiped for i in range(consts.PIN_MAX_TRIES): - assert not s.unlock(99991) + assert not s.unlock("9999") assert i == consts.PIN_MAX_TRIES - 1 # this should return False and raise an exception, the storage is wiped - assert not s.unlock(2221) + assert not s.unlock("222") with pytest.raises(RuntimeError): assert s.get(0x0202) == b"Hello" diff --git a/storage/tests/tests/test_random.py b/storage/tests/tests/test_random.py index 01f4f71c64..ad8c8169a6 100644 --- a/storage/tests/tests/test_random.py +++ b/storage/tests/tests/test_random.py @@ -12,7 +12,7 @@ class StorageComparison(RuleBasedStateMachine): self.sc, self.sp = common.init(unlock=True) self.sm = StorageModel() self.sm.init(b"") - self.sm.unlock(1) + self.sm.unlock("") self.storages = (self.sc, self.sp, self.sm) keys = Bundle("keys") @@ -29,7 +29,10 @@ class StorageComparison(RuleBasedStateMachine): @rule(target=pins, p=st.integers(1, 3)) def p(self, p): - return p + if p == 1: + return "" + else: + return str(p) @rule(k=keys, v=values) def set(self, k, v): diff --git a/storage/tests/tests/test_random_upgrade.py b/storage/tests/tests/test_random_upgrade.py index 4aaa1a507b..0b573705d2 100644 --- a/storage/tests/tests/test_random_upgrade.py +++ b/storage/tests/tests/test_random_upgrade.py @@ -33,7 +33,10 @@ class StorageUpgrade(RuleBasedStateMachine): @rule(target=pins, p=st.integers(1, 3)) def p(self, p): - return p + if p == 1: + return "" + else: + return str(p) @rule(k=keys, v=values) def set(self, k, v): diff --git a/storage/tests/tests/test_set_get.py b/storage/tests/tests/test_set_get.py index cb313cf84c..d46c8b12c9 100644 --- a/storage/tests/tests/test_set_get.py +++ b/storage/tests/tests/test_set_get.py @@ -27,8 +27,8 @@ def test_set_get(): assert common.memory_equals(sc, sp) for s in (sc, sp): - s.change_pin(1, 2221) - s.change_pin(2221, 991) + s.change_pin("", "222") + s.change_pin("222", "99") s.set(0xAAAA, b"something else") assert common.memory_equals(sc, sp) @@ -60,7 +60,7 @@ def test_set_get(): # check that storage functions after unlock for s in (sc, sp): - s.unlock(991) + s.unlock("99") s.set(0xAAAA, b"public") s.set(0x0902, b"protected") assert s.get(0xAAAA) == b"public" @@ -131,14 +131,14 @@ def test_set_similar(): for s in (sc, sp): s.wipe() - s.unlock(1) + s.unlock("") s.set(0xBEEF, b"satoshi") s.set(0xBEEF, b"Satoshi") assert common.memory_equals(sc, sp) for s in (sc, sp): s.wipe() - s.unlock(1) + s.unlock("") s.set(0xBEEF, b"satoshi") s.set(0xBEEF, b"Satoshi") s.set(0xBEEF, b"Satoshi") diff --git a/storage/tests/tests/test_upgrade.py b/storage/tests/tests/test_upgrade.py index a089438ca8..4d8c5805da 100644 --- a/storage/tests/tests/test_upgrade.py +++ b/storage/tests/tests/test_upgrade.py @@ -17,12 +17,12 @@ def set_values(s): s.set(0xBEEF, b"Hello") s.set(0xCAFE, b"world! ") s.set(0xDEAD, b"How\n") - s.change_pin(1, 1222) + s.change_pin("", "222") s.set(0xAAAA, b"are") s.set(0x0901, b"you?") s.set(0x0902, b"Lorem") s.set(0x0903, b"ipsum") - s.change_pin(1222, 199) + s.change_pin("222", "99") s.set(0xDEAD, b"A\n") s.set(0xDEAD, b"AAAAAAAAAAA") s.set(0x2200, b"BBBB") @@ -31,7 +31,7 @@ def set_values(s): def check_values(s): - assert s.unlock(199) + assert s.unlock("99") assert s.get(0xAAAA) == b"are" assert s.get(0x0901) == b"you?" assert s.get(0x0902) == b"Lorem" @@ -45,10 +45,10 @@ def check_values(s): def test_upgrade(): sc0 = StorageC0() sc0.init() - assert sc0.unlock(1) + assert sc0.unlock("") set_values(sc0) for _ in range(10): - assert not sc0.unlock(3) + assert not sc0.unlock("3") sc1 = StorageC() sc1._set_flash_buffer(sc0._get_flash_buffer()) @@ -60,10 +60,10 @@ def test_upgrade(): def test_python_set_sectors(): sp0 = StoragePy() sp0.init(common.test_uid) - assert sp0.unlock(1) + assert sp0.unlock("") set_values(sp0) for _ in range(10): - assert not sp0.unlock(3) + assert not sp0.unlock("3") assert sp0.get_pin_rem() == 6 sp1 = StoragePy()