diff --git a/Cargo.lock b/Cargo.lock index fd8177747..f7406b3ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -196,7 +196,7 @@ version = "0.1.20210325" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97f8932064288cc79feb4d343a399d353a6f6f001e586ece47fe518a9e8507df" dependencies = [ - "rustc_version", + "rustc_version 0.1.7", ] [[package]] @@ -383,7 +383,7 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "mbedtls" -version = "0.8.2" +version = "0.8.3" dependencies = [ "bit-vec", "bitflags", @@ -391,27 +391,42 @@ dependencies = [ "cbc", "cc", "cfg-if 1.0.0", - "chrono", "core_io", "hex", "hyper", "libc", "matches", + "mbedtls-platform-support", "mbedtls-sys-auto", "num-bigint", "rand", "rc2", "rs-libc", + "rustc_version 0.2.3", "serde", "serde_cbor", "serde_derive", - "spin", "yasna", ] +[[package]] +name = "mbedtls-platform-support" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85be113c8c2dc54cc6a5fba20130c7128f78dcb3ed0bb6797427333fa8cdb54d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "chrono", + "mbedtls-sys-auto", + "spin", +] + [[package]] name = "mbedtls-sys-auto" -version = "2.26.1" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2231108271d9a10052178d940926baf24b57a2eb1703732faae387592dd6ac3" dependencies = [ "bindgen", "cc", @@ -640,7 +655,16 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" dependencies = [ - "semver", + "semver 0.1.20", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", ] [[package]] @@ -655,6 +679,21 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "serde" version = "1.0.101" diff --git a/Cargo.toml b/Cargo.toml index 755259713..832230aec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["mbedtls", "mbedtls-sys"] +members = ["mbedtls"] diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index deb667aaa..ab53ae989 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mbedtls" -version = "0.8.2" +version = "0.8.3" authors = ["Jethro Beekman "] build = "build.rs" edition = "2018" @@ -20,7 +20,6 @@ keywords = ["MbedTLS","mbed","TLS","SSL","cryptography"] [dependencies] bitflags = "1" core_io = { version = "0.1", features = ["collections"], optional = true } -spin = { version = "0.4.0", default-features = false, optional = true } serde = { version = "1.0.7", default-features = false } serde_derive = "1.0.7" byteorder = "1.0.0" @@ -33,13 +32,14 @@ cfg-if = "1.0.0" [target.x86_64-fortanix-unknown-sgx.dependencies] rs-libc = "0.2.0" -chrono = "0.4" [dependencies.mbedtls-sys-auto] version = "2.25.0" default-features = false -features = ["custom_printf", "trusted_cert_callback", "threading"] -path = "../mbedtls-sys" +features = ["trusted_cert_callback", "threading"] + +[dependencies.mbedtls-platform-support] +version = "0.1" [dev-dependencies] libc = "0.2.0" @@ -51,19 +51,20 @@ hyper = { version = "0.10.16", default-features = false } [build-dependencies] cc = "1.0" +rustc_version = "0.2" [features] # Features are documented in the README default = ["std", "aesni", "time", "padlock"] -std = ["mbedtls-sys-auto/std", "serde/std", "yasna"] +std = ["mbedtls-sys-auto/std", "serde/std", "yasna", "mbedtls-platform-support/std"] debug = ["mbedtls-sys-auto/debug"] -no_std_deps = ["core_io", "spin"] -force_aesni_support = ["mbedtls-sys-auto/custom_has_support", "mbedtls-sys-auto/aes_alt", "aesni"] +no_std_deps = ["core_io", "mbedtls-platform-support/spin"] +force_aesni_support = ["mbedtls-platform-support/force_aesni_support", "mbedtls-sys-auto/custom_has_support", "mbedtls-sys-auto/aes_alt", "aesni"] mpi_force_c_code = ["mbedtls-sys-auto/mpi_force_c_code"] rdrand = [] -aesni = ["mbedtls-sys-auto/aesni"] +aesni = ["mbedtls-platform-support/aesni"] zlib = ["mbedtls-sys-auto/zlib"] -time = ["mbedtls-sys-auto/time"] +time = ["mbedtls-platform-support/time"] padlock = ["mbedtls-sys-auto/padlock"] dsa = ["std", "yasna", "num-bigint", "bit-vec"] pkcs12 = ["std", "yasna"] diff --git a/mbedtls/build.rs b/mbedtls/build.rs index 32047d486..d873384be 100644 --- a/mbedtls/build.rs +++ b/mbedtls/build.rs @@ -6,10 +6,40 @@ * option. This file may not be copied, modified, or distributed except * according to those terms. */ +use rustc_version::{version, Version}; use std::collections::{HashMap, HashSet}; use std::env; +/// Return the crate hash that Cargo will be passing to `rustc -C metadata=`. +// If there's a panic in this code block, that means Cargo's way of running the +// build script has changed, and this code should be updated to handle the new +// case. +fn get_compilation_metadata_hash() -> String { + let out_dir: std::path::PathBuf = std::env::var_os("OUT_DIR").unwrap().into(); + let mut out_dir_it = out_dir.iter().rev(); + assert_eq!(out_dir_it.next().unwrap(), "out"); + let crate_ = out_dir_it.next().unwrap().to_string_lossy(); + assert!(crate_.starts_with("mbedtls-")); + crate_[8..].to_owned() +} + +/// Set cfg attribute to enable unstable feature based on `rustc`'s version. +/// Some of code needs feature that is unstable when compiling with rust version +/// that needed by `core-io`. +fn check_and_enable_feature() { + let min_version_with_feature = Version::parse("1.54.0").unwrap(); + let rustc_version = version().unwrap(); + if rustc_version < min_version_with_feature { + println!("cargo:rustc-cfg=enable_extended_key_value_attributes"); + } +} + fn main() { + check_and_enable_feature(); + + let metadata_hash = get_compilation_metadata_hash(); + println!("cargo:rustc-env=RUST_MBEDTLS_METADATA_HASH={}", metadata_hash); + 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, "=")) { @@ -24,17 +54,13 @@ fn main() { let config_file = format!(r#""{}""#, env::var("DEP_MBEDTLS_CONFIG_H").unwrap()); b.define("MBEDTLS_CONFIG_FILE", Some(config_file.as_str())); + b.define("RUST_MBEDTLS_METADATA_HASH", Some(metadata_hash.as_str())); b.file("src/mbedtls_malloc.c"); - 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.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"); } diff --git a/mbedtls/src/alloc.rs b/mbedtls/src/alloc.rs index bd28023e2..6bca70a5f 100644 --- a/mbedtls/src/alloc.rs +++ b/mbedtls/src/alloc.rs @@ -15,7 +15,10 @@ use core::mem::ManuallyDrop; use mbedtls_sys::types::raw_types::c_void; extern "C" { - pub(crate) fn forward_mbedtls_free(n: *mut mbedtls_sys::types::raw_types::c_void); + #[link_name = concat!("\u{1}forward_mbedtls_free_", env!("RUST_MBEDTLS_METADATA_HASH"))] + pub(crate) fn mbedtls_free(n: *mut mbedtls_sys::types::raw_types::c_void); + #[link_name = concat!("\u{1}forward_mbedtls_calloc_", env!("RUST_MBEDTLS_METADATA_HASH"))] + pub(crate) fn mbedtls_calloc(n: mbedtls_sys::types::size_t, size: mbedtls_sys::types::size_t) -> *mut mbedtls_sys::types::raw_types::c_void; } #[repr(transparent)] @@ -53,7 +56,7 @@ impl Drop for Box { fn drop(&mut self) { unsafe { drop_in_place(self.inner.as_ptr()); - forward_mbedtls_free(self.inner.as_ptr() as *mut c_void) + mbedtls_free(self.inner.as_ptr() as *mut c_void) } } } diff --git a/mbedtls/src/lib.rs b/mbedtls/src/lib.rs index 07b18e9d1..b68911297 100644 --- a/mbedtls/src/lib.rs +++ b/mbedtls/src/lib.rs @@ -9,13 +9,12 @@ #![deny(warnings)] #![allow(unused_doc_comments)] #![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(enable_extended_key_value_attributes, feature(extended_key_value_attributes))] #[cfg(not(any(feature = "std", feature = "no_std_deps")))] compile_error!("Either the `std` or `no_std_deps` feature needs to be enabled"); -#[cfg(not(feature = "std"))] -#[macro_use] -extern crate alloc as rust_alloc; + #[macro_use] extern crate bitflags; #[macro_use] @@ -38,7 +37,7 @@ pub mod ecp; pub mod hash; pub mod pk; pub mod rng; -pub mod self_test; +pub use mbedtls_platform_support::self_test as self_test; pub mod ssl; pub mod x509; pub mod alloc; @@ -51,37 +50,24 @@ pub mod pkcs12; // ============== mod private; -// needs to be pub for global visiblity +// needs to be pub for global visibility #[doc(hidden)] #[cfg(sys_threading_component = "custom")] pub mod threading; cfg_if::cfg_if! { if #[cfg(any(feature = "force_aesni_support", target_env = "sgx"))] { - // needs to be pub for global visiblity + // needs to be pub for global visibility #[doc(hidden)] - #[no_mangle] - pub extern "C" fn mbedtls_aesni_has_support(_what: u32) -> i32 { - return 1; - } + pub use mbedtls_platform_support::mbedtls_aesni_has_support; - // needs to be pub for global visiblity + // needs to be pub for global visibility #[doc(hidden)] - #[no_mangle] - 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") - } + pub use mbedtls_platform_support::mbedtls_internal_aes_encrypt; - // needs to be pub for global visiblity + // needs to be pub for global visibility #[doc(hidden)] - #[no_mangle] - 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") - } + pub use mbedtls_platform_support::mbedtls_internal_aes_decrypt; } } @@ -93,6 +79,10 @@ mod mbedtls { pub use super::*; } +#[cfg(not(feature = "std"))] +#[macro_use] +extern crate alloc as rust_alloc; + #[cfg(not(feature = "std"))] mod alloc_prelude { #![allow(unused)] @@ -107,46 +97,14 @@ mod alloc_prelude { cfg_if::cfg_if! { if #[cfg(sys_time_component = "custom")] { - use mbedtls_sys::types::{time_t, tm}; - // needs to be pub for global visiblity + // needs to be pub for global visibility #[doc(hidden)] - #[no_mangle] - pub unsafe extern "C" fn mbedtls_platform_gmtime_r(tt: *const time_t, tp: *mut tm) -> *mut tm { - use chrono::prelude::*; - - //0 means no TZ offset - let naive = if tp.is_null() { - return core::ptr::null_mut() - } else { - NaiveDateTime::from_timestamp(*tt, 0) - }; - let utc = DateTime::::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 = utc.year() as i32 - 1900; - tp.tm_wday = utc.weekday().num_days_from_monday() as i32; - tp.tm_yday = utc.ordinal0() as i32; - tp.tm_isdst = 0; - - tp - } + pub use mbedtls_platform_support::mbedtls_platform_gmtime_r; - // needs to be pub for global visiblity + // needs to be pub for global visibility #[doc(hidden)] - #[no_mangle] - pub unsafe extern "C" fn mbedtls_time(tp: *mut time_t) -> time_t { - let timestamp = chrono::Utc::now().timestamp() as time_t; - if !tp.is_null() { - *tp = timestamp; - } - timestamp - } + pub use mbedtls_platform_support::mbedtls_time; } } diff --git a/mbedtls/src/mbedtls_malloc.c b/mbedtls/src/mbedtls_malloc.c index a7f051f7a..e6c4a0678 100644 --- a/mbedtls/src/mbedtls_malloc.c +++ b/mbedtls/src/mbedtls_malloc.c @@ -21,11 +21,15 @@ #define mbedtls_free free #endif -extern void *forward_mbedtls_calloc( size_t n, size_t size ) { +// Use several macros to get the preprocessor to actually replace RUST_MBEDTLS_METADATA_HASH +#define append_macro_inner(a, b) a##_##b +#define append_macro(a, b) append_macro_inner(a, b) +#define APPEND_METADATA_HASH(f) append_macro(f, RUST_MBEDTLS_METADATA_HASH) + +extern void *APPEND_METADATA_HASH(forward_mbedtls_calloc)( size_t n, size_t size ) { return mbedtls_calloc(n, size); } -extern void forward_mbedtls_free( void *ptr ) { +extern void APPEND_METADATA_HASH(forward_mbedtls_free)( void *ptr ) { mbedtls_free(ptr); } - diff --git a/mbedtls/src/pk/mod.rs b/mbedtls/src/pk/mod.rs index 8dcdd9fd6..1c05bdf31 100644 --- a/mbedtls/src/pk/mod.rs +++ b/mbedtls/src/pk/mod.rs @@ -832,6 +832,11 @@ impl Pk { sig: &mut [u8], rng: &mut F, ) -> Result { + // If hash or sig are allowed with size 0 (&[]) then mbedtls will attempt to auto-detect size and cause an invalid write. + if hash.len() == 0 || sig.len() == 0 { + return Err(Error::PkBadInputData) + } + match self.pk_type() { Type::Rsa | Type::RsaAlt | Type::RsassaPss => { if sig.len() < (self.len() / 8) { @@ -868,6 +873,11 @@ impl Pk { sig: &mut [u8], rng: &mut F, ) -> Result { + // If hash or sig are allowed with size 0 (&[]) then mbedtls will attempt to auto-detect size and cause an invalid write. + if hash.len() == 0 || sig.len() == 0 { + return Err(Error::PkBadInputData) + } + use crate::rng::RngCallbackMut; if self.pk_type() == Type::Ecdsa || self.pk_type() == Type::Eckey { @@ -913,6 +923,11 @@ impl Pk { } pub fn verify(&mut self, md: MdType, hash: &[u8], sig: &[u8]) -> Result<()> { + // If hash or sig are allowed with size 0 (&[]) then mbedtls will attempt to auto-detect size and cause an invalid write. + if hash.len() == 0 || sig.len() == 0 { + return Err(Error::PkBadInputData) + } + unsafe { pk_verify( &mut self.inner, @@ -1040,7 +1055,7 @@ impl Pk { #[cfg(test)] mod tests { use super::*; - use crate::hash::Type; + use crate::hash::{Type, MdInfo}; use crate::pk::Type as PkType; // This is test data that must match library output *exactly* @@ -1242,7 +1257,7 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi fn rsa_sign_verify_pkcs1v15() { let mut pk = Pk::generate_rsa(&mut crate::test_support::rand::test_rng(), 2048, 0x10001).unwrap(); - let data = b"SIGNATURE TEST SIGNATURE TEST SI"; + let data = b"SIGNATURE TEST SIGNATURE TEST SIGNATURE TEST SIGNATURE TEST SIGN"; let mut signature = vec![0u8; (pk.len() + 7) / 8]; let digests = [ @@ -1258,16 +1273,34 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi Type::Ripemd, ]; - for digest in &digests { + for &digest in &digests { + let data = if let Some(md @ MdInfo { .. }) = digest.into() { + &data[..md.size()] + } else { + &data[..] + }; + let len = pk .sign( - *digest, + digest, data, &mut signature, &mut crate::test_support::rand::test_rng(), ) .unwrap(); - pk.verify(*digest, data, &signature[0..len]).unwrap(); + pk.verify(digest, data, &signature[0..len]).unwrap(); + + assert_eq!(pk.verify(digest, data, &[]).unwrap_err(), Error::PkBadInputData); + assert_eq!(pk.verify(digest, &[], &signature[0..len]).unwrap_err(), Error::PkBadInputData); + + + let mut dummy_sig = []; + assert_eq!(pk.sign(digest, data, &mut dummy_sig, &mut crate::test_support::rand::test_rng()).unwrap_err(), Error::PkBadInputData); + assert_eq!(pk.sign(digest, &[], &mut signature, &mut crate::test_support::rand::test_rng()).unwrap_err(), Error::PkBadInputData); + + assert_eq!(pk.sign_deterministic(digest, data, &mut dummy_sig, &mut crate::test_support::rand::test_rng()).unwrap_err(), Error::PkBadInputData); + assert_eq!(pk.sign_deterministic(digest, &[], &mut signature, &mut crate::test_support::rand::test_rng()).unwrap_err(), Error::PkBadInputData); + } } @@ -1275,7 +1308,7 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi fn rsa_sign_verify_pss() { let mut pk = Pk::generate_rsa(&mut crate::test_support::rand::test_rng(), 2048, 0x10001).unwrap(); - let data = b"SIGNATURE TEST SIGNATURE TEST SI"; + let data = b"SIGNATURE TEST SIGNATURE TEST SIGNATURE TEST SIGNATURE TEST SIGN"; let mut signature = vec![0u8; (pk.len() + 7) / 8]; let digests = [ @@ -1291,15 +1324,21 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi Type::Ripemd, ]; - for digest in &digests { + for &digest in &digests { + let data = if let Some(md @ MdInfo { .. }) = digest.into() { + &data[..md.size()] + } else { + &data[..] + }; + pk.set_options(Options::Rsa { - padding: RsaPadding::Pkcs1V21 { mgf: *digest }, + padding: RsaPadding::Pkcs1V21 { mgf: digest }, }); - if *digest == Type::None { + if digest == Type::None { assert!(pk .sign( - *digest, + digest, data, &mut signature, &mut crate::test_support::rand::test_rng() @@ -1308,13 +1347,13 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi } else { let len = pk .sign( - *digest, + digest, data, &mut signature, &mut crate::test_support::rand::test_rng(), ) .unwrap(); - pk.verify(*digest, data, &signature[0..len]).unwrap(); + pk.verify(digest, data, &signature[0..len]).unwrap(); } } } diff --git a/mbedtls/src/rust_printf.c b/mbedtls/src/rust_printf.c deleted file mode 100644 index c3b2ac93c..000000000 --- a/mbedtls/src/rust_printf.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) Fortanix, Inc. - * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except - * according to those terms. */ - -#include -#include - -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[n]; - - va_start(ap,fmt); - n=vsnprintf(p,n,fmt,ap); - va_end(ap); - - if (n<0) - return -1; - - mbedtls_log(p); - - return n; -} diff --git a/mbedtls/src/self_test.rs b/mbedtls/src/self_test.rs deleted file mode 100644 index 2dde8c3d9..000000000 --- a/mbedtls/src/self_test.rs +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright (c) Fortanix, Inc. - * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 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 = 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_if::cfg_if! { - if #[cfg(any(not(feature = "std"), target_env = "sgx"))] { - #[allow(non_upper_case_globals)] - static mut rand_f: Option c_int> = None; - - // needs to be pub for global visiblity - #[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) { - #[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, 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 -}; diff --git a/mbedtls/src/threading.rs b/mbedtls/src/threading.rs index 887f026e0..bf7d8168f 100644 --- a/mbedtls/src/threading.rs +++ b/mbedtls/src/threading.rs @@ -6,105 +6,20 @@ * option. This file may not be copied, modified, or distributed except * according to those terms. */ -#[cfg(not(feature = "std"))] -use crate::alloc_prelude::*; - -cfg_if::cfg_if! { - if #[cfg(feature = "std")] { - use std::sync::{Mutex, MutexGuard}; - } else { - use spin::{Mutex, MutexGuard}; - } -} - -use core::ptr; - -use mbedtls_sys::types::raw_types::c_int; - -pub struct StaticMutex { - guard: Option>, - mutex: Mutex<()>, -} - -#[no_mangle] #[allow(non_upper_case_globals)] -pub static mut mbedtls_mutex_init: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) = - StaticMutex::init; -#[no_mangle] +pub use mbedtls_platform_support::threading::mbedtls_mutex_free; #[allow(non_upper_case_globals)] -pub static mut mbedtls_mutex_free: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) = - StaticMutex::free; -#[no_mangle] +pub use mbedtls_platform_support::threading::mbedtls_mutex_init; #[allow(non_upper_case_globals)] -pub static mut mbedtls_mutex_lock: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) -> c_int = - StaticMutex::lock; -#[no_mangle] +pub use mbedtls_platform_support::threading::mbedtls_mutex_lock; #[allow(non_upper_case_globals)] -pub static mut mbedtls_mutex_unlock: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) -> c_int = - StaticMutex::unlock; - -// The nightly compiler complains that StaticMutex has no representation hint, -// but this is not an issue because this pointer is opaque to mbedtls -#[allow(improper_ctypes)] -impl StaticMutex { - unsafe extern "C" fn init(mutex: *mut *mut StaticMutex) { - if let Some(m) = mutex.as_mut() { - *m = Box::into_raw(Box::new(StaticMutex { - guard: None, - mutex: Mutex::new(()), - })); - } - } - - unsafe extern "C" fn free(mutex: *mut *mut StaticMutex) { - if let Some(m) = mutex.as_mut() { - if *m != ptr::null_mut() { - let mut mutex = Box::from_raw(*m); - mutex.guard.take(); - *m = ptr::null_mut(); - } - } - } - - unsafe extern "C" fn lock(mutex: *mut *mut StaticMutex) -> c_int { - if let Some(m) = mutex.as_mut().and_then(|p| p.as_mut()) { - let guard = m.mutex.lock(); - - cfg_if::cfg_if! { - if #[cfg(feature = "std")] { - m.guard = Some(guard.unwrap()); - } else { - m.guard = Some(guard); - } - } - - 0 - } else { - ::mbedtls_sys::ERR_THREADING_BAD_INPUT_DATA - } - } - - unsafe extern "C" fn unlock(mutex: *mut *mut StaticMutex) -> c_int { - if let Some(m) = mutex.as_mut().and_then(|p| p.as_mut()) { - m.guard.take(); - 0 - } else { - ::mbedtls_sys::ERR_THREADING_BAD_INPUT_DATA - } - } -} +pub use mbedtls_platform_support::threading::mbedtls_mutex_unlock; #[cfg(test)] mod tests { - use super::*; #[test] fn double_free() { - unsafe { - let mut mutex: *mut StaticMutex = ptr::null_mut(); - mbedtls_mutex_init(&mut mutex); - mbedtls_mutex_free(&mut mutex); - mbedtls_mutex_free(&mut mutex); - } + mbedtls_platform_support::threading::test_double_free() } } diff --git a/mbedtls/src/x509/certificate.rs b/mbedtls/src/x509/certificate.rs index 16ae14b40..9e14cb3af 100644 --- a/mbedtls/src/x509/certificate.rs +++ b/mbedtls/src/x509/certificate.rs @@ -13,7 +13,7 @@ use core::ptr::NonNull; use mbedtls_sys::*; use mbedtls_sys::types::raw_types::{c_char, c_void}; -use crate::alloc::{List as MbedtlsList, Box as MbedtlsBox}; +use crate::alloc::{List as MbedtlsList, Box as MbedtlsBox, mbedtls_calloc}; #[cfg(not(feature = "std"))] use crate::alloc_prelude::*; use crate::error::{Error, IntoResult, Result}; @@ -23,10 +23,6 @@ use crate::private::UnsafeFrom; use crate::rng::Random; use crate::x509::{self, Time, VerifyCallback}; -extern "C" { - pub(crate) fn forward_mbedtls_calloc(n: mbedtls_sys::types::size_t, size: mbedtls_sys::types::size_t) -> *mut mbedtls_sys::types::raw_types::c_void; -} - #[cfg(feature = "std")] use yasna::{BERDecodable, BERReader, ASN1Result, ASN1Error, ASN1ErrorKind, models::ObjectIdentifier}; @@ -499,7 +495,7 @@ impl<'a> Builder<'a> { impl MbedtlsBox { fn init() -> Result { unsafe { - let inner = forward_mbedtls_calloc(1, core::mem::size_of::()) as *mut x509_crt; + let inner = mbedtls_calloc(1, core::mem::size_of::()) as *mut x509_crt; // If alignment is wrong it means someone pushed their own allocator to mbedtls and that is not functioning correctly. assert_eq!(inner.align_offset(core::mem::align_of::()), 0);