From 9ba589fac5610757cee19e379e3350dcd558840f Mon Sep 17 00:00:00 2001 From: "bors[bot]" <26634292+bors[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 23:39:44 +0000 Subject: [PATCH 1/8] Merge #243 243: Namespace symbols for mbedtls_malloc to avoid conflicts. r=Taowyoo a=jethrogb Dependents of this crate may use multiple different versions of this crate. These different versions all define mbedtls_calloc and mbedtls_free, which can result in linking conflicts. Since these functions are defined in and only used by this crate, we can namespace the symbols to avoid conflicts. We use Cargo's crate disambiguator for this purpose. Co-authored-by: Jethro Beekman --- mbedtls/build.rs | 17 +++++++++++++++++ mbedtls/src/alloc.rs | 7 +++++-- mbedtls/src/mbedtls_malloc.c | 10 +++++++--- mbedtls/src/x509/certificate.rs | 8 ++------ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/mbedtls/build.rs b/mbedtls/build.rs index 32047d486..03b0695f4 100644 --- a/mbedtls/build.rs +++ b/mbedtls/build.rs @@ -9,7 +9,23 @@ 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() +} + fn main() { + 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,6 +40,7 @@ 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"); 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/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/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); From 1aa2013a9b492587ceeb6e01d39f1f8592d572b5 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Tue, 18 Apr 2023 17:02:41 -0700 Subject: [PATCH 2/8] separate self test logic into another crate --- Cargo.lock | 14 ++++- Cargo.toml | 8 +++ mbedtls/Cargo.toml | 9 ++-- mbedtls/build.rs | 5 -- mbedtls/src/lib.rs | 2 +- mbedtls/src/rust_printf.c | 37 -------------- mbedtls/src/self_test.rs | 105 -------------------------------------- 7 files changed, 28 insertions(+), 152 deletions(-) delete mode 100644 mbedtls/src/rust_printf.c delete mode 100644 mbedtls/src/self_test.rs diff --git a/Cargo.lock b/Cargo.lock index fd8177747..d480a316e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -383,7 +383,7 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "mbedtls" -version = "0.8.2" +version = "0.8.3" dependencies = [ "bit-vec", "bitflags", @@ -397,6 +397,7 @@ dependencies = [ "hyper", "libc", "matches", + "mbedtls-selftest", "mbedtls-sys-auto", "num-bigint", "rand", @@ -409,6 +410,17 @@ dependencies = [ "yasna", ] +[[package]] +name = "mbedtls-selftest" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b5950daa65ba1c71120766dfe975d1946289d4d6fdc4757778d631037098673" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "mbedtls-sys-auto", +] + [[package]] name = "mbedtls-sys-auto" version = "2.26.1" diff --git a/Cargo.toml b/Cargo.toml index 755259713..c6aba1bdd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,10 @@ [workspace] members = ["mbedtls", "mbedtls-sys"] + +[patch.crates-io] +# This patch resolves a local dependency conflict between `mbedtls` and `mbedtls-selftest`. +# Both of these crates require the native library `mbedtls-sys-auto`. +# By default, Cargo chooses the `mbedtls-sys-auto` version from crates.io for `mbedtls-selftest`, +# which conflicts with the local `mbedtls-sys-auto` used by `mbedtls`. +# This patch ensures the local `mbedtls-sys-auto` is used for both crates. +mbedtls-sys-auto = { path = "./mbedtls-sys" } diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index deb667aaa..916996feb 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" @@ -38,9 +38,12 @@ chrono = "0.4" [dependencies.mbedtls-sys-auto] version = "2.25.0" default-features = false -features = ["custom_printf", "trusted_cert_callback", "threading"] +features = ["trusted_cert_callback", "threading"] path = "../mbedtls-sys" +[dependencies.mbedtls-selftest] +version = "0.1" + [dev-dependencies] libc = "0.2.0" rand = "0.4.0" @@ -55,7 +58,7 @@ cc = "1.0" [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-selftest/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"] diff --git a/mbedtls/build.rs b/mbedtls/build.rs index 03b0695f4..b334a6c28 100644 --- a/mbedtls/build.rs +++ b/mbedtls/build.rs @@ -43,15 +43,10 @@ fn main() { 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/lib.rs b/mbedtls/src/lib.rs index 07b18e9d1..aad2dc210 100644 --- a/mbedtls/src/lib.rs +++ b/mbedtls/src/lib.rs @@ -38,7 +38,7 @@ pub mod ecp; pub mod hash; pub mod pk; pub mod rng; -pub mod self_test; +pub use mbedtls_selftest as self_test; pub mod ssl; pub mod x509; pub mod alloc; 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 -}; From c12b9f6a18631575bc3363e07be17067f815c0aa Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Wed, 19 Apr 2023 17:16:08 -0700 Subject: [PATCH 3/8] fix feature problem --- mbedtls/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mbedtls/src/lib.rs b/mbedtls/src/lib.rs index aad2dc210..3095e05be 100644 --- a/mbedtls/src/lib.rs +++ b/mbedtls/src/lib.rs @@ -9,6 +9,8 @@ #![deny(warnings)] #![allow(unused_doc_comments)] #![cfg_attr(not(feature = "std"), no_std)] +#![allow(stable_features)] +#![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"); From 926ed6e6ec0b2c117aae765e470dee35a4ab036e Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Wed, 19 Apr 2023 21:45:40 -0700 Subject: [PATCH 4/8] fix compile error Use `rustc_version` conditionally add `extended_key_value_attributes` feature to fix problem: PR #243 code use unstable feature when compile with nightly-2021-03-25 rustc. --- Cargo.lock | 29 +++++++++++++++++++++++++++-- mbedtls/Cargo.toml | 1 + mbedtls/build.rs | 14 ++++++++++++++ mbedtls/src/lib.rs | 3 +-- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d480a316e..2dc5a86a1 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]] @@ -403,6 +403,7 @@ dependencies = [ "rand", "rc2", "rs-libc", + "rustc_version 0.2.3", "serde", "serde_cbor", "serde_derive", @@ -652,7 +653,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]] @@ -667,6 +677,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/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index 916996feb..dbf1ba9ea 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -54,6 +54,7 @@ hyper = { version = "0.10.16", default-features = false } [build-dependencies] cc = "1.0" +rustc_version = "0.2" [features] # Features are documented in the README diff --git a/mbedtls/build.rs b/mbedtls/build.rs index b334a6c28..d873384be 100644 --- a/mbedtls/build.rs +++ b/mbedtls/build.rs @@ -6,6 +6,7 @@ * 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; @@ -22,7 +23,20 @@ fn get_compilation_metadata_hash() -> String { 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); diff --git a/mbedtls/src/lib.rs b/mbedtls/src/lib.rs index 3095e05be..204941c58 100644 --- a/mbedtls/src/lib.rs +++ b/mbedtls/src/lib.rs @@ -9,8 +9,7 @@ #![deny(warnings)] #![allow(unused_doc_comments)] #![cfg_attr(not(feature = "std"), no_std)] -#![allow(stable_features)] -#![feature(extended_key_value_attributes)] +#![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"); From 8b0332aff817d33eb19a6435a4d0ca516aa3f86c Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 5 May 2023 17:00:16 -0700 Subject: [PATCH 5/8] Use crate `mbedtls-platform-support` --- Cargo.lock | 14 +++--- Cargo.toml | 5 ++- mbedtls/Cargo.toml | 15 +++---- mbedtls/src/lib.rs | 77 +++++++------------------------- mbedtls/src/pk/mod.rs | 63 +++++++++++++++++++++----- mbedtls/src/threading.rs | 95 +++------------------------------------- 6 files changed, 89 insertions(+), 180 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2dc5a86a1..eb96248c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -391,13 +391,12 @@ dependencies = [ "cbc", "cc", "cfg-if 1.0.0", - "chrono", "core_io", "hex", "hyper", "libc", "matches", - "mbedtls-selftest", + "mbedtls-platform-support", "mbedtls-sys-auto", "num-bigint", "rand", @@ -407,24 +406,25 @@ dependencies = [ "serde", "serde_cbor", "serde_derive", - "spin", "yasna", ] [[package]] -name = "mbedtls-selftest" +name = "mbedtls-platform-support" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5950daa65ba1c71120766dfe975d1946289d4d6fdc4757778d631037098673" +source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=yx/mbedtls-platform-support#4f7ad204f85ec69ef1b253068f80c81b6982b5a6" 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 = "git+https://github.com/fortanix/rust-mbedtls.git?branch=yx/mbedtls-platform-support#4f7ad204f85ec69ef1b253068f80c81b6982b5a6" dependencies = [ "bindgen", "cc", diff --git a/Cargo.toml b/Cargo.toml index c6aba1bdd..4c6f45c6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["mbedtls", "mbedtls-sys"] +members = ["mbedtls"] [patch.crates-io] # This patch resolves a local dependency conflict between `mbedtls` and `mbedtls-selftest`. @@ -7,4 +7,5 @@ members = ["mbedtls", "mbedtls-sys"] # By default, Cargo chooses the `mbedtls-sys-auto` version from crates.io for `mbedtls-selftest`, # which conflicts with the local `mbedtls-sys-auto` used by `mbedtls`. # This patch ensures the local `mbedtls-sys-auto` is used for both crates. -mbedtls-sys-auto = { path = "./mbedtls-sys" } +mbedtls-platform-support = { git = "https://github.com/fortanix/rust-mbedtls.git", branch = "yx/mbedtls-platform-support"} +mbedtls-sys-auto = { git = "https://github.com/fortanix/rust-mbedtls.git", branch = "yx/mbedtls-platform-support"} diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index dbf1ba9ea..ab53ae989 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -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,15 +32,13 @@ 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 = ["trusted_cert_callback", "threading"] -path = "../mbedtls-sys" -[dependencies.mbedtls-selftest] +[dependencies.mbedtls-platform-support] version = "0.1" [dev-dependencies] @@ -59,15 +56,15 @@ rustc_version = "0.2" [features] # Features are documented in the README default = ["std", "aesni", "time", "padlock"] -std = ["mbedtls-sys-auto/std", "serde/std", "yasna", "mbedtls-selftest/std"] +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/src/lib.rs b/mbedtls/src/lib.rs index 204941c58..b68911297 100644 --- a/mbedtls/src/lib.rs +++ b/mbedtls/src/lib.rs @@ -14,9 +14,7 @@ #[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] @@ -39,7 +37,7 @@ pub mod ecp; pub mod hash; pub mod pk; pub mod rng; -pub use mbedtls_selftest as self_test; +pub use mbedtls_platform_support::self_test as self_test; pub mod ssl; pub mod x509; pub mod alloc; @@ -52,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; } } @@ -94,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)] @@ -108,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/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/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() } } From b65b992136b23605abebf4c5fef94f52fbe4d8a5 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Mon, 8 May 2023 22:48:25 -0700 Subject: [PATCH 6/8] update patch branch --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb96248c1..ddb8974ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,7 +412,7 @@ dependencies = [ [[package]] name = "mbedtls-platform-support" version = "0.1.0" -source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=yx/mbedtls-platform-support#4f7ad204f85ec69ef1b253068f80c81b6982b5a6" +source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=yx/mbedtls-platform-support#8fb58d4371a2e7b6617a60dfed9a67da08533db8" dependencies = [ "cc", "cfg-if 1.0.0", @@ -424,7 +424,7 @@ dependencies = [ [[package]] name = "mbedtls-sys-auto" version = "2.28.0" -source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=yx/mbedtls-platform-support#4f7ad204f85ec69ef1b253068f80c81b6982b5a6" +source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=yx/mbedtls-platform-support#8fb58d4371a2e7b6617a60dfed9a67da08533db8" dependencies = [ "bindgen", "cc", From 2ae7e20a45876dcc18a00eba65194fc14f366382 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Thu, 11 May 2023 10:50:06 -0700 Subject: [PATCH 7/8] testing: update patch to master branch --- Cargo.lock | 4 ++-- Cargo.toml | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ddb8974ec..d262b7785 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,7 +412,7 @@ dependencies = [ [[package]] name = "mbedtls-platform-support" version = "0.1.0" -source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=yx/mbedtls-platform-support#8fb58d4371a2e7b6617a60dfed9a67da08533db8" +source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=master#95a24391ce2afc22aecc1ee9f44f00e895fd0461" dependencies = [ "cc", "cfg-if 1.0.0", @@ -424,7 +424,7 @@ dependencies = [ [[package]] name = "mbedtls-sys-auto" version = "2.28.0" -source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=yx/mbedtls-platform-support#8fb58d4371a2e7b6617a60dfed9a67da08533db8" +source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=master#95a24391ce2afc22aecc1ee9f44f00e895fd0461" dependencies = [ "bindgen", "cc", diff --git a/Cargo.toml b/Cargo.toml index 4c6f45c6b..ba3f62c8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,6 @@ members = ["mbedtls"] # By default, Cargo chooses the `mbedtls-sys-auto` version from crates.io for `mbedtls-selftest`, # which conflicts with the local `mbedtls-sys-auto` used by `mbedtls`. # This patch ensures the local `mbedtls-sys-auto` is used for both crates. -mbedtls-platform-support = { git = "https://github.com/fortanix/rust-mbedtls.git", branch = "yx/mbedtls-platform-support"} -mbedtls-sys-auto = { git = "https://github.com/fortanix/rust-mbedtls.git", branch = "yx/mbedtls-platform-support"} +# TODO: remove these patches once `mbedtls-platform-support v0.1.0` is published +mbedtls-platform-support = { git = "https://github.com/fortanix/rust-mbedtls.git", branch = "master"} +mbedtls-sys-auto = { git = "https://github.com/fortanix/rust-mbedtls.git", branch = "master"} From ac84a02ed7858940da65c2a62ac5624fc9dad64b Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Thu, 11 May 2023 17:05:58 -0700 Subject: [PATCH 8/8] remove patch --- Cargo.lock | 6 ++++-- Cargo.toml | 10 ---------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d262b7785..f7406b3ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,7 +412,8 @@ dependencies = [ [[package]] name = "mbedtls-platform-support" version = "0.1.0" -source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=master#95a24391ce2afc22aecc1ee9f44f00e895fd0461" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85be113c8c2dc54cc6a5fba20130c7128f78dcb3ed0bb6797427333fa8cdb54d" dependencies = [ "cc", "cfg-if 1.0.0", @@ -424,7 +425,8 @@ dependencies = [ [[package]] name = "mbedtls-sys-auto" version = "2.28.0" -source = "git+https://github.com/fortanix/rust-mbedtls.git?branch=master#95a24391ce2afc22aecc1ee9f44f00e895fd0461" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2231108271d9a10052178d940926baf24b57a2eb1703732faae387592dd6ac3" dependencies = [ "bindgen", "cc", diff --git a/Cargo.toml b/Cargo.toml index ba3f62c8d..832230aec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,2 @@ [workspace] members = ["mbedtls"] - -[patch.crates-io] -# This patch resolves a local dependency conflict between `mbedtls` and `mbedtls-selftest`. -# Both of these crates require the native library `mbedtls-sys-auto`. -# By default, Cargo chooses the `mbedtls-sys-auto` version from crates.io for `mbedtls-selftest`, -# which conflicts with the local `mbedtls-sys-auto` used by `mbedtls`. -# This patch ensures the local `mbedtls-sys-auto` is used for both crates. -# TODO: remove these patches once `mbedtls-platform-support v0.1.0` is published -mbedtls-platform-support = { git = "https://github.com/fortanix/rust-mbedtls.git", branch = "master"} -mbedtls-sys-auto = { git = "https://github.com/fortanix/rust-mbedtls.git", branch = "master"}