Skip to content

feat(SHA256): Add initial hardware acceleration impl for SHA256 #19

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

Closed
Closed
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
13 changes: 13 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ esp-mbedtls = { path = "./esp-mbedtls" }

[target.xtensa-esp32s3-none-elf.dependencies]

[[example]]
name = "crypto_self_test"
required-features = ["esp-wifi/wifi-logs"]

[[example]]
name = "async_client"
required-features = ["async"]
Expand All @@ -66,3 +70,12 @@ esp32s2 = ["esp32s2-hal/embassy-time-timg0", "esp-backtrace/esp32s2", "esp-print
esp32s3 = ["esp32s3-hal/embassy-time-timg0", "esp-backtrace/esp32s3", "esp-println/esp32s3", "embassy-executor?/arch-xtensa", "esp-wifi/esp32s3", "esp-mbedtls/esp32s3"]
async = ["esp-wifi/async", "esp-wifi/embassy-net", "embassy-executor", "embassy-net", "embassy-time", "embedded-io/async", "esp-mbedtls/async"]

[patch."https://github.com/esp-rs/esp-wifi.git"]
# Change PATH and patch for interrupt changes
esp-wifi = { package = "esp-wifi", path = "../esp-wifi/esp-wifi/" }

[patch.crates-io]
esp32-hal = { package = "esp32-hal", git = "https://github.com/esp-rs/esp-hal.git", rev = "44e968f7a83f80be43d60cdc01c10eccab4b39cf" }
esp32c3-hal = { package = "esp32c3-hal", git = "https://github.com/esp-rs/esp-hal.git", rev = "44e968f7a83f80be43d60cdc01c10eccab4b39cf" }
esp32s2-hal = { package = "esp32s2-hal", git = "https://github.com/esp-rs/esp-hal.git", rev = "44e968f7a83f80be43d60cdc01c10eccab4b39cf" }
esp32s3-hal = { package = "esp32s3-hal", git = "https://github.com/esp-rs/esp-hal.git", rev = "44e968f7a83f80be43d60cdc01c10eccab4b39cf" }
2 changes: 1 addition & 1 deletion esp-mbedtls-sys/headers/esp32/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -3069,7 +3069,7 @@
*
* This module adds support for SHA-224.
*/
#define MBEDTLS_SHA224_C
// #define MBEDTLS_SHA224_C

/**
* \def MBEDTLS_SHA256_C
Expand Down
2 changes: 1 addition & 1 deletion esp-mbedtls-sys/headers/esp32c3/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@
//#define MBEDTLS_RIPEMD160_ALT
//#define MBEDTLS_RSA_ALT
//#define MBEDTLS_SHA1_ALT
//#define MBEDTLS_SHA256_ALT
#define MBEDTLS_SHA256_ALT
//#define MBEDTLS_SHA512_ALT

/*
Expand Down
7 changes: 7 additions & 0 deletions esp-mbedtls-sys/headers/esp32c3/sha256_alt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

typedef struct mbedtls_sha256_context {
void* peripheral;
void* hasher;
} mbedtls_sha256_context;


9 changes: 0 additions & 9 deletions esp-mbedtls-sys/src/include/esp32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,6 @@ pub const MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY: u32 = 1;
pub const PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY: u32 = 1;
pub const MBEDTLS_PSA_BUILTIN_ALG_SHA_1: u32 = 1;
pub const PSA_WANT_ALG_SHA_1: u32 = 1;
pub const MBEDTLS_PSA_BUILTIN_ALG_SHA_224: u32 = 1;
pub const PSA_WANT_ALG_SHA_224: u32 = 1;
pub const MBEDTLS_PSA_BUILTIN_ALG_SHA_256: u32 = 1;
pub const PSA_WANT_ALG_SHA_256: u32 = 1;
pub const MBEDTLS_PSA_BUILTIN_ALG_SHA_384: u32 = 1;
Expand Down Expand Up @@ -13457,13 +13455,6 @@ extern "C" {
is224: crate::c_types::c_int,
) -> crate::c_types::c_int;
}
extern "C" {
/// \brief The SHA-224 checkup routine.
///
/// \return \c 0 on success.
/// \return \c 1 on failure.
pub fn mbedtls_sha224_self_test(verbose: crate::c_types::c_int) -> crate::c_types::c_int;
}
extern "C" {
/// \brief The SHA-256 checkup routine.
///
Expand Down
11 changes: 2 additions & 9 deletions esp-mbedtls-sys/src/include/esp32c3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13324,18 +13324,11 @@ extern "C" {
/// \return \c 1 on failure.
pub fn mbedtls_sha1_self_test(verbose: crate::c_types::c_int) -> crate::c_types::c_int;
}
/// \brief The SHA-256 context structure.
///
/// The structure is used both for SHA-256 and for SHA-224
/// checksum calculations. The choice between these two is
/// made in the call to mbedtls_sha256_starts().
#[repr(C)]
#[derive(Copy, Clone)]
pub struct mbedtls_sha256_context {
pub private_total: [u32; 2usize],
pub private_state: [u32; 8usize],
pub private_buffer: [crate::c_types::c_uchar; 64usize],
pub private_is224: crate::c_types::c_int,
pub peripheral: *mut crate::c_types::c_void,
pub hasher: *mut crate::c_types::c_void,
}
extern "C" {
/// \brief This function initializes a SHA-256 context.
Expand Down
1 change: 1 addition & 0 deletions esp-mbedtls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ esp32-hal = { version = "0.15.0", optional = true }
esp32c3-hal = { version = "0.12.0", optional = true }
esp32s2-hal = { version = "0.12.0", optional = true }
esp32s3-hal = { version = "0.12.0", optional = true }
nb = "1.1.0"

[features]
async = ["embedded-io/async"]
Expand Down
4 changes: 2 additions & 2 deletions esp-mbedtls/src/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use core::ffi::VaListImpl;
use core::fmt::Write;

#[no_mangle]
extern "C" fn putchar() {
todo!()
extern "C" fn putchar(c: crate::c_int) {
log::info!("{c}");
}

#[no_mangle]
Expand Down
20 changes: 20 additions & 0 deletions esp-mbedtls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@ use embedded_io::Io;
use esp_mbedtls_sys::bindings::*;
use esp_mbedtls_sys::c_types::*;

/// Re-export self-tests
pub use esp_mbedtls_sys::bindings::{
// AES
mbedtls_aes_self_test,
// MD5
mbedtls_md5_self_test,
// RSA
mbedtls_rsa_self_test,
// SHA
mbedtls_sha1_self_test,
mbedtls_sha256_self_test,
mbedtls_sha384_self_test,
mbedtls_sha512_self_test,
};

#[cfg(not(feature = "esp32"))]
pub use esp_mbedtls_sys::bindings::mbedtls_sha224_self_test;

mod sha;

// these will come from esp-wifi (i.e. this can only be used together with esp-wifi)
extern "C" {
fn free(ptr: *const u8);
Expand Down
15 changes: 15 additions & 0 deletions esp-mbedtls/src/sha/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//! Re-export SHA Hardware implementation based on availability.
//!
//! # Hardware support
//! This does not reflect the current implementation but rather the support
//! for the SHA modes on the specific SoCs.
//!
//! | Modes | esp32 | esp32c3 | esp32s2 | esp32s3 |
//! | ------- | ------- | ------- | ------- | ------- |
//! | SHA1 | ✓ | ✓ | ✓ | ✓ |
//! | SHA224 | x | ✓ | ✓ | ✓ |
//! | SHA256 | ✓ | ✓ | ✓ | ✓ |
//! | SHA384 | ✓ | x | ✓ | ✓ |
//! | SHA512 | ✓ | x | ✓ | ✓ |

mod sha256;
77 changes: 77 additions & 0 deletions esp-mbedtls/src/sha/sha256.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use crate::hal::peripherals::SHA;
use crate::hal::sha::Sha;
use crate::hal::sha::ShaMode;
use esp_mbedtls_sys::c_types::*;
use nb::block;

#[repr(C)]
pub struct mbedtls_sha256_context<'a> {
peripheral: SHA,
hasher: Sha<'a>,
}

#[no_mangle]
pub unsafe extern "C" fn mbedtls_sha256_init(ctx: *mut mbedtls_sha256_context) {
(*ctx).peripheral = SHA::steal();
}

#[no_mangle]
pub unsafe extern "C" fn mbedtls_sha256_free(_ctx: *mut mbedtls_sha256_context) {
// Do nothing
}

#[no_mangle]
pub unsafe extern "C" fn mbedtls_sha256_clone<'a>(
dst: *mut mbedtls_sha256_context<'a>,
src: *const mbedtls_sha256_context<'a>,
) {
core::ptr::copy_nonoverlapping(src, dst, 1)
}

#[allow(unused_variables)]
#[no_mangle]
pub unsafe extern "C" fn mbedtls_sha256_starts(
ctx: *mut mbedtls_sha256_context,
is224: c_int,
) -> c_int {
#[cfg(not(feature = "esp32"))]
let mode = if is224 == 1 {
ShaMode::SHA224
} else {
ShaMode::SHA256
};

#[cfg(feature = "esp32")]
let mode = ShaMode::SHA256;

let hasher = Sha::new(&mut (*ctx).peripheral, mode);

(*ctx).hasher = hasher;
0
}

#[no_mangle]
pub unsafe extern "C" fn mbedtls_sha256_update(
ctx: *mut mbedtls_sha256_context,
input: *const c_uchar,
ilen: usize,
) -> c_int {
let slice = core::ptr::slice_from_raw_parts(input as *const u8, ilen as usize);
let mut remaining = &*slice;

while remaining.len() > 0 {
remaining = block!((*ctx).hasher.update(remaining)).unwrap();
}
0
}

#[no_mangle]
pub unsafe extern "C" fn mbedtls_sha256_finish(
ctx: *mut mbedtls_sha256_context,
output: *mut c_uchar,
) -> c_int {
let mut data = [0u8; 32];
block!((*ctx).hasher.finish(&mut data)).unwrap();
core::ptr::copy_nonoverlapping(data.as_ptr(), output, data.len());
0
}
19 changes: 3 additions & 16 deletions examples/async_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,13 @@ fn main() -> ! {
init_logger(log::LevelFilter::Info);

let peripherals = Peripherals::take();
#[cfg(feature = "esp32")]
let mut system = peripherals.DPORT.split();
#[cfg(not(feature = "esp32"))]
#[allow(unused_mut)]
let mut system = peripherals.SYSTEM.split();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::max(system.clock_control).freeze();

#[cfg(feature = "esp32c3")]
let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0;
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
let timer = hal::timer::TimerGroup::new(
peripherals.TIMG1,
&clocks,
&mut system.peripheral_clock_control,
)
.timer0;
let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks).timer0;
let init = initialize(
EspWifiInitFor::Wifi,
timer,
Expand All @@ -86,11 +77,7 @@ fn main() -> ! {
let (wifi_interface, controller) =
esp_wifi::wifi::new_with_mode(&init, wifi, WifiMode::Sta).unwrap();

let timer_group0 = TimerGroup::new(
peripherals.TIMG0,
&clocks,
&mut system.peripheral_clock_control,
);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
embassy::init(&clocks, timer_group0.timer0);

let config = Config::dhcpv4(Default::default());
Expand Down
19 changes: 3 additions & 16 deletions examples/async_client_mTLS.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,13 @@ fn main() -> ! {
init_logger(log::LevelFilter::Info);

let peripherals = Peripherals::take();
#[cfg(feature = "esp32")]
let mut system = peripherals.DPORT.split();
#[cfg(not(feature = "esp32"))]
#[allow(unused_mut)]
let mut system = peripherals.SYSTEM.split();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::max(system.clock_control).freeze();

#[cfg(feature = "esp32c3")]
let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0;
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
let timer = hal::timer::TimerGroup::new(
peripherals.TIMG1,
&clocks,
&mut system.peripheral_clock_control,
)
.timer0;
let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks).timer0;
let init = initialize(
EspWifiInitFor::Wifi,
timer,
Expand All @@ -86,11 +77,7 @@ fn main() -> ! {
let (wifi_interface, controller) =
esp_wifi::wifi::new_with_mode(&init, wifi, WifiMode::Sta).unwrap();

let timer_group0 = TimerGroup::new(
peripherals.TIMG0,
&clocks,
&mut system.peripheral_clock_control,
);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
embassy::init(&clocks, timer_group0.timer0);

let config = Config::dhcpv4(Default::default());
Expand Down
19 changes: 3 additions & 16 deletions examples/async_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,13 @@ fn main() -> ! {
init_logger(log::LevelFilter::Info);

let peripherals = Peripherals::take();
#[cfg(feature = "esp32")]
let mut system = peripherals.DPORT.split();
#[cfg(not(feature = "esp32"))]
#[allow(unused_mut)]
let mut system = peripherals.SYSTEM.split();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::max(system.clock_control).freeze();

#[cfg(feature = "esp32c3")]
let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0;
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
let timer = hal::timer::TimerGroup::new(
peripherals.TIMG1,
&clocks,
&mut system.peripheral_clock_control,
)
.timer0;
let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks).timer0;
let init = initialize(
EspWifiInitFor::Wifi,
timer,
Expand All @@ -90,11 +81,7 @@ fn main() -> ! {
let (wifi_interface, controller) =
esp_wifi::wifi::new_with_mode(&init, wifi, WifiMode::Sta).unwrap();

let timer_group0 = TimerGroup::new(
peripherals.TIMG0,
&clocks,
&mut system.peripheral_clock_control,
);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
embassy::init(&clocks, timer_group0.timer0);

let config = Config::dhcpv4(Default::default());
Expand Down
19 changes: 3 additions & 16 deletions examples/async_server_mTLS.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,13 @@ fn main() -> ! {
init_logger(log::LevelFilter::Info);

let peripherals = Peripherals::take();
#[cfg(feature = "esp32")]
let mut system = peripherals.DPORT.split();
#[cfg(not(feature = "esp32"))]
#[allow(unused_mut)]
let mut system = peripherals.SYSTEM.split();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::max(system.clock_control).freeze();

#[cfg(feature = "esp32c3")]
let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0;
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
let timer = hal::timer::TimerGroup::new(
peripherals.TIMG1,
&clocks,
&mut system.peripheral_clock_control,
)
.timer0;
let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks).timer0;
let init = initialize(
EspWifiInitFor::Wifi,
timer,
Expand All @@ -107,11 +98,7 @@ fn main() -> ! {
let (wifi_interface, controller) =
esp_wifi::wifi::new_with_mode(&init, wifi, WifiMode::Sta).unwrap();

let timer_group0 = TimerGroup::new(
peripherals.TIMG0,
&clocks,
&mut system.peripheral_clock_control,
);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
embassy::init(&clocks, timer_group0.timer0);

let config = Config::dhcpv4(Default::default());
Expand Down
Loading