55use crate :: target:: ECB ;
66use 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 ) ]
1010pub 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`.
3416pub struct Ecb {
3517 regs : ECB ,
36- data : EcbData ,
3718}
3819
3920impl 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