Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
Customized mbedtls-platform-support crate to upgrade spin
Browse files Browse the repository at this point in the history
Fix #120

Signed-off-by: xiaoyuxlu <[email protected]>
  • Loading branch information
xiaoyuxlu authored and jyao1 committed Oct 26, 2023
1 parent 3c68622 commit 483e2ed
Show file tree
Hide file tree
Showing 9 changed files with 458 additions and 9 deletions.
10 changes: 1 addition & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,4 @@ resolver = "2"
[patch.crates-io]
ring = { path = "external/ring" }
webpki = { path = "external/webpki" }
mbedtls-platform-support = { path = "spdmlib_crypto_mbedtls/mbedtls-platform-support" }
45 changes: 45 additions & 0 deletions spdmlib_crypto_mbedtls/mbedtls-platform-support/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[package]
name = "mbedtls-platform-support"
version = "0.1.1"
authors = ["Yuxiang Cao <[email protected]>"]
build = "build.rs"
edition = "2018"
license = "Apache-2.0 OR GPL-2.0-or-later"
description = """
This Rust crate is a support library for the `mbedtls` crate, providing platform and target specific
implementations of all necessary functions. By separating this logic into a separate crate, multiple
versions of the mbedtls crate can coexist within a single crate.This helps to avoid link name conflict
errors. The crate exports Rust functions and defines C functions to support external overrides as
needed for custom implementation under various platforms or targets.
"""
readme = "../README.md"
repository = "https://github.com/fortanix/rust-mbedtls"
documentation = "https://docs.rs/mbedtls-platform-support/"
keywords = ["MbedTLS", "mbed", "TLS", "SSL", "cryptography"]
links = "mbedtls-platform-support"

[dependencies]
cfg-if = "1.0.0"
spin = { version = "0.5.2", default-features = false, optional = true }
chrono = { version = "0.4", optional = true }

[target.x86_64-fortanix-unknown-sgx.dependencies]
chrono = "0.4"

[dependencies.mbedtls-sys-auto]
version = "2.25.0"
default-features = false
features = ["threading", "custom_printf"]

[build-dependencies]
cc = "1.0"

[features]
time = ["mbedtls-sys-auto/time"]
std = ["mbedtls-sys-auto/std"]
spin_threading = ["spin", "mbedtls-sys-auto/custom_threading"]
rust_threading = ["mbedtls-sys-auto/custom_threading", "std"]
custom_gmtime_r = ["mbedtls-sys-auto/custom_gmtime_r", "chrono"]
custom_time = ["mbedtls-sys-auto/custom_time", "chrono"]
force_aesni_support = ["mbedtls-sys-auto/custom_has_support","mbedtls-sys-auto/aes_alt", "aesni"]
aesni = ["mbedtls-sys-auto/aesni"]
1 change: 1 addition & 0 deletions spdmlib_crypto_mbedtls/mbedtls-platform-support/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Customized mbedtls-platform-support crate for rust-mbedtls
39 changes: 39 additions & 0 deletions spdmlib_crypto_mbedtls/mbedtls-platform-support/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* Copyright (c) Fortanix, Inc.
*
* Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
* https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
* 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
* option. This file may not be copied, modified, or distributed except
* according to those terms. */

use std::collections::{HashMap, HashSet};
use std::env;

fn main() {
let env_components = env::var("DEP_MBEDTLS_PLATFORM_COMPONENTS").unwrap();
let mut sys_platform_components = HashMap::<_, HashSet<_>>::new();
for mut kv in env_components.split(",").map(|component| component.splitn(2, "=")) {
let k = kv.next().unwrap();
let v = kv.next().unwrap();
sys_platform_components.entry(k).or_insert_with(Default::default).insert(v);
println!(r#"cargo:rustc-cfg=sys_{}="{}""#, k, v);
}

let mut b = cc::Build::new();
b.include(env::var_os("DEP_MBEDTLS_INCLUDE").unwrap());
let config_file = format!(r#""{}""#, env::var("DEP_MBEDTLS_CONFIG_H").unwrap());
b.define("MBEDTLS_CONFIG_FILE",
Some(config_file.as_str()));

b.file("src/rust_printf.c");
if sys_platform_components.get("c_compiler").map_or(false, |comps| comps.contains("freestanding")) {
b.flag("-U_FORTIFY_SOURCE")
.define("_FORTIFY_SOURCE", Some("0"))
.flag("-ffreestanding");
}
b.compile("librust-mbedtls-platform-support.a");
// Force correct link order for mbedtls_printf
println!("cargo:rustc-link-lib=static=mbedtls");
println!("cargo:rustc-link-lib=static=mbedx509");
println!("cargo:rustc-link-lib=static=mbedcrypto");
}
108 changes: 108 additions & 0 deletions spdmlib_crypto_mbedtls/mbedtls-platform-support/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* Copyright (c) Fortanix, Inc.
*
* Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
* https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
* 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
* option. This file may not be copied, modified, or distributed except
* according to those terms. */

#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(not(feature = "std"))]
#[allow(unused)]
#[macro_use]
extern crate alloc as rust_alloc;

#[cfg(not(feature = "std"))]
mod alloc_prelude {
#![allow(unused)]
pub(crate) use rust_alloc::borrow::ToOwned;
pub(crate) use rust_alloc::boxed::Box;
pub(crate) use rust_alloc::sync::Arc;
pub(crate) use rust_alloc::string::String;
pub(crate) use rust_alloc::string::ToString;
pub(crate) use rust_alloc::vec::Vec;
pub(crate) use rust_alloc::borrow::Cow;
}

pub mod self_test;

#[cfg(any(feature = "spin_threading", feature = "rust_threading", sys_threading_component = "custom"))]
#[doc(hidden)]
pub mod threading;

#[cfg(any(feature = "force_aesni_support", target_env = "sgx"))]
#[doc(hidden)]
#[no_mangle]
// needs to be pub for global visibility
pub extern "C" fn mbedtls_aesni_has_support(_what: u32) -> i32 {
return 1;
}

#[cfg(any(feature = "force_aesni_support", target_env = "sgx"))]
#[doc(hidden)]
#[no_mangle]
// needs to be pub for global visibility
pub extern "C" fn mbedtls_internal_aes_encrypt(_ctx: *mut mbedtls_sys::types::raw_types::c_void,
_input: *const u8,
_output: *mut u8) -> i32 {
panic!("AES-NI support is forced but the T-tables code was invoked")
}

#[cfg(any(feature = "force_aesni_support", target_env = "sgx"))]
#[doc(hidden)]
#[no_mangle]
// needs to be pub for global visibility
pub extern "C" fn mbedtls_internal_aes_decrypt(_ctx: *mut mbedtls_sys::types::raw_types::c_void,
_input: *const u8,
_output: *mut u8) -> i32 {
panic!("AES-NI support is forced but the T-tables code was invoked")
}


#[cfg(any(all(feature = "time", feature = "custom_gmtime_r"), sys_time_component = "custom"))]
#[doc(hidden)]
#[no_mangle]
// needs to be pub for global visibility
pub unsafe extern "C" fn mbedtls_platform_gmtime_r(tt: *const mbedtls_sys::types::time_t, tp: *mut mbedtls_sys::types::tm) -> *mut mbedtls_sys::types::tm {
use chrono::prelude::*;

//0 means no TZ offset
let naive = if tp.is_null() {
return core::ptr::null_mut()
} else {
match NaiveDateTime::from_timestamp_opt(*tt, 0) {
Some(t) => t,
None => return core::ptr::null_mut()
}
};
let utc = DateTime::<Utc>::from_utc(naive, Utc);

let tp = &mut *tp;
tp.tm_sec = utc.second() as i32;
tp.tm_min = utc.minute() as i32;
tp.tm_hour = utc.hour() as i32;
tp.tm_mday = utc.day() as i32;
tp.tm_mon = utc.month0() as i32;
tp.tm_year = match (utc.year() as i32).checked_sub(1900) {
Some(year) => year,
None => return core::ptr::null_mut()
};
tp.tm_wday = utc.weekday().num_days_from_sunday() as i32;
tp.tm_yday = utc.ordinal0() as i32;
tp.tm_isdst = 0;

tp
}

#[cfg(any(all(feature = "time", feature = "custom_time"), sys_time_component = "custom"))]
#[doc(hidden)]
#[no_mangle]
// needs to be pub for global visibility
pub unsafe extern "C" fn mbedtls_time(tp: *mut mbedtls_sys::types::time_t) -> mbedtls_sys::types::time_t {
let timestamp = chrono::Utc::now().timestamp() as mbedtls_sys::types::time_t;
if !tp.is_null() {
*tp = timestamp;
}
timestamp
}
43 changes: 43 additions & 0 deletions spdmlib_crypto_mbedtls/mbedtls-platform-support/src/rust_printf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Copyright (c) Fortanix, Inc.
*
* Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
* https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
* 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
* option. This file may not be copied, modified, or distributed except
* according to those terms. */

#include <stdio.h>
#include <stdarg.h>
#ifdef _WIN32
#define alloca _alloca
#include <malloc.h>
#else
#include <alloca.h>
#endif

extern void mbedtls_log(const char* msg);

extern int mbedtls_printf(const char *fmt, ...) {
va_list ap;

va_start(ap,fmt);
int n=vsnprintf(0,0,fmt,ap);
va_end(ap);

if (n<0)
return -1;

n++;
char *p = alloca(n);

va_start(ap,fmt);
n=vsnprintf(p,n,fmt,ap);
va_end(ap);

if (n<0)
return -1;

mbedtls_log(p);

return n;
}
104 changes: 104 additions & 0 deletions spdmlib_crypto_mbedtls/mbedtls-platform-support/src/self_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* Copyright (c) Fortanix, Inc.
*
* Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
* https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
* 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
* option. This file may not be copied, modified, or distributed except
* according to those terms. */

//! MbedTLS self tests.
//!
//! Calling MbedTLS self test functions before they're enabled using the
//! `enable()` function here will result in a panic.
//!
//! Using this module in multithreaded or async environment will fail. The self
//! test functions rely on global variables to track operations and anything
//! non-self-test related operations will clobber these variables, resulting in
//! self test failures. Make sure no other code uses MbedTLS while running the
//! self tests. Multiple self test operations done simultaneously may also
//! return failures.
use mbedtls_sys::types::raw_types::{c_char, c_int};

cfg_if::cfg_if! {
if #[cfg(feature = "std")] {
// needs to be pub for global visiblity
#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn mbedtls_log(msg: *const std::os::raw::c_char) {
print!("{}", std::ffi::CStr::from_ptr(msg).to_string_lossy());
}
} else {
#[allow(non_upper_case_globals)]
static mut log_f: Option<unsafe fn(*const c_char)> = None;

// needs to be pub for global visiblity
#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn mbedtls_log(msg: *const c_char) {
log_f.expect("Called self-test log without enabling self-test")(msg)
}
}
}

#[cfg(any(not(feature = "std"), target_env = "sgx"))]
#[allow(non_upper_case_globals)]
static mut rand_f: Option<fn() -> c_int> = None;

// needs to be pub for global visiblity
#[cfg(all(any(not(feature = "std"), target_env = "sgx"), not(target_env = "msvc")))]
#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn rand() -> c_int {
rand_f.expect("Called self-test rand without enabling self-test")()
}

/// Set callback functions to enable the MbedTLS self tests.
///
/// `rand` only needs to be set on platforms that don't have a `rand()`
/// function in libc. `log` only needs to be set when using `no_std`, i.e.
/// the `std` feature of this create is not enabled. If neither function
/// needs to be set, you don't have to call `enable()`.
///
/// # Safety
///
/// The caller needs to ensure this function is not called while any other
/// function in this module is called.
#[allow(unused)]
pub unsafe fn enable(rand: fn() -> c_int, log: Option<unsafe fn(*const c_char)>) {
#[cfg(any(not(feature = "std"), target_env = "sgx"))] {
rand_f = Some(rand);
}
#[cfg(not(feature = "std"))] {
log_f = log;
}
}

/// # Safety
///
/// The caller needs to ensure this function is not called while any other
/// function in this module is called.
pub unsafe fn disable() {
#[cfg(any(not(feature = "std"), target_env = "sgx"))] {
rand_f = None;
}
#[cfg(not(feature = "std"))] {
log_f = None;
}
}

/// # Safety
///
/// The caller needs to ensure this function is not called while *any other*
/// MbedTLS function is called. See the module documentation for more
/// information.
pub use mbedtls_sys::{
aes_self_test as aes, arc4_self_test as arc4, aria_self_test as aria, base64_self_test as base64,
camellia_self_test as camellia, ccm_self_test as ccm, ctr_drbg_self_test as ctr_drbg,
des_self_test as des, dhm_self_test as dhm, ecjpake_self_test as ecjpake, ecp_self_test as ecp,
entropy_self_test as entropy, gcm_self_test as gcm, hmac_drbg_self_test as hmac_drbg,
md2_self_test as md2, md4_self_test as md4, md5_self_test as md5, mpi_self_test as mpi,
pkcs5_self_test as pkcs5, ripemd160_self_test as ripemd160, rsa_self_test as rsa,
sha1_self_test as sha1, sha256_self_test as sha256, sha512_self_test as sha512,
x509_self_test as x509, xtea_self_test as xtea, nist_kw_self_test as nist_kw, cmac_self_test as cmac
};
Loading

0 comments on commit 483e2ed

Please sign in to comment.