diff --git a/storage/storage.c b/storage/storage.c index 395e2363a..f158dad93 100644 --- a/storage/storage.c +++ b/storage/storage.c @@ -57,6 +57,9 @@ // Norcow storage key of the storage upgrade flag. #define STORAGE_UPGRADED_KEY ((APP_STORAGE << 8) | 0x07) +// The PIN value corresponding to an invalid PIN. +#define PIN_INVALID 0 + // The PIN value corresponding to an empty PIN. #define PIN_EMPTY 1 @@ -943,7 +946,7 @@ static secbool decrypt_dek(const uint8_t *kek, const uint8_t *keiv) { } static secbool unlock(uint32_t pin, const uint8_t *ext_salt) { - if (sectrue != initialized) { + if (sectrue != initialized || pin == PIN_INVALID) { return secfalse; } @@ -1317,7 +1320,8 @@ uint32_t storage_get_pin_rem(void) { secbool storage_change_pin(uint32_t oldpin, uint32_t newpin, const uint8_t *old_ext_salt, const uint8_t *new_ext_salt) { - if (sectrue != initialized) { + if (sectrue != initialized || oldpin == PIN_INVALID || + newpin == PIN_INVALID) { return secfalse; } @@ -1345,7 +1349,8 @@ secbool storage_has_wipe_code(void) { secbool storage_change_wipe_code(uint32_t pin, const uint8_t *ext_salt, uint32_t wipe_code) { - if (sectrue != initialized || (pin != PIN_EMPTY && pin == wipe_code)) { + if (sectrue != initialized || (pin != PIN_EMPTY && pin == wipe_code) || + pin == PIN_INVALID || wipe_code == PIN_INVALID) { memzero(&pin, sizeof(pin)); memzero(&wipe_code, sizeof(wipe_code)); return secfalse; diff --git a/storage/tests/python/src/consts.py b/storage/tests/python/src/consts.py index 2fb2e1146..c70a1c97a 100644 --- a/storage/tests/python/src/consts.py +++ b/storage/tests/python/src/consts.py @@ -21,6 +21,9 @@ 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 + # The PIN value corresponding to an empty PIN. PIN_EMPTY = 1 diff --git a/storage/tests/python/src/storage.py b/storage/tests/python/src/storage.py index 744fe7043..65267244d 100644 --- a/storage/tests/python/src/storage.py +++ b/storage/tests/python/src/storage.py @@ -74,6 +74,9 @@ class Storage: self._init_pin() def check_pin(self, pin: int) -> bool: + if pin == 0: + return False + self.pin_log.write_attempt() data = self.nc.get(consts.EDEK_ESEK_PVC_KEY) @@ -115,7 +118,12 @@ class Storage: 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: + if ( + not self.initialized + or not self.unlocked + or oldpin == consts.PIN_INVALID + or newpin == consts.PIN_INVALID + ): return False if not self.check_pin(oldpin): return False diff --git a/storage/tests/tests/test_pin.py b/storage/tests/tests/test_pin.py index 915deb4b3..efda1a330 100644 --- a/storage/tests/tests/test_pin.py +++ b/storage/tests/tests/test_pin.py @@ -17,13 +17,14 @@ def test_change_pin(): sc, sp = common.init(unlock=True) for s in (sc, sp): assert s.change_pin(1, 2221) - # invalid PIN - assert not s.change_pin(99991, 1) + 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) + assert not s.unlock(99991) # invalid PIN assert common.memory_equals(sc, sp)