Skip to content

Commit

Permalink
Add example and fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
thalesfragoso committed Jun 4, 2020
1 parent c094860 commit 0982e76
Show file tree
Hide file tree
Showing 13 changed files with 307 additions and 5 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ members = [
"examples/spi-demo",
"examples/twi-ssd1306",
"examples/ecb-demo",
"examples/ccm-demo",
]

[profile.dev]
Expand Down
29 changes: 29 additions & 0 deletions examples/ccm-demo/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "ccm-demo"
version = "0.0.1"
edition = "2018"
authors = [ "Thales Fragoso <[email protected]>"]

[dependencies]
cortex-m = "0.6.2"
cortex-m-rt = "0.6.12"
rtt-target = {version = "0.2.0", features = ["cortex-m"] }
rand_core = "0.5.1"

nrf52810-hal = { path = "../../nrf52810-hal", features = ["rt"], optional = true }
nrf52832-hal = { path = "../../nrf52832-hal", features = ["rt"], optional = true }
nrf52840-hal = { path = "../../nrf52840-hal", features = ["rt"], optional = true }
nrf52833-hal = { path = "../../nrf52833-hal", features = ["rt"], optional = true }
nrf51-hal = { path = "../../nrf51-hal", features = ["rt"], optional = true}

[[bin]]
name = "ccm-demo"
doc = false
test = false

[features]
51 = ["nrf51-hal"]
52810 = ["nrf52810-hal"]
52832 = ["nrf52832-hal"]
52840 = ["nrf52840-hal"]
52833 = ["nrf52833-hal"]
46 changes: 46 additions & 0 deletions examples/ccm-demo/Embed.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[probe]
# The index of the probe in the connected probe list.
# probe_index = 0
# The protocol to be used for communicating with the target.
protocol = "Swd"
# The speed in kHz of the data link to the target.
# speed = 1337

[flashing]
# Whether or not the target should be flashed.
enabled = true
# Whether or not the target should be halted after flashing.
halt_afterwards = false
# Whether or not bytes erased but not rewritten with data from the ELF
# should be restored with their contents before erasing.
restore_unwritten_bytes = false
# The path where an SVG of the assembled flash layout should be written to.
# flash_layout_output_path = "out.svg"

[general]
# The chip name of the chip to be debugged.
chip = "nRF52832"
# A list of chip descriptions to be loaded during runtime.
chip_descriptions = []
# The default log level to be used.
log_level = "Warn"

[rtt]
# Whether or not an RTTUI should be opened after flashing.
# This is exclusive and cannot be used with GDB at the moment.
enabled = true
# A list of channel associations to be displayed. If left empty, all channels are displayed.
channels = [
# { up = 0, down = 0, name = "name" }
]
# The duration in ms for which the logger should retry to attach to RTT.
timeout = 3000
# Whether timestamps in the RTTUI are enabled
show_timestamps = true

[gdb]
# Whether or not a GDB server should be opened after flashing.
# This is exclusive and cannot be used with RTT at the moment.
enabled = false
# The connection string in host:port format wher the GDB server will open a socket.
# gdb_connection_string
19 changes: 19 additions & 0 deletions examples/ccm-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# AES-CCM demo

Choose the microcontroller with one of the following features:
- 51
- 52810
- 52832
- 52840

Also, if using `cargo-embed`, change the `chip` and `protocol` fields in [Embed.toml](Embed.toml).

This demo uses the [rtt-target](https://crates.io/crates/rtt-target) crate for communication.

If using `cargo-embed`, just run

```console
$ cargo embed --release --features=52832 --target=thumbv7em-none-eabihf
```

Replace `52832` and `thumbv7em-none-eabihf` with the correct feature and target for your microcontroller.
146 changes: 146 additions & 0 deletions examples/ccm-demo/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#![no_std]
#![no_main]

// Import the right HAL/PAC crate, depending on the target chip
#[cfg(feature = "51")]
pub use nrf51_hal as hal;
#[cfg(feature = "52810")]
pub use nrf52810_hal as hal;
#[cfg(feature = "52832")]
pub use nrf52832_hal as hal;
#[cfg(feature = "52833")]
pub use nrf52833_hal as hal;
#[cfg(feature = "52840")]
pub use nrf52840_hal as hal;

use {
core::{
panic::PanicInfo,
sync::atomic::{compiler_fence, Ordering},
},
cortex_m_rt::entry,
hal::{
ccm::{CcmData, DataRate},
rng::Rng,
Ccm, Clocks,
},
rand_core::RngCore,
rtt_target::{rprintln, rtt_init_print},
};

mod stopwatch;
use stopwatch::StopWatch;

const MSG: [u8; 251] = *b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis justo
libero, commodo eget tincidunt quis, elementum at ipsum. Praesent pharetra imperdiet eros, at
vestibulum diam mattis ac. Nunc viverra cursus justo, sollicitudin placerat justo lectus.";

const KEY: [u8; 16] = *b"aaaaaaaaaaaaaaaa";
const HEADER_SIZE: usize = 3;
const MIC_SIZE: usize = 4;
const LENGTH_INDEX: usize = 1;

#[entry]
fn main() -> ! {
let p = hal::pac::Peripherals::take().unwrap();

let _clocks = Clocks::new(p.CLOCK).enable_ext_hfosc();
rtt_init_print!();

let mut rng = Rng::new(p.RNG);
let mut iv = [0u8; 8];
rng.fill_bytes(&mut iv);

let mut ccm_data_enc = CcmData::new(KEY, iv);
let mut ccm_data_dec = CcmData::new(KEY, iv);
let mut ccm = Ccm::init(p.CCM, p.AAR, DataRate::_1Mbit);

let mut clear_buffer = [0u8; 254];
let mut cipher_buffer = [0u8; 258];
let mut strach_area = [0u8; 271];

(&mut clear_buffer[HEADER_SIZE..]).copy_from_slice(&MSG[..]);

let mut stop_watch = StopWatch::new(p.TIMER0);

let payload_lengths: [usize; 5] = [251, 128, 64, 32, 16];

for &length in payload_lengths.iter() {
// Adjust payload length
clear_buffer[LENGTH_INDEX] = length as u8;

rprintln!("Starting Encryption of {} bytes", length);
stop_watch.start();

ccm.encrypt_packet(
&mut ccm_data_enc,
&clear_buffer[..],
&mut cipher_buffer[..],
&mut strach_area[..],
)
.unwrap();

let now = stop_watch.now();
stop_watch.stop();

assert_eq!(cipher_buffer[LENGTH_INDEX], (length + MIC_SIZE) as u8);

rprintln!("Encryption Took: {} us", now);

//rprint!("Cipher Packet: ");
//for number in cipher_buffer.iter().take(length + MIC_SIZE + HEADER_SIZE) {
// rprint!("{:x} ", *number);
//}

// Since we're both encrypting and decrypting, we need to decrement the counter to have the
// same counter that encrypted the message. `encrypt_packet` and `decrypt_packet`
// automatically increments the counter when the operation succeeds.
//ccm_data.decrement_counter();

// Clears the buffer, so we can inspect the decrypted text
clear_buffer = [0u8; 254];

rprintln!("\r\nStarting Decryption of {} bytes", length + MIC_SIZE);
stop_watch.start();

ccm.decrypt_packet(
&mut ccm_data_dec,
&mut clear_buffer[..],
&cipher_buffer[..],
&mut strach_area[..],
)
.unwrap();

let now = stop_watch.now();
stop_watch.stop();

rprintln!("Decryption Took: {} us\n\n", now);

assert_eq!(clear_buffer[LENGTH_INDEX], length as u8);
assert_eq!(
&clear_buffer[HEADER_SIZE..length + HEADER_SIZE],
&MSG[..length]
);

//let msg = core::str::from_utf8(&clear_buffer[HEADER_SIZE..length]).unwrap();
//rprintln!("Clear text: {}\n", msg);

// Clears the cipher text for next round
cipher_buffer = [0u8; 258];
}

rprintln!("Done");

loop {
compiler_fence(Ordering::SeqCst);
}
}

#[inline(never)]
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
rprintln!("{}", info);
loop {
compiler_fence(Ordering::SeqCst);
}
}
50 changes: 50 additions & 0 deletions examples/ccm-demo/src/stopwatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use super::hal::pac::TIMER0;

pub struct StopWatch {
regs: TIMER0,
}

impl StopWatch {
pub fn new(regs: TIMER0) -> Self {
// NOTE(unsafe) 1 is a valid pattern to write to this register
regs.tasks_stop.write(|w| unsafe { w.bits(1) });

regs.bitmode.write(|w| w.bitmode()._32bit());

// 16 Mhz / 2**4 = 1 Mhz = µs resolution
// NOTE(unsafe) 4 is a valid pattern to write to this register
regs.prescaler.write(|w| unsafe { w.prescaler().bits(4) });
// NOTE(unsafe) 1 is a valid pattern to write to this register
regs.tasks_clear.write(|w| unsafe { w.bits(1) });

Self { regs }
}

#[inline(always)]
pub fn start(&mut self) {
// NOTE(unsafe) 1 is a valid pattern to write to this register
self.regs.tasks_start.write(|w| unsafe { w.bits(1) });
}

#[inline(always)]
pub fn now(&self) -> u32 {
// NOTE(unsafe) 1 is a valid pattern to write to this register
self.regs.tasks_capture[0].write(|w| unsafe { w.bits(1) });
self.regs.cc[0].read().bits()
}

//#[inline(always)]
//pub fn pause(&mut self) {
// // NOTE(unsafe) 1 is a valid pattern to write to this register
// self.regs.tasks_stop.write(|w| unsafe { w.bits(1) });
//}

#[inline(always)]
pub fn stop(&mut self) {
// NOTE(unsafe) 1 is a valid pattern to write to this register
self.regs.tasks_stop.write(|w| unsafe { w.bits(1) });

// NOTE(unsafe) 1 is a valid pattern to write to this register
self.regs.tasks_clear.write(|w| unsafe { w.bits(1) });
}
}
14 changes: 9 additions & 5 deletions nrf-hal-common/src/ccm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ pub enum CcmError {
///
/// The NONCE vector (as specified by the Bluetooth Core Specification) will be generated by
/// hardware based on this information.
#[derive(Debug, PartialEq)]
#[repr(C)]
pub struct CcmData {
key: [u8; 16],
Expand Down Expand Up @@ -188,7 +189,8 @@ impl Ccm {
///
/// The generated MIC will be appended to after the payload in the `cipher_packet`. The slices
/// passed to this method must have the correct size, for more information refer to the module
/// level documentation.
/// level documentation. The counter in `ccm_data` will be incremented if the operation
/// succeeds.
pub fn encrypt_packet(
&mut self,
ccm_data: &mut CcmData,
Expand Down Expand Up @@ -223,7 +225,7 @@ impl Ccm {
return Err(CcmError::InsufficientScratchArea);
}

let length_variant = if payload_len > MAXIMUM_LENGTH_5BITS {
let length_variant = if payload_len <= MAXIMUM_LENGTH_5BITS {
LENGTH_A::DEFAULT
} else {
#[cfg(any(feature = "52840", feature = "52833"))]
Expand Down Expand Up @@ -260,6 +262,7 @@ impl Ccm {
// Clear events
self.regs.events_endcrypt.reset();
self.regs.events_error.reset();
self.regs.events_endksgen.reset();

// "Preceding reads and writes cannot be moved past subsequent writes."
compiler_fence(Ordering::Release);
Expand Down Expand Up @@ -289,7 +292,7 @@ impl Ccm {
///
/// This method will return an error if the MIC verification fails. The slices passed to this
/// method must have the correct size, for more information refer to the module level
/// documentation.
/// documentation. The counter in `ccm_data` will be incremented if the operation succeeds.
pub fn decrypt_packet(
&mut self,
ccm_data: &mut CcmData,
Expand Down Expand Up @@ -329,7 +332,7 @@ impl Ccm {
return Err(CcmError::InsufficientScratchArea);
}

let length_variant = if payload_len > MAXIMUM_LENGTH_5BITS {
let length_variant = if payload_len <= MAXIMUM_LENGTH_5BITS {
LENGTH_A::DEFAULT
} else {
#[cfg(any(feature = "52840", feature = "52833"))]
Expand Down Expand Up @@ -366,11 +369,12 @@ impl Ccm {
// Clear events
self.regs.events_endcrypt.reset();
self.regs.events_error.reset();
self.regs.events_endksgen.reset();

// "Preceding reads and writes cannot be moved past subsequent writes."
compiler_fence(Ordering::Release);

// Start key generation, encryption will start automatically because of the enabled short
// Start key generation, decryption will start automatically because of the enabled short
// in init
// NOTE(unsafe) 1 is a valid pattern to write to this register
self.regs.tasks_ksgen.write(|w| unsafe { w.bits(1) });
Expand Down
1 change: 1 addition & 0 deletions nrf51-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod prelude {
}

pub use crate::adc::Adc;
pub use crate::ccm::Ccm;
pub use crate::clocks::Clocks;
pub use crate::ecb::Ecb;
pub use crate::rtc::Rtc;
Expand Down
1 change: 1 addition & 0 deletions nrf52810-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod prelude {
pub use crate::time::U32Ext;
}

pub use crate::ccm::Ccm;
pub use crate::clocks::Clocks;
pub use crate::delay::Delay;
pub use crate::ecb::Ecb;
Expand Down
1 change: 1 addition & 0 deletions nrf52832-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod prelude {
pub use nrf_hal_common::prelude::*;
}

pub use crate::ccm::Ccm;
pub use crate::clocks::Clocks;
pub use crate::delay::Delay;
pub use crate::ecb::Ecb;
Expand Down
Loading

0 comments on commit 0982e76

Please sign in to comment.