trezor.config: add public values (readable without unlock)

They are indicated via MSB bit of appid
This commit is contained in:
Pavol Rusnak 2018-01-13 15:21:40 +01:00
parent 0a9d42981d
commit 27d9abe883
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
3 changed files with 59 additions and 18 deletions

View File

@ -65,14 +65,17 @@ STATIC mp_obj_t mod_trezorconfig_change_pin(mp_obj_t pin, mp_obj_t newpin, mp_ob
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorconfig_change_pin_obj, mod_trezorconfig_change_pin);
/// def get(app: int, key: int) -> bytes:
/// def get(app: int, key: int, public: bool=False) -> bytes:
/// '''
/// Gets a value of given key for given app (or empty bytes if not set).
/// '''
STATIC mp_obj_t mod_trezorconfig_get(mp_obj_t app, mp_obj_t key) {
uint8_t a = mp_obj_get_int(app);
uint8_t k = mp_obj_get_int(key);
uint16_t appkey = a << 8 | k;
STATIC mp_obj_t mod_trezorconfig_get(size_t n_args, const mp_obj_t *args) {
uint8_t app = mp_obj_get_int(args[0]) & 0x7F;
uint8_t key = mp_obj_get_int(args[1]);
if (n_args > 2 && args[2] == mp_const_true) {
app |= 0x80;
}
uint16_t appkey = (app << 8) | key;
uint16_t len = 0;
const void *val;
if (sectrue != storage_get(appkey, &val, &len) || len == 0) {
@ -80,24 +83,27 @@ STATIC mp_obj_t mod_trezorconfig_get(mp_obj_t app, mp_obj_t key) {
}
return mp_obj_new_bytes(val, len);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorconfig_get_obj, mod_trezorconfig_get);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_get_obj, 2, 3, mod_trezorconfig_get);
/// def set(app: int, key: int, value: bytes) -> None:
/// def set(app: int, key: int, value: bytes, public: bool=False) -> None:
/// '''
/// Sets a value of given key for given app.
/// '''
STATIC mp_obj_t mod_trezorconfig_set(mp_obj_t app, mp_obj_t key, mp_obj_t value) {
uint8_t a = mp_obj_get_int(app);
uint8_t k = mp_obj_get_int(key);
uint16_t appkey = a << 8 | k;
mp_buffer_info_t v;
mp_get_buffer_raise(value, &v, MP_BUFFER_READ);
if (sectrue != storage_set(appkey, v.buf, v.len)) {
STATIC mp_obj_t mod_trezorconfig_set(size_t n_args, const mp_obj_t *args) {
uint8_t app = mp_obj_get_int(args[0]) & 0x7F;
uint8_t key = mp_obj_get_int(args[1]);
if (n_args > 3 && args[3] == mp_const_true) {
app |= 0x80;
}
uint16_t appkey = (app << 8) | key;
mp_buffer_info_t value;
mp_get_buffer_raise(args[2], &value, MP_BUFFER_READ);
if (sectrue != storage_set(appkey, value.buf, value.len)) {
mp_raise_msg(&mp_type_RuntimeError, "Could not save value");
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorconfig_set_obj, mod_trezorconfig_set);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_set_obj, 3, 4, mod_trezorconfig_set);
/// def wipe() -> None:
/// '''

View File

@ -169,7 +169,13 @@ secbool storage_unlock(const uint32_t pin, mp_obj_t callback)
secbool storage_get(uint16_t key, const void **val, uint16_t *len)
{
if (sectrue != initialized || sectrue != unlocked || (key >> 8) == 0) {
const uint8_t app = key >> 8;
// APP == 0 is reserved for PIN related values
if (sectrue != initialized || app == 0) {
return secfalse;
}
// top bit of APP set indicates the value can be read from unlocked device
if (sectrue != unlocked && ((app & 0x80) == 0)) {
return secfalse;
}
return norcow_get(key, val, len);
@ -177,7 +183,9 @@ secbool storage_get(uint16_t key, const void **val, uint16_t *len)
secbool storage_set(uint16_t key, const void *val, uint16_t len)
{
if (sectrue != initialized || sectrue != unlocked || (key >> 8) == 0) {
const uint8_t app = key >> 8;
// APP == 0 is reserved for PIN related values
if (sectrue != initialized || sectrue != unlocked || app == 0) {
return secfalse;
}
return norcow_set(key, val, len);

View File

@ -11,7 +11,7 @@ PINKEY = 0x00
def random_entry():
while True:
appid, key = 1 + random.uniform(255), random.uniform(256)
appid, key = 1 + random.uniform(127), random.uniform(256)
if appid != PINAPP or key != PINKEY:
break
return appid, key
@ -56,6 +56,33 @@ class TestConfig(unittest.TestCase):
config.wipe()
self.assertEqual(config.change_pin(pin_to_int(''), pin_to_int('000'), None), False)
def test_public(self):
config.init()
config.wipe()
self.assertEqual(config.unlock(pin_to_int(''), None), True)
appid, key = random_entry()
value32 = random.bytes(32)
config.set(appid, key, value32)
value16 = random.bytes(16)
config.set(appid, key, value16, True)
v1 = config.get(appid, key)
v2 = config.get(appid, key, True)
self.assertNotEqual(v1, v2)
self.assertEqual(v1, value32)
self.assertEqual(v2, value16)
config.init()
v1 = config.get(appid, key)
v2 = config.get(appid, key, True)
self.assertNotEqual(v1, v2)
self.assertEqual(v1, bytes())
self.assertEqual(v2, value16)
def test_change_pin(self):
config.init()
config.wipe()