Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AES accelerator implementation #348

Merged
merged 1 commit into from
Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/esp32c3.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/esp32s2.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/esp32s3.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