storage: Check for invalid PIN.

pull/474/merge
Andrew Kozlik 4 years ago committed by Andrew Kozlik
parent 6fdbde98fd
commit 77bb6deb66

@ -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;

@ -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

@ -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

@ -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)

Loading…
Cancel
Save