Merge pull request #670 from akash-fortanix/sgx-target

Add support for x86_64-fortanix-unknown-sgx target
diff --git a/Cargo.toml b/Cargo.toml
index 5e02bcc..a5f3176 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -79,3 +79,6 @@
 
 [package.metadata.docs.rs]
 all-features = true
+
+[patch.crates-io]
+rand_core = { path = "rand_core", version = "0.3", default-features = false }
diff --git a/rand_os/Cargo.toml b/rand_os/Cargo.toml
index af03e3d..7413c15 100644
--- a/rand_os/Cargo.toml
+++ b/rand_os/Cargo.toml
@@ -34,3 +34,6 @@
 [target.wasm32-unknown-unknown.dependencies]
 wasm-bindgen = { version = "0.2.12", optional = true }
 stdweb = { version = "0.4", optional = true }
+
+[target.'cfg(target_env = "sgx")'.dependencies]
+rdrand = "0.4.0"
diff --git a/rand_os/src/lib.rs b/rand_os/src/lib.rs
index 979392a..4f139d9 100644
--- a/rand_os/src/lib.rs
+++ b/rand_os/src/lib.rs
@@ -142,6 +142,8 @@
           feature = "stdweb"))]
 #[macro_use] extern crate stdweb;
 
+#[cfg(target_env = "sgx")]
+extern crate rdrand;
 
 #[cfg(not(feature = "log"))]
 #[macro_use]
@@ -310,6 +312,7 @@
 mod_use!(cfg(target_os = "redox"), redox);
 mod_use!(cfg(target_os = "solaris"), solaris);
 mod_use!(cfg(windows), windows);
+mod_use!(cfg(target_env = "sgx"), sgx);
 
 mod_use!(
     cfg(all(
@@ -356,5 +359,6 @@
     target_os = "solaris",
     windows,
     target_arch = "wasm32",
+    target_env = "sgx"
 )))]
 compile_error!("OS RNG support is not available for this platform");
diff --git a/rand_os/src/sgx.rs b/rand_os/src/sgx.rs
new file mode 100644
index 0000000..43ae0ef
--- /dev/null
+++ b/rand_os/src/sgx.rs
@@ -0,0 +1,38 @@
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::OsRngImpl;
+use Error;
+use rdrand::RdRand;
+use rand_core::RngCore;
+use std::fmt::{Debug, Formatter, Result as FmtResult};
+
+#[derive(Clone)]
+pub struct OsRng{
+    gen: RdRand
+}
+
+impl OsRngImpl for OsRng {
+    fn new() -> Result<OsRng, Error> {
+        let rng = RdRand::new()?;
+        Ok(OsRng{ gen: rng })
+    }
+
+    fn fill_chunk(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        self.gen.try_fill_bytes(dest)
+    }
+
+    fn method_str(&self) -> &'static str { "RDRAND" }
+}
+
+impl Debug for OsRng {
+    fn fmt(&self, f: &mut Formatter) -> FmtResult {
+        f.debug_struct("OsRng")
+            .finish()
+    }
+}