diff --git a/embed/extmod/modtrezorconfig/modtrezorconfig.c b/embed/extmod/modtrezorconfig/modtrezorconfig.c index 0e9822f16a..09730bd353 100644 --- a/embed/extmod/modtrezorconfig/modtrezorconfig.c +++ b/embed/extmod/modtrezorconfig/modtrezorconfig.c @@ -133,7 +133,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorconfig_change_pin_obj, mod_trezorconf /// Raises a RuntimeError if decryption or authentication of the stored value fails. /// ''' STATIC mp_obj_t mod_trezorconfig_get(size_t n_args, const mp_obj_t *args) { - uint8_t app = trezor_obj_get_uint8(args[0]) & 0x7F; + uint8_t app = trezor_obj_get_uint8(args[0]) & 0x3F; uint8_t key = trezor_obj_get_uint8(args[1]); if (n_args > 2 && args[2] == mp_const_true) { app |= 0x80; @@ -161,7 +161,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_get_obj, 2, 3, mod_t /// Sets a value of given key for given app. /// ''' STATIC mp_obj_t mod_trezorconfig_set(size_t n_args, const mp_obj_t *args) { - uint8_t app = trezor_obj_get_uint8(args[0]) & 0x7F; + uint8_t app = trezor_obj_get_uint8(args[0]) & 0x3F; uint8_t key = trezor_obj_get_uint8(args[1]); if (n_args > 3 && args[3] == mp_const_true) { app |= 0x80; @@ -181,7 +181,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_set_obj, 3, 4, mod_t /// Deletes the given key of the given app. /// ''' STATIC mp_obj_t mod_trezorconfig_delete(size_t n_args, const mp_obj_t *args) { - uint8_t app = trezor_obj_get_uint8(args[0]) & 0x7F; + uint8_t app = trezor_obj_get_uint8(args[0]) & 0x3F; uint8_t key = trezor_obj_get_uint8(args[1]); if (n_args > 2 && args[2] == mp_const_true) { app |= 0x80; @@ -194,6 +194,54 @@ STATIC mp_obj_t mod_trezorconfig_delete(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_delete_obj, 2, 3, mod_trezorconfig_delete); +/// def set_counter(app: int, key: int, count: int, writable_locked: bool=False) -> bool: +/// ''' +/// Sets the given key of the given app as a counter with the given value. +/// ''' +STATIC mp_obj_t mod_trezorconfig_set_counter(size_t n_args, const mp_obj_t *args) { + uint8_t app = trezor_obj_get_uint8(args[0]) & 0x3F; + uint8_t key = trezor_obj_get_uint8(args[1]); + if (n_args > 3 && args[3] == mp_const_true) { + app |= 0xC0; + } else { + app |= 0x80; + } + uint16_t appkey = (app << 8) | key; + if (args[2] == mp_const_none) { + if (sectrue != storage_delete(appkey)) { + return mp_const_false; + } + } else { + uint32_t count = trezor_obj_get_uint(args[2]); + if (sectrue != storage_set_counter(appkey, count)) { + return mp_const_false; + } + } + return mp_const_true; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_set_counter_obj, 3, 4, mod_trezorconfig_set_counter); + +/// def next_counter(app: int, key: int, writable_locked: bool=False) -> bool: +/// ''' +/// Increments the counter stored under the given key of the given app and returns the new value. +/// ''' +STATIC mp_obj_t mod_trezorconfig_next_counter(size_t n_args, const mp_obj_t *args) { + uint8_t app = trezor_obj_get_uint8(args[0]) & 0x3F; + uint8_t key = trezor_obj_get_uint8(args[1]); + if (n_args > 2 && args[2] == mp_const_true) { + app |= 0xC0; + } else { + app |= 0x80; + } + uint16_t appkey = (app << 8) | key; + uint32_t count = 0; + if (sectrue != storage_next_counter(appkey, &count)) { + return mp_const_none; + } + return mp_obj_new_int_from_uint(count); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_next_counter_obj, 2, 3, mod_trezorconfig_next_counter); + /// def wipe() -> None: /// ''' /// Erases the whole config. Use with caution! @@ -216,6 +264,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorconfig_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&mod_trezorconfig_get_obj) }, { MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mod_trezorconfig_set_obj) }, { MP_ROM_QSTR(MP_QSTR_delete), MP_ROM_PTR(&mod_trezorconfig_delete_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_counter), MP_ROM_PTR(&mod_trezorconfig_set_counter_obj) }, + { MP_ROM_QSTR(MP_QSTR_next_counter), MP_ROM_PTR(&mod_trezorconfig_next_counter_obj) }, { MP_ROM_QSTR(MP_QSTR_wipe), MP_ROM_PTR(&mod_trezorconfig_wipe_obj) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_trezorconfig_globals, mp_module_trezorconfig_globals_table); diff --git a/src/apps/common/storage.py b/src/apps/common/storage.py index 4c16f69780..85780797d0 100644 --- a/src/apps/common/storage.py +++ b/src/apps/common/storage.py @@ -44,50 +44,6 @@ def _get_bool(app: int, key: int, public: bool = False) -> bool: return config.get(app, key, public) == _TRUE_BYTE -def _set_counter(app: int, key: int, count: int, public: bool = False) -> None: - if count is None: - config.delete(app, key, public) - return - - value = count.to_bytes(_COUNTER_HEAD_LEN, "big") - if public: - value += _COUNTER_TAIL_LEN * b"\xff" - config.set(app, key, value, public) - - -def _next_counter(app: int, key: int, public: bool = False) -> int: - # If the counter value is public, then it is stored as a four byte integer in - # big endian byte order, called the "head", followed an eight byte "tail". The - # counter value is equal to the integer value of the head plus the number of - # zero bits in the tail. The counter value 0 is stored as 00000000FFFFFFFFFFFFFFFF. - # With each increment the tail is shifted to the right by one bit. Thus after - # three increments the stored value is 000000001FFFFFFFFFFFFFFF. Once all the - # bits in the tail are set to zero, the next counter value is stored as - # 00000041FFFFFFFFFFFFFFFF. - - value = config.get(app, key, public) - if value is None: - _set_counter(app, key, 0, public) - return 0 - - head = value[:_COUNTER_HEAD_LEN] - tail = value[_COUNTER_HEAD_LEN:] - i = tail.rfind(b"\x00") + 1 - count = int.from_bytes(head, "big") + 1 + 8 * i - if i == len(tail): - _set_counter(app, key, count, public) - return count - - zero_count = 0 - while (tail[i] << zero_count) < 128: - zero_count += 1 - count += zero_count - - tail = tail[:i] + bytes([tail[i] >> 1]) + tail[i + 1 :] - config.set(app, key, head + tail, public) - return count - - def _new_device_id() -> str: return hexlify(random.bytes(12)).decode().upper() @@ -219,11 +175,11 @@ def set_autolock_delay_ms(delay_ms: int) -> None: def next_u2f_counter() -> int: - return _next_counter(_APP, _U2F_COUNTER, True) # public + return config.next_counter(_APP, _U2F_COUNTER) def set_u2f_counter(cntr: int) -> None: - _set_counter(_APP, _U2F_COUNTER, cntr, True) # public + config.set_counter(_APP, _U2F_COUNTER, cntr) def wipe(): @@ -238,6 +194,6 @@ def init_unlocked(): # Make the U2F counter public. counter = config.get(_APP, _U2F_COUNTER) if counter is not None: - _set_counter(_APP, _U2F_COUNTER, counter, True) # public + config.set_counter(_APP, _U2F_COUNTER, counter) config.delete(_APP, _U2F_COUNTER) config.set(_APP, _VERSION, _STORAGE_VERSION) diff --git a/vendor/trezor-storage b/vendor/trezor-storage index 4429888b93..5c2765740d 160000 --- a/vendor/trezor-storage +++ b/vendor/trezor-storage @@ -1 +1 @@ -Subproject commit 4429888b9325d200b699a90f7a0e1a07d08f09c0 +Subproject commit 5c2765740db064c99fe54cbae79f74a3d767973c