mbedtls/
lib.rs

1/* Copyright (c) Fortanix, Inc.
2 *
3 * Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
4 * https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
5 * 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
6 * option. This file may not be copied, modified, or distributed except
7 * according to those terms. */
8
9#![deny(warnings)]
10#![allow(unused_doc_comments, ambiguous_glob_reexports)] // allow ambiguous glob reexports for now in autogenerated bindings.
11#![cfg_attr(not(feature = "std"), no_std)]
12#![cfg_attr(nightly, feature(doc_auto_cfg))]
13
14#[cfg(not(any(feature = "std", feature = "no_std_deps")))]
15compile_error!("Either the `std` or `no_std_deps` feature needs to be enabled");
16
17#[macro_use]
18extern crate serde_derive;
19// required explicitly to force inclusion at link time
20#[cfg(target_env = "sgx")]
21extern crate rs_libc;
22
23#[macro_use]
24mod wrapper_macros;
25
26// ==============
27//      API
28// ==============
29pub mod bignum;
30pub mod error;
31pub use crate::error::{Error, Result};
32pub mod cipher;
33pub mod ecp;
34pub mod hash;
35pub mod pk;
36pub mod rng;
37pub use mbedtls_platform_support::self_test;
38#[cfg(any(feature = "x509", feature = "ssl", feature = "pkcs12"))]
39pub mod alloc;
40#[cfg(feature = "ssl")]
41pub mod ssl;
42#[cfg(feature = "x509")]
43pub mod x509;
44
45#[cfg(feature = "pkcs12")]
46pub mod pkcs12;
47
48pub fn zeroize(buf: &mut [u8]) {
49    unsafe { mbedtls_sys::platform_zeroize(buf.as_mut_ptr() as *mut mbedtls_sys::types::raw_types::c_void, buf.len()) }
50}
51
52// ==============
53//    Utility
54// ==============
55mod private;
56
57// needs to be pub for global visibility
58#[doc(hidden)]
59#[cfg(sys_threading_component = "custom")]
60pub mod threading;
61
62cfg_if::cfg_if! {
63    if #[cfg(any(feature = "force_aesni_support", target_env = "sgx"))] {
64        // needs to be pub for global visibility
65        #[doc(hidden)]
66        pub use mbedtls_platform_support::mbedtls_aesni_has_support;
67
68        // needs to be pub for global visibility
69        #[doc(hidden)]
70        pub use mbedtls_platform_support::mbedtls_internal_aes_encrypt;
71
72        // needs to be pub for global visibility
73        #[doc(hidden)]
74        pub use mbedtls_platform_support::mbedtls_internal_aes_decrypt;
75    }
76}
77
78#[cfg(test)]
79#[path = "../tests/support/mod.rs"]
80mod test_support;
81#[cfg(test)]
82mod mbedtls {
83    pub use super::*;
84}
85
86#[cfg(not(feature = "std"))]
87#[macro_use]
88extern crate alloc as rust_alloc;
89
90#[cfg(not(feature = "std"))]
91mod alloc_prelude {
92    #![allow(unused)]
93    pub(crate) use rust_alloc::borrow::Cow;
94    pub(crate) use rust_alloc::borrow::ToOwned;
95    pub(crate) use rust_alloc::boxed::Box;
96    pub(crate) use rust_alloc::string::String;
97    pub(crate) use rust_alloc::string::ToString;
98    pub(crate) use rust_alloc::sync::Arc;
99    pub(crate) use rust_alloc::vec::Vec;
100}
101
102cfg_if::cfg_if! {
103    if #[cfg(sys_time_component = "custom")] {
104
105        // needs to be pub for global visibility
106        #[doc(hidden)]
107        pub use mbedtls_platform_support::mbedtls_platform_gmtime_r;
108
109        // needs to be pub for global visibility
110        #[doc(hidden)]
111        pub use mbedtls_platform_support::mbedtls_time;
112    }
113}
114
115/// # Safety
116///
117/// The caller must ensure no other MbedTLS code is running when calling this
118/// function.
119#[cfg(feature = "debug")]
120pub unsafe fn set_global_debug_threshold(threshold: i32) {
121    mbedtls_sys::debug_set_threshold(threshold);
122}
123
124#[cfg(test)]
125mod tests {
126    #[allow(dead_code)]
127    /// Utilities for testing whether types implement certain traits.
128    ///
129    /// For each trait `Trait` that you want to be able to test, you should
130    /// implement:
131    /// ```ignore
132    /// impl<T: “Trait”> Testable<dyn “Trait”> for T {}
133    /// ```
134    ///
135    /// Then, to test whether a type `Type` implements `Trait`, call:
136    /// ```ignore
137    /// TestTrait::<dyn “Trait”, “Type”>::new().impls_trait()
138    /// ```
139    /// This returns a `bool` indicating whether the trait is implemented.
140    // This relies on auto-deref to distinguish between types that do and don't
141    // implement the trait.
142    mod testtrait {
143        use core::marker::PhantomData;
144
145        pub struct NonImplTrait<T> {
146            inner: PhantomData<T>,
147        }
148
149        pub struct TestTrait<TraitObj: ?Sized, Type> {
150            non_impl: NonImplTrait<Type>,
151            phantom: PhantomData<*const TraitObj>,
152        }
153
154        pub trait Testable<T: ?Sized> {}
155
156        impl<TraitObj: ?Sized, Type> TestTrait<TraitObj, Type> {
157            pub fn new() -> Self {
158                TestTrait {
159                    non_impl: NonImplTrait { inner: PhantomData },
160                    phantom: PhantomData,
161                }
162            }
163        }
164
165        impl<TraitObj: ?Sized, Type: Testable<TraitObj>> TestTrait<TraitObj, Type> {
166            pub fn impls_trait(&self) -> bool {
167                true
168            }
169        }
170
171        impl<T> NonImplTrait<T> {
172            pub fn impls_trait(&self) -> bool {
173                false
174            }
175        }
176
177        impl<TraitObj: ?Sized, Type> core::ops::Deref for TestTrait<TraitObj, Type> {
178            type Target = NonImplTrait<Type>;
179
180            fn deref(&self) -> &NonImplTrait<Type> {
181                &self.non_impl
182            }
183        }
184    }
185
186    pub use testtrait::{TestTrait, Testable};
187
188    impl<T: Send> Testable<dyn Send> for T {}
189    impl<T: Sync> Testable<dyn Sync> for T {}
190    impl<T: Send + Sync> Testable<dyn Send + Sync> for T {}
191}