Skip to content
Open
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
28 changes: 26 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ jobs:
echo "${LIBCLANG_PATH}/../bin:$PATH" >> "$GITHUB_PATH"
echo "LIBCLANG_PATH=${LIBCLANG_PATH}" >> "$GITHUB_ENV"
echo "CLANG_PATH=${CLANG_PATH}" >> "$GITHUB_ENV"

# TODO: Remove the manual espup installation and run once the action below
# supports the `-r` flag to install the Espressif RISCV GCC toolchain
# See https://github.com/esp-rs/xtensa-toolchain/issues/45 for more info
Expand Down Expand Up @@ -175,7 +175,7 @@ jobs:
retention-days: 1
path: |
mbedtls-rs-sys/libs
mbedtls-rs-sys/src
mbedtls-rs-sys/src/include

build-mcu:
name: Build-MCU
Expand Down Expand Up @@ -230,6 +230,30 @@ jobs:
- name: Fmt Check - Examples
run: cd examples/${{ matrix.mcu[0] }}; cargo fmt -- --check

- name: mbedtls init
run: git submodule update --init --recursive

- name: Detect host target triple
run: |
export HOST_TARGET=$(rustup show | grep "Default host" | sed -e 's/.* //')
echo "HOST_TARGET=$HOST_TARGET" >> $GITHUB_ENV

- name: Install espup
run: |
curl -LO https://github.com/esp-rs/espup/releases/latest/download/espup-${{ env.HOST_TARGET }}.zip
unzip -o espup-${{ env.HOST_TARGET }}.zip -d "$HOME/.cargo/bin"
chmod +x "$HOME/.cargo/bin/espup"*
echo "ESPUP_EXPORT_FILE=$HOME/exports" >> $GITHUB_ENV

- name: Install espup toolchains (xtensa and riscv)
run: |
source "$HOME/.cargo/env"
"$HOME/.cargo/bin/espup" install -e -r
source "$HOME/exports"
echo "${LIBCLANG_PATH}/../bin:$PATH" >> "$GITHUB_PATH"
echo "LIBCLANG_PATH=${LIBCLANG_PATH}" >> "$GITHUB_ENV"
echo "CLANG_PATH=${CLANG_PATH}" >> "$GITHUB_ENV"

- name: Clippy - Examples
run: export WIFI_SSID=ssid; export WIFI_PASS=pass; cd examples/${{ matrix.mcu[0] }}; cargo clippy --no-default-features --features ${{ matrix.mcu[1] }} --target ${{ matrix.mcu[2] }} -Zbuild-std=core,alloc,panic_abort -- -D warnings

Expand Down
14 changes: 7 additions & 7 deletions examples/esp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ opt-level = "z"

[features]
default = ["esp32c6"]
esp32 = ["esp-rtos/esp32", "esp-hal/esp32", "esp-backtrace/esp32", "esp-println/esp32", "esp-radio/esp32", "esp-bootloader-esp-idf/esp32", "esp-metadata-generated/esp32", "mbedtls-rs/accel-esp32"]
esp32c2 = ["esp-rtos/esp32c2", "esp-hal/esp32c2", "esp-backtrace/esp32c2", "esp-println/esp32c2", "esp-radio/esp32c2", "esp-bootloader-esp-idf/esp32c2", "esp-metadata-generated/esp32c2", "mbedtls-rs/accel-esp32c2"]
esp32c3 = ["esp-rtos/esp32c3", "esp-hal/esp32c3", "esp-backtrace/esp32c3", "esp-println/esp32c3", "esp-radio/esp32c3", "esp-bootloader-esp-idf/esp32c3", "esp-metadata-generated/esp32c3", "mbedtls-rs/accel-esp32c3"]
esp32c6 = ["esp-rtos/esp32c6", "esp-hal/esp32c6", "esp-backtrace/esp32c6", "esp-println/esp32c6", "esp-radio/esp32c6", "esp-bootloader-esp-idf/esp32c6", "esp-metadata-generated/esp32c6", "mbedtls-rs/accel-esp32c6"]
esp32h2 = ["esp-rtos/esp32h2", "esp-hal/esp32h2", "esp-backtrace/esp32h2", "esp-println/esp32h2", "esp-radio/esp32h2", "esp-bootloader-esp-idf/esp32h2", "esp-metadata-generated/esp32h2", "mbedtls-rs/accel-esp32h2"]
esp32s2 = ["esp-rtos/esp32s2", "esp-hal/esp32s2", "esp-backtrace/esp32s2", "esp-println/esp32s2", "esp-radio/esp32s2", "esp-bootloader-esp-idf/esp32s2", "esp-metadata-generated/esp32s2", "mbedtls-rs/accel-esp32s2"]
esp32s3 = ["esp-rtos/esp32s3", "esp-hal/esp32s3", "esp-backtrace/esp32s3", "esp-println/esp32s3", "esp-radio/esp32s3", "esp-bootloader-esp-idf/esp32s3", "esp-metadata-generated/esp32s3", "mbedtls-rs/accel-esp32s3"]
esp32 = ["esp-rtos/esp32", "esp-hal/esp32", "esp-backtrace/esp32", "esp-println/esp32", "esp-radio/esp32", "esp-bootloader-esp-idf/esp32", "esp-metadata-generated/esp32", "mbedtls-rs/accel-esp32", "mbedtls-rs/timer-embassy", "mbedtls-rs/wall-clock-esp32"]
esp32c2 = ["esp-rtos/esp32c2", "esp-hal/esp32c2", "esp-backtrace/esp32c2", "esp-println/esp32c2", "esp-radio/esp32c2", "esp-bootloader-esp-idf/esp32c2", "esp-metadata-generated/esp32c2", "mbedtls-rs/accel-esp32c2", "mbedtls-rs/timer-embassy", "mbedtls-rs/wall-clock-esp32c2"]
esp32c3 = ["esp-rtos/esp32c3", "esp-hal/esp32c3", "esp-backtrace/esp32c3", "esp-println/esp32c3", "esp-radio/esp32c3", "esp-bootloader-esp-idf/esp32c3", "esp-metadata-generated/esp32c3", "mbedtls-rs/accel-esp32c3", "mbedtls-rs/timer-embassy", "mbedtls-rs/wall-clock-esp32c3"]
esp32c6 = ["esp-rtos/esp32c6", "esp-hal/esp32c6", "esp-backtrace/esp32c6", "esp-println/esp32c6", "esp-radio/esp32c6", "esp-bootloader-esp-idf/esp32c6", "esp-metadata-generated/esp32c6", "mbedtls-rs/accel-esp32c6", "mbedtls-rs/timer-embassy", "mbedtls-rs/wall-clock-esp32c6"]
esp32h2 = ["esp-rtos/esp32h2", "esp-hal/esp32h2", "esp-backtrace/esp32h2", "esp-println/esp32h2", "esp-radio/esp32h2", "esp-bootloader-esp-idf/esp32h2", "esp-metadata-generated/esp32h2", "mbedtls-rs/accel-esp32h2", "mbedtls-rs/timer-embassy", "mbedtls-rs/wall-clock-esp32h2"]
esp32s2 = ["esp-rtos/esp32s2", "esp-hal/esp32s2", "esp-backtrace/esp32s2", "esp-println/esp32s2", "esp-radio/esp32s2", "esp-bootloader-esp-idf/esp32s2", "esp-metadata-generated/esp32s2", "mbedtls-rs/accel-esp32s2", "mbedtls-rs/timer-embassy", "mbedtls-rs/wall-clock-esp32s2"]
esp32s3 = ["esp-rtos/esp32s3", "esp-hal/esp32s3", "esp-backtrace/esp32s3", "esp-println/esp32s3", "esp-radio/esp32s3", "esp-bootloader-esp-idf/esp32s3", "esp-metadata-generated/esp32s3", "mbedtls-rs/accel-esp32s3", "mbedtls-rs/timer-embassy", "mbedtls-rs/wall-clock-esp32s3"]

[dependencies]
log = "0.4"
Expand Down
10 changes: 10 additions & 0 deletions examples/esp/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use std::time::{SystemTime, UNIX_EPOCH};

fn main() {
let current_time_ms = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis();

println!("cargo:rustc-env=CURRENT_TIME_MS={}", current_time_ms);
}
3 changes: 2 additions & 1 deletion examples/esp/src/bin/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ async fn main(spawner: Spawner) {

let stack_resources = mk_static!(StackResources<3>, StackResources::new());

let (mut tls, stack, mut accel) = bootstrap::bootstrap_stack(spawner, stack_resources).await;
let (mut tls, stack, mut accel, ..) =
bootstrap::bootstrap_stack(spawner, stack_resources).await;

tls.set_debug(1);

Expand Down
3 changes: 2 additions & 1 deletion examples/esp/src/bin/edge_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ async fn main(spawner: Spawner) {

let stack_resources = mk_static!(StackResources<3>, StackResources::new());

let (mut tls, stack, mut accel) = bootstrap::bootstrap_stack(spawner, stack_resources).await;
let (mut tls, stack, mut accel, ..) =
bootstrap::bootstrap_stack(spawner, stack_resources).await;

tls.set_debug(1);

Expand Down
3 changes: 2 additions & 1 deletion examples/esp/src/bin/edge_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ async fn main(spawner: Spawner) {

let stack_resources = mk_static!(StackResources<4>, StackResources::new());

let (mut tls, stack, mut accel) = bootstrap::bootstrap_stack(spawner, stack_resources).await;
let (mut tls, stack, mut accel, ..) =
bootstrap::bootstrap_stack(spawner, stack_resources).await;

tls.set_debug(1);

Expand Down
3 changes: 2 additions & 1 deletion examples/esp/src/bin/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ async fn main(spawner: Spawner) {

let stack_resources = mk_static!(StackResources<4>, StackResources::new());

let (mut tls, stack, mut accel) = bootstrap::bootstrap_stack(spawner, stack_resources).await;
let (mut tls, stack, mut accel, ..) =
bootstrap::bootstrap_stack(spawner, stack_resources).await;

tls.set_debug(1);

Expand Down
115 changes: 115 additions & 0 deletions examples/esp/src/bin/time_verification.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//! Example demonstrating certificate time validation using the async API.
//!
//! This example connects to `https://httpbin.org/ip` twice to verify that:
//! 1. Certificate validation succeeds with correct time
//! 2. Certificate validation fails when time is manipulated (simulating an expired certificate)

#![no_std]
#![no_main]
#![recursion_limit = "256"]

use core::net::SocketAddr;

use embassy_executor::Spawner;

use embassy_net::tcp::TcpSocket;
use embassy_net::StackResources;

use esp_alloc::heap_allocator;
use esp_backtrace as _;

use log::info;

use tinyrlibc as _;

use crate::bootstrap::RECLAIMED_RAM;

#[path = "../bootstrap.rs"]
mod bootstrap;
#[path = "../../../common/client.rs"]
mod client;

const HEAP_SIZE: usize = 140 * 1024;

#[esp_rtos::main]
async fn main(spawner: Spawner) {
heap_allocator!(size: HEAP_SIZE - RECLAIMED_RAM);

let stack_resources = mk_static!(StackResources<3>, StackResources::new());

let (mut tls, stack, mut accel, _timer, rtc) =
bootstrap::bootstrap_stack(spawner, stack_resources).await;

tls.set_debug(1);

let _accel_queue = accel.start();

for (index, (server_name_cstr, server_path, expired_cert)) in [
(c"httpbin.org", "/ip", false),
(c"httpbin.org", "/ip", true),
]
.into_iter()
.enumerate()
{
let server_name = server_name_cstr.to_str().unwrap();

info!(
"\n\n\n\nREQUEST {}, EXPIRED_CERT: {} =============================",
index, expired_cert
);

if expired_cert {
// double current time to cause certificate validation to fail
rtc.set_current_time_us(rtc.current_time_us() * 2);
}

info!("Resolving server {}", server_name);

let ip = *stack
.dns_query(server_name, embassy_net::dns::DnsQueryType::A)
.await
.unwrap()
.iter()
.next()
.unwrap();

info!("Using IP addr {}", ip);

info!("Creating TCP connection");

let mut rx_buf = [0; 1024];
let mut tx_buf = [0; 1024];

let mut socket = TcpSocket::new(stack, &mut rx_buf, &mut tx_buf);

//socket.set_timeout(Some(Duration::from_secs(10)));
socket
.connect(SocketAddr::new(ip.into(), 443))
.await
.unwrap();

let mut buf = [0u8; 1024];

match client::request(
tls.reference(),
socket,
server_name_cstr,
server_path,
false,
&mut buf,
)
.await
{
Ok(()) => {
if expired_cert {
panic!("request should have failed with failed certificate validation");
}
}
Err(e) => {
if !expired_cert {
panic!("request should have succeeded: {}", e);
}
}
}
}
}
38 changes: 36 additions & 2 deletions examples/esp/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use esp_hal::rng::TrngSource;
use esp_hal::timer::timg::TimerGroup;

use mbedtls_rs::sys::accel::esp::EspAccel;
use mbedtls_rs::sys::clock::esp::EspRtcWallClock;
use mbedtls_rs::sys::timer::embassy::EmbassyTimer;
use mbedtls_rs::Tls;

use esp_metadata_generated::memory_range;
Expand Down Expand Up @@ -51,11 +53,18 @@ esp_bootloader_esp_idf::esp_app_desc!();

const WIFI_SSID: &str = env!("WIFI_SSID");
const WIFI_PASS: &str = env!("WIFI_PASS");
const CURRENT_TIME_MS: &str = env!("CURRENT_TIME_MS");

pub async fn bootstrap_stack<const SOCKETS: usize>(
spawner: Spawner,
stack_resources: &'static mut StackResources<SOCKETS>,
) -> (Tls<'static>, Stack<'static>, EspAccel<'static>) {
) -> (
Tls<'static>,
Stack<'static>,
EspAccel<'static>,
&'static EmbassyTimer,
&'static esp_hal::rtc_cntl::Rtc<'static>,
) {
esp_println::logger::init_logger(log::LevelFilter::Info);

info!("Starting...");
Expand All @@ -72,6 +81,31 @@ pub async fn bootstrap_stack<const SOCKETS: usize>(
.software_interrupt0,
);

// Create static Embassy timer and "hook it" to mbedtls
let timer = mk_static!(EmbassyTimer, EmbassyTimer);
unsafe {
mbedtls_rs::sys::hook::timer::hook_timer(Some(timer));
}

// Setup RTC for EspRtcWallClock
let rtc = mk_static!(
esp_hal::rtc_cntl::Rtc,
esp_hal::rtc_cntl::Rtc::new(peripherals.LPWR)
);
// In a real-life scenario NTP or equivalent should be used here to initialize the RTC
rtc.set_current_time_us(
CURRENT_TIME_MS
.parse::<u64>()
.expect("Failed to parse CURRENT_TIME_MS")
* 1000, // Convert milliseconds to microseconds
);

// Make EspRtcWallClock static and "hook it" to mbedtls
let clock = mk_static!(EspRtcWallClock, EspRtcWallClock::new(rtc));
unsafe {
mbedtls_rs::sys::hook::wall_clock::hook_wall_clock(Some(clock));
}

#[cfg(not(any(feature = "esp32", feature = "esp32c2")))]
let accel = EspAccel::new(peripherals.SHA, peripherals.RSA);

Expand Down Expand Up @@ -100,7 +134,7 @@ pub async fn bootstrap_stack<const SOCKETS: usize>(

wait_ip(stack).await;

(Tls::new(trng).unwrap(), stack, accel)
(Tls::new(trng).unwrap(), stack, accel, timer, rtc)
}

async fn wait_ip(stack: Stack<'_>) {
Expand Down
21 changes: 21 additions & 0 deletions mbedtls-rs-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ nohook-sha1 = []
nohook-sha256 = []
nohook-sha512 = []
nohook-exp-mod = []

# Enable HW acceleration drivers for the ESP series of MCUs via `esp-hal`
accel-esp32 = ["esp-hal/esp32", "crypto-bigint"]
accel-esp32c2 = ["esp-hal/esp32c2"]
Expand All @@ -34,6 +35,22 @@ accel-esp32h2 = ["esp-hal/esp32h2", "crypto-bigint"]
accel-esp32s2 = ["esp-hal/esp32s2", "crypto-bigint"]
accel-esp32s3 = ["esp-hal/esp32s3", "crypto-bigint"]

# Enable timer/wall-clock hooks for custom time implementations
hook-timer = []
hook-wall-clock = ["hook-timer"] # 'hook-wall-clock' feature requires 'hook-timer' to be enabled. MbedTLS X.509 certificate validation requires both time() and gmtime_r() functions.

timer-embassy = ["embassy-time", "hook-timer"]
timer-std = ["hook-timer"]

wall-clock-std = ["time", "hook-wall-clock"]
wall-clock-esp32 = ["esp-hal/esp32", "time", "hook-wall-clock"]
wall-clock-esp32c2 = ["esp-hal/esp32c2", "time", "hook-wall-clock"]
wall-clock-esp32c3 = ["esp-hal/esp32c3", "time", "hook-wall-clock"]
wall-clock-esp32c6 = ["esp-hal/esp32c6", "time", "hook-wall-clock"]
wall-clock-esp32h2 = ["esp-hal/esp32h2", "time", "hook-wall-clock"]
wall-clock-esp32s2 = ["esp-hal/esp32s2", "time", "hook-wall-clock"]
wall-clock-esp32s3 = ["esp-hal/esp32s3", "time", "hook-wall-clock"]

[dependencies]
defmt = { version = "1", optional = true }
log = { version = "0.4", optional = true }
Expand All @@ -43,12 +60,16 @@ digest = { version = "0.10", default-features = false }
sha1 = { version = "0.10", default-features = false }
# For some reason, `soft` results in enormous slowdowns on xtensa and riscv32
sha2 = { version = "0.10", default-features = false, features = ["force-soft-compact"] }
time = { version = "0.3", default-features = false, optional = true }
critical-section = "1"

# For esp-hal accel
esp-hal = { version = "1", features = ["unstable"], optional = true }
crypto-bigint = { version = "0.5.3", default-features = false, features = ["extra-sizes"], optional = true }

# For embassy timer support
embassy-time = {version = "0.5.0", optional = true}

# ESP-IDF: The mbedtls lib distributed with ESP-IDF is used
# All other platforms: mbedtls libs and bindings are created on the fly
[target.'cfg(target_os = "espidf")'.dependencies]
Expand Down
Loading
Loading