diff --git a/.cargo/config.toml b/.cargo/config.toml index 41877aa..de0842a 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -42,3 +42,12 @@ build-std = ["core"] [alias] xtask = "run --manifest-path ./xtask/Cargo.toml --" + + +# Alias' for quickly building for different chips or running examples +# By default we enable +# - `default` HAL features to set up basic chip specific settings +esp32 = "run --features esp32 --target xtensa-esp32-none-elf --features esp32-hal/default" +esp32s2 = "run --features esp32s2 --target xtensa-esp32s2-none-elf --features esp32s2-hal/default" +esp32s3 = "run --features esp32s3 --target xtensa-esp32s3-none-elf --features esp32s3-hal/default" +esp32c3 = "run --features esp32c3 --target riscv32imc-unknown-none-elf --features esp32c3-hal/default" diff --git a/Cargo.toml b/Cargo.toml index 2fe3906..438b76d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,9 @@ static_cell = { version = "=1.2", features = ["nightly"] } 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" diff --git a/esp-mbedtls-sys/headers/esp32c3/config.h b/esp-mbedtls-sys/headers/esp32c3/config.h index 7eb82a8..de28467 100644 --- a/esp-mbedtls-sys/headers/esp32c3/config.h +++ b/esp-mbedtls-sys/headers/esp32c3/config.h @@ -326,6 +326,7 @@ //#define MBEDTLS_ECJPAKE_ALT //#define MBEDTLS_GCM_ALT //#define MBEDTLS_NIST_KW_ALT +#define MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK //#define MBEDTLS_MD5_ALT //#define MBEDTLS_POLY1305_ALT //#define MBEDTLS_RIPEMD160_ALT diff --git a/esp-mbedtls-sys/headers/esp32s2/config.h b/esp-mbedtls-sys/headers/esp32s2/config.h index 1f366db..72e4bba 100644 --- a/esp-mbedtls-sys/headers/esp32s2/config.h +++ b/esp-mbedtls-sys/headers/esp32s2/config.h @@ -326,6 +326,7 @@ //#define MBEDTLS_ECJPAKE_ALT //#define MBEDTLS_GCM_ALT //#define MBEDTLS_NIST_KW_ALT +#define MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK //#define MBEDTLS_MD5_ALT //#define MBEDTLS_POLY1305_ALT //#define MBEDTLS_RIPEMD160_ALT diff --git a/esp-mbedtls-sys/headers/esp32s3/config.h b/esp-mbedtls-sys/headers/esp32s3/config.h index 1f366db..72e4bba 100644 --- a/esp-mbedtls-sys/headers/esp32s3/config.h +++ b/esp-mbedtls-sys/headers/esp32s3/config.h @@ -326,6 +326,7 @@ //#define MBEDTLS_ECJPAKE_ALT //#define MBEDTLS_GCM_ALT //#define MBEDTLS_NIST_KW_ALT +#define MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK //#define MBEDTLS_MD5_ALT //#define MBEDTLS_POLY1305_ALT //#define MBEDTLS_RIPEMD160_ALT diff --git a/esp-mbedtls-sys/include/include.h b/esp-mbedtls-sys/include/include.h index 5355552..3dd7dde 100644 --- a/esp-mbedtls-sys/include/include.h +++ b/esp-mbedtls-sys/include/include.h @@ -8,3 +8,10 @@ #include "mbedtls/debug.h" #include "mbedtls/ctr_drbg.h" #include "psa/crypto_values.h" + +// Provides a function prototype to generate bindings for mbedtls_mpi_exp_mod_soft() +#if defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) + int mbedtls_mpi_exp_mod_soft(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR); +#endif diff --git a/esp-mbedtls-sys/src/include/esp32c3.rs b/esp-mbedtls-sys/src/include/esp32c3.rs index da4ff38..622cadf 100644 --- a/esp-mbedtls-sys/src/include/esp32c3.rs +++ b/esp-mbedtls-sys/src/include/esp32c3.rs @@ -22495,3 +22495,12 @@ extern "C" { /// \return \c 1 on failure. pub fn mbedtls_ctr_drbg_self_test(verbose: crate::c_types::c_int) -> crate::c_types::c_int; } +extern "C" { + pub fn mbedtls_mpi_exp_mod_soft( + X: *mut mbedtls_mpi, + A: *const mbedtls_mpi, + E: *const mbedtls_mpi, + N: *const mbedtls_mpi, + prec_RR: *mut mbedtls_mpi, + ) -> crate::c_types::c_int; +} diff --git a/esp-mbedtls-sys/src/include/esp32s2.rs b/esp-mbedtls-sys/src/include/esp32s2.rs index b0f8ec8..c22260b 100644 --- a/esp-mbedtls-sys/src/include/esp32s2.rs +++ b/esp-mbedtls-sys/src/include/esp32s2.rs @@ -22492,3 +22492,12 @@ extern "C" { /// \return \c 1 on failure. pub fn mbedtls_ctr_drbg_self_test(verbose: crate::c_types::c_int) -> crate::c_types::c_int; } +extern "C" { + pub fn mbedtls_mpi_exp_mod_soft( + X: *mut mbedtls_mpi, + A: *const mbedtls_mpi, + E: *const mbedtls_mpi, + N: *const mbedtls_mpi, + prec_RR: *mut mbedtls_mpi, + ) -> crate::c_types::c_int; +} diff --git a/esp-mbedtls-sys/src/include/esp32s3.rs b/esp-mbedtls-sys/src/include/esp32s3.rs index b0f8ec8..c22260b 100644 --- a/esp-mbedtls-sys/src/include/esp32s3.rs +++ b/esp-mbedtls-sys/src/include/esp32s3.rs @@ -22492,3 +22492,12 @@ extern "C" { /// \return \c 1 on failure. pub fn mbedtls_ctr_drbg_self_test(verbose: crate::c_types::c_int) -> crate::c_types::c_int; } +extern "C" { + pub fn mbedtls_mpi_exp_mod_soft( + X: *mut mbedtls_mpi, + A: *const mbedtls_mpi, + E: *const mbedtls_mpi, + N: *const mbedtls_mpi, + prec_RR: *mut mbedtls_mpi, + ) -> crate::c_types::c_int; +} diff --git a/esp-mbedtls/Cargo.toml b/esp-mbedtls/Cargo.toml index f11f1ce..e865779 100644 --- a/esp-mbedtls/Cargo.toml +++ b/esp-mbedtls/Cargo.toml @@ -9,10 +9,12 @@ esp-mbedtls-sys = { path = "../esp-mbedtls-sys" } log = "0.4.17" embedded-io = { version = "0.6.1" } embedded-io-async = { version = "0.6.0", optional = true } +crypto-bigint = { version = "0.5.3", default-features = false, features = ["extra-sizes"] } esp32-hal = { version = "0.18.0", optional = true } esp32c3-hal = { version = "0.15.0", optional = true } esp32s2-hal = { version = "0.15.0", optional = true } esp32s3-hal = { version = "0.15.0", optional = true } +cfg-if = "1.0.0" [features] async = ["dep:embedded-io-async"] diff --git a/esp-mbedtls/src/bignum.rs b/esp-mbedtls/src/bignum.rs new file mode 100644 index 0000000..3910a2c --- /dev/null +++ b/esp-mbedtls/src/bignum.rs @@ -0,0 +1,355 @@ +#![allow(non_snake_case)] + +use crate::hal::prelude::nb; +use crate::hal::rsa::{operand_sizes, Rsa, RsaModularExponentiation}; + +use crypto_bigint::*; + +use esp_mbedtls_sys::bindings::*; +use esp_mbedtls_sys::c_types::*; + +macro_rules! error_checked { + ($block:expr) => {{ + let res = $block; + if res != 0 { + panic!("Non zero error {:?}", res); + } else { + // Do nothing for now + } + }}; +} + +#[cfg(feature = "esp32")] +const SOC_RSA_MAX_BIT_LEN: usize = 4096; +#[cfg(feature = "esp32c3")] +const SOC_RSA_MAX_BIT_LEN: usize = 3072; +#[cfg(feature = "esp32s2")] +const SOC_RSA_MAX_BIT_LEN: usize = 4096; +#[cfg(feature = "esp32s3")] +const SOC_RSA_MAX_BIT_LEN: usize = 4096; + +/// Bad input parameters to function. +const MBEDTLS_ERR_MPI_BAD_INPUT_DATA: c_int = -0x0004; + +/// Calculate the number of words used for a hardware operation. +/// +/// For every chip except `esp32`, this will return `words` +/// For `esp32`, this will return the number of words rounded up to the 512 block count. +const fn calculate_hw_words(words: usize) -> usize { + // Round up number of words to nearest + // 512 bit (16 word) block count. + #[cfg(feature = "esp32")] + return (words + 0xF) & !0xF; + #[cfg(not(feature = "esp32"))] + words +} + +/// Return the number of words actually used to represent an mpi number. +fn mpi_words(X: &mbedtls_mpi) -> usize { + for i in (0..=X.private_n).rev() { + if unsafe { X.private_p.add(i - 1).read() } != 0 { + return i; + } + } + 0 +} + +#[inline] +fn copy_bytes(src: *const T, dst: *mut T, count: usize) +where + T: Copy, +{ + unsafe { core::ptr::copy_nonoverlapping(src, dst, count) }; +} + +fn compute_mprime(M: &mbedtls_mpi) -> u32 { + let mut t: u64 = 1; + let mut two_2_i_minus_1: u64 = 2; // 2^(i-1) + let mut two_2_i: u64 = 4; // 2^i + let n = unsafe { M.private_p.read() } as u64; + + for _ in 2..=32 { + if n * t % two_2_i >= two_2_i_minus_1 { + t += two_2_i_minus_1; + } + + two_2_i_minus_1 <<= 1; + two_2_i <<= 1; + } + + (u32::MAX as u64 - t + 1) as u32 +} + +/// Calculate Rinv = RR^2 mod M, where: +/// +/// R = b^n where b = 2^32, n=num_words, +/// R = 2^N (where N=num_bits) +/// RR = R^2 = 2^(2*N) (where N=num_bits=num_words*32) +/// +/// This calculation is computationally expensive (mbedtls_mpi_mod_mpi) +/// so caller should cache the result where possible. +/// +/// DO NOT call this function while holding esp_mpi_enable_hardware_hw_op(). +fn calculate_rinv(prec_RR: &mut mbedtls_mpi, M: &mbedtls_mpi, num_words: usize) -> c_int { + let ret = 0; + let num_bits = num_words * 32; + let mut RR = mbedtls_mpi { + private_s: 0, + private_n: 0, + private_p: core::ptr::null_mut(), + }; + + unsafe { + mbedtls_mpi_init(&mut RR); + error_checked!(mbedtls_mpi_set_bit(&mut RR, num_bits * 2, 1)); + error_checked!(mbedtls_mpi_mod_mpi(prec_RR, &RR, M)); + mbedtls_mpi_free(&mut RR); + } + + ret +} + +/// Z = X ^ Y mod M +#[no_mangle] +pub unsafe extern "C" fn mbedtls_mpi_exp_mod( + Z: *mut mbedtls_mpi, + X: &mbedtls_mpi, + Y: &mbedtls_mpi, + M: &mbedtls_mpi, + prec_RR: *mut mbedtls_mpi, +) -> c_int { + match crate::RSA_REF { + None => return unsafe { mbedtls_mpi_exp_mod_soft(Z, X, Y, M, prec_RR) }, + Some(ref mut rsa) => { + let x_words = mpi_words(X); + let y_words = mpi_words(Y); + let m_words = mpi_words(M); + + // All numbers must be the lame length, so choose longest number as + // cardinal length of operation + let num_words = + calculate_hw_words(core::cmp::max(m_words, core::cmp::max(x_words, y_words))); + + if num_words * 32 > SOC_RSA_MAX_BIT_LEN { + return unsafe { mbedtls_mpi_exp_mod_soft(Z, X, Y, M, prec_RR) }; + } + + if M.private_p.is_null() { + todo!("Handle this null"); + } + unsafe { + if mbedtls_mpi_cmp_int(M, 0) <= 0 || M.private_p.read() & 1 == 0 { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + if mbedtls_mpi_cmp_int(Y, 0) < 0 { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + if mbedtls_mpi_cmp_int(Y, 0) == 0 { + return mbedtls_mpi_lset(Z, 1); + } + } + + let mut rinv_new = mbedtls_mpi { + private_s: 0, + private_n: 0, + private_p: core::ptr::null_mut(), + }; + + // Determine RR pointer, either _RR for cached value or local RR_new + let rinv: &mut mbedtls_mpi = if prec_RR.is_null() { + unsafe { mbedtls_mpi_init(&mut rinv_new) }; + &mut rinv_new + } else { + // This is safe since we check above if pointer is not null + unsafe { &mut *prec_RR } + }; + + if rinv.private_p.is_null() { + calculate_rinv(rinv, M, num_words); + } + + unsafe { + error_checked!(mbedtls_mpi_grow(Z, m_words)); + } + + let mut rsa = Rsa::new(rsa); + nb::block!(rsa.ready()).unwrap(); + rsa.enable_disable_constant_time_acceleration(true); + rsa.enable_disable_search_acceleration(true); + unsafe { + match num_words { + U256::LIMBS => { + const OP_SIZE: usize = U256::LIMBS; + let mut base = [0u32; OP_SIZE]; + let mut exponent = [0u32; OP_SIZE]; + let mut modulus = [0u32; OP_SIZE]; + let mut r = [0u32; OP_SIZE]; + copy_bytes(X.private_p, base.as_mut_ptr(), x_words); + copy_bytes(Y.private_p, exponent.as_mut_ptr(), y_words); + copy_bytes(M.private_p, modulus.as_mut_ptr(), m_words); + copy_bytes(rinv.private_p, r.as_mut_ptr(), mpi_words(rinv)); + let mut mod_exp = RsaModularExponentiation::::new( + &mut rsa, + &exponent, // exponent (Y) Y_MEM + &modulus, // modulus (M) M_MEM + compute_mprime(M), // mprime + ); + let mut out = [0u32; OP_SIZE]; + mod_exp.start_exponentiation( + &base, // X_MEM + &r, // Z_MEM + ); + + mod_exp.read_results(&mut out); + copy_bytes(out.as_ptr(), (*Z).private_p, m_words); + } + U384::LIMBS => { + const OP_SIZE: usize = U384::LIMBS; + let mut base = [0u32; OP_SIZE]; + let mut exponent = [0u32; OP_SIZE]; + let mut modulus = [0u32; OP_SIZE]; + let mut r = [0u32; OP_SIZE]; + copy_bytes(X.private_p, base.as_mut_ptr(), x_words); + copy_bytes(Y.private_p, exponent.as_mut_ptr(), y_words); + copy_bytes(M.private_p, modulus.as_mut_ptr(), m_words); + copy_bytes(rinv.private_p, r.as_mut_ptr(), mpi_words(rinv)); + let mut mod_exp = RsaModularExponentiation::::new( + &mut rsa, + &exponent, // exponent (Y) Y_MEM + &modulus, // modulus (M) M_MEM + compute_mprime(M), // mprime + ); + let mut out = [0u32; OP_SIZE]; + mod_exp.start_exponentiation( + &base, // X_MEM + &r, // Z_MEM + ); + + mod_exp.read_results(&mut out); + copy_bytes(out.as_ptr(), (*Z).private_p, m_words); + } + U512::LIMBS => { + const OP_SIZE: usize = U512::LIMBS; + let mut base = [0u32; OP_SIZE]; + let mut exponent = [0u32; OP_SIZE]; + let mut modulus = [0u32; OP_SIZE]; + let mut r = [0u32; OP_SIZE]; + copy_bytes(X.private_p, base.as_mut_ptr(), x_words); + copy_bytes(Y.private_p, exponent.as_mut_ptr(), y_words); + copy_bytes(M.private_p, modulus.as_mut_ptr(), m_words); + copy_bytes(rinv.private_p, r.as_mut_ptr(), mpi_words(rinv)); + let mut mod_exp = RsaModularExponentiation::::new( + &mut rsa, + &exponent, // exponent (Y) Y_MEM + &modulus, // modulus (M) M_MEM + compute_mprime(M), // mprime + ); + let mut out = [0u32; OP_SIZE]; + mod_exp.start_exponentiation( + &base, // X_MEM + &r, // Z_MEM + ); + + mod_exp.read_results(&mut out); + copy_bytes(out.as_ptr(), (*Z).private_p, m_words); + } + U1024::LIMBS => { + const OP_SIZE: usize = U1024::LIMBS; + let mut base = [0u32; OP_SIZE]; + let mut exponent = [0u32; OP_SIZE]; + let mut modulus = [0u32; OP_SIZE]; + let mut r = [0u32; OP_SIZE]; + copy_bytes(X.private_p, base.as_mut_ptr(), x_words); + copy_bytes(Y.private_p, exponent.as_mut_ptr(), y_words); + copy_bytes(M.private_p, modulus.as_mut_ptr(), m_words); + copy_bytes(rinv.private_p, r.as_mut_ptr(), mpi_words(rinv)); + let mut mod_exp = RsaModularExponentiation::::new( + &mut rsa, + &exponent, // exponent (Y) Y_MEM + &modulus, // modulus (M) M_MEM + compute_mprime(M), // mprime + ); + let mut out = [0u32; OP_SIZE]; + mod_exp.start_exponentiation( + &base, // X_MEM + &r, // Z_MEM + ); + + mod_exp.read_results(&mut out); + copy_bytes(out.as_ptr(), (*Z).private_p, m_words); + } + U2048::LIMBS => { + const OP_SIZE: usize = U2048::LIMBS; + let mut base = [0u32; OP_SIZE]; + let mut exponent = [0u32; OP_SIZE]; + let mut modulus = [0u32; OP_SIZE]; + let mut r = [0u32; OP_SIZE]; + copy_bytes(X.private_p, base.as_mut_ptr(), x_words); + copy_bytes(Y.private_p, exponent.as_mut_ptr(), y_words); + copy_bytes(M.private_p, modulus.as_mut_ptr(), m_words); + copy_bytes(rinv.private_p, r.as_mut_ptr(), mpi_words(rinv)); + let mut mod_exp = RsaModularExponentiation::::new( + &mut rsa, + &exponent, // exponent (Y) Y_MEM + &modulus, // modulus (M) M_MEM + compute_mprime(M), // mprime + ); + let mut out = [0u32; OP_SIZE]; + mod_exp.start_exponentiation( + &base, // X_MEM + &r, // Z_MEM + ); + + mod_exp.read_results(&mut out); + copy_bytes(out.as_ptr(), (*Z).private_p, m_words); + } + #[cfg(not(feature = "esp32c3"))] + U4096::LIMBS => { + const OP_SIZE: usize = U4096::LIMBS; + let mut base = [0u32; OP_SIZE]; + let mut exponent = [0u32; OP_SIZE]; + let mut modulus = [0u32; OP_SIZE]; + let mut r = [0u32; OP_SIZE]; + copy_bytes(X.private_p, base.as_mut_ptr(), x_words); + copy_bytes(Y.private_p, exponent.as_mut_ptr(), y_words); + copy_bytes(M.private_p, modulus.as_mut_ptr(), m_words); + copy_bytes(rinv.private_p, r.as_mut_ptr(), mpi_words(rinv)); + let mut mod_exp = RsaModularExponentiation::::new( + &mut rsa, + &exponent, // exponent (Y) Y_MEM + &modulus, // modulus (M) M_MEM + compute_mprime(M), // mprime + ); + let mut out = [0u32; OP_SIZE]; + mod_exp.start_exponentiation( + &base, // X_MEM + &r, // Z_MEM + ); + + mod_exp.read_results(&mut out); + copy_bytes(out.as_ptr(), (*Z).private_p, m_words); + } + op => { + todo!("Implement operand: {}", op); + } + } + } + + assert_eq!(X.private_s, 1); + // Compensate for negative X + if X.private_s == -1 && unsafe { Y.private_p.read() & 1 } != 0 { + unsafe { (*Z).private_s = -1 }; + unsafe { error_checked!(mbedtls_mpi_add_mpi(Z, M, Z)) }; + } else { + unsafe { (*Z).private_s = 1 }; + } + + if prec_RR.is_null() { + unsafe { mbedtls_mpi_free(&mut rinv_new) }; + } + 0 + } + } +} diff --git a/esp-mbedtls/src/compat.rs b/esp-mbedtls/src/compat.rs index 249bf17..77aed29 100644 --- a/esp-mbedtls/src/compat.rs +++ b/esp-mbedtls/src/compat.rs @@ -115,8 +115,8 @@ extern "C" fn vsnprintf( } #[no_mangle] -extern "C" fn rand() { - todo!() +extern "C" fn rand() -> crate::c_ulong { + unsafe { crate::random() } } pub struct StrBuf { diff --git a/esp-mbedtls/src/lib.rs b/esp-mbedtls/src/lib.rs index 64a2240..104ba03 100644 --- a/esp-mbedtls/src/lib.rs +++ b/esp-mbedtls/src/lib.rs @@ -16,8 +16,13 @@ pub use esp32s2_hal as hal; #[cfg(feature = "esp32s3")] pub use esp32s3_hal as hal; +use crate::hal::peripherals::RSA; + mod compat; +#[cfg(any(feature = "esp32c3", feature = "esp32s2", feature = "esp32s3"))] +mod bignum; + use core::ffi::CStr; use core::mem::size_of; @@ -25,8 +30,18 @@ use compat::StrBuf; use embedded_io::Read; use embedded_io::Write; use esp_mbedtls_sys::bindings::*; +/// Re-export self-tests +pub use esp_mbedtls_sys::bindings::{ + // Bignum + mbedtls_mpi_self_test, + // RSA + mbedtls_rsa_self_test, +}; use esp_mbedtls_sys::c_types::*; +/// Hold the RSA peripheral for cryptographic operations. +static mut RSA_REF: Option = 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); @@ -390,9 +405,11 @@ impl Session { mode: Mode, min_version: TlsVersion, certificates: Certificates, + rsa: Option, ) -> Result { let (ssl_context, ssl_config, crt, client_crt, private_key) = certificates.init_ssl(servername, mode, min_version)?; + unsafe { RSA_REF = core::mem::transmute(rsa) } return Ok(Self { stream, ssl_context, @@ -595,9 +612,11 @@ pub mod asynch { mode: Mode, min_version: TlsVersion, certificates: Certificates, + rsa: Option, ) -> Result { let (ssl_context, ssl_config, crt, client_crt, private_key) = certificates.init_ssl(servername, mode, min_version)?; + unsafe { RSA_REF = core::mem::transmute(rsa) } return Ok(Self { stream, ssl_context, diff --git a/examples/async_client.rs b/examples/async_client.rs index 29c21cf..9fff4d5 100644 --- a/examples/async_client.rs +++ b/examples/async_client.rs @@ -128,6 +128,7 @@ async fn main(spawner: Spawner) -> ! { .ok(), ..Default::default() }, + Some(peripherals.RSA), ) .unwrap(); diff --git a/examples/async_client_mTLS.rs b/examples/async_client_mTLS.rs index 4b15fda..878732c 100644 --- a/examples/async_client_mTLS.rs +++ b/examples/async_client_mTLS.rs @@ -134,6 +134,7 @@ async fn main(spawner: Spawner) -> ! { Mode::Client, TlsVersion::Tls1_3, certificates, + Some(peripherals.RSA), ) .unwrap(); diff --git a/examples/async_server.rs b/examples/async_server.rs index 9513629..b68cda5 100644 --- a/examples/async_server.rs +++ b/examples/async_server.rs @@ -149,6 +149,7 @@ async fn main(spawner: Spawner) -> ! { .ok(), ..Default::default() }, + None, ) .unwrap(); diff --git a/examples/async_server_mTLS.rs b/examples/async_server_mTLS.rs index b8f33fc..4362410 100644 --- a/examples/async_server_mTLS.rs +++ b/examples/async_server_mTLS.rs @@ -168,6 +168,7 @@ async fn main(spawner: Spawner) -> ! { .ok(), ..Default::default() }, + None, ) .unwrap(); diff --git a/examples/crypto_self_test.rs b/examples/crypto_self_test.rs new file mode 100644 index 0000000..849227d --- /dev/null +++ b/examples/crypto_self_test.rs @@ -0,0 +1,146 @@ +//! Run crypto self tests to ensure their functionnality +#![no_std] +#![no_main] + +#[doc(hidden)] +#[cfg(feature = "esp32")] +pub use esp32_hal as hal; +#[doc(hidden)] +#[cfg(feature = "esp32c3")] +pub use esp32c3_hal as hal; +#[doc(hidden)] +#[cfg(feature = "esp32s2")] +pub use esp32s2_hal as hal; +#[doc(hidden)] +#[cfg(feature = "esp32s3")] +pub use esp32s3_hal as hal; + +use esp_backtrace as _; +use esp_mbedtls::set_debug; +use esp_println::{logger::init_logger, println}; + +/// Only used for ROM functions +#[allow(unused_imports)] +use esp_wifi::{initialize, EspWifiInitFor}; +use hal::{clock::ClockControl, peripherals::Peripherals, prelude::*, systimer::SystemTimer, Rng}; + +#[entry] +fn main() -> ! { + init_logger(log::LevelFilter::Info); + + // Init ESP-WIFI heap for malloc + 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 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).timer0; + let _ = initialize( + EspWifiInitFor::Wifi, + timer, + Rng::new(peripherals.RNG), + system.radio_clock_control, + &clocks, + ) + .unwrap(); + + set_debug(1); + + // println!("Testing AES"); + // unsafe { + // esp_mbedtls::mbedtls_aes_self_test(1i32); + // } + // println!("Testing MD5"); + // unsafe { + // esp_mbedtls::mbedtls_md5_self_test(1i32); + // } + println!("Testing RSA"); + unsafe { + esp_mbedtls::mbedtls_rsa_self_test(1i32); + } + // println!("Testing SHA"); + unsafe { + // esp_mbedtls::mbedtls_sha1_self_test(1i32); + // #[cfg(not(feature = "esp32"))] + // esp_mbedtls::mbedtls_sha224_self_test(1i32); + // esp_mbedtls::mbedtls_sha256_self_test(1i32); + // esp_mbedtls::mbedtls_sha384_self_test(1i32); + // esp_mbedtls::mbedtls_sha512_self_test(1i32); + + // HW Crypto: + // Testing RSA + // INFO - RSA key validation: + // INFO - passed + // PKCS#1 encryption : + // INFO - passed + // PKCS#1 decryption : + // INFO - passed + // INFO - PKCS#1 data sign : + // INFO - passed + // PKCS#1 sig. verify: + // INFO - passed + // INFO - 10 + // INFO - pre_cal 16377170 + // INFO - MPI test #1 (mul_mpi): + // INFO - passed + // INFO - MPI test #2 (div_mpi): + // INFO - passed + // INFO - MPI test #3 (exp_mod): + // INFO - passed + // INFO - MPI test #4 (inv_mod): + // INFO - passed + // INFO - MPI test #5 (simple gcd): + // INFO - passed + // INFO - 10 + // INFO - post_cal 17338357 + // Took 961187 cycles + // Done + + // SW Crypto: + // Testing RSA + // INFO - RSA key validation: + // INFO - passed + // PKCS#1 encryption : + // INFO - passed + // PKCS#1 decryption : + // INFO - passed + // INFO - PKCS#1 data sign : + // INFO - passed + // PKCS#1 sig. verify: + // INFO - passed + // INFO - 10 + // INFO - pre_cal 19067376 + // INFO - MPI test #1 (mul_mpi): + // INFO - passed + // INFO - MPI test #2 (div_mpi): + // INFO - passed + // INFO - MPI test #3 (exp_mod): + // INFO - passed + // INFO - MPI test #4 (inv_mod): + // INFO - passed + // INFO - MPI test #5 (simple gcd): + // INFO - passed + // INFO - 10 + // INFO - post_cal 20393146 + // Took 1325770 cycles + // Done + + let pre_calc = SystemTimer::now(); + log::info!("pre_cal {}", pre_calc); + esp_mbedtls::mbedtls_mpi_self_test(1i32); + let post_calc = SystemTimer::now(); + let hw_time = post_calc - pre_calc; + log::info!("post_cal {}", post_calc); + println!("Took {} cycles", hw_time); + } + + println!("Done"); + + loop {} +} diff --git a/examples/sync_client.rs b/examples/sync_client.rs index 531133e..21f56b0 100644 --- a/examples/sync_client.rs +++ b/examples/sync_client.rs @@ -124,6 +124,7 @@ fn main() -> ! { .ok(), ..Default::default() }, + None, ) .unwrap(); diff --git a/examples/sync_client_mTLS.rs b/examples/sync_client_mTLS.rs index d91de79..22e3d6e 100644 --- a/examples/sync_client_mTLS.rs +++ b/examples/sync_client_mTLS.rs @@ -130,6 +130,7 @@ fn main() -> ! { Mode::Client, TlsVersion::Tls1_3, certificates, + Some(peripherals.RSA), ) .unwrap(); diff --git a/examples/sync_server.rs b/examples/sync_server.rs index e607d7b..30aea66 100644 --- a/examples/sync_server.rs +++ b/examples/sync_server.rs @@ -144,6 +144,7 @@ fn main() -> ! { .ok(), ..Default::default() }, + None, ) .unwrap(); match tls.connect() { diff --git a/examples/sync_server_mTLS.rs b/examples/sync_server_mTLS.rs index 21848b6..392b8df 100644 --- a/examples/sync_server_mTLS.rs +++ b/examples/sync_server_mTLS.rs @@ -165,6 +165,7 @@ fn main() -> ! { .ok(), ..Default::default() }, + None, ) .unwrap(); match tls.connect() { diff --git a/libs/riscv32imc-unknown-none-elf/libmbedcrypto.a b/libs/riscv32imc-unknown-none-elf/libmbedcrypto.a index 93d9480..70b8d81 100644 Binary files a/libs/riscv32imc-unknown-none-elf/libmbedcrypto.a and b/libs/riscv32imc-unknown-none-elf/libmbedcrypto.a differ diff --git a/libs/riscv32imc-unknown-none-elf/libmbedtls.a b/libs/riscv32imc-unknown-none-elf/libmbedtls.a index c440158..f660cc6 100644 Binary files a/libs/riscv32imc-unknown-none-elf/libmbedtls.a and b/libs/riscv32imc-unknown-none-elf/libmbedtls.a differ diff --git a/libs/xtensa-esp32s2-none-elf/libmbedcrypto.a b/libs/xtensa-esp32s2-none-elf/libmbedcrypto.a index 34b2959..ff878b4 100644 Binary files a/libs/xtensa-esp32s2-none-elf/libmbedcrypto.a and b/libs/xtensa-esp32s2-none-elf/libmbedcrypto.a differ diff --git a/libs/xtensa-esp32s3-none-elf/libmbedcrypto.a b/libs/xtensa-esp32s3-none-elf/libmbedcrypto.a index 34b2959..ff878b4 100644 Binary files a/libs/xtensa-esp32s3-none-elf/libmbedcrypto.a and b/libs/xtensa-esp32s3-none-elf/libmbedcrypto.a differ diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 4a19887..91c7916 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -348,6 +348,29 @@ fn compile(workspace: &Path, compilation_target: &CompilationTarget) -> Result<( )?; file.write_all(content.replace("-Wdocumentation", "").as_bytes())?; + // This add the function prototype for `mbedtls_mpi_exp_mod_soft()` since it + // is not provided in the espressif fork of mbedtls. + if let Err(error) = writeln!( + fs::OpenOptions::new().write(true).append(true).open( + tmpsrc + .path() + .join("mbedtls") + .join("include") + .join("mbedtls") + .join("bignum.h"), + )?, + "int mbedtls_mpi_exp_mod_soft( + mbedtls_mpi *X, + const mbedtls_mpi *A, + const mbedtls_mpi *E, + const mbedtls_mpi *N, + mbedtls_mpi *prec_RR + );" + ) { + eprintln!("Could not write function prototype to bignum.h"); + eprintln!("{error}"); + } + // Compile mbedtls and generate libraries to link against log::info!("Compiling mbedtls"); let dst = Config::new(tmpsrc.path().join("mbedtls"))