config: Use efficient implementation of U2F counter from trezor-storage.

pull/25/head
andrew 5 years ago committed by Pavol Rusnak
parent 8b78e6710a
commit 52c7f0eb93
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

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

@ -1 +1 @@
Subproject commit 4429888b9325d200b699a90f7a0e1a07d08f09c0
Subproject commit 5c2765740db064c99fe54cbae79f74a3d767973c
Loading…
Cancel
Save