1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-22 14:38:27 +00:00

chore(core/rust): Add global serial number storage

This commit is contained in:
Jan Pochyla 2022-03-06 12:07:49 -03:00 committed by grdddj
parent 5fa9c7d43c
commit d9d2b3122f

View File

@ -5,8 +5,6 @@ use crate::trezorhal::secbool;
use super::ffi;
const MAX_IFACE_COUNT: usize = 4;
#[derive(Debug)]
pub enum UsbError {
FailedToAddInterface,
@ -87,19 +85,22 @@ impl Usb {
}
}
pub struct UsbConfig {
const MAX_INTERFACE_COUNT: usize = 4;
#[derive(Default)]
pub struct UsbConfig<'a> {
pub vendor_id: u16,
pub product_id: u16,
pub release_num: u16,
pub manufacturer: &'static CStr,
pub product: &'static CStr,
pub serial_number: &'static CStr,
pub interface: &'static CStr,
pub serial_number: &'a CStr,
pub usb21_landing: bool,
pub interfaces: Vec<IfaceConfig, MAX_IFACE_COUNT>,
pub interfaces: Vec<IfaceConfig, MAX_INTERFACE_COUNT>,
}
impl UsbConfig {
impl UsbConfig<'_> {
fn as_dev_info(&self) -> ffi::usb_dev_info_t {
ffi::usb_dev_info_t {
device_class: 0,
@ -110,8 +111,8 @@ impl UsbConfig {
release_num: self.release_num,
manufacturer: self.manufacturer.as_ptr(),
product: self.product.as_ptr(),
serial_number: self.serial_number.as_ptr(),
interface: self.interface.as_ptr(),
serial_number: set_global_serial_number(self.serial_number).as_ptr(),
usb21_enabled: secbool::TRUE,
usb21_landing: if self.usb21_landing {
secbool::TRUE
@ -166,8 +167,9 @@ impl WebUsbConfig {
fn as_webusb_info(&mut self) -> ffi::usb_webusb_info_t {
ffi::usb_webusb_info_t {
rx_buffer: self.rx_buffer.as_mut_ptr(), // With length of max_packet_len bytes.
max_packet_len: self.rx_buffer.len() as u8, // Length of the biggest report and of rx_buffer.
iface_num: self.iface_num, // Address of this WebUSB interface.
max_packet_len: self.rx_buffer.len() as u8, /* Length of the biggest report and of
* rx_buffer. */
iface_num: self.iface_num, // Address of this WebUSB interface.
// emu_port: self.emu_port, // UDP port of this interface in the emulator.
ep_in: self.ep_in, // Address of IN endpoint (with the highest bit set).
ep_out: self.ep_out, // Address of OUT endpoint.
@ -247,8 +249,9 @@ impl HidConfig {
report_desc: self.report_desc.as_ptr(), // With length of report_desc_len bytes.
report_desc_len: self.report_desc.len() as u8, // Length of report_desc.
rx_buffer: self.rx_buffer.as_mut_ptr(), // With length of max_packet_len bytes.
max_packet_len: self.rx_buffer.len() as u8, // Length of the biggest report and of rx_buffer.
iface_num: self.iface_num, // Address of this HID interface.
max_packet_len: self.rx_buffer.len() as u8, /* Length of the biggest report and of
* rx_buffer. */
iface_num: self.iface_num, // Address of this HID interface.
// emu_port: self.emu_port, // UDP port of this interface in the emulator.
ep_in: self.ep_in, // Address of IN endpoint (with the highest bit set).
ep_out: self.ep_out, // Address of OUT endpoint.
@ -328,17 +331,24 @@ impl VcpConfig {
fn as_vcp_info(&mut self) -> ffi::usb_vcp_info_t {
ffi::usb_vcp_info_t {
tx_packet: self.tx_packet.as_mut_ptr(), // Buffer for one packet, with length of at least max_packet_len bytes.
tx_buffer: self.tx_buffer.as_mut_ptr(), // Buffer for IN EP ring buffer, with length of at least tx_buffer_len bytes.
rx_packet: self.rx_packet.as_mut_ptr(), // Buffer for one packet, with length of at least max_packet_len bytes.
rx_buffer: self.rx_buffer.as_mut_ptr(), // Buffer for OUT EP ring buffer, with length of at least rx_buffer_len bytes.
max_packet_len: self.rx_packet.len() as u8, // Length of the biggest packet, and of tx_packet and rx_packet.
tx_packet: self.tx_packet.as_mut_ptr(), /* Buffer for one packet, with length of at
* least max_packet_len bytes. */
tx_buffer: self.tx_buffer.as_mut_ptr(), /* Buffer for IN EP ring buffer, with length
* of at least tx_buffer_len bytes. */
rx_packet: self.rx_packet.as_mut_ptr(), /* Buffer for one packet, with length of at
* least max_packet_len bytes. */
rx_buffer: self.rx_buffer.as_mut_ptr(), /* Buffer for OUT EP ring buffer, with length
* of at least rx_buffer_len bytes. */
max_packet_len: self.rx_packet.len() as u8, /* Length of the biggest packet, and of
* tx_packet and rx_packet. */
tx_buffer_len: self.tx_buffer.len(), // Length of tx_buffer, needs to be a power of 2.
rx_buffer_len: self.rx_buffer.len(), // Length of rx_buffer, needs to be a power of 2.
rx_intr_fn: self.rx_intr_fn, // Callback called from usb_vcp_class_data_out IRQ handler if rx_intr_byte matches.
rx_intr_fn: self.rx_intr_fn, /* Callback called from usb_vcp_class_data_out
* IRQ handler if rx_intr_byte matches. */
rx_intr_byte: self.rx_intr_byte, // Value matched against every received byte.
iface_num: self.iface_num, // Address of this VCP interface.
data_iface_num: self.data_iface_num, // Address of data interface of the VCP interface association.
iface_num: self.iface_num, // Address of this VCP interface.
data_iface_num: self.data_iface_num, /* Address of data interface of the VCP interface
* association. */
// emu_port: self.emu_port, // UDP port of this interface in the emulator.
ep_cmd: self.ep_cmd, // Address of IN CMD endpoint (with the highest bit set).
ep_in: self.ep_in, // Address of IN endpoint (with the highest bit set).
@ -376,15 +386,15 @@ mod tests {
release_num: 0x0200,
manufacturer: cstr!("SatoshiLabs"),
product: cstr!("TREZOR"),
serial_number: cstr!(""), // TODO
serial_number: cstr!(""),
interface: cstr!("TREZOR Interface"),
usb21_landing: false,
interfaces: Vec::new(),
..UsbConfig::default()
};
let id_wire = iface_iter.next().unwrap();
let iface_wire = WebUsbConfig {
rx_buffer: &mut [0; 64], // TODO
rx_buffer: &mut [0; 64],
iface_num: id_wire,
ep_in: 0x81 + id_wire,
ep_out: 0x01 + id_wire,
@ -395,7 +405,7 @@ mod tests {
if ENABLE_IFACE_DEBUG {
let id_debug = iface_iter.next().unwrap();
let iface_debug = WebUsbConfig {
rx_buffer: &mut [0; 64], // TODO
rx_buffer: &mut [0; 64],
iface_num: id_debug,
ep_in: 0x81 + id_debug,
ep_out: 0x01 + id_debug,
@ -425,7 +435,7 @@ mod tests {
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
],
rx_buffer: &mut [0; 64], // TODO
rx_buffer: &mut [0; 64],
iface_num: id_webauthn,
ep_in: 0x81 + id_webauthn,
ep_out: 0x01 + id_webauthn,
@ -438,12 +448,12 @@ mod tests {
let id_vcp = iface_iter.next().unwrap();
let id_vcp_data = iface_iter.next().unwrap();
let iface_vcp = VcpConfig {
rx_buffer: &mut [0; 1024], // TODO
tx_buffer: &mut [0; 1024], // TODO
rx_packet: &mut [0; 64], // TODO
tx_packet: &mut [0; 64], // TODO
rx_intr_fn: None, // Use pendsv_kbd_intr here.
rx_intr_byte: 3, // Ctrl-C
rx_buffer: &mut [0; 1024],
tx_buffer: &mut [0; 1024],
rx_packet: &mut [0; 64],
tx_packet: &mut [0; 64],
rx_intr_fn: None, // Use pendsv_kbd_intr here.
rx_intr_byte: 3, // Ctrl-C
iface_num: id_vcp,
data_iface_num: id_vcp_data,
ep_in: 0x81 + id_vcp,
@ -457,3 +467,19 @@ mod tests {
let usb = Usb::open(config).unwrap();
}
}
fn set_global_serial_number(sn: &CStr) -> &'static CStr {
static mut GLOBAL_BUFFER: [u8; 64] = [0; 64];
// SAFETY: We are in a single threaded context, no the only possible race on
// `GLOBAL_BUFFER` is with the USB stack. We should take care to only call
// `set_global_serial_number` with the USB stopped.
unsafe {
let sn_nul = sn.to_bytes_with_nul();
// Panics if `sn_nul` is bigger then `GLOBAL_BUFFER`.
&mut GLOBAL_BUFFER[..sn_nul.len()].copy_from_slice(sn_nul);
CStr::from_bytes_with_nul_unchecked(&GLOBAL_BUFFER[..sn_nul.len()])
}
}