mirror of
https://github.com/laanwj/k210-sdk-stuff.git
synced 2024-11-22 01:16:20 +04:00
rust: Split AES into three parts, setup, process data and finish
Might want to re-use the setup/finish code for streaming data and/or DMA.
This commit is contained in:
parent
68ddf3b1bc
commit
e080a03821
@ -30,30 +30,16 @@ fn write4pad(arr: &mut [u8], ofs: usize, val: u32) {
|
|||||||
arr[ofs..ofs+n].copy_from_slice(&val.to_le_bytes()[0..n]);
|
arr[ofs..ofs+n].copy_from_slice(&val.to_le_bytes()[0..n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** AES operation (encrypt or decrypt) using hardware engine. Takes a &mut
|
fn setup(
|
||||||
* AES as only one operation can be active at a time.
|
|
||||||
*
|
|
||||||
* Supported modes:
|
|
||||||
*
|
|
||||||
* Mode Keybits Extra input Extra output
|
|
||||||
* ---- --------------- ------------------------ ----------------
|
|
||||||
* ECB 128 / 192 / 256 no IV
|
|
||||||
* CBC 128 / 192 / 256 128 bit IV
|
|
||||||
* GCM 128 / 192 / 256 96 bit IV + ? bytes AAD) 128 bit tag (optional)
|
|
||||||
*/
|
|
||||||
pub fn run(
|
|
||||||
aes: &mut pac::AES,
|
aes: &mut pac::AES,
|
||||||
cipher_mode: cipher_mode,
|
cipher_mode: cipher_mode,
|
||||||
encrypt_sel: encrypt_sel,
|
encrypt_sel: encrypt_sel,
|
||||||
key: &[u8],
|
key: &[u8],
|
||||||
iv: &[u8],
|
iv: &[u8],
|
||||||
aad: &[u8],
|
aad: &[u8],
|
||||||
ind: &[u8],
|
len: usize,
|
||||||
outd: &mut [u8],
|
) {
|
||||||
tag: &mut [u8],
|
assert!(len != 0);
|
||||||
)
|
|
||||||
{
|
|
||||||
assert!(ind.len() != 0);
|
|
||||||
match cipher_mode {
|
match cipher_mode {
|
||||||
cipher_mode::ECB => assert!(iv.len() == 0 && aad.len() == 0),
|
cipher_mode::ECB => assert!(iv.len() == 0 && aad.len() == 0),
|
||||||
cipher_mode::CBC => assert!(iv.len() == 16 && aad.len() == 0),
|
cipher_mode::CBC => assert!(iv.len() == 16 && aad.len() == 0),
|
||||||
@ -89,7 +75,7 @@ pub fn run(
|
|||||||
aes.encrypt_sel.write(|w|
|
aes.encrypt_sel.write(|w|
|
||||||
w.encrypt_sel().variant(encrypt_sel));
|
w.encrypt_sel().variant(encrypt_sel));
|
||||||
aes.aad_num.write(|w| w.bits((aad.len() as u32).wrapping_sub(1)));
|
aes.aad_num.write(|w| w.bits((aad.len() as u32).wrapping_sub(1)));
|
||||||
aes.pc_num.write(|w| w.bits((ind.len() as u32).wrapping_sub(1)));
|
aes.pc_num.write(|w| w.bits((len as u32).wrapping_sub(1)));
|
||||||
|
|
||||||
// Turn on engine
|
// Turn on engine
|
||||||
aes.en.write(|w|
|
aes.en.write(|w|
|
||||||
@ -103,21 +89,16 @@ pub fn run(
|
|||||||
aes.aad_data.write(|w| w.bits(read4pad(aad, i * 4)));
|
aes.aad_data.write(|w| w.bits(read4pad(aad, i * 4)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send and receive plaintext/ciphertext
|
}
|
||||||
let mut iptr = 0;
|
}
|
||||||
let mut optr = 0;
|
|
||||||
while optr < ind.len() {
|
|
||||||
while iptr < ind.len() && aes.data_in_flag.read().data_in_flag() == DATA_IN_FLAG_A::CAN_INPUT {
|
|
||||||
aes.text_data.write(|w| w.bits(read4pad(ind, iptr)));
|
|
||||||
iptr += 4;
|
|
||||||
}
|
|
||||||
while aes.data_out_flag.read().data_out_flag() == DATA_OUT_FLAG_A::CAN_OUTPUT {
|
|
||||||
write4pad(outd, optr, aes.out_data.read().bits());
|
|
||||||
optr += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if cipher_mode == cipher_mode::GCM && tag.len() != 0 {
|
fn finish(
|
||||||
|
aes: &mut pac::AES,
|
||||||
|
cipher_mode: cipher_mode,
|
||||||
|
tag: &mut [u8],
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
if cipher_mode == cipher_mode::GCM {
|
||||||
// Read and store tag, if requested
|
// Read and store tag, if requested
|
||||||
// TODO: the engine also supports writing a tag through gcm_in_tag
|
// TODO: the engine also supports writing a tag through gcm_in_tag
|
||||||
// and verifying it, presumably in linear time.
|
// and verifying it, presumably in linear time.
|
||||||
@ -134,9 +115,11 @@ pub fn run(
|
|||||||
atomic::compiler_fence(Ordering::SeqCst)
|
atomic::compiler_fence(Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..4 {
|
if tag.len() != 0 {
|
||||||
let val = aes.gcm_out_tag[3 - i].read().bits();
|
for i in 0..4 {
|
||||||
tag[i*4..i*4+4].copy_from_slice(&val.to_be_bytes());
|
let val = aes.gcm_out_tag[3 - i].read().bits();
|
||||||
|
tag[i*4..i*4+4].copy_from_slice(&val.to_be_bytes());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,3 +129,48 @@ pub fn run(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** AES operation (encrypt or decrypt) using hardware engine. Takes a &mut
|
||||||
|
* AES as only one operation can be active at a time.
|
||||||
|
*
|
||||||
|
* Supported modes:
|
||||||
|
*
|
||||||
|
* Mode Keybits Extra input Extra output
|
||||||
|
* ---- --------------- ------------------------ ----------------
|
||||||
|
* ECB 128 / 192 / 256 no IV
|
||||||
|
* CBC 128 / 192 / 256 128 bit IV
|
||||||
|
* GCM 128 / 192 / 256 96 bit IV + ? bytes AAD) 128 bit tag (optional)
|
||||||
|
*/
|
||||||
|
pub fn run(
|
||||||
|
aes: &mut pac::AES,
|
||||||
|
cipher_mode: cipher_mode,
|
||||||
|
encrypt_sel: encrypt_sel,
|
||||||
|
key: &[u8],
|
||||||
|
iv: &[u8],
|
||||||
|
aad: &[u8],
|
||||||
|
ind: &[u8],
|
||||||
|
outd: &mut [u8],
|
||||||
|
tag: &mut [u8],
|
||||||
|
)
|
||||||
|
{
|
||||||
|
setup(aes, cipher_mode, encrypt_sel, key, iv, aad, ind.len());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// Send and receive plaintext/ciphertext
|
||||||
|
let mut iptr = 0;
|
||||||
|
let mut optr = 0;
|
||||||
|
while optr < ind.len() {
|
||||||
|
while iptr < ind.len() && aes.data_in_flag.read().data_in_flag() == DATA_IN_FLAG_A::CAN_INPUT {
|
||||||
|
aes.text_data.write(|w| w.bits(read4pad(ind, iptr)));
|
||||||
|
iptr += 4;
|
||||||
|
}
|
||||||
|
while aes.data_out_flag.read().data_out_flag() == DATA_OUT_FLAG_A::CAN_OUTPUT {
|
||||||
|
write4pad(outd, optr, aes.out_data.read().bits());
|
||||||
|
optr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
finish(aes, cipher_mode, tag);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user