Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Acruceru/mbedtls8 async support #163

Closed
wants to merge 3 commits into from
Closed
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
522 changes: 512 additions & 10 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
[workspace]
members = ["mbedtls", "mbedtls-sys"]

[patch.crates-io]
mio = { git = "https://github.com/mzohreva/mio", branch = "mz/sgx-port-0.7.6" }
tokio = { git = "https://github.com/mzohreva/tokio", branch = "mz/sgx-port-0.3.4" }

5 changes: 2 additions & 3 deletions mbedtls-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ quote = "1.0.9"
# * strstr/strlen/strncpy/strncmp/strcmp/snprintf
# * memmove/memcpy/memcmp/memset
# * rand/printf (used only for self tests. optionally use custom_printf)
default = ["std", "debug", "threading", "zlib", "time", "aesni", "padlock", "legacy_protocols"]
std = ["debug"] # deprecated automatic enabling of debug, can be removed on major version bump
debug = []
default = ["std", "threading", "zlib", "time", "aesni", "padlock", "legacy_protocols"]
std = [] # deprecated automatic enabling of debug, can be removed on major version bump
custom_printf = []
custom_has_support = []
aes_alt = []
Expand Down
31 changes: 28 additions & 3 deletions mbedtls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ bit-vec = { version = "0.5", optional = true }
block-modes = { version = "0.3", optional = true }
rc2 = { version = "0.3", optional = true }
cfg-if = "1.0.0"
tokio = { version = "0.3.4", optional = true }

[target.x86_64-fortanix-unknown-sgx.dependencies]
rs-libc = "0.2.0"
rs-libc = "0.1.0"
chrono = "0.4"

[dependencies.mbedtls-sys-auto]
version = "2.25.0"
version = "2.26.0"
default-features = false
features = ["custom_printf", "trusted_cert_callback", "threading"]
path = "../mbedtls-sys"
Expand All @@ -48,6 +49,11 @@ serde_cbor = "0.6"
hex = "0.3"
matches = "0.1.8"
hyper = { version = "0.10.16", default-features = false }
hyper13 = { package = "hyper", version = "0.13", default-features = false, features = ["stream"] }
tokio-02 = { package = "tokio", version = "0.2", default-features = false }
async-stream = "0.3.0"
futures = "0.3"
tracing = "0.1"

[build-dependencies]
cc = "1.0"
Expand All @@ -56,7 +62,6 @@ cc = "1.0"
# Features are documented in the README
default = ["std", "aesni", "time", "padlock"]
std = ["mbedtls-sys-auto/std", "serde/std", "yasna"]
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"]
mpi_force_c_code = ["mbedtls-sys-auto/mpi_force_c_code"]
Expand All @@ -68,6 +73,9 @@ padlock = ["mbedtls-sys-auto/padlock"]
dsa = ["std", "yasna", "num-bigint", "bit-vec"]
pkcs12 = ["std", "yasna"]
pkcs12_rc2 = ["pkcs12", "rc2", "block-modes"]
async = ["std", "tokio","tokio/net","tokio/io-util", "tokio/macros"]
async-rt = ["async", "tokio/rt", "tokio/sync", "tokio/rt-multi-thread"]
migration_mode=[]

[[example]]
name = "client"
Expand All @@ -92,3 +100,20 @@ required-features = ["std"]
[[test]]
name = "hyper"
required-features = ["std"]

[[test]]
name = "hyper13"
required-features = ["std", "async-rt"]

[[test]]
name = "async_session"
path = "tests/async_session.rs"
required-features = ["async-rt"]


[package.metadata.fortanix-sgx]
threads = 100
heap-size = 0x40000000
stack-size = 0x100000
# The following are not processed by the EDP tools but are picked up by build-enclave.sh:
#isvprodid = 66
7 changes: 5 additions & 2 deletions mbedtls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ mod private;

// needs to be pub for global visiblity
#[doc(hidden)]
#[cfg(sys_threading_component = "custom")]

#[cfg(all(sys_threading_component = "custom", not(feature = "migration_mode")))]
pub mod threading;

#[cfg(not(feature = "migration_mode"))]
cfg_if::cfg_if! {
if #[cfg(any(feature = "force_aesni_support", target_env = "sgx"))] {
// needs to be pub for global visiblity
Expand Down Expand Up @@ -105,6 +107,7 @@ mod alloc_prelude {
pub(crate) use rust_alloc::borrow::Cow;
}

#[cfg(not(feature = "migration_mode"))]
cfg_if::cfg_if! {
if #[cfg(sys_time_component = "custom")] {
use mbedtls_sys::types::{time_t, tm};
Expand Down Expand Up @@ -154,7 +157,7 @@ cfg_if::cfg_if! {
///
/// The caller must ensure no other MbedTLS code is running when calling this
/// function.
#[cfg(feature = "debug")]
#[cfg(all(feature = "debug", not(feature = "migration_mode")))]
pub unsafe fn set_global_debug_threshold(threshold: i32) {
mbedtls_sys::debug_set_threshold(threshold);
}
22 changes: 19 additions & 3 deletions mbedtls/src/pk/dsa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,13 @@ fn sample_secret_value<F: Random>(upper_bound: &Mpi, rng: &mut F) -> Result<Mpi>
Ok(c)
}

fn encode_dsa_signature(r: &Mpi, s: &Mpi) -> Result<Vec<u8>> {
let r = BigUint::from_bytes_be(&r.to_binary()?);
let s = BigUint::from_bytes_be(&s.to_binary()?);
pub fn encode_dsa_signature(r: &Mpi, s: &Mpi) -> Result<Vec<u8>> {
serialize_signature(&r.to_binary()?, &s.to_binary()?)
}

pub fn serialize_signature(r: &[u8], s: &[u8]) -> Result<Vec<u8>> {
let r = BigUint::from_bytes_be(r);
let s = BigUint::from_bytes_be(s);

Ok(yasna::construct_der(|w| {
w.write_sequence(|w| {
Expand All @@ -229,6 +233,18 @@ fn encode_dsa_signature(r: &Mpi, s: &Mpi) -> Result<Vec<u8>> {
}))
}

pub fn deserialize_signature(signature: &Vec<u8>) -> Result<(Vec<u8>, Vec<u8>)> {
let (r,s) = yasna::parse_der(signature, |r| {
r.read_sequence(|rdr| {
let r = rdr.next().read_biguint()?;
let s = rdr.next().read_biguint()?;
Ok((r,s))
})
}).map_err(|_| Error::X509InvalidSignature)?;

Ok((r.to_bytes_be(), s.to_bytes_be()))
}

impl DsaPrivateKey {
pub fn from_components(params: DsaParams, x: Mpi) -> Result<Self> {
if x <= Mpi::new(1)? || x >= params.q {
Expand Down
43 changes: 10 additions & 33 deletions mbedtls/src/pk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,34 +201,7 @@ define!(
//
// - Only used when creating/freeing - which is safe by design - eckey_alloc_wrap / eckey_free_wrap
//
// 3. ECDSA: mbedtls_ecdsa_info at ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:729
// This does not use internal locks but avoids interior mutability.
//
// - Const access / copies context to stack based variables:
// ecdsa_verify_wrap: ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:544
// This copies the public key on the stack - in buf[] and copies the group id and nbits.
// That is done via: mbedtls_pk_write_pubkey( &p, buf, &key ) where key.pk_ctx = ctx;
// And the key is a const parameter to mbedtls_pk_write_pubkey - ../../../mbedtls-sys/vendor/crypto/library/pkwrite.c:158
//
// - Const access with additional notes due to call stacks involved.
//
// ecdsa_sign_wrap: ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:657
// mbedtls_ecdsa_write_signature ../../../mbedtls-sys/vendor/crypto/library/ecdsa.c:688
// mbedtls_ecdsa_write_signature_restartable ../../../mbedtls-sys/vendor/crypto/library/ecdsa.c:640
// MBEDTLS_ECDSA_DETERMINISTIC is not defined.
// MBEDTLS_ECDSA_SIGN_ALT is not defined.
// Passes grp to: ecdsa_sign_restartable: ../../../mbedtls-sys/vendor/crypto/library/ecdsa.c:253
// Const access to group - reads parameters, passed as const to mbedtls_ecp_gen_privkey,
// mbedtls_ecp_mul_restartable: ../../../mbedtls-sys/vendor/crypto/library/ecp.c:2351
// MBEDTLS_ECP_INTERNAL_ALT is not defined. (otherwise it might not be safe depending on ecp_init/ecp_free) ../../../mbedtls-sys/build/config.rs:131
// Passes as const to: mbedtls_ecp_check_privkey / mbedtls_ecp_check_pubkey / mbedtls_ecp_get_type( grp
//
// - Ignored due to not defined: ecdsa_verify_rs_wrap, ecdsa_sign_rs_wrap, ecdsa_rs_alloc, ecdsa_rs_free
// (Undefined - MBEDTLS_ECP_RESTARTABLE - ../../../mbedtls-sys/build/config.rs:173)
//
// - Only const access to context: eckey_check_pair
//
// - Only used when creating/freeing - which is safe by design: ecdsa_alloc_wrap, ecdsa_free_wrap
// 3. ECDSA - code uses mbedtls_pk wrappers. In this case code goes through ECKEY logic above. (mbedtls_pk_parse_key intentionally never calls mbedtls_pk_info_from_type with MBEDTLS_PK_ECDSA)
//
unsafe impl Sync for Pk {}

Expand Down Expand Up @@ -826,7 +799,7 @@ impl Pk {
///
/// On success, returns the actual number of bytes written to `sig`.
pub fn sign<F: Random>(
&mut self,
&self,
md: MdType,
hash: &[u8],
sig: &mut [u8],
Expand All @@ -848,7 +821,7 @@ impl Pk {
let mut ret = 0usize;
unsafe {
pk_sign(
&mut self.inner,
&self.inner as *const _ as *mut _,
md.into(),
hash.as_ptr(),
hash.len(),
Expand Down Expand Up @@ -912,10 +885,14 @@ impl Pk {
}
}

pub fn verify(&mut self, md: MdType, hash: &[u8], sig: &[u8]) -> Result<()> {
pub fn verify(&self, md: MdType, hash: &[u8], sig: &[u8]) -> Result<()> {
if hash.len() == 0 || sig.len() == 0 {
return Err(Error::PkBadInputData)
}

unsafe {
pk_verify(
&mut self.inner,
&self.inner as *const _ as *mut _,
md.into(),
hash.as_ptr(),
hash.len(),
Expand Down Expand Up @@ -1240,7 +1217,7 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi

#[test]
fn rsa_sign_verify_pkcs1v15() {
let mut pk =
let pk =
Pk::generate_rsa(&mut crate::test_support::rand::test_rng(), 2048, 0x10001).unwrap();
let data = b"SIGNATURE TEST SIGNATURE TEST SI";
let mut signature = vec![0u8; (pk.len() + 7) / 8];
Expand Down
31 changes: 28 additions & 3 deletions mbedtls/src/rng/ctr_drbg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ use mbedtls_sys::types::size_t;
#[cfg(not(feature = "std"))]
use crate::alloc_prelude::*;
use crate::error::{IntoResult, Result};
use crate::rng::{EntropyCallback, RngCallback, RngCallbackMut};
use crate::rng::{EntropyCallback, EntropyCallbackMut, RngCallback, RngCallbackMut};

enum EntropyHolder {
Shared(Arc<dyn EntropyCallback + 'static>),
Unique(Box<dyn EntropyCallbackMut + 'static>),
}

define!(
// `ctr_drbg_context` inlines an `aes_context`, which is immovable. See
Expand All @@ -30,7 +35,7 @@ define!(
#[c_box_ty(ctr_drbg_context)]
#[repr(C)]
struct CtrDrbg {
entropy: Arc<dyn EntropyCallback + 'static>,
entropy: EntropyHolder,
};
const drop: fn(&mut Self) = ctr_drbg_free;
impl<'a> Into<ptr> {}
Expand Down Expand Up @@ -63,8 +68,28 @@ impl CtrDrbg {
).into_result()?;
}

Ok(CtrDrbg { inner, entropy })
Ok(CtrDrbg { inner, entropy: EntropyHolder::Shared(entropy) })
}

pub fn new_mut<T: EntropyCallbackMut + 'static>(entropy: T, additional_entropy: Option<&[u8]>) -> Result<Self> {
let mut inner = Box::new(ctr_drbg_context::default());

// We take sole ownership of entropy, all access is guarded via mutexes.
let mut entropy = Box::new(entropy);
unsafe {
ctr_drbg_init(&mut *inner);
ctr_drbg_seed(
&mut *inner,
Some(T::call_mut),
entropy.data_ptr_mut(),
additional_entropy.map(<[_]>::as_ptr).unwrap_or(::core::ptr::null()),
additional_entropy.map(<[_]>::len).unwrap_or(0)
).into_result()?;
}

Ok(CtrDrbg { inner, entropy: EntropyHolder::Unique(entropy) })
}


pub fn prediction_resistance(&self) -> bool {
if self.inner.prediction_resistance == CTR_DRBG_PR_OFF {
Expand Down
4 changes: 2 additions & 2 deletions mbedtls/src/rust_printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <stdio.h>
#include <stdarg.h>

extern void mbedtls_log(const char* msg);
extern void mbedtls8_log(const char* msg);

extern int mbedtls_printf(const char *fmt, ...) {
va_list ap;
Expand All @@ -31,7 +31,7 @@ extern int mbedtls_printf(const char *fmt, ...) {
if (n<0)
return -1;

mbedtls_log(p);
mbedtls8_log(p);

return n;
}
8 changes: 6 additions & 2 deletions mbedtls/src/self_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ cfg_if::cfg_if! {
// 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) {
pub unsafe extern "C" fn mbedtls8_log(msg: *const std::os::raw::c_char) {
print!("{}", std::ffi::CStr::from_ptr(msg).to_string_lossy());
}
} else {
Expand All @@ -35,11 +35,13 @@ cfg_if::cfg_if! {
// needs to be pub for global visiblity
#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn mbedtls_log(msg: *const c_char) {
pub unsafe extern "C" fn mbedtls8_log(msg: *const c_char) {
log_f.expect("Called self-test log without enabling self-test")(msg)
}
}
}

#[cfg(not(feature = "migration_mode"))]
cfg_if::cfg_if! {
if #[cfg(any(not(feature = "std"), target_env = "sgx"))] {
#[allow(non_upper_case_globals)]
Expand All @@ -66,6 +68,7 @@ cfg_if::cfg_if! {
/// The caller needs to ensure this function is not called while any other
/// function in this module is called.
#[allow(unused)]
#[cfg(not(feature = "migration_mode"))]
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);
Expand All @@ -79,6 +82,7 @@ pub unsafe fn enable(rand: fn() -> c_int, log: Option<unsafe fn(*const c_char)>)
///
/// The caller needs to ensure this function is not called while any other
/// function in this module is called.
#[cfg(not(feature = "migration_mode"))]
pub unsafe fn disable() {
#[cfg(any(not(feature = "std"), target_env = "sgx"))] {
rand_f = None;
Expand Down
Loading