Skip to content

Commit

Permalink
refactor(SHA): Use new SHA driver API from esp_hal
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyGrondin committed Sep 4, 2024
1 parent 0265213 commit 1bbf5ef
Show file tree
Hide file tree
Showing 15 changed files with 198 additions and 79 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,6 @@ async = [
"esp-mbedtls/async",
"esp-hal/async",
]

[patch.crates-io]
esp-hal = { git = "https://github.com/Dominaezzz/esp-hal", branch = "improve_sha" }
4 changes: 2 additions & 2 deletions esp-mbedtls-sys/headers/esp32/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,9 @@
//#define MBEDTLS_POLY1305_ALT
//#define MBEDTLS_RIPEMD160_ALT
//#define MBEDTLS_RSA_ALT
#define MBEDTLS_SHA1_ALT
// #define MBEDTLS_SHA1_ALT
//#define MBEDTLS_SHA256_ALT
#define MBEDTLS_SHA512_ALT
// #define MBEDTLS_SHA512_ALT

/*
* When replacing the elliptic curve module, please consider, that it is
Expand Down
3 changes: 0 additions & 3 deletions esp-mbedtls-sys/headers/esp32/sha1_alt.h

This file was deleted.

5 changes: 0 additions & 5 deletions esp-mbedtls-sys/headers/esp32/sha512_alt.h

This file was deleted.

29 changes: 25 additions & 4 deletions esp-mbedtls-sys/src/include/esp32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13167,10 +13167,20 @@ extern "C" {
/// \return 0 if successful, or 1 if the test failed
pub fn mbedtls_ripemd160_self_test(verbose: crate::c_types::c_int) -> crate::c_types::c_int;
}
/// \brief The SHA-1 context structure.
///
/// \warning SHA-1 is considered a weak message digest and its use
/// constitutes a security risk. We recommend considering
/// stronger message digests instead.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct mbedtls_sha1_context {
pub hasher: *mut crate::c_types::c_void,
///< The number of Bytes processed.
pub private_total: [u32; 2usize],
///< The intermediate digest state.
pub private_state: [u32; 5usize],
///< The data block being processed.
pub private_buffer: [crate::c_types::c_uchar; 64usize],
}
extern "C" {
/// \brief This function initializes a SHA-1 context.
Expand Down Expand Up @@ -13472,12 +13482,23 @@ extern "C" {
/// \return \c 1 on failure.
pub fn mbedtls_sha256_self_test(verbose: crate::c_types::c_int) -> crate::c_types::c_int;
}
/// \brief The SHA-512 context structure.
///
/// The structure is used both for SHA-384 and for SHA-512
/// checksum calculations. The choice between these two is
/// made in the call to mbedtls_sha512_starts().
#[repr(C)]
#[derive(Copy, Clone)]
pub struct mbedtls_sha512_context {
pub sha384_hasher: *mut crate::c_types::c_void,
pub sha512_hasher: *mut crate::c_types::c_void,
pub is384: crate::c_types::c_int,
///< The number of Bytes processed.
pub private_total: [u64; 2usize],
///< The intermediate digest state.
pub private_state: [u64; 8usize],
///< The data block being processed.
pub private_buffer: [crate::c_types::c_uchar; 128usize],
///< Determines which function to use:
///0: Use SHA-512, or 1: Use SHA-384.
pub private_is384: crate::c_types::c_int,
}
extern "C" {
/// \brief This function initializes a SHA-512 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 @@ -15,6 +15,7 @@ cfg-if = "1.0.0"
edge-nal = { package = "edge-nal", git = "https://github.com/ivmarkov/edge-net/", optional = true }
edge-nal-embassy = { package = "edge-nal-embassy", git = "https://github.com/ivmarkov/edge-net/", optional = true }
embassy-net = { version = "0.4", features = [ "tcp", "medium-ethernet"], optional = true }
critical-section = "1.0.1"

[features]
async = ["dep:embedded-io-async"]
Expand Down
21 changes: 20 additions & 1 deletion esp-mbedtls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,24 @@
use embedded_io::ErrorType;
#[doc(hidden)]
pub use esp_hal as hal;
use hal::{peripheral::Peripheral, peripherals::RSA, rsa::Rsa};
use hal::{
peripheral::Peripheral,
peripherals::{RSA, SHA},
rsa::Rsa,
sha::Sha,
};

mod compat;

#[cfg(any(feature = "esp32c3", feature = "esp32s2", feature = "esp32s3"))]
mod bignum;
#[cfg(not(feature = "esp32"))]
mod sha;

use core::cell::RefCell;
use core::ffi::CStr;
use core::mem::size_of;
use critical_section::Mutex;

use compat::StrBuf;
use embedded_io::Read;
Expand Down Expand Up @@ -44,6 +52,9 @@ use esp_mbedtls_sys::c_types::*;
/// hardware accelerated RSA driver until the session called with this function is dropped.
static mut RSA_REF: Option<Rsa<esp_hal::Blocking>> = None;

/// Hold the SHA peripheral for cryptographic operations.
static SHARED_SHA: Mutex<RefCell<Option<Sha<'static>>>> = Mutex::new(RefCell::new(None));

// 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 Expand Up @@ -478,6 +489,10 @@ impl<T> Session<T> {
min_version: TlsVersion,
certificates: Certificates,
) -> Result<Self, TlsError> {
// TODO: Take peripheral from user
let sha = Sha::new(unsafe { SHA::steal() });
critical_section::with(|cs| SHARED_SHA.borrow_ref_mut(cs).replace(sha));

let (drbg_context, ssl_context, ssl_config, crt, client_crt, private_key) =
certificates.init_ssl(servername, mode, min_version)?;
return Ok(Self {
Expand Down Expand Up @@ -730,6 +745,10 @@ pub mod asynch {
rx_buffer: &'a mut [u8; RX_SIZE],
tx_buffer: &'a mut [u8; TX_SIZE],
) -> Result<Self, TlsError> {
// TODO: Take peripheral from user
let sha = Sha::new(unsafe { SHA::steal() });
critical_section::with(|cs| SHARED_SHA.borrow_ref_mut(cs).replace(sha));

let (drbg_context, ssl_context, ssl_config, crt, client_crt, private_key) =
certificates.init_ssl(servername, mode, min_version)?;
return Ok(Self {
Expand Down
7 changes: 6 additions & 1 deletion esp-mbedtls/src/sha/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use crate::hal::{
prelude::nb,
sha::{Context, ShaDigest},
};

mod sha1;
#[cfg(any(feature = "esp32s2", feature = "esp32s3"))]
mod sha256;
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
#[cfg(any(feature = "esp32s2", feature = "esp32s3"))]
mod sha512;
32 changes: 22 additions & 10 deletions esp-mbedtls/src/sha/sha1.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use core::ffi::{c_int, c_uchar};

use esp_hal::sha::Digest;
use esp_hal::sha::Sha1;
use super::{nb, Context, ShaDigest};
use crate::{hal::sha::Sha1, SHARED_SHA};

#[repr(C)]
pub struct mbedtls_sha1_context {
hasher: *mut Sha1<esp_hal::Blocking>,
hasher: *mut Context<Sha1>,
}

#[no_mangle]
pub unsafe extern "C" fn mbedtls_sha1_init(ctx: *mut mbedtls_sha1_context) {
let hasher_mem = crate::calloc(1, core::mem::size_of::<Sha1<esp_hal::Blocking>>() as u32)
as *mut Sha1<esp_hal::Blocking>;
core::ptr::write(hasher_mem, Sha1::default());
let hasher_mem =
crate::calloc(1, core::mem::size_of::<Context<Sha1>>() as u32) as *mut Context<Sha1>;
core::ptr::write(hasher_mem, Context::<Sha1>::new());
(*ctx).hasher = hasher_mem;
}

Expand Down Expand Up @@ -43,8 +43,15 @@ pub unsafe extern "C" fn mbedtls_sha1_update(
input: *const c_uchar,
ilen: usize,
) -> c_int {
let slice = core::ptr::slice_from_raw_parts(input as *const u8, ilen as usize);
(*ctx).hasher.as_mut().unwrap().update(&*slice);
let mut data = core::ptr::slice_from_raw_parts(input as *const u8, ilen as usize);
critical_section::with(|cs| {
let mut sha = SHARED_SHA.borrow_ref_mut(cs);
let mut hasher = ShaDigest::restore(sha.as_mut().unwrap(), (*ctx).hasher.as_mut().unwrap());
while !data.is_empty() {
data = nb::block!(hasher.update(&*data)).unwrap();
}
nb::block!(hasher.save((*ctx).hasher.as_mut().unwrap())).unwrap();
});
0
}

Expand All @@ -53,8 +60,13 @@ pub unsafe extern "C" fn mbedtls_sha1_finish(
ctx: *mut mbedtls_sha1_context,
output: *mut c_uchar,
) -> c_int {
let hasher = core::ptr::replace((*ctx).hasher, Sha1::default());
let data: [u8; 20] = hasher.finalize().into();
let mut data: [u8; 20] = [0u8; 20];
critical_section::with(|cs| {
let mut sha = SHARED_SHA.borrow_ref_mut(cs);
let mut hasher = ShaDigest::restore(sha.as_mut().unwrap(), (*ctx).hasher.as_mut().unwrap());
nb::block!(hasher.finish(&mut data)).unwrap();
nb::block!(hasher.save((*ctx).hasher.as_mut().unwrap())).unwrap();
});
core::ptr::copy_nonoverlapping(data.as_ptr(), output, data.len());
0
}
81 changes: 57 additions & 24 deletions esp-mbedtls/src/sha/sha256.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
use core::ffi::{c_int, c_uchar};

use esp_hal::sha::{Digest, Sha224, Sha256};
use super::{nb, Context, ShaDigest};
use crate::{
hal::sha::{Sha224, Sha256},
SHARED_SHA,
};

#[repr(C)]
pub struct mbedtls_sha256_context {
sha224_hasher: *mut Sha224<esp_hal::Blocking>,
sha256_hasher: *mut Sha256<esp_hal::Blocking>,
sha224_hasher: *mut Context<Sha224>,
sha256_hasher: *mut Context<Sha256>,
is224: c_int,
}

#[no_mangle]
pub unsafe extern "C" fn mbedtls_sha256_init(ctx: *mut mbedtls_sha256_context) {
let sha224_mem = crate::calloc(1, core::mem::size_of::<Sha224<esp_hal::Blocking>>() as u32)
as *mut Sha224<esp_hal::Blocking>;
let sha256_mem = crate::calloc(1, core::mem::size_of::<Sha256<esp_hal::Blocking>>() as u32)
as *mut Sha256<esp_hal::Blocking>;
let sha224_mem =
crate::calloc(1, core::mem::size_of::<Context<Sha224>>() as u32) as *mut Context<Sha224>;
let sha256_mem =
crate::calloc(1, core::mem::size_of::<Context<Sha256>>() as u32) as *mut Context<Sha256>;
(*ctx).sha224_hasher = sha224_mem;
(*ctx).sha256_hasher = sha256_mem;
}
Expand Down Expand Up @@ -51,9 +55,9 @@ pub unsafe extern "C" fn mbedtls_sha256_starts(
) -> c_int {
if is224 == 1 {
(*ctx).is224 = 1;
core::ptr::write((*ctx).sha224_hasher, Sha224::default());
core::ptr::write((*ctx).sha224_hasher, Context::new());
} else {
core::ptr::write((*ctx).sha256_hasher, Sha256::default());
core::ptr::write((*ctx).sha256_hasher, Context::new());
}
0
}
Expand All @@ -64,12 +68,29 @@ pub unsafe extern "C" fn mbedtls_sha256_update(
input: *const c_uchar,
ilen: usize,
) -> c_int {
let slice = core::ptr::slice_from_raw_parts(input as *const u8, ilen as usize);
if (*ctx).is224 == 1 {
(*ctx).sha224_hasher.as_mut().unwrap().update(&*slice);
} else {
(*ctx).sha256_hasher.as_mut().unwrap().update(&*slice);
}
let mut data = core::ptr::slice_from_raw_parts(input as *const u8, ilen as usize);
critical_section::with(|cs| {
let mut sha = SHARED_SHA.borrow_ref_mut(cs);
if (*ctx).is224 == 1 {
let mut hasher = ShaDigest::restore(
sha.as_mut().unwrap(),
(*ctx).sha224_hasher.as_mut().unwrap(),
);
while !data.is_empty() {
data = nb::block!(hasher.update(&*data)).unwrap();
}
nb::block!(hasher.save((*ctx).sha224_hasher.as_mut().unwrap())).unwrap();
} else {
let mut hasher = ShaDigest::restore(
sha.as_mut().unwrap(),
(*ctx).sha256_hasher.as_mut().unwrap(),
);
while !data.is_empty() {
data = nb::block!(hasher.update(&*data)).unwrap();
}
nb::block!(hasher.save((*ctx).sha256_hasher.as_mut().unwrap())).unwrap();
}
});
0
}

Expand All @@ -78,14 +99,26 @@ pub unsafe extern "C" fn mbedtls_sha256_finish(
ctx: *mut mbedtls_sha256_context,
output: *mut c_uchar,
) -> c_int {
if (*ctx).is224 == 1 {
let hasher = core::ptr::replace((*ctx).sha224_hasher, Sha224::default());
let data: [u8; 28] = hasher.finalize().into();
core::ptr::copy_nonoverlapping(data.as_ptr(), output, data.len());
} else {
let hasher = core::ptr::replace((*ctx).sha256_hasher, Sha256::default());
let data: [u8; 32] = hasher.finalize().into();
core::ptr::copy_nonoverlapping(data.as_ptr(), output, data.len());
}
let mut data: [u8; 32] = [0u8; 32];
critical_section::with(|cs| {
let mut sha = SHARED_SHA.borrow_ref_mut(cs);

if (*ctx).is224 == 1 {
let mut hasher = ShaDigest::restore(
sha.as_mut().unwrap(),
(*ctx).sha224_hasher.as_mut().unwrap(),
);
nb::block!(hasher.finish(&mut data)).unwrap();
nb::block!(hasher.save((*ctx).sha224_hasher.as_mut().unwrap())).unwrap();
} else {
let mut hasher = ShaDigest::restore(
sha.as_mut().unwrap(),
(*ctx).sha256_hasher.as_mut().unwrap(),
);
nb::block!(hasher.finish(&mut data)).unwrap();
nb::block!(hasher.save((*ctx).sha256_hasher.as_mut().unwrap())).unwrap();
}
});
core::ptr::copy_nonoverlapping(data.as_ptr(), output, data.len());
0
}
Loading

0 comments on commit 1bbf5ef

Please sign in to comment.