mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-21 23:18:13 +00:00
config: Use efficient implementation of U2F counter from trezor-storage.
This commit is contained in:
parent
8b78e6710a
commit
52c7f0eb93
@ -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);
|
||||
|
@ -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)
|
||||
|
2
vendor/trezor-storage
vendored
2
vendor/trezor-storage
vendored
@ -1 +1 @@
|
||||
Subproject commit 4429888b9325d200b699a90f7a0e1a07d08f09c0
|
||||
Subproject commit 5c2765740db064c99fe54cbae79f74a3d767973c
|
Loading…
Reference in New Issue
Block a user