Add component for USB CTAP.

This commit is contained in:
Guillaume Endignoux
2020-09-23 15:37:24 +02:00
parent 7d7204a35b
commit 359b243eb6

View File

@@ -1,16 +1,111 @@
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<ClientCtapHID<'static, 'static, $C>> = MaybeUninit::uninit();
+ static mut BUF2: MaybeUninit<CtapUsbSyscallDriver<'static, 'static, $C>> =
+ MaybeUninit::uninit();
+ (&mut BUF1, &mut BUF2)
+ };};
+}
+
+pub struct UsbCtapComponent<C: 'static + hil::usb::UsbController<'static>> {
+ board_kernel: &'static kernel::Kernel,
+ controller: &'static C,
+ max_ctrl_packet_size: u8,
+ vendor_id: u16,
+ product_id: u16,
+ strings: &'static [&'static str],
+}
+
+impl<C: 'static + hil::usb::UsbController<'static>> UsbCtapComponent<C> {
+ 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<C: 'static + hil::usb::UsbController<'static>> Component for UsbCtapComponent<C> {
+ type StaticInput = (
+ &'static mut MaybeUninit<ClientCtapHID<'static, 'static, C>>,
+ &'static mut MaybeUninit<CtapUsbSyscallDriver<'static, 'static, C>>,
+ );
+ 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;
@@ -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,
@@ -40,7 +135,7 @@ index d72d204..8b97f8d 100644
}
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,57 +143,29 @@ 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,
@@ -107,18 +174,10 @@ index d72d204..8b97f8d 100644
};
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;
@@ -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,
@@ -148,7 +207,7 @@ index 2ebb384..303a451 100644
}
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,57 +215,29 @@ 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,
@@ -215,7 +246,7 @@ index 2ebb384..303a451 100644
};
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 {
@@ -227,7 +258,7 @@ index 256fc0e..ae458b3 100644
// 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,7 +1006,7 @@ 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 @@