Skip to content

Commit 7c60aa9

Browse files
committed
Change to jonas API
1 parent f080b06 commit 7c60aa9

3 files changed

Lines changed: 61 additions & 69 deletions

File tree

examples/ecb-demo/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This demo uses the [rtt-target](https://crates.io/crates/rtt-target) crate for c
1313
If using `cargo-embed`, just run
1414

1515
```console
16-
$ cargo embed --release --features=52832
16+
$ cargo embed --release --features=52832 --target=thumbv7em-none-eabihf
1717
```
1818

19-
Replace `52832` with the correct feature for your microcontroller.
19+
Replace `52832` and `thumbv7em-none-eabihf` with the correct feature and target for your microcontroller.

examples/ecb-demo/src/main.rs

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ use {
1717
sync::atomic::{compiler_fence, Ordering},
1818
},
1919
cortex_m_rt::entry,
20-
hal::{ecb::EcbData, Clocks, Ecb},
20+
hal::{Clocks, Ecb},
2121
rtt_target::{rprint, rprintln, rtt_init_print},
2222
};
2323

24-
const MSG: &[u8; 16] = b"Message to encry";
25-
const KEY: &[u8; 16] = b"aaaaaaaaaaaaaaaa";
24+
const MSG: [u8; 16] = *b"Message to encry";
25+
const KEY: [u8; 16] = *b"aaaaaaaaaaaaaaaa";
2626
const CIPHER_MSG: [u8; 16] = [
2727
0xFE, 0xF1, 0x63, 0x82, 0xB4, 0x54, 0x6B, 0xE4, 0xEB, 0x9A, 0x5C, 0x0E, 0xB6, 0x0E, 0x49, 0x2F,
2828
];
@@ -34,26 +34,21 @@ fn main() -> ! {
3434
let _clocks = Clocks::new(p.CLOCK).enable_ext_hfosc();
3535
rtt_init_print!();
3636

37-
let data = EcbData::new(*KEY, None);
38-
let mut ecb = Ecb::init(p.ECB, data);
39-
40-
let clear_text = ecb.clear_text();
41-
*clear_text = *MSG;
42-
rprintln!(
43-
"Clear text: {}",
44-
core::str::from_utf8(&clear_text[..]).unwrap(),
45-
);
37+
let mut ecb = Ecb::init(p.ECB);
4638

4739
loop {
48-
ecb.encrypt().unwrap();
49-
let chiper_text = ecb.cipher_text();
50-
for number in chiper_text.iter() {
40+
rprintln!("Starting Encryption\n");
41+
rprintln!("Clear text: {}", core::str::from_utf8(&MSG[..]).unwrap());
42+
43+
let cipher_text = ecb.crypt_block(MSG, KEY).unwrap();
44+
rprint!("Cipher Text: ");
45+
for number in cipher_text.iter() {
5146
rprint!("{:x} ", *number);
5247
}
53-
assert_eq!(*chiper_text, CIPHER_MSG);
54-
rprintln!("\n Encryption Done\n");
48+
assert_eq!(cipher_text, CIPHER_MSG);
49+
rprintln!("\r\n Encryption Done\n");
5550

56-
cortex_m::asm::delay(68_000_000);
51+
cortex_m::asm::delay(136_000_000);
5752
}
5853
}
5954

nrf-hal-common/src/ecb.rs

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,76 +5,73 @@
55
use crate::target::ECB;
66
use core::sync::atomic::{compiler_fence, Ordering};
77

8-
#[derive(Debug, Copy, Clone)]
98
/// Error type to represent a sharing conflict during encryption
9+
#[derive(Debug, Copy, Clone)]
1010
pub struct EncryptionError {}
1111

12-
#[repr(C)]
13-
/// Type that represents the data structure used by the ECB module
14-
pub struct EcbData {
15-
key: [u8; 16],
16-
clear_text: [u8; 16],
17-
chiper_text: [u8; 16],
18-
}
19-
20-
impl EcbData {
21-
/// Creates the data structures needed for ECB utilization
22-
///
23-
/// If `clear_text` is `None` it will be initialized to zero
24-
pub fn new(key: [u8; 16], clear_text: Option<[u8; 16]>) -> Self {
25-
Self {
26-
key,
27-
clear_text: clear_text.unwrap_or_default(),
28-
chiper_text: [0; 16],
29-
}
30-
}
31-
}
32-
33-
/// HAL structure interface to use the capabilities of the ECB peripheral
12+
/// A safe, blocking wrapper around the AES-ECB peripheral.
13+
///
14+
/// It's really just blockwise AES and not an ECB stream cipher. Blocks can be
15+
/// encrypted by calling `crypt_block`.
3416
pub struct Ecb {
3517
regs: ECB,
36-
data: EcbData,
3718
}
3819

3920
impl Ecb {
40-
/// Method for initialization
41-
pub fn init(regs: ECB, data: EcbData) -> Self {
21+
/// Takes ownership of the `ECB` peripheral, returning a safe wrapper.
22+
pub fn init(regs: ECB) -> Self {
4223
// Disable all interrupts
4324
regs.intenclr
4425
.write(|w| w.endecb().clear().errorecb().clear());
4526

4627
// NOTE(unsafe) 1 is a valid pattern to write to this register
4728
regs.tasks_stopecb.write(|w| unsafe { w.bits(1) });
48-
Self { regs, data }
29+
Self { regs }
4930
}
5031

51-
/// Gets a reference to the clear text memory
52-
///
53-
/// This is the data that will be encrypted by the encrypt method
54-
#[inline]
55-
pub fn clear_text(&mut self) -> &mut [u8; 16] {
56-
&mut self.data.clear_text
57-
}
32+
/// Destroys `self`, giving the `ECB` peripheral back.
33+
pub fn into_inner(self) -> ECB {
34+
// Clear all events
35+
self.regs.events_endecb.reset();
36+
self.regs.events_errorecb.reset();
5837

59-
/// Get a reference to the cipher text memory
60-
///
61-
/// This will contain the encrypted data after a successful encryption
62-
#[inline]
63-
pub fn cipher_text(&mut self) -> &mut [u8; 16] {
64-
&mut self.data.chiper_text
38+
self.regs
6539
}
6640

67-
/// Encrypts the data in the `clear_text` field, the encrypted data will be located in the
68-
/// cipher text field only if this method returns `Ok`
41+
/// Blocking encryption.
6942
///
70-
/// In case of an error, this method will return `Err(EncryptionError)`, in this case, the data
71-
/// in `cipher_text` is not valid
72-
pub fn encrypt(&mut self) -> Result<(), EncryptionError> {
73-
// Ecb data is repr(C) and has no padding
74-
let data_ptr = &mut self.data as *mut _ as u32;
43+
/// Encrypts a `block` with `key`.
44+
///
45+
/// # Errors
46+
///
47+
/// An error will be returned when the AES hardware raises an `ERRORECB`
48+
/// event. This can happen when an operation is started that shares the AES
49+
/// hardware resources with the AES ECB peripheral while an encryption
50+
/// operation is running.
51+
pub fn crypt_block(
52+
&mut self,
53+
block: [u8; 16],
54+
key: [u8; 16],
55+
) -> Result<[u8; 16], EncryptionError> {
56+
#[repr(C)]
57+
struct EcbData {
58+
key: [u8; 16],
59+
clear_text: [u8; 16],
60+
cipher_text: [u8; 16],
61+
}
62+
63+
// We allocate the DMA'd buffer on the stack, which means that we must
64+
// not panic or return before the AES operation is finished.
65+
let mut buf = EcbData {
66+
key,
67+
clear_text: block,
68+
cipher_text: [0; 16],
69+
};
7570

7671
// NOTE(unsafe) Any 32bits pattern is safe to write to this register
77-
self.regs.ecbdataptr.write(|w| unsafe { w.bits(data_ptr) });
72+
self.regs
73+
.ecbdataptr
74+
.write(|w| unsafe { w.bits(&mut buf as *mut _ as u32) });
7875

7976
// Clear all events
8077
self.regs.events_endecb.reset();
@@ -96,6 +93,6 @@ impl Ecb {
9693
// It's ok to return here, the events will be cleared before the next encryption
9794
return Err(EncryptionError {});
9895
}
99-
Ok(())
96+
Ok(buf.cipher_text)
10097
}
10198
}

0 commit comments

Comments
 (0)