Skip to content

Commit

Permalink
AES accelerator implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
matrixhead committed Jan 24, 2023
1 parent 4d036c3 commit 37f2dce
Show file tree
Hide file tree
Showing 20 changed files with 888 additions and 2 deletions.
5 changes: 5 additions & 0 deletions esp-hal-common/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ fn main() {
// - 'uart2'
// - 'usb_otg'
// - 'usb_serial_jtag'
// - 'aes'
//
// New symbols can be added as needed, but please be sure to update both this
// comment and the required vectors below.
Expand All @@ -60,6 +61,7 @@ fn main() {
"timg0",
"timg1",
"uart2",
"aes",
]
} else if esp32c2 {
vec![
Expand All @@ -83,6 +85,7 @@ fn main() {
"timg0",
"timg1",
"usb_serial_jtag",
"aes",
]
} else if esp32s2 {
vec![
Expand All @@ -99,6 +102,7 @@ fn main() {
"timg0",
"timg1",
"usb_otg",
"aes",
]
} else if esp32s3 {
vec![
Expand All @@ -117,6 +121,7 @@ fn main() {
"uart2",
"usb_otg",
"usb_serial_jtag",
"aes",
]
} else {
unreachable!(); // We've already confirmed exactly one chip was selected
Expand Down
84 changes: 84 additions & 0 deletions esp-hal-common/src/aes/esp32.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use crate::{
aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
};

impl<'d> Aes<'d> {
pub(super) fn init(&mut self, peripheral_clock_control: &mut PeripheralClockControl) {
peripheral_clock_control.enable(PeripheralEnable::Aes);
self.write_endianness(
Endianness::BigEndian,
Endianness::BigEndian,
Endianness::BigEndian,
Endianness::BigEndian,
Endianness::BigEndian,
Endianness::BigEndian,
);
}

pub(super) fn write_key(&mut self, key: &[u8]) {
debug_assert!(key.len() <= self.aes.key_.len() * ALIGN_SIZE);
debug_assert_eq!(key.len() % ALIGN_SIZE, 0);
Self::write_to_regset(key, self.aes.key_.len(), &mut self.aes.key_[0]);
}

pub(super) fn write_block(&mut self, block: &[u8]) {
debug_assert_eq!(block.len(), self.aes.text_.len() * ALIGN_SIZE);
Self::write_to_regset(block, self.aes.text_.len(), &mut self.aes.text_[0]);
}

pub(super) fn write_mode(&mut self, mode: u32) {
Self::write_to_register(&mut self.aes.mode, mode);
}

/// Configures how the state matrix would be laid out
pub fn write_endianness(
&mut self,
input_text_word_endianess: Endianness,
input_text_byte_endianess: Endianness,
output_text_word_endianess: Endianness,
output_text_byte_endianess: Endianness,
key_word_endianess: Endianness,
key_byte_endianess: Endianness,
) {
let mut to_write = 0_u32;
to_write |= key_byte_endianess as u32;
to_write |= (key_word_endianess as u32) << 1;
to_write |= (input_text_byte_endianess as u32) << 2;
to_write |= (input_text_word_endianess as u32) << 3;
to_write |= (output_text_byte_endianess as u32) << 4;
to_write |= (output_text_word_endianess as u32) << 5;
Self::write_to_register(&mut self.aes.endian, to_write);
}

pub(super) fn write_start(&mut self) {
self.aes.start.write(|w| w.start().set_bit())
}

pub(super) fn read_idle(&mut self) -> bool {
self.aes.idle.read().idle().bit_is_set()
}

pub(super) fn read_block(&self, block: &mut [u8]) {
debug_assert_eq!(block.len(), self.aes.text_.len() * ALIGN_SIZE);
Self::read_from_regset(block, self.aes.text_.len(), &self.aes.text_[0]);
}
}

impl AesFlavour for Aes128 {
type KeyType<'b> = &'b [u8; 16];
const ENCRYPT_MODE: u32 = 0;
const DECRYPT_MODE: u32 = 4;
}

impl AesFlavour for Aes192 {
type KeyType<'b> = &'b [u8; 24];
const ENCRYPT_MODE: u32 = 1;
const DECRYPT_MODE: u32 = 5;
}

impl AesFlavour for Aes256 {
type KeyType<'b> = &'b [u8; 32];
const ENCRYPT_MODE: u32 = 2;
const DECRYPT_MODE: u32 = 6;
}
58 changes: 58 additions & 0 deletions esp-hal-common/src/aes/esp32_c3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use crate::{
aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
};

impl<'d> Aes<'d> {
pub(super) fn init(&mut self, peripheral_clock_control: &mut PeripheralClockControl) {
peripheral_clock_control.enable(PeripheralEnable::Aes);
self.write_dma(false);
}

fn write_dma(&mut self, enable_dma: bool) {
match enable_dma {
true => self.aes.dma_enable.write(|w| w.dma_enable().set_bit()),
false => self.aes.dma_enable.write(|w| w.dma_enable().clear_bit()),
}
}

pub(super) fn write_key(&mut self, key: &[u8]) {
debug_assert!(key.len() <= 8 * ALIGN_SIZE);
debug_assert_eq!(key.len() % ALIGN_SIZE, 0);
Self::write_to_regset(key, 8, &mut self.aes.key_0);
}

pub(super) fn write_block(&mut self, block: &[u8]) {
debug_assert_eq!(block.len(), 4 * ALIGN_SIZE);
Self::write_to_regset(block, 4, &mut self.aes.text_in_0);
}

pub(super) fn write_mode(&mut self, mode: u32) {
Self::write_to_register(&mut self.aes.mode, mode);
}

pub(super) fn write_start(&mut self) {
self.aes.trigger.write(|w| w.trigger().set_bit())
}

pub(super) fn read_idle(&mut self) -> bool {
self.aes.state.read().state().bits() == 0
}

pub(super) fn read_block(&self, block: &mut [u8]) {
debug_assert_eq!(block.len(), 4 * ALIGN_SIZE);
Self::read_from_regset(block, 4, &self.aes.text_out_0);
}
}

impl AesFlavour for Aes128 {
type KeyType<'b> = &'b [u8; 16];
const ENCRYPT_MODE: u32 = 0;
const DECRYPT_MODE: u32 = 4;
}

impl AesFlavour for Aes256 {
type KeyType<'b> = &'b [u8; 32];
const ENCRYPT_MODE: u32 = 2;
const DECRYPT_MODE: u32 = 6;
}
92 changes: 92 additions & 0 deletions esp-hal-common/src/aes/esp32_s2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use crate::{
aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
};

impl<'d> Aes<'d> {
pub(super) fn init(&mut self, peripheral_clock_control: &mut PeripheralClockControl) {
peripheral_clock_control.enable(PeripheralEnable::Aes);
self.write_dma(false);
self.write_endianness(
Endianness::BigEndian,
Endianness::BigEndian,
Endianness::BigEndian,
Endianness::BigEndian,
Endianness::BigEndian,
Endianness::BigEndian,
);
}

fn write_dma(&mut self, enable_dma: bool) {
match enable_dma {
true => self.aes.dma_enable.write(|w| w.dma_enable().set_bit()),
false => self.aes.dma_enable.write(|w| w.dma_enable().clear_bit()),
}
}

pub(super) fn write_key(&mut self, key: &[u8]) {
debug_assert!(key.len() <= self.aes.key_.len() * ALIGN_SIZE);
debug_assert_eq!(key.len() % ALIGN_SIZE, 0);
Self::write_to_regset(key, self.aes.key_.len(), &mut self.aes.key_[0]);
}

pub(super) fn write_block(&mut self, block: &[u8]) {
debug_assert_eq!(block.len(), self.aes.text_in_.len() * ALIGN_SIZE);
Self::write_to_regset(block, self.aes.text_in_.len(), &mut self.aes.text_in_[0]);
}

pub(super) fn write_mode(&mut self, mode: u32) {
Self::write_to_register(&mut self.aes.mode, mode);
}

/// Configures how the state matrix would be laid out.
pub fn write_endianness(
&mut self,
input_text_word_endianess: Endianness,
input_text_byte_endianess: Endianness,
output_text_word_endianess: Endianness,
output_text_byte_endianess: Endianness,
key_word_endianess: Endianness,
key_byte_endianess: Endianness,
) {
let mut to_write = 0_u32;
to_write |= key_byte_endianess as u32;
to_write |= (key_word_endianess as u32) << 1;
to_write |= (input_text_byte_endianess as u32) << 2;
to_write |= (input_text_word_endianess as u32) << 3;
to_write |= (output_text_byte_endianess as u32) << 4;
to_write |= (output_text_word_endianess as u32) << 5;
Self::write_to_register(&mut self.aes.endian, to_write);
}

pub(super) fn write_start(&mut self) {
self.aes.trigger.write(|w| w.trigger().set_bit())
}

pub(super) fn read_idle(&mut self) -> bool {
self.aes.state.read().state().bits() == 0
}

pub(super) fn read_block(&self, block: &mut [u8]) {
debug_assert_eq!(block.len(), self.aes.text_out_.len() * ALIGN_SIZE);
Self::read_from_regset(block, self.aes.text_out_.len(), &self.aes.text_out_[0]);
}
}

impl AesFlavour for Aes128 {
type KeyType<'b> = &'b [u8; 16];
const ENCRYPT_MODE: u32 = 0;
const DECRYPT_MODE: u32 = 4;
}

impl AesFlavour for Aes192 {
type KeyType<'b> = &'b [u8; 24];
const ENCRYPT_MODE: u32 = 1;
const DECRYPT_MODE: u32 = 5;
}

impl AesFlavour for Aes256 {
type KeyType<'b> = &'b [u8; 32];
const ENCRYPT_MODE: u32 = 2;
const DECRYPT_MODE: u32 = 6;
}
58 changes: 58 additions & 0 deletions esp-hal-common/src/aes/esp32_s3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use crate::{
aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
};

impl<'d> Aes<'d> {
pub(super) fn init(&mut self, peripheral_clock_control: &mut PeripheralClockControl) {
peripheral_clock_control.enable(PeripheralEnable::Aes);
self.write_dma(false);
}

fn write_dma(&mut self, enable_dma: bool) {
match enable_dma {
true => self.aes.dma_enable.write(|w| w.dma_enable().set_bit()),
false => self.aes.dma_enable.write(|w| w.dma_enable().clear_bit()),
}
}

pub(super) fn write_key(&mut self, key: &[u8]) {
debug_assert!(key.len() <= self.aes.key_.len() * ALIGN_SIZE);
debug_assert_eq!(key.len() % ALIGN_SIZE, 0);
Self::write_to_regset(key, self.aes.key_.len(), &mut self.aes.key_[0]);
}

pub(super) fn write_block(&mut self, block: &[u8]) {
debug_assert_eq!(block.len(), self.aes.text_in_.len() * ALIGN_SIZE);
Self::write_to_regset(block, self.aes.text_in_.len(), &mut self.aes.text_in_[0]);
}

pub(super) fn write_mode(&mut self, mode: u32) {
Self::write_to_register(&mut self.aes.mode, mode);
}

pub(super) fn write_start(&mut self) {
self.aes.trigger.write(|w| w.trigger().set_bit())
}

pub(super) fn read_idle(&mut self) -> bool {
self.aes.state.read().state().bits() == 0
}

pub(super) fn read_block(&self, block: &mut [u8]) {
debug_assert_eq!(block.len(), self.aes.text_out_.len() * ALIGN_SIZE);
Self::read_from_regset(block, self.aes.text_out_.len(), &self.aes.text_out_[0]);
}
}

impl AesFlavour for Aes128 {
type KeyType<'b> = &'b [u8; 16];
const ENCRYPT_MODE: u32 = 0;
const DECRYPT_MODE: u32 = 4;
}

impl AesFlavour for Aes256 {
type KeyType<'b> = &'b [u8; 32];
const ENCRYPT_MODE: u32 = 2;
const DECRYPT_MODE: u32 = 6;
}
Loading

0 comments on commit 37f2dce

Please sign in to comment.