diff --git a/Cargo.toml b/Cargo.toml index a4ebf49e12..0f8794b4c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ members = [ "boards/wm1110dev", "boards/makepython-nrf52840", "boards/nordic/nrf52840dk", + "boards/nordic/nrf52840dk-bonus", "boards/nordic/nrf52840_dongle", "boards/nordic/nrf52dk", "boards/sma_q3", diff --git a/boards/nordic/nrf52840dk-bonus/Cargo.toml b/boards/nordic/nrf52840dk-bonus/Cargo.toml new file mode 100644 index 0000000000..f1dc8b9a18 --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/Cargo.toml @@ -0,0 +1,21 @@ +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2022. + +[package] +name = "nrf52840dk-bonus" +version.workspace = true +authors.workspace = true +build = "../../build.rs" +edition.workspace = true + +[dependencies] +components = { path = "../../components" } +cortexm4 = { path = "../../../arch/cortex-m4" } +kernel = { path = "../../../kernel" } +nrf52840 = { path = "../../../chips/nrf52840" } +nrf52_components = { path = "../nrf52_components" } +nrf52840dk = { path = "../nrf52840dk" } + +capsules-core = { path = "../../../capsules/core" } +capsules-extra = { path = "../../../capsules/extra" } diff --git a/boards/nordic/nrf52840dk-bonus/Makefile b/boards/nordic/nrf52840dk-bonus/Makefile new file mode 100644 index 0000000000..d6ca69fc79 --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/Makefile @@ -0,0 +1,39 @@ +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2022. + +# Makefile for building the tock kernel for the nRF development kit + +TARGET=thumbv7em-none-eabi +PLATFORM=nrf52840dk-bonus + +include ../../Makefile.common + +TOCKLOADER=tockloader + +# Where in the SAM4L flash to load the kernel with `tockloader` +KERNEL_ADDRESS=0x00000 + +# Upload programs over uart with tockloader +ifdef PORT + TOCKLOADER_GENERAL_FLAGS += --port $(PORT) +endif + +# Default target for installing the kernel. +.PHONY: install +install: flash + +# Upload the kernel over JTAG +.PHONY: flash +flash: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin + $(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --jlink $< + +# Upload the kernel over JTAG using OpenOCD +.PHONY: flash-openocd +flash-openocd: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin + $(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --openocd $< + +# Upload the kernel over serial/bootloader +.PHONY: program +program: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).hex + $(error Cannot program nRF52840DK over USB. Use \`make flash\` and JTAG) diff --git a/boards/nordic/nrf52840dk-bonus/README.md b/boards/nordic/nrf52840dk-bonus/README.md new file mode 100644 index 0000000000..3a05a5e970 --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/README.md @@ -0,0 +1,63 @@ +Platform-Specific Instructions: nRF52840-DK +=================================== + +The [nRF52840 Development +Kit](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) is a platform +based around the nRF52840, an SoC with an ARM Cortex-M4 and a BLE +radio. The kit is Arduino shield compatible and includes several +buttons. + +## Getting Started + +First, follow the [Tock Getting Started guide](../../../doc/Getting_Started.md) + +JTAG is the preferred method to program. The development kit has an +integrated JTAG debugger, you simply need to [install JTAG +software](../../../doc/Getting_Started.md#loading-the-kernel-onto-a-board). + +## Programming the kernel +Once you have all software installed, you should be able to simply run +make flash in this directory to install a fresh kernel. + +## Programming user-level applications +You can program an application over USB using the integrated JTAG and `tockloader`: + +```bash +$ cd libtock-c/examples/ +$ make +$ tockloader install --jlink --board nrf52dk +``` + +The same options (`--jlink --board nrf52dk`) must be passed for other tockloader commands +such as `erase-apps` or `list`. + +Viewing console output on the nrf52840dk is slightly different from other boards. You must use +```bash +$ tockloader listen +``` +**followed by a press of the reset button** in order to view console output starting from the boot +sequence. Notably, you should not +pass the `--jlink` option to `tockloader listen`. + +## Console output + +This board supports two methods for writing messages to a console interface +(console driver for applications as well as debug statements in the kernel). + +By default, messages are written to a UART interface over the GPIO pins `P0.05` +to `P0.08` (see the [main.rs](src/main.rs) file). + +If you don't have any UART cables or want to use a different interface, there is +also a console over the Segger RTT protocol. This only requires a micro-USB +cable on the USB debugging port (the same used to flash Tock on the board), and +is enabled by setting the `USB_DEBUGGING` constant to `true` in the +[main.rs](src/main.rs) file. +This disables the UART interface. + +For instructions about how to receive RTT messages on the host, see the +[corresponding capsule](../../../capsules/src/segger_rtt.rs). + +## Debugging + +See the [nrf52dk README](../nrf52dk/README.md) for information about debugging +the nRF52840dk. diff --git a/boards/nordic/nrf52840dk-bonus/jtag/gdbinit_pca10040.jlink b/boards/nordic/nrf52840dk-bonus/jtag/gdbinit_pca10040.jlink new file mode 100644 index 0000000000..8094e76819 --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/jtag/gdbinit_pca10040.jlink @@ -0,0 +1,28 @@ +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2018. +# +# +# +# J-LINK GDB SERVER initialization +# +# This connects to a GDB Server listening +# for commands on localhost at tcp port 2331 +target remote localhost:2331 +monitor speed 30 +file ../../../../target/thumbv7em-none-eabi/release/nrf52dk +monitor reset +# +# CPU core initialization (to be done by user) +# +# Set the processor mode +# monitor reg cpsr = 0xd3 +# Set auto JTAG speed +monitor speed auto +# Setup GDB FOR FASTER DOWNLOADS +set remote memory-write-packet-size 1024 +set remote memory-write-packet-size fixed +# tui enable +# layout split +# layout service_pending_interrupts +b initialize_ram_jump_to_main diff --git a/boards/nordic/nrf52840dk-bonus/jtag/jdbserver_pca10040.sh b/boards/nordic/nrf52840dk-bonus/jtag/jdbserver_pca10040.sh new file mode 100755 index 0000000000..5edf8b5cb8 --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/jtag/jdbserver_pca10040.sh @@ -0,0 +1,5 @@ +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2023. + +JLinkGDBServer -device nrf52 -speed 1200 -if swd -AutoConnect 1 -port 2331 diff --git a/boards/nordic/nrf52840dk-bonus/layout.ld b/boards/nordic/nrf52840dk-bonus/layout.ld new file mode 100644 index 0000000000..3eccbaa12d --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/layout.ld @@ -0,0 +1,6 @@ +/* Licensed under the Apache License, Version 2.0 or the MIT License. */ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* Copyright Tock Contributors 2023. */ + +INCLUDE ../nrf52840_chip_layout.ld +INCLUDE ../../kernel_layout.ld diff --git a/boards/nordic/nrf52840dk-bonus/src/io.rs b/boards/nordic/nrf52840dk-bonus/src/io.rs new file mode 100644 index 0000000000..2645e61a52 --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/src/io.rs @@ -0,0 +1,114 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2022. + +use core::fmt::Write; +use core::panic::PanicInfo; +use kernel::debug; +use kernel::debug::IoWrite; +use kernel::hil::led; +use kernel::hil::uart; +use kernel::hil::uart::Configure; +use nrf52840::gpio::Pin; +use nrf52840::uart::{Uarte, UARTE0_BASE}; + +use crate::CHIP; +use crate::PROCESSES; +use crate::PROCESS_PRINTER; + +enum Writer { + WriterUart(/* initialized */ bool), + WriterRtt(&'static capsules_extra::segger_rtt::SeggerRttMemory<'static>), +} + +static mut WRITER: Writer = Writer::WriterUart(false); + +// Wait a fixed number of cycles to avoid missing characters over the RTT console +fn wait() { + for _ in 0..1000 { + cortexm4::support::nop(); + } +} + +/// Set the RTT memory buffer used to output panic messages. +pub unsafe fn set_rtt_memory( + rtt_memory: &'static capsules_extra::segger_rtt::SeggerRttMemory<'static>, +) { + WRITER = Writer::WriterRtt(rtt_memory); +} + +impl Write for Writer { + fn write_str(&mut self, s: &str) -> ::core::fmt::Result { + self.write(s.as_bytes()); + Ok(()) + } +} + +impl IoWrite for Writer { + fn write(&mut self, buf: &[u8]) -> usize { + match self { + Writer::WriterUart(ref mut initialized) => { + // Here, we create a second instance of the Uarte struct. + // This is okay because we only call this during a panic, and + // we will never actually process the interrupts + let uart = Uarte::new(UARTE0_BASE); + if !*initialized { + *initialized = true; + let _ = uart.configure(uart::Parameters { + baud_rate: 115200, + stop_bits: uart::StopBits::One, + parity: uart::Parity::None, + hw_flow_control: false, + width: uart::Width::Eight, + }); + } + for &c in buf { + unsafe { + uart.send_byte(c); + } + while !uart.tx_ready() {} + } + } + Writer::WriterRtt(rtt_memory) => { + let up_buffer = unsafe { &*rtt_memory.get_up_buffer_ptr() }; + let buffer_len = up_buffer.length.get(); + let buffer = unsafe { + core::slice::from_raw_parts_mut( + up_buffer.buffer.get() as *mut u8, + buffer_len as usize, + ) + }; + + let mut write_position = up_buffer.write_position.get(); + + for &c in buf { + buffer[write_position as usize] = c; + write_position = (write_position + 1) % buffer_len; + up_buffer.write_position.set(write_position); + wait(); + } + } + }; + buf.len() + } +} + +#[cfg(not(test))] +#[no_mangle] +#[panic_handler] +/// Panic handler +pub unsafe fn panic_fmt(pi: &PanicInfo) -> ! { + // The nRF52840DK LEDs (see back of board) + let led_kernel_pin = &nrf52840::gpio::GPIOPin::new(Pin::P0_13); + let led = &mut led::LedLow::new(led_kernel_pin); + let writer = &mut WRITER; + debug::panic( + &mut [led], + writer, + pi, + &cortexm4::support::nop, + &PROCESSES, + &CHIP, + &PROCESS_PRINTER, + ) +} diff --git a/boards/nordic/nrf52840dk-bonus/src/main.rs b/boards/nordic/nrf52840dk-bonus/src/main.rs new file mode 100644 index 0000000000..2f078f5ee8 --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/src/main.rs @@ -0,0 +1,247 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2022. + +//! Tock kernel for the Nordic Semiconductor nRF52840 development kit (DK). +//! +//! It is based on nRF52840 SoC (Cortex M4 core with a BLE transceiver) with +//! many exported I/O and peripherals. +//! +//! Pin Configuration +//! ------------------- +//! +//! ### `GPIO` +//! +//! | # | Pin | Ix | Header | Arduino | +//! |----|-------|----|--------|---------| +//! | 0 | P1.01 | 33 | P3 1 | D0 | +//! | 1 | P1.02 | 34 | P3 2 | D1 | +//! | 2 | P1.03 | 35 | P3 3 | D2 | +//! | 3 | P1.04 | 36 | P3 4 | D3 | +//! | 4 | P1.05 | 37 | P3 5 | D4 | +//! | 5 | P1.06 | 38 | P3 6 | D5 | +//! | 6 | P1.07 | 39 | P3 7 | D6 | +//! | 7 | P1.08 | 40 | P3 8 | D7 | +//! | 8 | P1.10 | 42 | P4 1 | D8 | +//! | 9 | P1.11 | 43 | P4 2 | D9 | +//! | 10 | P1.12 | 44 | P4 3 | D10 | +//! | 11 | P1.13 | 45 | P4 4 | D11 | +//! | 12 | P1.14 | 46 | P4 5 | D12 | +//! | 13 | P1.15 | 47 | P4 6 | D13 | +//! | 14 | P0.26 | 26 | P4 9 | D14 | +//! | 15 | P0.27 | 27 | P4 10 | D15 | +//! +//! ### `GPIO` / Analog Inputs +//! +//! | # | Pin | Header | Arduino | +//! |----|------------|--------|---------| +//! | 16 | P0.03 AIN1 | P2 1 | A0 | +//! | 17 | P0.04 AIN2 | P2 2 | A1 | +//! | 18 | P0.28 AIN4 | P2 3 | A2 | +//! | 19 | P0.29 AIN5 | P2 4 | A3 | +//! | 20 | P0.30 AIN6 | P2 5 | A4 | +//! | 21 | P0.31 AIN7 | P2 6 | A5 | +//! | 22 | P0.02 AIN0 | P4 8 | AVDD | +//! +//! ### Onboard Functions +//! +//! | Pin | Header | Function | +//! |-------|--------|----------| +//! | P0.05 | P6 3 | UART RTS | +//! | P0.06 | P6 4 | UART TXD | +//! | P0.07 | P6 5 | UART CTS | +//! | P0.08 | P6 6 | UART RXT | +//! | P0.11 | P24 1 | Button 1 | +//! | P0.12 | P24 2 | Button 2 | +//! | P0.13 | P24 3 | LED 1 | +//! | P0.14 | P24 4 | LED 2 | +//! | P0.15 | P24 5 | LED 3 | +//! | P0.16 | P24 6 | LED 4 | +//! | P0.18 | P24 8 | Reset | +//! | P0.19 | P24 9 | SPI CLK | +//! | P0.20 | P24 10 | SPI MOSI | +//! | P0.21 | P24 11 | SPI MISO | +//! | P0.22 | P24 12 | SPI CS | +//! | P0.24 | P24 14 | Button 3 | +//! | P0.25 | P24 15 | Button 4 | +//! | P0.26 | P24 16 | I2C SDA | +//! | P0.27 | P24 17 | I2C SCL | + +#![no_std] +// Disable this attribute when documenting, as a workaround for +// https://github.com/rust-lang/rust/issues/62184. +#![cfg_attr(not(doc), no_main)] +#![deny(missing_docs)] + +use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm; +use capsules_extra::net::ieee802154::MacAddress; +use capsules_extra::net::ipv6::ip_utils::IPAddr; +use kernel::component::Component; +use kernel::hil::led::LedLow; +use kernel::hil::time::Counter; +#[allow(unused_imports)] +use kernel::hil::usb::Client; +use kernel::platform::{KernelResources, SyscallDriverLookup}; +use kernel::scheduler::round_robin::RoundRobinSched; +#[allow(unused_imports)] +use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init}; +use nrf52840::gpio::Pin; +use nrf52840::interrupt_service::Nrf52840DefaultPeripherals; +use nrf52_components::{UartChannel, UartPins}; + +#[allow(dead_code)] +mod test; + +// The nRF52840DK LEDs (see back of board) +const LED1_PIN: Pin = Pin::P0_13; +const LED2_PIN: Pin = Pin::P0_14; +const LED3_PIN: Pin = Pin::P0_15; +const LED4_PIN: Pin = Pin::P0_16; + +// The nRF52840DK buttons (see back of board) +const BUTTON1_PIN: Pin = Pin::P0_11; +const BUTTON2_PIN: Pin = Pin::P0_12; +const BUTTON3_PIN: Pin = Pin::P0_24; +const BUTTON4_PIN: Pin = Pin::P0_25; +const BUTTON_RST_PIN: Pin = Pin::P0_18; + +const UART_RTS: Option = Some(Pin::P0_05); +const UART_TXD: Pin = Pin::P0_06; +const UART_CTS: Option = Some(Pin::P0_07); +const UART_RXD: Pin = Pin::P0_08; + +const SPI_MOSI: Pin = Pin::P0_20; +const SPI_MISO: Pin = Pin::P0_21; +const SPI_CLK: Pin = Pin::P0_19; +const SPI_CS: Pin = Pin::P0_22; + +const SPI_MX25R6435F_CHIP_SELECT: Pin = Pin::P0_17; +const SPI_MX25R6435F_WRITE_PROTECT_PIN: Pin = Pin::P0_22; +const SPI_MX25R6435F_HOLD_PIN: Pin = Pin::P0_23; + +/// I2C pins +const I2C_SDA_PIN: Pin = Pin::P0_26; +const I2C_SCL_PIN: Pin = Pin::P0_27; + +// Constants related to the configuration of the 15.4 network stack +const PAN_ID: u16 = 0xABCD; +const DST_MAC_ADDR: capsules_extra::net::ieee802154::MacAddress = + capsules_extra::net::ieee802154::MacAddress::Short(49138); +const DEFAULT_CTX_PREFIX_LEN: u8 = 8; //Length of context for 6LoWPAN compression +const DEFAULT_CTX_PREFIX: [u8; 16] = [0x0_u8; 16]; //Context for 6LoWPAN Compression + +/// Debug Writer +pub mod io; + +// Whether to use UART debugging or Segger RTT (USB) debugging. +// - Set to false to use UART. +// - Set to true to use Segger RTT over USB. +const USB_DEBUGGING: bool = false; + +// State for loading and holding applications. +// How should the kernel respond when a process faults. +const FAULT_RESPONSE: kernel::process::PanicFaultPolicy = kernel::process::PanicFaultPolicy {}; + +// Number of concurrent processes this platform supports. +const NUM_PROCS: usize = 8; + +static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] = + [None; NUM_PROCS]; + +static mut CHIP: Option<&'static nrf52840::chip::NRF52> = None; +static mut PROCESS_PRINTER: Option<&'static kernel::process::ProcessPrinterText> = None; + +/// Dummy buffer that causes the linker to reserve enough space for the stack. +#[no_mangle] +#[link_section = ".stack_buffer"] +pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000]; + +//------------------------------------------------------------------------------ +// SYSCALL DRIVER TYPE DEFINITIONS +//------------------------------------------------------------------------------ + +/// Supported drivers by the platform +pub struct BonusPlatform { + root_platform: nrf52840dk::Platform, +} + +impl SyscallDriverLookup for BonusPlatform { + fn with_driver(&self, driver_num: usize, f: F) -> R + where + F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R, + { + match driver_num { + _ => self.root_platform.with_driver(driver_num, f), + } + } +} + +impl KernelResources>> + for BonusPlatform +{ + type SyscallDriverLookup = Self; + type SyscallFilter = (); + type ProcessFault = (); + type CredentialsCheckingPolicy = (); + type Scheduler = RoundRobinSched<'static>; + type SchedulerTimer = cortexm4::systick::SysTick; + type WatchDog = (); + type ContextSwitchCallback = (); + + fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup { + self + } + fn syscall_filter(&self) -> &Self::SyscallFilter { + &() + } + fn process_fault(&self) -> &Self::ProcessFault { + &() + } + fn credentials_checking_policy(&self) -> &'static Self::CredentialsCheckingPolicy { + &() + } + fn scheduler(&self) -> &Self::Scheduler { + self.root_platform.scheduler + } + fn scheduler_timer(&self) -> &Self::SchedulerTimer { + &self.root_platform.systick + } + fn watchdog(&self) -> &Self::WatchDog { + &() + } + fn context_switch_callback(&self) -> &Self::ContextSwitchCallback { + &() + } +} + +// /// This is in a separate, inline(never) function so that its stack frame is +// /// removed when this function returns. Otherwise, the stack space used for +// /// these static_inits is wasted. +// #[inline(never)] +// pub unsafe fn start() -> ( +// &'static kernel::Kernel, +// Platform, +// &'static nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>, +// ) { + +// (board_kernel, platform, chip) +// } + +/// Main function called after RAM initialized. +#[no_mangle] +pub unsafe fn main() { + let main_loop_capability = create_capability!(capabilities::MainLoopCapability); + + let (board_kernel, platform, chip) = nrf52840dk::start(); + + let bonus_platform = BonusPlatform { + root_platform: platform, + }; + + board_kernel.kernel_loop( + &bonus_platform, + chip, + Some(&bonus_platform.root_platform.ipc), + &main_loop_capability, + ); +} diff --git a/boards/nordic/nrf52840dk-bonus/src/test/aes_test.rs b/boards/nordic/nrf52840dk-bonus/src/test/aes_test.rs new file mode 100644 index 0000000000..4a7b215f4f --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/src/test/aes_test.rs @@ -0,0 +1,95 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2022. + +//! Test that AES (either CTR or CBC mode) is working properly. +//! +//! To test CBC mode, add the following line to the imix boot sequence: +//! ``` +//! test::aes_test::run_aes128_cbc(); +//! ``` +//! You should see the following output: +//! ``` +//! aes_test passed (CBC Enc Src/Dst) +//! aes_test passed (CBC Dec Src/Dst) +//! aes_test passed (CBC Enc In-place) +//! aes_test passed (CBC Dec In-place) +//! ``` +//! To test CTR mode, add the following line to the imix boot sequence: +//! ``` +//! test::aes_test::run_aes128_ctr(); +//! ``` +//! You should see the following output: +//! ``` +//! aes_test CTR passed: (CTR Enc Ctr Src/Dst) +//! aes_test CTR passed: (CTR Dec Ctr Src/Dst) +//! ``` + +use capsules_extra::test::aes::TestAes128Cbc; +use capsules_extra::test::aes::TestAes128Ctr; +use capsules_extra::test::aes::TestAes128Ecb; +use kernel::hil::symmetric_encryption::{AES128, AES128_BLOCK_SIZE, AES128_KEY_SIZE}; +use kernel::static_init; +use nrf52840::aes::AesECB; + +pub unsafe fn run_aes128_ctr(aes: &'static AesECB) { + let t = static_init_test_ctr(aes); + aes.set_client(t); + + t.run(); +} + +pub unsafe fn run_aes128_cbc(aes: &'static AesECB) { + let t = static_init_test_cbc(aes); + aes.set_client(t); + + t.run(); +} + +pub unsafe fn run_aes128_ecb(aes: &'static AesECB) { + let t = static_init_test_ecb(aes); + aes.set_client(t); + + t.run(); +} + +unsafe fn static_init_test_ctr( + aes: &'static AesECB, +) -> &'static TestAes128Ctr<'static, AesECB<'static>> { + let source = static_init!([u8; 4 * AES128_BLOCK_SIZE], [0; 4 * AES128_BLOCK_SIZE]); + let data = static_init!([u8; 6 * AES128_BLOCK_SIZE], [0; 6 * AES128_BLOCK_SIZE]); + let key = static_init!([u8; AES128_KEY_SIZE], [0; AES128_KEY_SIZE]); + let iv = static_init!([u8; AES128_BLOCK_SIZE], [0; AES128_BLOCK_SIZE]); + + static_init!( + TestAes128Ctr<'static, AesECB>, + TestAes128Ctr::new(aes, key, iv, source, data, true) + ) +} + +unsafe fn static_init_test_cbc( + aes: &'static AesECB, +) -> &'static TestAes128Cbc<'static, AesECB<'static>> { + let source = static_init!([u8; 4 * AES128_BLOCK_SIZE], [0; 4 * AES128_BLOCK_SIZE]); + let data = static_init!([u8; 6 * AES128_BLOCK_SIZE], [0; 6 * AES128_BLOCK_SIZE]); + let key = static_init!([u8; AES128_KEY_SIZE], [0; AES128_KEY_SIZE]); + let iv = static_init!([u8; AES128_BLOCK_SIZE], [0; AES128_BLOCK_SIZE]); + + static_init!( + TestAes128Cbc<'static, AesECB>, + TestAes128Cbc::new(aes, key, iv, source, data, false) + ) +} + +unsafe fn static_init_test_ecb( + aes: &'static AesECB, +) -> &'static TestAes128Ecb<'static, AesECB<'static>> { + let source = static_init!([u8; 4 * AES128_BLOCK_SIZE], [0; 4 * AES128_BLOCK_SIZE]); + let data = static_init!([u8; 6 * AES128_BLOCK_SIZE], [0; 6 * AES128_BLOCK_SIZE]); + let key = static_init!([u8; AES128_KEY_SIZE], [0; AES128_KEY_SIZE]); + + static_init!( + TestAes128Ecb<'static, AesECB>, + TestAes128Ecb::new(aes, key, source, data, false) + ) +} diff --git a/boards/nordic/nrf52840dk-bonus/src/test/hmac_sha256_test.rs b/boards/nordic/nrf52840dk-bonus/src/test/hmac_sha256_test.rs new file mode 100644 index 0000000000..308f1b0b01 --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/src/test/hmac_sha256_test.rs @@ -0,0 +1,59 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2022. + +//! This tests a software HMAC-SHA256 implementation. To run this test, add this +//! line to the imix boot sequence: +//! +//! ``` +//! test::hmac_sha256_test::run_hmacsha256(); +//! ``` + +use capsules_extra::hmac_sha256::HmacSha256Software; +use capsules_extra::sha256::Sha256Software; +use capsules_extra::test::hmac_sha256::TestHmacSha256; +use kernel::deferred_call::DeferredCallClient; +use kernel::static_init; + +pub unsafe fn run_hmacsha256() { + let t = static_init_test_hmacsha256(); + t.run(); +} + +pub static mut DIGEST_DATA: [u8; 32] = [0; 32]; + +// Test from https://en.wikipedia.org/wiki/HMAC#Examples +pub static mut WIKI_STR: [u8; 43] = *b"The quick brown fox jumps over the lazy dog"; +pub static mut WIKI_KEY: [u8; 3] = *b"key"; +pub static mut WIKI_HMAC: [u8; 32] = [ + 0xf7, 0xbc, 0x83, 0xf4, 0x30, 0x53, 0x84, 0x24, 0xb1, 0x32, 0x98, 0xe6, 0xaa, 0x6f, 0xb1, 0x43, + 0xef, 0x4d, 0x59, 0xa1, 0x49, 0x46, 0x17, 0x59, 0x97, 0x47, 0x9d, 0xbc, 0x2d, 0x1a, 0x3c, 0xd8, +]; + +unsafe fn static_init_test_hmacsha256() -> &'static TestHmacSha256 { + let sha256_hash_buf = static_init!([u8; 64], [0; 64]); + + let sha256 = static_init!(Sha256Software<'static>, Sha256Software::new()); + sha256.register(); + + let hmacsha256_verify_buf = static_init!([u8; 32], [0; 32]); + + let hmacsha256 = static_init!( + HmacSha256Software<'static, Sha256Software<'static>>, + HmacSha256Software::new(sha256, sha256_hash_buf, hmacsha256_verify_buf) + ); + kernel::hil::digest::Digest::set_client(sha256, hmacsha256); + + let test = static_init!( + TestHmacSha256, + TestHmacSha256::new( + hmacsha256, + &mut WIKI_KEY, + &mut WIKI_STR, + &mut DIGEST_DATA, + &WIKI_HMAC + ) + ); + + test +} diff --git a/boards/nordic/nrf52840dk-bonus/src/test/mod.rs b/boards/nordic/nrf52840dk-bonus/src/test/mod.rs new file mode 100644 index 0000000000..4929973fbf --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/src/test/mod.rs @@ -0,0 +1,7 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2023. + +pub(crate) mod aes_test; +pub(crate) mod hmac_sha256_test; +pub(crate) mod siphash24_test; diff --git a/boards/nordic/nrf52840dk-bonus/src/test/siphash24_test.rs b/boards/nordic/nrf52840dk-bonus/src/test/siphash24_test.rs new file mode 100644 index 0000000000..e7223ec0b2 --- /dev/null +++ b/boards/nordic/nrf52840dk-bonus/src/test/siphash24_test.rs @@ -0,0 +1,40 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2023. + +//! This tests a software SipHash24 implementation. To run this test, +//! add this line to the boot sequence: +//! ``` +//! test::siphash24_test::run_siphash24(); +//! ``` + +use capsules_extra::sip_hash::SipHasher24; +use capsules_extra::test::siphash24::TestSipHash24; +use kernel::static_init; + +pub unsafe fn run_siphash24() { + let t = static_init_test_siphash24(); + t.run(); +} + +pub static mut HSTRING: [u8; 15] = *b"tickv-super-key"; +pub static mut HBUF: [u8; 64] = [0; 64]; + +pub static mut HHASH: [u8; 8] = [0; 8]; +pub static mut CHASH: [u8; 8] = [0xd1, 0xdc, 0x3b, 0x92, 0xc2, 0x5a, 0x1b, 0x30]; + +unsafe fn static_init_test_siphash24() -> &'static TestSipHash24 { + let sha = static_init!(SipHasher24<'static>, SipHasher24::new()); + kernel::deferred_call::DeferredCallClient::register(sha); + + // Copy to the 64 byte buffer because we always hash 64 bytes. + for i in 0..15 { + HBUF[i] = HSTRING[i]; + } + let test = static_init!( + TestSipHash24, + TestSipHash24::new(sha, &mut HBUF, &mut HHASH, &mut CHASH) + ); + + test +}