From 359b243eb6057da05b20eed9e4d83927a4111c9b Mon Sep 17 00:00:00 2001 From: Guillaume Endignoux Date: Wed, 23 Sep 2020 15:37:24 +0200 Subject: [PATCH] Add component for USB CTAP. --- patches/tock/02-usb.patch | 303 +++++++++++++++++++++----------------- 1 file changed, 170 insertions(+), 133 deletions(-) diff --git a/patches/tock/02-usb.patch b/patches/tock/02-usb.patch index 9650633..135369d 100644 --- a/patches/tock/02-usb.patch +++ b/patches/tock/02-usb.patch @@ -1,19 +1,114 @@ +diff --git a/boards/components/src/lib.rs b/boards/components/src/lib.rs +index dc56c94d2..917497af4 100644 +--- a/boards/components/src/lib.rs ++++ b/boards/components/src/lib.rs +@@ -36,3 +36,4 @@ pub mod spi; + pub mod st7735; + pub mod temperature; + pub mod touch; ++pub mod usb_ctap; +diff --git a/boards/components/src/usb_ctap.rs b/boards/components/src/usb_ctap.rs +new file mode 100644 +index 000000000..69e95c3c7 +--- /dev/null ++++ b/boards/components/src/usb_ctap.rs +@@ -0,0 +1,88 @@ ++//! Component for CTAP over USB. ++ ++use capsules::usb::usb_ctap::CtapUsbSyscallDriver; ++use capsules::usb::usbc_ctap_hid::ClientCtapHID; ++use core::mem::MaybeUninit; ++use kernel::capabilities; ++use kernel::component::Component; ++use kernel::create_capability; ++use kernel::hil; ++use kernel::static_init_half; ++ ++// Setup static space for the objects. ++#[macro_export] ++macro_rules! usb_ctap_component_buf { ++ ($C:ty) => {{ ++ use capsules::usb::usb_ctap::CtapUsbSyscallDriver; ++ use capsules::usb::usbc_ctap_hid::ClientCtapHID; ++ use core::mem::MaybeUninit; ++ static mut BUF1: MaybeUninit> = MaybeUninit::uninit(); ++ static mut BUF2: MaybeUninit> = ++ MaybeUninit::uninit(); ++ (&mut BUF1, &mut BUF2) ++ };}; ++} ++ ++pub struct UsbCtapComponent> { ++ board_kernel: &'static kernel::Kernel, ++ controller: &'static C, ++ max_ctrl_packet_size: u8, ++ vendor_id: u16, ++ product_id: u16, ++ strings: &'static [&'static str], ++} ++ ++impl> UsbCtapComponent { ++ pub fn new( ++ board_kernel: &'static kernel::Kernel, ++ controller: &'static C, ++ max_ctrl_packet_size: u8, ++ vendor_id: u16, ++ product_id: u16, ++ strings: &'static [&'static str], ++ ) -> Self { ++ Self { ++ board_kernel, ++ controller, ++ max_ctrl_packet_size, ++ vendor_id, ++ product_id, ++ strings, ++ } ++ } ++} ++ ++impl> Component for UsbCtapComponent { ++ type StaticInput = ( ++ &'static mut MaybeUninit>, ++ &'static mut MaybeUninit>, ++ ); ++ type Output = &'static CtapUsbSyscallDriver<'static, 'static, C>; ++ ++ unsafe fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output { ++ let grant_cap = create_capability!(capabilities::MemoryAllocationCapability); ++ ++ let usb_ctap = static_init_half!( ++ static_buffer.0, ++ ClientCtapHID<'static, 'static, C>, ++ ClientCtapHID::new( ++ self.controller, ++ self.max_ctrl_packet_size, ++ self.vendor_id, ++ self.product_id, ++ self.strings, ++ ) ++ ); ++ self.controller.set_client(usb_ctap); ++ ++ // Configure the USB userspace driver ++ let usb_driver = static_init_half!( ++ static_buffer.1, ++ CtapUsbSyscallDriver<'static, 'static, C>, ++ CtapUsbSyscallDriver::new(usb_ctap, self.board_kernel.create_grant(&grant_cap)) ++ ); ++ usb_ctap.set_client(usb_driver); ++ ++ usb_driver ++ } ++} diff --git a/boards/nordic/nrf52840_dongle/src/main.rs b/boards/nordic/nrf52840_dongle/src/main.rs -index d72d204..8b97f8d 100644 +index d72d20482..118ea6d68 100644 --- a/boards/nordic/nrf52840_dongle/src/main.rs +++ b/boards/nordic/nrf52840_dongle/src/main.rs -@@ -15,6 +15,7 @@ use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferred - use kernel::component::Component; - #[allow(unused_imports)] - use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init}; -+use kernel::hil::usb::UsbController; - use nrf52840::gpio::Pin; - use nrf52_components::{self, UartChannel, UartPins}; - -@@ -45,6 +46,17 @@ const PAN_ID: u16 = 0xABCD; +@@ -45,6 +45,17 @@ const PAN_ID: u16 = 0xABCD; /// UART Writer pub mod io; - + +const VENDOR_ID: u16 = 0x1915; // Nordic Semiconductor +const PRODUCT_ID: u16 = 0x521f; // nRF52840 Dongle (PCA10059) +static STRINGS: &'static [&'static str] = &[ @@ -28,7 +123,7 @@ index d72d204..8b97f8d 100644 // State for loading and holding applications. // How should the kernel respond when a process faults. const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic; -@@ -96,6 +108,11 @@ pub struct Platform { +@@ -96,6 +107,11 @@ pub struct Platform { capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52840::rtc::Rtc<'static>>, >, nvmc: &'static nrf52840::nvmc::SyscallDriver, @@ -38,9 +133,9 @@ index d72d204..8b97f8d 100644 + nrf52840::usbd::Usbd<'static>, + >, } - + impl kernel::Platform for Platform { -@@ -115,6 +132,7 @@ impl kernel::Platform for Platform { +@@ -115,6 +131,7 @@ impl kernel::Platform for Platform { capsules::temperature::DRIVER_NUM => f(Some(self.temp)), capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)), nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)), @@ -48,80 +143,44 @@ index d72d204..8b97f8d 100644 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)), _ => f(None), } -@@ -323,6 +341,49 @@ pub unsafe fn reset_handler() { +@@ -323,6 +340,21 @@ pub unsafe fn reset_handler() { ) ); - + ++ // Enable power events to be sent to USB controller ++ nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD); ++ nrf52840::power::POWER.enable_interrupts(); ++ + // Configure USB controller -+ let usb: -+ &'static capsules::usb::usb_ctap::CtapUsbSyscallDriver< -+ 'static, -+ 'static, -+ nrf52840::usbd::Usbd<'static>, -+ > = { -+ let usb_ctap = static_init!( -+ capsules::usb::usbc_ctap_hid::ClientCtapHID< -+ 'static, -+ 'static, -+ nrf52840::usbd::Usbd<'static>, -+ >, -+ capsules::usb::usbc_ctap_hid::ClientCtapHID::new( -+ &nrf52840::usbd::USBD, -+ capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840, -+ VENDOR_ID, -+ PRODUCT_ID, -+ STRINGS, -+ ) -+ ); -+ nrf52840::usbd::USBD.set_client(usb_ctap); -+ -+ // Enable power events to be sent to USB controller -+ nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD); -+ nrf52840::power::POWER.enable_interrupts(); -+ -+ // Configure the USB userspace driver -+ let usb_driver = static_init!( -+ capsules::usb::usb_ctap::CtapUsbSyscallDriver< -+ 'static, -+ 'static, -+ nrf52840::usbd::Usbd<'static>, -+ >, -+ capsules::usb::usb_ctap::CtapUsbSyscallDriver::new( -+ usb_ctap, -+ board_kernel.create_grant(&memory_allocation_capability) -+ ) -+ ); -+ usb_ctap.set_client(usb_driver); -+ usb_driver as &'static _ -+ }; ++ let usb = components::usb_ctap::UsbCtapComponent::new( ++ board_kernel, ++ &nrf52840::usbd::USBD, ++ capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840, ++ VENDOR_ID, ++ PRODUCT_ID, ++ STRINGS, ++ ) ++ .finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd)); + nrf52_components::NrfClockComponent::new().finalize(()); - + let platform = Platform { -@@ -338,6 +399,7 @@ pub unsafe fn reset_handler() { +@@ -338,6 +370,7 @@ pub unsafe fn reset_handler() { alarm, analog_comparator, nvmc, + usb, ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), }; - + diff --git a/boards/nordic/nrf52840dk/src/main.rs b/boards/nordic/nrf52840dk/src/main.rs -index 2ebb384..303a451 100644 +index 2ebb384d8..4a7bfffdd 100644 --- a/boards/nordic/nrf52840dk/src/main.rs +++ b/boards/nordic/nrf52840dk/src/main.rs -@@ -72,6 +72,7 @@ use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferred - use kernel::component::Component; - #[allow(unused_imports)] - use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init}; -+use kernel::hil::usb::UsbController; - use nrf52840::gpio::Pin; - use nrf52_components::{self, UartChannel, UartPins}; - -@@ -113,6 +114,17 @@ pub mod io; +@@ -113,6 +113,17 @@ pub mod io; // - Set to true to use Segger RTT over USB. const USB_DEBUGGING: bool = false; - + +const VENDOR_ID: u16 = 0x1915; // Nordic Semiconductor +const PRODUCT_ID: u16 = 0x521f; // nRF52840 Dongle (PCA10059) +static STRINGS: &'static [&'static str] = &[ @@ -136,7 +195,7 @@ index 2ebb384..303a451 100644 // State for loading and holding applications. // How should the kernel respond when a process faults. const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic; -@@ -164,6 +176,11 @@ pub struct Platform { +@@ -164,6 +175,11 @@ pub struct Platform { >, nonvolatile_storage: &'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>, nvmc: &'static nrf52840::nvmc::SyscallDriver, @@ -146,9 +205,9 @@ index 2ebb384..303a451 100644 + nrf52840::usbd::Usbd<'static>, + >, } - + impl kernel::Platform for Platform { -@@ -184,6 +201,7 @@ impl kernel::Platform for Platform { +@@ -184,6 +200,7 @@ impl kernel::Platform for Platform { capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)), capsules::nonvolatile_storage_driver::DRIVER_NUM => f(Some(self.nonvolatile_storage)), nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)), @@ -156,66 +215,38 @@ index 2ebb384..303a451 100644 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)), _ => f(None), } -@@ -448,6 +466,49 @@ pub unsafe fn reset_handler() { +@@ -448,6 +465,21 @@ pub unsafe fn reset_handler() { ) ); - + ++ // Enable power events to be sent to USB controller ++ nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD); ++ nrf52840::power::POWER.enable_interrupts(); ++ + // Configure USB controller -+ let usb: -+ &'static capsules::usb::usb_ctap::CtapUsbSyscallDriver< -+ 'static, -+ 'static, -+ nrf52840::usbd::Usbd<'static>, -+ > = { -+ let usb_ctap = static_init!( -+ capsules::usb::usbc_ctap_hid::ClientCtapHID< -+ 'static, -+ 'static, -+ nrf52840::usbd::Usbd<'static>, -+ >, -+ capsules::usb::usbc_ctap_hid::ClientCtapHID::new( -+ &nrf52840::usbd::USBD, -+ capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840, -+ VENDOR_ID, -+ PRODUCT_ID, -+ STRINGS, -+ ) -+ ); -+ nrf52840::usbd::USBD.set_client(usb_ctap); -+ -+ // Enable power events to be sent to USB controller -+ nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD); -+ nrf52840::power::POWER.enable_interrupts(); -+ -+ // Configure the USB userspace driver -+ let usb_driver = static_init!( -+ capsules::usb::usb_ctap::CtapUsbSyscallDriver< -+ 'static, -+ 'static, -+ nrf52840::usbd::Usbd<'static>, -+ >, -+ capsules::usb::usb_ctap::CtapUsbSyscallDriver::new( -+ usb_ctap, -+ board_kernel.create_grant(&memory_allocation_capability) -+ ) -+ ); -+ usb_ctap.set_client(usb_driver); -+ usb_driver as &'static _ -+ }; ++ let usb = components::usb_ctap::UsbCtapComponent::new( ++ board_kernel, ++ &nrf52840::usbd::USBD, ++ capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840, ++ VENDOR_ID, ++ PRODUCT_ID, ++ STRINGS, ++ ) ++ .finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd)); + nrf52_components::NrfClockComponent::new().finalize(()); - + let platform = Platform { -@@ -464,6 +525,7 @@ pub unsafe fn reset_handler() { +@@ -464,6 +496,7 @@ pub unsafe fn reset_handler() { analog_comparator, nonvolatile_storage, nvmc, + usb, ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), }; - + diff --git a/capsules/src/driver.rs b/capsules/src/driver.rs -index 256fc0e..ae458b3 100644 +index 256fc0e9d..ae458b309 100644 --- a/capsules/src/driver.rs +++ b/capsules/src/driver.rs @@ -26,6 +26,7 @@ pub enum NUM { @@ -223,11 +254,11 @@ index 256fc0e..ae458b3 100644 UsbUser = 0x20005, I2cMasterSlave = 0x20006, + UsbCtap = 0x20009, - + // Radio BleAdvertising = 0x30000, diff --git a/capsules/src/usb/mod.rs b/capsules/src/usb/mod.rs -index 767f5de..3f3a4f6 100644 +index 767f5de83..3f3a4f646 100644 --- a/capsules/src/usb/mod.rs +++ b/capsules/src/usb/mod.rs @@ -1,5 +1,7 @@ @@ -240,7 +271,7 @@ index 767f5de..3f3a4f6 100644 +pub mod usbc_ctap_hid; diff --git a/capsules/src/usb/usb_ctap.rs b/capsules/src/usb/usb_ctap.rs new file mode 100644 -index 0000000..da3d16d +index 000000000..da3d16d85 --- /dev/null +++ b/capsules/src/usb/usb_ctap.rs @@ -0,0 +1,355 @@ @@ -601,10 +632,10 @@ index 0000000..da3d16d +} diff --git a/capsules/src/usb/usbc_ctap_hid.rs b/capsules/src/usb/usbc_ctap_hid.rs new file mode 100644 -index 0000000..d97b72d +index 000000000..642039120 --- /dev/null +++ b/capsules/src/usb/usbc_ctap_hid.rs -@@ -0,0 +1,363 @@ +@@ -0,0 +1,369 @@ +//! A USB HID client of the USB hardware interface + +use super::descriptors; @@ -687,7 +718,7 @@ index 0000000..d97b72d + max_ctrl_packet_size: u8, + vendor_id: u16, + product_id: u16, -+ strings: &'static [&'static str] ++ strings: &'static [&'static str], + ) -> Self { + let interfaces: &mut [InterfaceDescriptor] = &mut [ + // Interface declared in the FIDO2 specification, section 8.1.8.1 @@ -701,13 +732,19 @@ index 0000000..d97b72d + + let endpoints: &[&[EndpointDescriptor]] = &[&[ + EndpointDescriptor { -+ endpoint_address: EndpointAddress::new_const(ENDPOINT_NUM, TransferDirection::HostToDevice), ++ endpoint_address: EndpointAddress::new_const( ++ ENDPOINT_NUM, ++ TransferDirection::HostToDevice, ++ ), + transfer_type: TransferType::Interrupt, + max_packet_size: 64, + interval: 5, + }, + EndpointDescriptor { -+ endpoint_address: EndpointAddress::new_const(ENDPOINT_NUM, TransferDirection::DeviceToHost), ++ endpoint_address: EndpointAddress::new_const( ++ ENDPOINT_NUM, ++ TransferDirection::DeviceToHost, ++ ), + transfer_type: TransferType::Interrupt, + max_packet_size: 64, + interval: 5, @@ -717,8 +754,8 @@ index 0000000..d97b72d + let (device_descriptor_buffer, other_descriptor_buffer) = + descriptors::create_descriptor_buffers( + descriptors::DeviceDescriptor { -+ vendor_id: vendor_id, -+ product_id: product_id, ++ vendor_id, ++ product_id, + manufacturer_string: 1, + product_string: 2, + serial_number_string: 3, @@ -969,11 +1006,11 @@ index 0000000..d97b72d + } +} diff --git a/chips/nrf52840/src/lib.rs b/chips/nrf52840/src/lib.rs -index 942d028..ce73e1f 100644 +index 942d0288f..ce73e1f82 100644 --- a/chips/nrf52840/src/lib.rs +++ b/chips/nrf52840/src/lib.rs @@ -2,7 +2,7 @@ - + pub use nrf52::{ acomp, adc, aes, ble_radio, clock, constants, crt1, ficr, i2c, ieee802154_radio, init, nvmc, - pinmux, ppi, pwm, rtc, spi, temperature, timer, trng, uart, uicr, usbd,