mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-24 15:38:22 +00:00
WIP - get_device_id and random bytes in rust
This commit is contained in:
parent
715ed53bcf
commit
a15930dd4a
@ -29,6 +29,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_set_rotation;
|
||||
MP_QSTR_get_label;
|
||||
MP_QSTR_set_label;
|
||||
MP_QSTR_get_device_id;
|
||||
MP_QSTR_get_mnemonic_secret;
|
||||
MP_QSTR_set_mnemonic_secret;
|
||||
MP_QSTR_is_passphrase_enabled;
|
||||
|
@ -7,12 +7,12 @@ use crate::{
|
||||
obj::Obj,
|
||||
qstr::Qstr,
|
||||
},
|
||||
trezorhal::secbool,
|
||||
trezorhal::{random, secbool},
|
||||
util,
|
||||
};
|
||||
|
||||
use cstr_core::cstr;
|
||||
use heapless::Vec;
|
||||
use heapless::{String, Vec};
|
||||
|
||||
use core::{
|
||||
convert::{TryFrom, TryInto},
|
||||
@ -196,6 +196,26 @@ extern "C" fn storagedevice_set_label(label: Obj) -> Obj {
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn storagedevice_get_device_id() -> Obj {
|
||||
let block = || {
|
||||
let key = _get_appkey(DEVICE_ID, true);
|
||||
let device_id = &storagedevice_storage_get(key) as &[u8];
|
||||
|
||||
// TODO: is there some easier way?
|
||||
// TODO: replace unwrap() with "?"
|
||||
if device_id.is_empty() {
|
||||
let new_device_id = &random::get_random_bytes(12) as &[u8];
|
||||
let hex_id = _hexlify_bytes(new_device_id);
|
||||
let device_id_bytes = hex_id.as_str().as_bytes();
|
||||
storagedevice_storage_set(key, device_id_bytes.as_ptr(), device_id_bytes.len() as u16);
|
||||
hex_id.as_str().try_into()
|
||||
} else {
|
||||
str::from_utf8(device_id).unwrap().try_into()
|
||||
}
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn storagedevice_get_mnemonic_secret() -> Obj {
|
||||
let block = || {
|
||||
let key = _get_appkey(_MNEMONIC_SECRET, false);
|
||||
@ -548,13 +568,7 @@ pub fn storagedevice_storage_get(key: u16) -> Vec<u8, MAX_LEN> {
|
||||
// Would mean having Option<XXX> as the return type
|
||||
|
||||
let result = &buf[..len as usize];
|
||||
// TODO: can we somehow convert it more easily?
|
||||
let mut vector_result = Vec::<u8, MAX_LEN>::new();
|
||||
for byte in result {
|
||||
vector_result.push(*byte).unwrap();
|
||||
}
|
||||
|
||||
vector_result
|
||||
result.iter().cloned().collect()
|
||||
}
|
||||
|
||||
// TODO: is it worth having a special function to not allocate so much in all
|
||||
@ -693,6 +707,23 @@ fn _normalize_autolock_delay(delay_ms: u32) -> u32 {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: could be put elsewhere to be available for all modules
|
||||
pub fn _hexlify_bytes(bytes: &[u8]) -> String<64> {
|
||||
let mut buf = String::<64>::from("");
|
||||
for byte in bytes {
|
||||
fn hex_from_digit(num: u8) -> char {
|
||||
if num < 10 {
|
||||
(b'0' + num) as char
|
||||
} else {
|
||||
(b'A' + num - 10) as char
|
||||
}
|
||||
}
|
||||
buf.push(hex_from_digit(byte / 16)).unwrap();
|
||||
buf.push(hex_from_digit(byte % 16)).unwrap();
|
||||
}
|
||||
buf
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub static mp_module_trezorstoragedevice: Module = obj_module! {
|
||||
Qstr::MP_QSTR___name_storage__ => Qstr::MP_QSTR_trezorstoragedevice.to_obj(),
|
||||
@ -734,6 +765,10 @@ pub static mp_module_trezorstoragedevice: Module = obj_module! {
|
||||
/// """Set label."""
|
||||
Qstr::MP_QSTR_set_label => obj_fn_1!(storagedevice_set_label).as_obj(),
|
||||
|
||||
/// def get_device_id() -> str:
|
||||
/// """Get device ID."""
|
||||
Qstr::MP_QSTR_get_device_id => obj_fn_0!(storagedevice_get_device_id).as_obj(),
|
||||
|
||||
/// def get_mnemonic_secret() -> bytes:
|
||||
/// """Get mnemonic secret."""
|
||||
Qstr::MP_QSTR_get_mnemonic_secret => obj_fn_0!(storagedevice_get_mnemonic_secret).as_obj(),
|
||||
@ -917,4 +952,11 @@ mod tests {
|
||||
let result = _normalize_autolock_delay(1_000_000);
|
||||
assert_eq!(result, 1_000_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hexlify_bytes() {
|
||||
let bytes: &[u8; 6] = &[52, 241, 6, 151, 173, 74];
|
||||
let result = _hexlify_bytes(bytes);
|
||||
assert_eq!(result, String::<64>::from("34F10697AD4A"));
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,14 @@
|
||||
use heapless::Vec;
|
||||
|
||||
extern "C" {
|
||||
// trezor-crypto/rand.h
|
||||
fn random_uniform(n: u32) -> u32;
|
||||
fn random_buffer(buf: *const u8, len: u16);
|
||||
}
|
||||
|
||||
// TODO: what is the sensible max size not to allocate too much every time?
|
||||
const MAX_LEN: usize = u8::MAX as usize;
|
||||
|
||||
pub fn uniform(n: u32) -> u32 {
|
||||
unsafe { random_uniform(n) }
|
||||
}
|
||||
@ -15,6 +21,10 @@ pub fn shuffle<T>(slice: &mut [T]) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: create random_bytes()
|
||||
// from trezorcrypto import random
|
||||
// random_buffer
|
||||
pub fn get_random_bytes(len: u8) -> Vec<u8, MAX_LEN> {
|
||||
let mut buf: [u8; MAX_LEN] = [0; MAX_LEN];
|
||||
unsafe { random_buffer(&mut buf as *mut _, len as u16) };
|
||||
|
||||
let result = &buf[..len as usize];
|
||||
result.iter().cloned().collect()
|
||||
}
|
||||
|
@ -43,6 +43,11 @@ def set_label(label: str) -> bool:
|
||||
"""Set label."""
|
||||
|
||||
|
||||
# rust/src/storagedevice/storage_device.rs
|
||||
def get_device_id() -> str:
|
||||
"""Get device ID."""
|
||||
|
||||
|
||||
# rust/src/storagedevice/storage_device.rs
|
||||
def get_mnemonic_secret() -> bytes:
|
||||
"""Get mnemonic secret."""
|
||||
|
@ -42,7 +42,7 @@ def get_features() -> Features:
|
||||
patch_version=utils.VERSION_PATCH,
|
||||
revision=utils.SCM_REVISION,
|
||||
model=utils.MODEL,
|
||||
device_id=storage.device.get_device_id(),
|
||||
device_id=storagedevice.get_device_id(),
|
||||
label=storagedevice.get_label(),
|
||||
pin_protection=config.has_pin(),
|
||||
unlocked=config.is_unlocked(),
|
||||
|
@ -45,9 +45,9 @@ with unimport_manager:
|
||||
del boot
|
||||
|
||||
# start the USB
|
||||
import storage.device
|
||||
from trezor import storagedevice
|
||||
|
||||
usb.bus.open(storage.device.get_device_id())
|
||||
usb.bus.open(storagedevice.get_device_id())
|
||||
|
||||
# run the endless loop
|
||||
while True:
|
||||
|
@ -27,7 +27,7 @@ def reset() -> None:
|
||||
"""
|
||||
Wipes storage but keeps the device id unchanged.
|
||||
"""
|
||||
device_id = device.get_device_id()
|
||||
device_id = storagedevice.get_device_id()
|
||||
wipe()
|
||||
common.set(common.APP_DEVICE, device.DEVICE_ID, device_id.encode(), public=True)
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
from micropython import const
|
||||
from typing import TYPE_CHECKING
|
||||
from ubinascii import hexlify
|
||||
|
||||
import storage.cache
|
||||
from storage import common
|
||||
|
||||
# from ubinascii import hexlify
|
||||
|
||||
|
||||
# TODO: try ... from trezorstoragedevice import *
|
||||
|
||||
|
||||
@ -82,18 +84,18 @@ SD_SALT_AUTH_KEY_LEN_BYTES = const(16)
|
||||
# return common.get_bool(_NAMESPACE, INITIALIZED, public=True)
|
||||
|
||||
|
||||
def _new_device_id() -> str:
|
||||
from trezorcrypto import random # avoid pulling in trezor.crypto
|
||||
# def _new_device_id() -> str:
|
||||
# from trezorcrypto import random # avoid pulling in trezor.crypto
|
||||
|
||||
return hexlify(random.bytes(12)).decode().upper()
|
||||
# return hexlify(random.bytes(12)).decode().upper()
|
||||
|
||||
|
||||
def get_device_id() -> str:
|
||||
dev_id = common.get(_NAMESPACE, DEVICE_ID, public=True)
|
||||
if not dev_id:
|
||||
dev_id = _new_device_id().encode()
|
||||
common.set(_NAMESPACE, DEVICE_ID, dev_id, public=True)
|
||||
return dev_id.decode()
|
||||
# def get_device_id() -> str:
|
||||
# dev_id = common.get(_NAMESPACE, DEVICE_ID, public=True)
|
||||
# if not dev_id:
|
||||
# dev_id = _new_device_id().encode()
|
||||
# common.set(_NAMESPACE, DEVICE_ID, dev_id, public=True)
|
||||
# return dev_id.decode()
|
||||
|
||||
|
||||
# def get_rotation() -> int:
|
||||
|
@ -1,7 +1,6 @@
|
||||
from micropython import const
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import storage.device
|
||||
from trezor import io, storagedevice
|
||||
from trezor.sdcard import with_filesystem
|
||||
from trezor.utils import consteq
|
||||
@ -32,7 +31,7 @@ def compute_auth_tag(salt: bytes, auth_key: bytes) -> bytes:
|
||||
|
||||
|
||||
def _get_device_dir() -> str:
|
||||
return f"/trezor/device_{storage.device.get_device_id().lower()}"
|
||||
return f"/trezor/device_{storagedevice.get_device_id().lower()}"
|
||||
|
||||
|
||||
def _get_salt_path(new: bool = False) -> str:
|
||||
|
Loading…
Reference in New Issue
Block a user