From e86ca3af115889aba8c86cbd9b160b13723f262e Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Wed, 30 Jan 2019 11:26:15 +0530 Subject: [PATCH 1/5] Implement entropy source for SGX I agree to license my contributions to each file under the terms given at the top of each file I changed. Co-authored-by: Akash Anand --- Cargo.toml | 1 + build.rs | 1 + crypto/fipsmodule/rand/asm/rdrand-x86_64.pl | 79 +++++++++++++++++++++ src/rand.rs | 36 ++++++++++ 4 files changed, 117 insertions(+) create mode 100644 crypto/fipsmodule/rand/asm/rdrand-x86_64.pl diff --git a/Cargo.toml b/Cargo.toml index 4a66b38f77..7c45715d44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,6 +83,7 @@ include = [ "crypto/fipsmodule/modes/asm/ghashv8-armx.pl", "crypto/fipsmodule/modes/gcm.c", "crypto/fipsmodule/modes/internal.h", + "crypto/fipsmodule/rand/asm/rdrand-x86_64.pl", "crypto/fipsmodule/sha/asm/sha256-586.pl", "crypto/fipsmodule/sha/asm/sha256-armv4.pl", "crypto/fipsmodule/sha/asm/sha512-586.pl", diff --git a/build.rs b/build.rs index 45cfab7ec7..3cafc7fc6a 100644 --- a/build.rs +++ b/build.rs @@ -91,6 +91,7 @@ const RING_SRCS: &[(&[&str], &str)] = &[ (&[X86_64], "crypto/fipsmodule/modes/asm/ghash-x86_64.pl"), (&[X86_64], "crypto/poly1305/asm/poly1305-x86_64.pl"), (&[X86_64], SHA512_X86_64), + (&[X86_64], "crypto/fipsmodule/rand/asm/rdrand-x86_64.pl"), (&[AARCH64, ARM], "crypto/fipsmodule/aes/asm/aesv8-armx.pl"), (&[AARCH64, ARM], "crypto/fipsmodule/modes/asm/ghashv8-armx.pl"), diff --git a/crypto/fipsmodule/rand/asm/rdrand-x86_64.pl b/crypto/fipsmodule/rand/asm/rdrand-x86_64.pl new file mode 100644 index 0000000000..056dd74878 --- /dev/null +++ b/crypto/fipsmodule/rand/asm/rdrand-x86_64.pl @@ -0,0 +1,79 @@ +#!/usr/bin/env perl + +# Copyright (c) 2015, Google Inc. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}../../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +print<<___; +.text + +# CRYPTO_rdrand writes eight bytes of random data from the hardware RNG to +# |out|. It returns one on success or zero on hardware failure. +# int CRYPTO_rdrand(uint8_t out[8]); +.globl CRYPTO_rdrand +.type CRYPTO_rdrand,\@function,1 +.align 16 +CRYPTO_rdrand: +.cfi_startproc + xorq %rax, %rax + # This is rdrand %rcx. It sets rcx to a random value and sets the carry + # flag on success. + .byte 0x48, 0x0f, 0xc7, 0xf1 + # An add-with-carry of zero effectively sets %rax to the carry flag. + adcq %rax, %rax + movq %rcx, 0(%rdi) + retq +.cfi_endproc + +# CRYPTO_rdrand_multiple8_buf fills |len| bytes at |buf| with random data from +# the hardware RNG. The |len| argument must be a multiple of eight. It returns +# one on success and zero on hardware failure. +# int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len); +.globl CRYPTO_rdrand_multiple8_buf +.type CRYPTO_rdrand_multiple8_buf,\@function,2 +.align 16 +CRYPTO_rdrand_multiple8_buf: +.cfi_startproc + test %rsi, %rsi + jz .Lout + movq \$8, %rdx +.Lloop: + # This is rdrand %rcx. It sets rcx to a random value and sets the carry + # flag on success. + .byte 0x48, 0x0f, 0xc7, 0xf1 + jnc .Lerr + movq %rcx, 0(%rdi) + addq %rdx, %rdi + subq %rdx, %rsi + jnz .Lloop +.Lout: + movq \$1, %rax + retq +.Lerr: + xorq %rax, %rax + retq +.cfi_endproc +___ + +close STDOUT; # flush diff --git a/src/rand.rs b/src/rand.rs index b6fb6bc4ca..f6a7c24dae 100644 --- a/src/rand.rs +++ b/src/rand.rs @@ -60,6 +60,8 @@ pub trait SecureRandom: sealed::Sealed { /// On Windows, `fill` is implemented using the platform's API for secure /// random number generation. /// +/// On SGX, `fill()` is implemented using the `RDRAND` instruction. +/// /// Otherwise, `fill()` is implemented by reading from `/dev/urandom`. (This is /// something that should be improved for any platform that adds something /// better.) @@ -100,6 +102,7 @@ impl sealed::Sealed for SystemRandom {} target_os = "macos", target_os = "ios", target_os = "fuchsia", + target_env = "sgx", windows )) ))] @@ -120,6 +123,9 @@ use self::darwin::fill as fill_impl; #[cfg(any(target_os = "fuchsia"))] use self::fuchsia::fill as fill_impl; +#[cfg(target_env = "sgx")] +use self::rdrandom::fill as fill_impl; + use crate::sealed; #[cfg(target_os = "linux")] @@ -312,6 +318,36 @@ mod fuchsia { } } +#[cfg(all(target_env = "sgx", target_feature = "rdrand"))] +mod rdrandom { + use crate::{bssl, error}; + + fn rdrand_loop() -> Result<[u8; 8], error::Unspecified> { + extern "C" { + fn CRYPTO_rdrand(out: &mut [u8; 8]) -> bssl::Result; + } + + for _ in 0..10 { + let mut buf = [0u8; 8]; + match Result::from(unsafe { CRYPTO_rdrand(&mut buf) }) { + Ok(()) => return Ok(buf), + Err(_) => continue + } + } + Err(error::Unspecified) + } + + pub fn fill(dest: &mut [u8]) -> Result<(), error::Unspecified> { + for dst in dest.chunks_mut(8) { + let src = rdrand_loop()?; + let dst_len = dst.len(); + dst.copy_from_slice(&src[..dst_len]) + } + + Ok(()) + } +} + #[cfg(test)] mod tests { use crate::rand::{self, SecureRandom}; From 7c29308410aa4cb06874fdac3caaff1802073860 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Wed, 30 Jan 2019 11:36:52 +0530 Subject: [PATCH 2/5] Disable AES/GCM `Fallback` implementations on SGX I agree to license my contributions to each file under the terms given at the top of each file I changed. --- src/aead/aes.rs | 13 ++++++++++++- src/aead/gcm.rs | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/aead/aes.rs b/src/aead/aes.rs index 5bd20eb7d3..203e99a139 100644 --- a/src/aead/aes.rs +++ b/src/aead/aes.rs @@ -74,6 +74,7 @@ impl Key { })?; }, + #[cfg(not(target_env = "sgx"))] _ => { extern "C" { fn GFp_aes_nohw_set_encrypt_key( @@ -121,6 +122,7 @@ impl Key { } }, + #[cfg(not(target_env = "sgx"))] _ => { extern "C" { fn GFp_aes_nohw_encrypt(a: *const Block, r: *mut Block, key: &AES_KEY); @@ -246,6 +248,7 @@ pub enum Implementation { #[cfg(target_arch = "arm")] BSAES = 3, + #[cfg(not(target_env = "sgx"))] Fallback = 4, } @@ -268,7 +271,15 @@ fn detect_implementation(cpu_features: cpu::Features) -> Implementation { } } - Implementation::Fallback + #[cfg(not(target_env = "sgx"))] + { + Implementation::Fallback + } + + #[cfg(target_env = "sgx")] + { + panic!("No AES implementation available!") + } } #[must_use] diff --git a/src/aead/gcm.rs b/src/aead/gcm.rs index 46522c2905..4a350aedc3 100644 --- a/src/aead/gcm.rs +++ b/src/aead/gcm.rs @@ -57,6 +57,7 @@ impl Key { } }, + #[cfg(not(target_env = "sgx"))] Implementation::Fallback => { extern "C" { fn GFp_gcm_init_4bit(key: &mut Key, h: &[u64; 2]); @@ -139,6 +140,7 @@ impl Context { } }, + #[cfg(not(target_env = "sgx"))] Implementation::Fallback => { extern "C" { fn GFp_gcm_ghash_4bit( @@ -177,6 +179,7 @@ impl Context { } }, + #[cfg(not(target_env = "sgx"))] Implementation::Fallback => { extern "C" { fn GFp_gcm_gmult_4bit(ctx: &mut Context, Htable: *const GCM128_KEY); @@ -199,6 +202,7 @@ impl Context { pub(super) fn is_avx2(&self, cpu_features: cpu::Features) -> bool { match detect_implementation(cpu_features) { Implementation::CLMUL => has_avx_movbe(self.cpu_features), + #[cfg(not(target_env = "sgx"))] _ => false, } } @@ -234,6 +238,7 @@ enum Implementation { #[cfg(target_arch = "arm")] NEON, + #[cfg(not(target_env = "sgx"))] Fallback, } @@ -252,7 +257,15 @@ fn detect_implementation(cpu: cpu::Features) -> Implementation { } } - Implementation::Fallback + #[cfg(not(target_env = "sgx"))] + { + Implementation::Fallback + } + + #[cfg(target_env = "sgx")] + { + panic!("No GCM implementation available!") + } } #[cfg(target_arch = "x86_64")] From 2cb1d0c8be44efabea55b6142c36c1898ace0f56 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Wed, 30 Jan 2019 17:08:18 +0530 Subject: [PATCH 3/5] Optionally use std::is_x86_feature_detected for feature detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audit of all CPUID features use by *ring* at the time of the commit: | | chacha | aesni | mont5 | mont | ghash | sha512 | poly1305 | Rust | |--------------|--------|-------|-------|------|-------|--------|----------|------| | ADX | | | * | * | | | | | | AES | | | | | | | | * | | AVX | | * | | | | * | * | * | | AVX2 | * | | | * | | * | * | | | AVX512F | * | | | | | | | | | BMI1 | | | * | | | * | | | | BMI2 | | | * | * | | * | | | | FXSR | | | | | | | | 5 | | “intel CPU” | | | | | | * | | | | MOVBE | 1,2 | * | | | 1,3 | | | 6 | | PCLMULQDQ | | | | | | | | * | | SHA | | | | | | * | | | | SSSE3 | * | | | | | * | | * | | XOP | | 4 | | | | | | | | XSAVE | 1 | 1 | | | 1 | | | | 1. Instruction not used, only used to detect Atom processors 2. If Atom, change the input lengths for which different code paths are taken (presumably for performance) 3. If Atom, avoid one code path for performance 4. Instruction not used 5. Instruction not used, only used to detect PCLMULQDQ 6. Instruction not used, only used to detect AVX I agree to license my contributions to each file under the terms given at the top of each file I changed. --- Cargo.toml | 1 + src/cpu.rs | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++-- src/lib.rs | 6 +++ 3 files changed, 145 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7c45715d44..6e905cbaa9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -325,6 +325,7 @@ internal_benches = [] slow_tests = [] test_logging = [] use_heap = [] +force_std_detection = [] # XXX: debug = false because of https://github.com/rust-lang/rust/issues/34122 diff --git a/src/cpu.rs b/src/cpu.rs index 7b1b299401..0794f315f7 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -32,11 +32,145 @@ pub(crate) fn features() -> Features { let () = INIT.call_once(|| { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { - extern "C" { - fn GFp_cpuid_setup(); + #[cfg(any(feature = "force_std_detection", all(target_env = "sgx" /*, target_vendor = "fortanix"*/)))] + { + extern "C" { + static mut GFp_ia32cap_P: [u32; 4]; + } + let [l1edx, l1ecx, l7ebx, l7ecx] = unsafe { &mut GFp_ia32cap_P }; + + if is_x86_feature_detected!("aes") { + *l1ecx |= 1<<25; + } + if is_x86_feature_detected!("pclmulqdq") { + *l1ecx |= 1<<1; + } + if is_x86_feature_detected!("rdrand") { + *l1ecx |= 1<<30; + } + if is_x86_feature_detected!("rdseed") { + *l7ebx |= 1<<18; + } + if is_x86_feature_detected!("tsc") { + *l1edx |= 1<<4; + } + if is_x86_feature_detected!("mmx") { + *l1edx |= 1<<23; + } + if is_x86_feature_detected!("sse") { + *l1edx |= 1<<25; + } + if is_x86_feature_detected!("sse2") { + *l1edx |= 1<<26; + } + if is_x86_feature_detected!("sse3") { + *l1ecx |= 1<<0; + } + if is_x86_feature_detected!("ssse3") { + *l1ecx |= 1<<9; + } + if is_x86_feature_detected!("sse4.1") { + *l1ecx |= 1<<19; + } + if is_x86_feature_detected!("sse4.2") { + *l1ecx |= 1<<20; + } + if is_x86_feature_detected!("sha") { + *l7ebx |= 1<<29; + } + if is_x86_feature_detected!("avx") { + *l1ecx |= 1<<28; + } + if is_x86_feature_detected!("avx2") { + *l7ebx |= 1<<5; + } + if is_x86_feature_detected!("avx512f") { + *l7ebx |= 1<<16; + } + if is_x86_feature_detected!("avx512cd") { + *l7ebx |= 1<<28; + } + if is_x86_feature_detected!("avx512er") { + *l7ebx |= 1<<27; + } + if is_x86_feature_detected!("avx512pf") { + *l7ebx |= 1<<26; + } + if is_x86_feature_detected!("avx512bw") { + *l7ebx |= 1<<30; + } + if is_x86_feature_detected!("avx512dq") { + *l7ebx |= 1<<17; + } + if is_x86_feature_detected!("avx512vl") { + *l7ebx |= 1<<31; + } + if is_x86_feature_detected!("avx512ifma") { + *l7ebx |= 1<<21; + } + if is_x86_feature_detected!("avx512vbmi") { + *l7ecx |= 1<<1; + } + if is_x86_feature_detected!("avx512vpopcntdq") { + *l7ecx |= 1<<14; + } + if is_x86_feature_detected!("fma") { + *l1ecx |= 1<<12; + } + if is_x86_feature_detected!("bmi1") { + *l7ebx |= 1<<3; + } + if is_x86_feature_detected!("bmi2") { + *l7ebx |= 1<<8; + } + if is_x86_feature_detected!("popcnt") { + *l1ecx |= 1<<23; + } + if is_x86_feature_detected!("fxsr") { + *l1edx |= 1<<24; + } + if is_x86_feature_detected!("xsave") { + *l1ecx |= 1<<26; + } + /* will be stable on 1.33.0 + if is_x86_feature_detected!("cmpxchg16b") { + *l1ecx |= 1<<13; + } + if is_x86_feature_detected!("adx") { + *l7ebx |= 1<<19; + } + */ + + // Rust can't detect the MOVBE feature yet, but it's widely + // available. + *l1ecx |= 1<<22; + + // This bit is reserved in the CPUID specification, but the + // BoringSSL detection code uses it to represent that this + // is an Intel CPU. However, this bit is only used in + // conjunction with the AVX bit to test for presence of + // AVX, thus serving no purpose. Always set it. + *l1edx |= 1<<30; + + // Features that don't map to leaf 1 or leaf 7: + // Leaf 0xd: + // * xsaveopt + // * xsaves + // * xsavec + // Leaf 0x8000_0001: + // * sse4a + // * abm + // * lzcnt + // * tbm } - unsafe { - GFp_cpuid_setup(); + #[cfg(not(any(feature = "force_std_detection", all(target_env = "sgx" /*, target_vendor = "fortanix"*/))))] + { + extern "C" { + fn GFp_cpuid_setup(); + } + unsafe { + GFp_cpuid_setup(); + } } } diff --git a/src/lib.rs b/src/lib.rs index 62e956bba3..1e028c4401 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,6 +30,12 @@ //! dev_urandom_fallback feature is disabled, such //! fallbacks will not occur. See the documentation for //! rand::SystemRandom for more details. +//! force_std_detection +//! This is only applicable to x86. By default, ring will use +//! custom logic with the CPUID instruction to figure out which CPU +//! features are available. With this feature, the standard +//! std::is_x86_feature_detected macro will be used +//! instead. //! use_heap (default) //! Enable features that require use of the heap, RSA in particular. //! From 3759ffacbcc542b2638ef938d6f2bd0ffc7e7fc5 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 15 Jan 2019 14:26:08 +0530 Subject: [PATCH 4/5] Add x86_64-fortanix-unknown-sgx to CI I agree to license my contributions to each file under the terms given at the top of each file I changed. --- .travis.yml | 32 ++++++++++++++++++++++++++++++++ mk/travis.sh | 6 +++++- mk/update-travis-yml.py | 32 ++++++++++++++++++++------------ 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 56a738fc00..4346001c9a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -416,6 +416,38 @@ matrix: sources: - ubuntu-toolchain-r-test + - env: TARGET_X=x86_64-fortanix-unknown-sgx FEATURES_X= MODE_X=DEBUG KCOV=0 + rust: nightly + os: linux + dist: trusty + + - env: TARGET_X=x86_64-fortanix-unknown-sgx FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 + rust: nightly + os: linux + dist: trusty + + - env: TARGET_X=x86_64-fortanix-unknown-sgx CC_X=gcc-7 FEATURES_X= MODE_X=DEBUG KCOV=0 + rust: nightly + os: linux + dist: trusty + addons: + apt: + packages: + - gcc-7 + sources: + - ubuntu-toolchain-r-test + + - env: TARGET_X=x86_64-fortanix-unknown-sgx CC_X=gcc-7 FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 + rust: nightly + os: linux + dist: trusty + addons: + apt: + packages: + - gcc-7 + sources: + - ubuntu-toolchain-r-test + - env: TARGET_X=x86_64-apple-darwin FEATURES_X= MODE_X=DEBUG KCOV=0 rust: beta os: osx diff --git a/mk/travis.sh b/mk/travis.sh index 20545eb387..639f03ad75 100755 --- a/mk/travis.sh +++ b/mk/travis.sh @@ -47,7 +47,7 @@ if [[ "$TARGET_X" =~ ^(arm|aarch64) && ! "$TARGET_X" =~ android ]]; then sudo apt-get install --no-install-recommends binfmt-support qemu-user-binfmt -y fi -if [[ ! "$TARGET_X" =~ "x86_64-" ]]; then +if [[ "$TARGET_X" != "$(rustc --version --verbose|sed -n 's/^host: //p')" ]]; then rustup target add "$TARGET_X" # By default cargo/rustc seems to use cc for linking, We installed the @@ -122,6 +122,10 @@ armv7-linux-androideabi) adb emu kill + ;; +x86_64-fortanix-unknown-sgx) + # Can't run SGX in Travis. Only build, but don't run, the tests + RUSTFLAGS="-C target-feature=+aes,+pclmul" cargo test -vv -j2 --no-run ${mode-} ${FEATURES_X-} --target=$TARGET_X ;; *) cargo test -vv -j2 ${mode-} ${FEATURES_X-} --target=$TARGET_X diff --git a/mk/update-travis-yml.py b/mk/update-travis-yml.py index 88b4177e1d..1222d68fd3 100755 --- a/mk/update-travis-yml.py +++ b/mk/update-travis-yml.py @@ -47,6 +47,7 @@ "arm-unknown-linux-gnueabihf" : [ "arm-linux-gnueabihf-gcc" ], "i686-unknown-linux-gnu" : linux_compilers, "x86_64-unknown-linux-gnu" : linux_compilers, + "x86_64-fortanix-unknown-sgx" : linux_compilers, "x86_64-apple-darwin" : osx_compilers, } @@ -76,17 +77,20 @@ "aarch64-unknown-linux-gnu", "i686-unknown-linux-gnu", "arm-unknown-linux-gnueabihf", + "x86_64-fortanix-unknown-sgx", ], } def format_entries(): - return "\n".join([format_entry(os, target, compiler, rust, mode, features) - for rust in rusts - for os in oss - for target in targets[os] - for compiler in compilers[target] - for mode in modes - for features in feature_sets]) + return "\n".join([entry for entry in + (format_entry(os, target, compiler, rust, mode, features) + for rust in rusts + for os in oss + for target in targets[os] + for compiler in compilers[target] + for mode in modes + for features in feature_sets) + if entry is not None]) # We use alternative names (the "_X" suffix) so that, in mk/travis.sh, we can # ensure that we set the specific variables we want and that no relevant @@ -111,6 +115,12 @@ def format_entries(): %(sources)s""" def format_entry(os, target, compiler, rust, mode, features): + if target == "x86_64-fortanix-unknown-sgx" and rust != "nightly": + return + # Tracked in https://github.com/fortanix/rust-sgx/issues/64 + if target == "x86_64-fortanix-unknown-sgx" and compiler == "clang": + return + target_words = target.split("-") arch = target_words[0] vendor = target_words[1] @@ -127,13 +137,11 @@ def format_entry(os, target, compiler, rust, mode, features): mode == "DEBUG") if sys == "darwin": - abi = sys sys = "macos" elif sys == "androideabi": - abi = sys sys = "linux" - else: - abi = target_words[3] + elif target == "x86_64-fortanix-unknown-sgx": + sys = "linux" def prefix_all(prefix, xs): return [prefix + x for x in xs] @@ -263,7 +271,7 @@ def main(): file.seek(0) file.write(new_contents) file.truncate() - print new_contents + print new_contents, if __name__ == '__main__': main() From 5b5b3792fc409288039937ca422ebdd8426de8a8 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Wed, 30 Jan 2019 18:31:31 +0530 Subject: [PATCH 5/5] Add SGX-specific notes to the documentation I agree to license my contributions to each file under the terms given at the top of each file I changed. --- src/lib.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 1e028c4401..e2d6155ccd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -137,3 +137,41 @@ mod sealed { // ``` pub trait Sealed {} } + +/// # Information about using *ring* in SGX +/// +/// ## CPU feature detection +/// On `x86_64-fortanix-unknown-sgx`, feature detection is done using the +/// `std::is_x86_feature_detected` macro, which currently only supports +/// features enabled at compile-time. You must enable at least the `aes` and +/// `pclmul` features, otherwise *ring* will panic at runtime. See the [GitHub +/// issue](https://github.com/fortanix/rust-sgx/issues/26) for more +/// information. +/// +/// To set compile-time features, you can either specify them as an environment +/// variable: +/// +/// ```text +/// RUSTFLAGS="-C target-feature=+aes,+pclmul" +/// ``` +/// +/// Or you may configure them per target in [`.cargo/config`]. +/// +/// [`.cargo/config`]: https://doc.rust-lang.org/cargo/reference/config.html#configuration-keys +/// +/// ## Entropy source +/// The entropy source used in SGX is the hardware random number generator +/// provided by the RDRAND instruction. +/// +/// ## Nightly only +/// The `x86_64-fortanix-unknown-sgx` target is only available on nightly, and +/// *ring* Continuous Builds only build it for nightly. See the [GitHub +/// issue](https://github.com/briansmith/ring/issues/779) for more information. +/// +/// ## Continuous Testing +/// While the *ring* test suite works in SGX, and it is run manually from time +/// to time, it doesn't run automatically as part of a Continuous Testing +/// setup. See the [GitHub issue](https://github.com/briansmith/ring/issues/778) +/// for more information. +#[cfg(target_env = "sgx")] +pub mod sgx {}