From a9fdd1aff43f04486c4adbcbcafe89bd52ce216b Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Tue, 31 Mar 2020 10:53:16 -0500 Subject: [PATCH 01/11] BLD: key exchange + quote (WIP) --- .gitignore | 4 +- client/index.js | 23 +- enclave/rust-toolchain | 2 +- enclave/safetrace/Makefile | 14 +- enclave/safetrace/app/Cargo.toml | 9 +- enclave/safetrace/app/src/common_u/errors.rs | 5 +- .../safetrace/app/src/enigma_types/hash.rs | 106 -------- enclave/safetrace/app/src/enigma_types/lib.rs | 37 --- enclave/safetrace/app/src/enigma_types/mod.rs | 2 - .../safetrace/app/src/enigma_types/traits.rs | 45 --- .../safetrace/app/src/enigma_types/types.rs | 256 ------------------ enclave/safetrace/app/src/esgx/equote.rs | 80 ++++++ enclave/safetrace/app/src/esgx/general.rs | 18 ++ enclave/safetrace/app/src/esgx/mod.rs | 2 + enclave/safetrace/app/src/keys_u.rs | 3 +- enclave/safetrace/app/src/main.rs | 20 +- .../app/src/networking/ipc_listener.rs | 68 +++-- .../safetrace/app/src/networking/messages.rs | 14 +- enclave/safetrace/app/src/ocalls_u.rs | 27 +- enclave/safetrace/enclave/Cargo.toml | 56 +--- enclave/safetrace/enclave/Enclave.edl | 10 + enclave/safetrace/enclave/Makefile | 49 ++-- enclave/safetrace/enclave/src/data.rs | 199 ++++++++++++-- enclave/safetrace/enclave/src/keys_t.rs | 204 +------------- enclave/safetrace/enclave/src/lib.rs | 94 ++++--- 25 files changed, 511 insertions(+), 836 deletions(-) delete mode 100644 enclave/safetrace/app/src/enigma_types/hash.rs delete mode 100644 enclave/safetrace/app/src/enigma_types/lib.rs delete mode 100644 enclave/safetrace/app/src/enigma_types/mod.rs delete mode 100644 enclave/safetrace/app/src/enigma_types/traits.rs delete mode 100644 enclave/safetrace/app/src/enigma_types/types.rs create mode 100644 enclave/safetrace/app/src/esgx/equote.rs create mode 100644 enclave/safetrace/app/src/esgx/general.rs create mode 100644 enclave/safetrace/app/src/esgx/mod.rs diff --git a/.gitignore b/.gitignore index 88c90e4..ee453d6 100644 --- a/.gitignore +++ b/.gitignore @@ -116,4 +116,6 @@ crashlytics-build.properties fabric.properties /target -**/*.rs.bk \ No newline at end of file +**/*.rs.bk + +enigma-types.h \ No newline at end of file diff --git a/client/index.js b/client/index.js index 8ef8d51..a29ac97 100644 --- a/client/index.js +++ b/client/index.js @@ -113,10 +113,19 @@ async function add_data(userId, data){ } -add_data('myUserId', 'myDataString') - - - -let seed = ''; - - +let myData = [ + { + "lat": 40.757339, + "lng": -73.985992, + "startTS": 1583064000, + "endTS": 1583067600 + }, + { + "lat": 40.793840, + "lng": -73.956900, + "startTS": 1583150400, + "endTS": 1583154000 + }, +] + +add_data('myUserId', JSON.stringify(myData)) diff --git a/enclave/rust-toolchain b/enclave/rust-toolchain index 7b9d999..a42a259 100644 --- a/enclave/rust-toolchain +++ b/enclave/rust-toolchain @@ -1 +1 @@ -nightly-2020-03-12 \ No newline at end of file +nightly-2019-08-01 \ No newline at end of file diff --git a/enclave/safetrace/Makefile b/enclave/safetrace/Makefile index 1b5440d..bf2012d 100644 --- a/enclave/safetrace/Makefile +++ b/enclave/safetrace/Makefile @@ -21,7 +21,9 @@ SGX_SDK ?= $(HOME)/.sgxsdk/sgxsdk # The path to the incubator-teaclave-sgx-sdk code. -SGX_SDK_RUST ?= ../incubator-teaclave-sgx-sdk/ +# SGX_SDK_RUST ?= ../incubator-teaclave-sgx-sdk/ + +SGX_SDK_RUST ?= $(HOME)/sgx SGX_MODE ?= HW @@ -78,6 +80,7 @@ Enclave_EDL_Files := enclave/Enclave_t.c enclave/Enclave_t.h app/Enclave_u.c app ######## APP Settings ######## App_Rust_Flags := --release +Rust_target_dir := release App_SRC_Files := $(shell find app/ -type f -name '*.rs') $(shell find app/ -type f -name 'Cargo.toml') # Include paths for untrusted EDL object @@ -86,7 +89,7 @@ App_Include_Paths := -I ./app -I./include -I$(SGX_SDK)/include -I$(CUSTOM_EDL_PA # C compilation flags for untrusted EDL object App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) -App_Rust_Path := ./app/target/release +App_Rust_Path := ./app/target/$(Rust_target_dir) App_Enclave_u_Object :=app/libEnclave_u.a App_Name := safetrace-app @@ -160,7 +163,8 @@ enclave/Enclave_t.o: $(Enclave_EDL_Files) # Enclave DLL $(RustEnclave_Name): enclave compiler-rt $(App_Name) enclave/Enclave_t.o - cp ../incubator-teaclave-sgx-sdk/compiler-rt/libcompiler-rt-patch.a ./lib + mkdir -p $(CUSTOM_LIBRARY_PATH) + cp $(SGX_SDK_RUST)/compiler-rt/libcompiler-rt-patch.a $(CUSTOM_LIBRARY_PATH) @$(CXX) enclave/Enclave_t.o -o $@ $(RustEnclave_Link_Flags) @echo "LINK => $@" @@ -173,7 +177,7 @@ $(Signed_RustEnclave_Name): $(RustEnclave_Name) .PHONY: enclave # Invocation of Makefile in ./enclave, which builds trusted Rust static library and copies it to $(CUSTOM_LIBRARY_PATH) -enclave: +enclave: $(Enclave_EDL_Files) mkdir -p $(CUSTOM_LIBRARY_PATH) $(MAKE) -C ./enclave/ CARGO_FLAGS=$(App_Rust_Flags) Rust_target_dir=$(Rust_target_dir) @@ -184,7 +188,7 @@ compiler-rt: .PHONY: clean clean: - @rm -f $(App_Name) $(RustEnclave_Name) $(Signed_RustEnclave_Name) enclave/*_t.* app/*_u.* lib/*.a + @rm -f $(CUSTOM_BIN_PATH)/$(App_Name) $(RustEnclave_Name) $(Signed_RustEnclave_Name) enclave/*_t.* app/*_u.* $(CUSTOM_LIBRARY_PATH)/*.a @rm -rf enclave/enigma-types.h app/enigma-types.h @cd enclave && cargo clean && rm -f Cargo.lock @cd app && cargo clean && rm -f Cargo.lock diff --git a/enclave/safetrace/app/Cargo.toml b/enclave/safetrace/app/Cargo.toml index 007cf63..51c1f06 100644 --- a/enclave/safetrace/app/Cargo.toml +++ b/enclave/safetrace/app/Cargo.toml @@ -7,6 +7,10 @@ build = "build.rs" [dependencies] sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } sgx_urts = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } +enigma-types = { git = "https://github.com/enigmampc/enigma-core.git", features = ["std"] } +enigma-tools-u = { git = "https://github.com/enigmampc/enigma-core.git" } +enigma-tools-m = { git = "https://github.com/enigmampc/enigma-core.git" } +enigma-crypto = { git = "https://github.com/enigmampc/enigma-core.git" } futures = { version = "0.1.25", default-features = false } tokio-zmq = "0.9.0" @@ -15,8 +19,11 @@ failure = "0.1.3" serde = { version = "1.0", default-features = false, features=["serde_derive"] } serde_json = "1.0" serde_repr = "0.1" -rustc-hex = "1.0.0" # 2.0.1? rmp-serde = "0.14.0" +rustc-hex = "1.0.0" +lazy_static = "1.3.0" +log = "0.4.6" + [patch.'https://github.com/apache/teaclave-sgx-sdk.git'] sgx_types = { path = "../../incubator-teaclave-sgx-sdk/sgx_types" } diff --git a/enclave/safetrace/app/src/common_u/errors.rs b/enclave/safetrace/app/src/common_u/errors.rs index 688138d..fb67a52 100644 --- a/enclave/safetrace/app/src/common_u/errors.rs +++ b/enclave/safetrace/app/src/common_u/errors.rs @@ -1,5 +1,4 @@ #![allow(dead_code)] -use crate::enigma_types::types::*; use sgx_types::*; use std::fmt; use failure::Error; @@ -82,6 +81,6 @@ impl fmt::Display for DBErrKind { #[derive(Fail, Debug)] #[fail(display = "Error inside the Enclave = ({:?})", err)] pub struct EnclaveFailError { - pub err: EnclaveReturn, + pub err: enigma_types::EnclaveReturn, pub status: sgx_status_t, -} +} \ No newline at end of file diff --git a/enclave/safetrace/app/src/enigma_types/hash.rs b/enclave/safetrace/app/src/enigma_types/hash.rs deleted file mode 100644 index cb56f36..0000000 --- a/enclave/safetrace/app/src/enigma_types/hash.rs +++ /dev/null @@ -1,106 +0,0 @@ -//! # Hash Module -//! This module provides a struct meant for containing Hashes (Kecack256 or Sha256). - -use core::ops::{Deref, DerefMut}; -use rustc_hex::{FromHex, FromHexError}; -use arrayvec::ArrayVec; -use crate::serde::{Serialize, Deserialize}; - -/// This struct is basically a wrapper over `[u8; 32]`, and is meant to be returned from whatever hashing functions we use. -/// `#[repr(C)]` is a Rust feature which makes the struct be aligned just like C structs. -/// See [`Repr(C)`][https://doc.rust-lang.org/nomicon/other-reprs.html] -#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Default)] -#[serde(crate = "crate::serde")] -#[repr(C)] -pub struct Hash256([u8; 32]); - - -impl Hash256 { - /// This method exposes rust's built in [`copy_from_slice`][https://doc.rust-lang.org/std/primitive.slice.html#method.copy_from_slice] - /// Copies the elements from `src` into `self`. - /// - /// The length of `src` must be the same as `self`. - /// - /// # Panics - /// - /// This function will panic if the two slices have different lengths. - /// - /// This might not be needed since we implement `Deref` and `DerefMut` for the inner array. - pub fn copy_from_slice(&mut self, src: &[u8]) { - self.0.copy_from_slice(src) - } - - /// This function converts a hex string into `Hash256` type. - /// the hex must not contain `0x` (as is usually the case in hexs in rust) - /// if the hex length isn't 64 (which will be converted into the 32 bytes) it will return an error. - pub fn from_hex(hex: &str) -> Result { - if hex.len() != 64 { - return Err(FromHexError::InvalidHexLength); - } - let hex_vec: ArrayVec<[u8; 32]> = hex.from_hex()?; - let mut result = Self::default(); - result.copy_from_slice(&hex_vec); - Ok(result) - } - - /// Checks if the struct contains only zeroes or not. - pub fn is_zero(&self) -> bool { - self.0 == [0u8;32] - } -} - - -impl From<[u8; 32]> for Hash256 { - fn from(arr: [u8; 32]) -> Self { - Hash256(arr) - } -} - -impl Into<[u8; 32]> for Hash256 { - fn into(self) -> [u8; 32] { - self.0 - } -} - -impl Deref for Hash256 { - type Target = [u8; 32]; - - fn deref(&self) -> &[u8; 32] { - &self.0 - } -} - -impl DerefMut for Hash256 { - fn deref_mut(&mut self) -> &mut [u8; 32] { - &mut self.0 - } -} - -impl AsRef<[u8]> for Hash256 { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -impl AsMut<[u8]> for Hash256 { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } -} - -#[cfg(test)] -mod test { - use super::Hash256; - #[test] - fn test_hex_succeed() { - let a = "0101010101010101010101010101010101010101010101010101010101010101"; - Hash256::from_hex(&a).unwrap(); - } - - #[should_panic] - #[test] - fn test_hex_long() { - let a = "02020202020202020202020202020202020202020202020202020202020202020202024444020202020202"; - Hash256::from_hex(&a).unwrap(); - } -} \ No newline at end of file diff --git a/enclave/safetrace/app/src/enigma_types/lib.rs b/enclave/safetrace/app/src/enigma_types/lib.rs deleted file mode 100644 index 99b9a31..0000000 --- a/enclave/safetrace/app/src/enigma_types/lib.rs +++ /dev/null @@ -1,37 +0,0 @@ -#![cfg_attr(all(not(feature = "std"), not(test)), no_std)] -#![deny(unused_extern_crates, missing_docs, warnings)] -//! # Enigma Types -//! This library is meant to supply all the types that are specific to our protocol.
-//! Inside of this library I abstracted the std as `localstd` so that you can use it without knowing if it's `sgx_tstd` or regular std. -//! *But* Unlike other crates this isn't just abstracting 2 different std's, -//! but this crate is expected to work even without std at all(except some parts maybe). -//! -//! in the `build.rs` I use `cbindgen` to auto generate `enigma-types.h` header so it can be included into the edl. -//! that way we can pass rust structs through the SGX bridge(which is C) -//! -//! This crate is Rust 2018 Edition, -//! meaning there's no `extern crate` and `use` statements need to start with `crate`/`self`/`super`. - - -pub mod traits; -mod types; -mod hash; - -#[cfg(all(feature = "sgx", not(feature = "std")))] -use serde_sgx as serde; - -#[cfg(not(feature = "sgx"))] -use serde_std as serde; - -use crate::traits::SliceCPtr; -pub use crate::types::*; - -/// This is a bit safer wrapper of [`core::ptr::copy_nonoverlapping`] -/// it checks that the src len is at least as big as `count` otherwise it will panic. -/// *and* it uses [`SliceCPtr`](crate::traits::SliceCPtr) trait to pass a C compatible pointer. -pub unsafe fn write_ptr(src: &[T], dst: *mut T, count: usize) { - if src.len() > count { - unimplemented!() - } - core::ptr::copy_nonoverlapping(src.as_c_ptr(), dst, src.len()); -} diff --git a/enclave/safetrace/app/src/enigma_types/mod.rs b/enclave/safetrace/app/src/enigma_types/mod.rs deleted file mode 100644 index 0bc8eda..0000000 --- a/enclave/safetrace/app/src/enigma_types/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod types; -pub mod traits; diff --git a/enclave/safetrace/app/src/enigma_types/traits.rs b/enclave/safetrace/app/src/enigma_types/traits.rs deleted file mode 100644 index c9f5b7d..0000000 --- a/enclave/safetrace/app/src/enigma_types/traits.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! # Traits module -//! This module should provide low level traits that are required on both sides of the SGX. -//! right now it only contains the [`SliceCPtr`] trait which is used to *always* provide valid C pointers. - -static EMPTY: [u8; 1] = [0]; - -/// This trait provides an interface into `C` like pointers. -/// in Rust if you try to get a pointer to an empty vector you'll get: -/// 0x0000000000000001 OR 0x0000000000000000, although bear in mind this *isn't* officially defined. -/// this behavior is UB in C's `malloc`, passing an invalid pointer with size 0 to `malloc` is implementation defined. -/// in the case of Intel's + GCC what we observed is a Segmentation Fault. -/// this is why if the vec/slice is empty we use this trait to pass a pointer to a stack allocated static `[0]` array. -/// this will make the pointer valid, and when the len is zero -/// `malloc` won't allocate anything but also won't produce a SegFault -pub trait SliceCPtr { - /// The Target for the trait. - /// this trait can't be generic because it should only be implemented once per type - /// (See [Associated Types][https://doc.rust-lang.org/rust-by-example/generics/assoc_items/types.html]) - type Target; - /// This function is what will produce a valid C pointer to the target - /// even if the target is 0 sized (and rust will produce a C *invalid* pointer for it ) - fn as_c_ptr(&self) -> *const Self::Target; -} - -impl SliceCPtr for [T] { - type Target = T; - fn as_c_ptr(&self) -> *const Self::Target { - if self.is_empty() { - EMPTY.as_ptr() as *const _ - } else { - self.as_ptr() - } - } -} - -impl SliceCPtr for str { - type Target = u8; - fn as_c_ptr(&self) -> *const Self::Target { - if self.is_empty() { - EMPTY.as_ptr() as *const _ - } else { - self.as_ptr() - } - } -} diff --git a/enclave/safetrace/app/src/enigma_types/types.rs b/enclave/safetrace/app/src/enigma_types/types.rs deleted file mode 100644 index e76e6d6..0000000 --- a/enclave/safetrace/app/src/enigma_types/types.rs +++ /dev/null @@ -1,256 +0,0 @@ -//! # Types module -//! This module should provide low level types, enums and structures that are required on both sides of the SGX. -//! All enums and structures should have `#[repr(C)]` on them so they would be aligned just like in C -//! See [`Repr(C)`][https://doc.rust-lang.org/nomicon/other-reprs.html] -//! -//! Any new type here that should pass through the edl should be added into the [`build.rs]` file, -//! so it will put it into the auto generated C header. -//! -//! Note: Please use the right types even if they're only aliases right now, -//! this helps both for readability and if in the future we decide to change the alias. - -// use core::{fmt, mem, ptr, default::Default}; - -/// The size of the symmetric 256 bit key we use for encryption (in bytes). -pub const SYMMETRIC_KEY_SIZE: usize = 256 / 8; -/// symmetric key we use for encryption. -pub type SymmetricKey = [u8; SYMMETRIC_KEY_SIZE]; -/// StateKey is the key used for state encryption. -pub type StateKey = SymmetricKey; -/// DHKey is the key that results from the ECDH [`enigma_crypto::KeyPair::derive_key`](../replace_me) -pub type DhKey = SymmetricKey; - -/// PubKey is a public key that is used for ECDSA signing. -pub type PubKey = [u8; 64]; - - -/// This enum is used to return from an ecall/ocall to represent if the operation was a success and if not then what was the error. -/// The goal is to not reveal anything sensitive -/// `#[repr(C)]` is a Rust feature which makes the struct be aligned just like C structs. -/// See [`Repr(C)`][https://doc.rust-lang.org/nomicon/other-reprs.html] -#[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum EnclaveReturn { - /// Success, the function returned without any failure. - Success, - /// TaskFailure, the task(Deploy/Compute) has failed - TaskFailure, - /// KeysError, There's a key missing or failed to derive a key. - KeysError, - /// Failure in Encryption, couldn't decrypt the variable / failed to encrypt the results. - EncryptionError, - // TODO: I'm not sure this error is used anywhere. - /// SigningError, for some reason it failed on signing the results. - SigningError, - // TODO: Also don't think this is needed. - /// RecoveringError, Something failed in recovering the public key. - RecoveringError, - ///PermissionError, Received a permission error from an ocall, (i.e. opening the signing keys file or something like that) - PermissionError, - /// SgxError, Error that came from the SGX specific stuff (i.e DRAND, Sealing etc.) - SgxError, - /// StateError, an Error in the State. (i.e. failed applying delta, failed deserializing it etc.) - StateError, - /// OcallError, an error from an ocall. - OcallError, - /// OcallDBError, an error from the Database in the untrusted part, couldn't get/save something. - OcallDBError, - /// MessagingError, a message that received couldn't be processed (i.e. KM Message, User Key Exchange etc.) - MessagingError, - /// WorkerAuthError, Failed to authenticate the worker, this is specific to the KM node. - WorkerAuthError, - // TODO: should consider merging with a different error. - /// Missing StateKeys in the KM node. - KeyProvisionError, - /// Something went really wrong. - Other -} - - -/// This struct is basically some sort of a boolean that says if an operation was a success or a failure. -#[repr(C)] -#[derive(Debug, PartialEq)] -pub enum ResultStatus { - /// Ok = Success = 1. - Ok = 1, - /// Failure = Error = 0. - Failure = 0, -} - - -/// This struct is what returned from a Deploy/Compute ecall, it contains all the needed data. -#[repr(C)] -#[derive(Clone, Copy)] -pub struct ExecuteResult { - /// A pointer to the output of the execution using [`ocall_save_to_memory`](../replace_me) (on the untrusted stack) - pub output: *const u8, - /// A pointer to the resulting delta using [`ocall_save_to_memory`](../replace_me) (on the untrusted stack) - pub delta_ptr: *const u8, - /// The delta index number. - pub delta_index: u32, - /// A pointer to the Ethereum payload using [`ocall_save_to_memory`](../replace_me) (on the untrusted stack) - pub ethereum_payload_ptr: *const u8, - /// The ethereum address that the payload belongs to. - pub ethereum_address: [u8; 20], - /// A signature by the enclave on all of the results. - pub signature: [u8; 65], - /// The gas used by the execution. - pub used_gas: u64, -} - -// /// This struct is a wrapper to a raw pointer. -// /// when you pass a pointer through the SGX bridge(EDL) the SGX Edger8r will copy the data that it's pointing to -// /// using `memalloc` and `memset` to the other side of the bridge, then it changes the pointer to point to the new data. -// /// -// /// So this struct is needed if you want to pass a pointer from one side to the other while the pointer still points to the right locaiton. -// /// -// /// Say you want to give the enclave a DB on the untrusted, so that the enclave can then pass that pointer to an ocall. -// /// This will let you do it without the Edger8r messing with the pointer. -// /// -// /// And I tried to add a mutability bool to make it a little more safe by giving you a pointer based on the original mutability. -// #[repr(C)] -// #[derive(Clone, Copy, Debug)] -// pub struct RawPointer { -// ptr: *const u8, -// _mut: bool -// } - -// impl RawPointer { -// /// Creates a new RawPointer wrapper. -// /// it will auto cast the reference into a raw pointer. -// pub unsafe fn new(reference: &T) -> Self { -// RawPointer { ptr: reference as *const T as *const u8, _mut: false } -// } - -// /// Creates a new mutable RawPointer wrapper. -// /// This is needed if when you unwrap this you want a mutable pointer. -// pub unsafe fn new_mut(reference: &mut T) -> Self { -// RawPointer { ptr: reference as *mut T as *const u8, _mut: true } -// } - -// /// This will return the underlying const raw pointer. -// pub fn get_ptr(&self) -> *const T { -// self.ptr as *const T -// } - -// /// this will return a Result and if the RawPointer was created with `new_mut` -// /// it Will return `Ok` with the underlying mut raw pointer. -// /// if the struct was created with just `new` it will return `Err`. -// pub fn get_mut_ptr(&self) -> Result<*mut T, &'static str> { -// if !self._mut { -// Err("This DoublePointer is not mutable") -// } else { -// Ok(self.ptr as *mut T) -// } -// } - -// /// This will unsafely cast the underlying pointer back into a reference. -// pub unsafe fn get_ref(&self) -> &T { -// &*(self.ptr as *const T) -// } - -// /// This will unsafely cast the underlying pointer back into a mut pointer. -// /// it will return a result and have the same rules as [`get_mut_ptr`] -// /// -// /// [`get_mut_ptr`]: #method.get_mut_ptr -// pub unsafe fn get_mut_ref(&self) -> Result<&mut T, &'static str> { -// if !self._mut { -// Err("This DoublePointer is not mutable") -// } else { -// Ok(&mut *(self.ptr as *mut T) ) -// } -// } - - -// } - -impl From for ResultStatus { - fn from(i: bool) -> Self { - if i { - ResultStatus::Ok - } else { - ResultStatus::Failure - } - } -} - -// impl Default for ExecuteResult { -// fn default() -> ExecuteResult { -// ExecuteResult { -// output: ptr::null(), -// delta_ptr: ptr::null(), -// ethereum_payload_ptr: ptr::null(), -// .. unsafe { mem::zeroed() } -// } -// } -// } - -// impl fmt::Debug for ExecuteResult { -// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -// let mut debug_trait_builder = f.debug_struct("ExecuteResult"); -// debug_trait_builder.field("output", &(self.output)); -// debug_trait_builder.field("delta_ptr", &(self.delta_ptr)); -// debug_trait_builder.field("delta_index", &(self.delta_index)); -// debug_trait_builder.field("ethereum_payload_ptr", &(self.ethereum_payload_ptr)); -// debug_trait_builder.field("ethereum_address", &(self.ethereum_address)); -// debug_trait_builder.field("signature", &(&self.signature[..])); -// debug_trait_builder.field("used_gas", &(self.used_gas)); -// debug_trait_builder.finish() -// } -// } - -impl Default for EnclaveReturn { - fn default() -> EnclaveReturn { EnclaveReturn::Success } -} - -// impl fmt::Display for EnclaveReturn { -// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -// use self::EnclaveReturn::*; -// let p = match *self { -// Success => "EnclaveReturn: Success", -// TaskFailure => "EnclaveReturn: Task failure", -// KeysError => "EnclaveReturn: KeysError", -// EncryptionError => "EnclaveReturn: EncryptionError", -// SigningError => "EnclaveReturn: SigningError", -// RecoveringError => "EnclaveReturn: RecoveringError", -// PermissionError => "EnclaveReturn: PermissionError", -// SgxError => "EnclaveReturn: SgxError", -// StateError => "EnclaveReturn: StateError", -// OcallError => "EnclaveReturn: OcallError", -// OcallDBError => "EnclaveReturn: OcallDBError", -// MessagingError => "EnclaveReturn: MessagingError", -// WorkerAuthError => "EnclaveReturn: WorkerAuthError", -// KeyProvisionError => "EnclaveReturn: KeyProvisionError", -// Other => "EnclaveReturn: Other", -// }; -// write!(f, "{}", p) -// } -// } - - -/// This trait will convert a Result into EnclaveReturn. -/// -/// I used this because there's a problem. -/// we want to convert [`enigma_tools_t::common::errors::EnclaveError`](../replace_me) into [`EnclaveReturn`] to return it back through the EDL. -/// *but* in this module we can't impl [`From`](core::convert::From) from `EnclaveError` to `EnclaveReturn` because this crate is `std` pure -/// so it doesn't have access to `enigma_tools_t`. -/// And we can't implement this as `Into for Result<(), EnclaveError>` in `enigma_tools_t` -/// because in rust you can't implement an imported trait(`From`/`Into`) on a type you imported (`Result`). -/// -/// So my solution was to declare a new trait, and to implement [`core::convert::From`] on whatever implements my trait through generics. -/// that way all we need is to implement `ResultToEnclaveReturn` on `EnclaveError` and it will auto generate a `From` impl for it. -/// -/// And if the Result is `Ok` it will return `EnclaveReturn::Success` and if `Err` it will convert using this trait. -pub trait ResultToEnclaveReturn { - /// Should return a EnclaveReturn while consuming self. - fn into_enclave_return(self) -> EnclaveReturn; -} - -impl From> for EnclaveReturn { - fn from(res: Result<(), T>) -> Self { - match res { - Ok(()) => EnclaveReturn::Success, - Err(e) => ResultToEnclaveReturn::into_enclave_return(e), - } - } -} diff --git a/enclave/safetrace/app/src/esgx/equote.rs b/enclave/safetrace/app/src/esgx/equote.rs new file mode 100644 index 0000000..6a89253 --- /dev/null +++ b/enclave/safetrace/app/src/esgx/equote.rs @@ -0,0 +1,80 @@ +use common_u::errors; +use failure::Error; +use sgx_types::*; +use std::str; +use crate::ocalls_u::ecall_get_signing_address; +// this struct is returned during the process registration back to the surface. +// quote: the base64 encoded quote +// address : the clear text public key for ecdsa signing and registration +#[derive(Serialize, Deserialize, Debug)] +pub struct GetRegisterResult { + pub errored: bool, + pub quote: String, + pub address: String, +} + +// wrapper function for getting the enclave public sign key (the one attached with produce_quote()) +//#[logfn(TRACE)] +pub fn get_register_signing_address(eid: sgx_enclave_id_t) -> Result<[u8; 20], Error> { + let mut address = [0u8; 20]; + let status = unsafe { ecall_get_signing_address(eid, &mut address) }; + if status == sgx_status_t::SGX_SUCCESS { + Ok(address) + } else { + Err(errors::GetRegisterKeyErr { status, message: String::from("error in get_register_signing_key") }.into()) + } +} + + +#[cfg(test)] +mod test { + use crate::esgx::general::init_enclave_wrapper; + use enigma_tools_u::attestation_service::{self, service::AttestationService}; + use enigma_tools_u::esgx::equote::retry_quote; + + const SPID: &str = "B0335FD3BC1CCA8F804EB98A6420592D"; // Enigma's SPID + + #[test] + fn test_produce_quote() { + // initiate the enclave + let enclave = init_enclave_wrapper().unwrap(); + // produce a quote + + let tested_encoded_quote = match retry_quote(enclave.geteid(), &SPID, 18) { + Ok(encoded_quote) => encoded_quote, + Err(e) => { + println!("[-] Produce quote Err {}, {}", e.as_fail(), e.backtrace()); + assert_eq!(0, 1); + return; + } + }; + println!("-------------------------"); + println!("{}", tested_encoded_quote); + println!("-------------------------"); + enclave.destroy(); + assert!(!tested_encoded_quote.is_empty()); + //assert_eq!(real_encoded_quote, tested_encoded_quote); + } + + #[test] + fn test_produce_and_verify_qoute() { + let enclave = init_enclave_wrapper().unwrap(); + let quote = retry_quote(enclave.geteid(), &SPID, 18).unwrap(); + let service = AttestationService::new(attestation_service::constants::ATTESTATION_SERVICE_URL); + let as_response = service.get_report(quote).unwrap(); + + assert!(as_response.result.verify_report().unwrap()); + } + + #[test] + fn test_signing_key_against_quote() { + let enclave = init_enclave_wrapper().unwrap(); + let quote = retry_quote(enclave.geteid(), &SPID, 18).unwrap(); + let service = AttestationService::new(attestation_service::constants::ATTESTATION_SERVICE_URL); + let as_response = service.get_report(quote).unwrap(); + assert!(as_response.result.verify_report().unwrap()); + let key = super::get_register_signing_address(enclave.geteid()).unwrap(); + let quote = as_response.get_quote().unwrap(); + assert_eq!(key, "e.report_body.report_data[..20]); + } +} diff --git a/enclave/safetrace/app/src/esgx/general.rs b/enclave/safetrace/app/src/esgx/general.rs new file mode 100644 index 0000000..7df0919 --- /dev/null +++ b/enclave/safetrace/app/src/esgx/general.rs @@ -0,0 +1,18 @@ +use enigma_tools_u::{self, esgx::general::storage_dir}; +use sgx_types::*; +use sgx_urts::SgxEnclave; +use std::fs; +//use log; + +static ENCLAVE_FILE: &'static str = "../bin/enclave.signed.so"; +pub static ENCLAVE_DIR: &'static str = ".enigma"; + +//#[logfn(INFO)] +pub fn init_enclave_wrapper() -> SgxResult { + // Create a folder for storage (Sealed, etc) + // If the storage folder is inaccessible, the enclave would not be able to seal info + let storage_path = storage_dir(ENCLAVE_DIR).unwrap(); + fs::create_dir_all(&storage_path).map_err(|e| { format_err!("Unable to create storage directory {}: {}", storage_path.display(), e) }).unwrap(); + + enigma_tools_u::esgx::init_enclave(&ENCLAVE_FILE) +} diff --git a/enclave/safetrace/app/src/esgx/mod.rs b/enclave/safetrace/app/src/esgx/mod.rs new file mode 100644 index 0000000..337679c --- /dev/null +++ b/enclave/safetrace/app/src/esgx/mod.rs @@ -0,0 +1,2 @@ +pub mod equote; +pub mod general; diff --git a/enclave/safetrace/app/src/keys_u.rs b/enclave/safetrace/app/src/keys_u.rs index 2217c69..ce9465e 100644 --- a/enclave/safetrace/app/src/keys_u.rs +++ b/enclave/safetrace/app/src/keys_u.rs @@ -1,7 +1,8 @@ use crate::common_u::errors::EnclaveFailError; use failure::Error; use sgx_types::{sgx_enclave_id_t, sgx_status_t}; -use crate::enigma_types::types::{EnclaveReturn}; +use enigma_types::{EnclaveReturn}; + extern { pub fn ecall_get_user_key( diff --git a/enclave/safetrace/app/src/main.rs b/enclave/safetrace/app/src/main.rs index 2b2fb9e..155694b 100644 --- a/enclave/safetrace/app/src/main.rs +++ b/enclave/safetrace/app/src/main.rs @@ -30,26 +30,28 @@ extern crate serde_repr; pub extern crate serde_json; extern crate rmp_serde; extern crate rustc_hex as hex; +#[macro_use] +pub extern crate log; use sgx_types::*; use sgx_urts::SgxEnclave; -pub mod enigma_types; +extern crate enigma_types; +pub extern crate enigma_tools_u; +extern crate enigma_tools_m; +extern crate enigma_crypto; + pub mod common_u; pub mod keys_u; pub mod networking; pub mod ocalls_u; +pub mod esgx; -use networking::{ipc_listener, IpcListener}; use futures::Future; -pub use ocalls_u::{ocall_save_to_memory}; +use networking::{ipc_listener, IpcListener}; static ENCLAVE_FILE: &'static str = "enclave.signed.so"; -extern { - fn say_something(eid: sgx_enclave_id_t, retval: *mut sgx_status_t, - some_string: *const u8, len: usize) -> sgx_status_t; -} fn init_enclave() -> SgxResult { let mut launch_token: sgx_launch_token_t = [0; 1024]; @@ -79,8 +81,10 @@ fn main() { let server = IpcListener::new(&format!("tcp://*:5552")); + const SPID: &str = "B0335FD3BC1CCA8F804EB98A6420592D"; + server - .run(move |multi| ipc_listener::handle_message(multi, &format!("SPID"), enclave.geteid(), 1)) + .run(move |multi| ipc_listener::handle_message(multi, SPID, enclave.geteid(), 1)) //.run(move |multi| ipc_listener::handle_message(multi, &opt.spid, eid, opt.retries)) // .run(|mul| { diff --git a/enclave/safetrace/app/src/networking/ipc_listener.rs b/enclave/safetrace/app/src/networking/ipc_listener.rs index 2fe52cb..094c161 100644 --- a/enclave/safetrace/app/src/networking/ipc_listener.rs +++ b/enclave/safetrace/app/src/networking/ipc_listener.rs @@ -1,5 +1,5 @@ use crate::networking::messages::*; -use sgx_types::{sgx_enclave_id_t, sgx_status_t}; +use sgx_types::sgx_enclave_id_t; use futures::{Future, Stream}; use std::sync::Arc; use tokio_zmq::prelude::*; @@ -49,12 +49,18 @@ pub fn handle_message(request: Multipart, spid: &str, eid: sgx_enclave_id_t, ret pub(self) mod handling { use crate::networking::messages::*; use crate::keys_u; + use crate::esgx::equote; use failure::Error; use sgx_types::{sgx_enclave_id_t, sgx_status_t}; use hex::{FromHex, ToHex}; use std::str; + use rmp_serde::Deserializer; use serde::Deserialize; use serde_json::Value; + use enigma_tools_u::{ + esgx::equote as equote_tools, + attestation_service::{service::AttestationService, constants::ATTESTATION_SERVICE_URL}, + }; extern { fn ecall_add_personal_data( @@ -74,8 +80,31 @@ pub(self) mod handling { pubkey: Vec } + //#[logfn(TRACE)] pub fn get_enclave_report(eid: sgx_enclave_id_t, spid: &str, retries: u32) -> ResponseResult { - let result = IpcResults::EnclaveReport { spid: spid.to_string() }; + + let signing_key = equote::get_register_signing_address(eid)?; + + let enc_quote = equote_tools::retry_quote(eid, spid, 18)?; + println!("{:?}", enc_quote); + + + // *Important* `option_env!()` runs on *Compile* time. + // This means that if you want Simulation mode you need to run `export SGX_MODE=SW` Before compiling. + let (signature, report_hex) = if option_env!("SGX_MODE").unwrap_or_default() == "SW" { // Simulation Mode + let report = enc_quote.as_bytes().to_hex(); + let sig = String::new(); + (sig, report) + } else { // Hardware Mode + let service: AttestationService = AttestationService::new_with_retries(ATTESTATION_SERVICE_URL, retries); + let response = service.get_report(enc_quote)?; + let report = response.result.report_string.as_bytes().to_hex(); + let sig = response.result.signature; + (sig, report) + }; + + let result = IpcResults::EnclaveReport { signing_key: signing_key.to_hex(), report: report_hex, signature }; + Ok(IpcResponse::GetEnclaveReport { result }) } @@ -87,20 +116,11 @@ pub(self) mod handling { let (msg, sig) = keys_u::get_user_key(eid, &user_pubkey)?; - // Enigma-core implementation used MessagePack, but rmp-serde is not available - // so replaced MessagePack serialization with plain JSON serialization - //let mut des = Deserializer::new(&msg[..]); - //let res: Value = Deserialize::deserialize(&mut des).unwrap(); - //let pubkey = serde_json::from_value::>(res["pubkey"].clone())?; - //let pubkey = serde_json::from_slice::>(&msg)?; - let res = match str::from_utf8(&msg) { - Ok(v) => v, - Err(e) => panic!("Invalid UTF-8 sequence: {}", e), - }; - - let pubkey: PubkeyResult = serde_json::from_str(res)?; + let mut des = Deserializer::new(&msg[..]); + let res: Value = Deserialize::deserialize(&mut des).unwrap(); + let pubkey = serde_json::from_value::>(res["pubkey"].clone())?; - let result = IpcResults::DHKey {taskPubKey: pubkey.pubkey.to_hex(), sig: sig.to_hex() }; + let result = IpcResults::DHKey {taskPubKey: pubkey.to_hex(), sig: sig.to_hex() }; Ok(IpcResponse::NewTaskEncryptionKey { result }) } @@ -110,18 +130,18 @@ pub(self) mod handling { pub fn add_personal_data( input: IpcInput, eid: sgx_enclave_id_t) -> ResponseResult { let mut ret = sgx_status_t::SGX_SUCCESS; - let encryptedUserId = input.encryptedUserId.from_hex()?; - let encryptedData = input.encryptedData.from_hex()?; - let mut userPubKey = [0u8; 64]; - userPubKey.clone_from_slice(&input.userPubKey.from_hex()?); + let encrypted_userid = input.encrypted_userid.from_hex()?; + let encrypted_data = input.encrypted_data.from_hex()?; + let mut user_pub_key = [0u8; 64]; + user_pub_key.clone_from_slice(&input.user_pub_key.from_hex()?); unsafe { ecall_add_personal_data(eid, &mut ret as *mut sgx_status_t, - encryptedUserId.as_ptr() as * const u8, - encryptedUserId.len(), - encryptedData.as_ptr() as * const u8, - encryptedData.len(), - &userPubKey) }; + encrypted_userid.as_ptr() as * const u8, + encrypted_userid.len(), + encrypted_data.as_ptr() as * const u8, + encrypted_data.len(), + &user_pub_key) }; let result = IpcResults::AddPersonalData { status: Status::Passed }; Ok(IpcResponse::AddPersonalData { result }) diff --git a/enclave/safetrace/app/src/networking/messages.rs b/enclave/safetrace/app/src/networking/messages.rs index 843dcda..72be19e 100644 --- a/enclave/safetrace/app/src/networking/messages.rs +++ b/enclave/safetrace/app/src/networking/messages.rs @@ -1,8 +1,6 @@ use serde_json; use serde_repr::{Serialize_repr, Deserialize_repr}; use zmq::Message; -use failure::Error; -use hex::ToHex; // These attributes enable the status to be casted as an i8 object as well @@ -44,8 +42,7 @@ pub enum IpcResults { #[serde(rename = "result")] Request { request: String, sig: String }, #[serde(rename = "result")] - //EnclaveReport { #[serde(rename = "signingKey")] signing_key: String, report: String, signature: String }, - EnclaveReport { spid: String }, + EnclaveReport { #[serde(rename = "signingKey")] signing_key: String, report: String, signature: String }, #[serde(rename = "result")] DHKey { taskPubKey: String, sig: String }, AddPersonalData { status: Status }, @@ -63,9 +60,9 @@ pub enum IpcRequest { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct IpcInput { - pub encryptedUserId: String, - pub encryptedData: String, - pub userPubKey: String, + #[serde(rename = "encryptedUserId")] pub encrypted_userid: String, + #[serde(rename = "encryptedData")] pub encrypted_data: String, + #[serde(rename = "userPubKey")] pub user_pub_key: String, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -112,8 +109,7 @@ impl UnwrapError for Result { match self { Ok(m) => m, Err(e) => { - //error!("Unwrapped Message failed: {}", e); - panic!("Unwrapped Message failed: {}", e); + error!("Unwrapped Message failed: {}", e); IpcResponse::Error {msg: format!("{}", e)} } } diff --git a/enclave/safetrace/app/src/ocalls_u.rs b/enclave/safetrace/app/src/ocalls_u.rs index 9a3538c..a60fac4 100644 --- a/enclave/safetrace/app/src/ocalls_u.rs +++ b/enclave/safetrace/app/src/ocalls_u.rs @@ -1,10 +1,25 @@ -use std::{ptr, slice}; -use enigma_types::traits::SliceCPtr; +use sgx_types::{sgx_enclave_id_t, sgx_status_t, sgx_target_info_t, sgx_report_t}; + //use crate::esgx::general; +// #[no_mangle] +// pub unsafe extern "C" fn ocall_save_to_memory(data_ptr: *const u8, data_len: usize) -> u64 { +// let data = slice::from_raw_parts(data_ptr, data_len).to_vec(); +// let ptr = Box::into_raw(Box::new(data.into_boxed_slice())) as *const u8; +// ptr as u64 +// } + +#[no_mangle] +extern "C" { + pub fn ecall_get_registration_quote( + eid: sgx_enclave_id_t, + retval: *mut sgx_status_t, + target_info: *const sgx_target_info_t, + report: *mut sgx_report_t, + ) -> sgx_status_t; +} + #[no_mangle] -pub unsafe extern "C" fn ocall_save_to_memory(data_ptr: *const u8, data_len: usize) -> u64 { - let data = slice::from_raw_parts(data_ptr, data_len).to_vec(); - let ptr = Box::into_raw(Box::new(data.into_boxed_slice())) as *const u8; - ptr as u64 +extern "C" { + pub fn ecall_get_signing_address(eid: sgx_enclave_id_t, arr: *mut [u8; 20usize]) -> sgx_status_t; } \ No newline at end of file diff --git a/enclave/safetrace/enclave/Cargo.toml b/enclave/safetrace/enclave/Cargo.toml index 6091e85..b56a194 100644 --- a/enclave/safetrace/enclave/Cargo.toml +++ b/enclave/safetrace/enclave/Cargo.toml @@ -10,47 +10,21 @@ crate-type = ["staticlib"] [features] default = [] -[target.'cfg(not(target_env = "sgx"))'.dependencies] -sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } -sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git", features = ["backtrace"] } -sgx_trts = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } -sgx_rand = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } -sgx_tseal = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } - [dependencies] -arrayvec = { version = "0.4.10", default-features = false } -rustc-hex = { version = "2.0.1", default-features = false } -serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = ["derive"] } -serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } -libsecp256k1 = { version = "0.2" } -lazy_static = {version = "1.3.0", features = ["spin_no_std"] } -tiny-keccak = { version = "1.4" } -sha2 = { version = "0.8.0", default-features = false} -ring = { git = "https://github.com/elichai/ring.git", rev = "sgx-manual", default-features = false } +enigma-types = { git = "https://github.com/enigmampc/enigma-core.git", branch="develop", default-features = false, features = ["sgx"] } +enigma-crypto = { git = "https://github.com/enigmampc/enigma-core.git", branch="develop", default-features = false, features = ["sgx", "asymmetric"] } +enigma-tools-t = { git = "https://github.com/enigmampc/enigma-core.git", branch="develop" } +enigma-tools-m = { git = "https://github.com/enigmampc/enigma-core.git", branch="develop", default-features = false, features = ["sgx"] } +enigma-runtime-t = { git = "https://github.com/enigmampc/enigma-core.git", branch="develop" } +# rustc-hex = { version = "2.0", default-features = false } +serde = { git = "https://github.com/mesalock-linux/serde-sgx.git", rev = "sgx_1.0.9", features=["serde_derive"] } +serde_json = { git = "https://github.com/enigmampc/serde-json-sgx.git", rev = "1.0.39-sgx-1.0.9" } +# serde_cbor = { git = "https://github.com/mesalock-linux/cbor-sgx.git", rev = "sgx_1.0.9", default-features = false, features=["mesalock_sgx"] } +lazy_static = {version = "1.4.0", features = ["spin_no_std"] } -[patch.'https://github.com/apache/teaclave-sgx-sdk.git'] -sgx_alloc = { path = "../../incubator-teaclave-sgx-sdk/sgx_alloc" } -sgx_build_helper = { path = "../../incubator-teaclave-sgx-sdk/sgx_build_helper" } -sgx_cov = { path = "../../incubator-teaclave-sgx-sdk/sgx_cov" } -sgx_crypto_helper = { path = "../../incubator-teaclave-sgx-sdk/sgx_crypto_helper" } -sgx_libc = { path = "../../incubator-teaclave-sgx-sdk/sgx_libc" } -sgx_rand = { path = "../../incubator-teaclave-sgx-sdk/sgx_rand" } -sgx_rand_derive = { path = "../../incubator-teaclave-sgx-sdk/sgx_rand_derive" } -sgx_serialize = { path = "../../incubator-teaclave-sgx-sdk/sgx_serialize" } -sgx_serialize_derive = { path = "../../incubator-teaclave-sgx-sdk/sgx_serialize_derive" } -sgx_serialize_derive_internals = { path = "../../incubator-teaclave-sgx-sdk/sgx_serialize_derive_internals" } -sgx_tcrypto = { path = "../../incubator-teaclave-sgx-sdk/sgx_tcrypto" } -sgx_tcrypto_helper = { path = "../../incubator-teaclave-sgx-sdk/sgx_tcrypto_helper" } -sgx_tdh = { path = "../../incubator-teaclave-sgx-sdk/sgx_tdh" } -sgx_tkey_exchange = { path = "../../incubator-teaclave-sgx-sdk/sgx_tkey_exchange" } -sgx_tprotected_fs = { path = "../../incubator-teaclave-sgx-sdk/sgx_tprotected_fs" } -sgx_trts = { path = "../../incubator-teaclave-sgx-sdk/sgx_trts" } -sgx_tse = { path = "../../incubator-teaclave-sgx-sdk/sgx_tse" } -sgx_tseal = { path = "../../incubator-teaclave-sgx-sdk/sgx_tseal" } -sgx_tstd = { path = "../../incubator-teaclave-sgx-sdk/sgx_tstd" } -sgx_tunittest = { path = "../../incubator-teaclave-sgx-sdk/sgx_tunittest" } -sgx_types = { path = "../../incubator-teaclave-sgx-sdk/sgx_types" } -sgx_ucrypto = { path = "../../incubator-teaclave-sgx-sdk/sgx_ucrypto" } -sgx_unwind = { path = "../../incubator-teaclave-sgx-sdk/sgx_unwind" } -sgx_urts = { path = "../../incubator-teaclave-sgx-sdk/sgx_urts" } +sgx_types = { git = "https://github.com/baidu/rust-sgx-sdk.git", rev = "v1.0.9" } +sgx_tstd = { git = "https://github.com/baidu/rust-sgx-sdk.git", rev = "v1.0.9" } +sgx_trts = { git = "https://github.com/baidu/rust-sgx-sdk.git", rev = "v1.0.9" } +sgx_rand = { git = "https://github.com/baidu/rust-sgx-sdk.git", rev = "v1.0.9" } +sgx_tseal = { git = "https://github.com/baidu/rust-sgx-sdk.git", rev = "v1.0.9" } diff --git a/enclave/safetrace/enclave/Enclave.edl b/enclave/safetrace/enclave/Enclave.edl index 99f6a94..cf788d5 100644 --- a/enclave/safetrace/enclave/Enclave.edl +++ b/enclave/safetrace/enclave/Enclave.edl @@ -22,6 +22,8 @@ enclave { from "sgx_tstdc.edl" import *; from "sgx_fs.edl" import *; + include "sgx_key_exchange.h" + include "enigma-types.h" trusted { /* define ECALLs here. */ @@ -39,6 +41,14 @@ enclave { [in] uint8_t pubkey[64], [out] uint64_t* serialized_ptr ); + + public sgx_status_t ecall_get_registration_quote( + [in] const sgx_target_info_t * target_info , + [out] sgx_report_t * report + ); + + public void ecall_get_signing_address([out] uint8_t arr[20]); + }; untrusted { uint64_t ocall_save_to_memory([in, count=data_len] const uint8_t* data_ptr, size_t data_len); diff --git a/enclave/safetrace/enclave/Makefile b/enclave/safetrace/enclave/Makefile index 5f41187..23a9b31 100644 --- a/enclave/safetrace/enclave/Makefile +++ b/enclave/safetrace/enclave/Makefile @@ -1,32 +1,35 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. +# Because build-dependencies and regular dependencies are mixed together it's not possible to import +# bindgen into the enclave's build.rs (https://github.com/rust-lang/cargo/issues/2589) +# The solution is to install the bindgen CLI in the docker and use it manually in the Makefile. + +SGX_SDK ?= /opt/sgxsdk + Rust_Enclave_Name := libenclave.a Rust_Enclave_Files := $(wildcard src/*.rs) -Rust_Target_Path := $(CURDIR)/../../incubator-teaclave-sgx-sdk/xargo +# Rust_Target_Path := $(CURDIR)/../../incubator-teaclave-sgx-sdk/xargo + +BINDGEN_OUTPUT_FILE := src/auto_ffi.rs +BINDGEN_RAW_LINES := "\#![allow(dead_code)] use enigma_types::*; use sgx_types::*;" +BINDGEN_CLANG_FLAGS := -I$(SGX_SDK)/include -I$(HOME)/sgx/edl +BINDGEN_FLAGS := --default-enum-style=rust --rust-target=nightly \ + --no-recursive-whitelist --use-array-pointers-in-arguments \ + --whitelist-function ocall_.* --raw-line $(BINDGEN_RAW_LINES) -.PHONY: all -all: $(Rust_Enclave_Name) +all: bindgen $(Rust_Enclave_Name) $(Rust_Enclave_Name): $(Rust_Enclave_Files) ifeq ($(XARGO_SGX), 1) - RUST_TARGET_PATH=$(Rust_Target_Path) xargo build --target x86_64-unknown-linux-sgx --release - cp ./target/x86_64-unknown-linux-sgx/release/libsafetraceenclave.a ../lib/libenclave.a + RUST_TARGET_PATH=$(shell pwd) xargo build --target x86_64-unknown-linux-sgx $(CARGO_FLAGS) + cp ./target/x86_64-unknown-linux-sgx/$(Rust_target_dir)/libsafetraceenclave.a ../lib/libenclave.a else - cargo build --release - cp ./target/release/libsafetraceenclave.a ../lib/libenclave.a + cargo build $(CARGO_FLAGS) + cp ./target/$(Rust_target_dir)/libsafetraceenclave.a ../lib/libenclave.a endif + + +.PHONY: bindgen +bindgen: Enclave_t.h + cargo build -p enigma-types $(CARGO_FLAGS) # Meant to make sure `enigma-types.h` already exists and can be included. + bindgen Enclave_t.h $(BINDGEN_FLAGS) -- $(BINDGEN_CLANG_FLAGS) > $(BINDGEN_OUTPUT_FILE) + rustfmt $(BINDGEN_OUTPUT_FILE) diff --git a/enclave/safetrace/enclave/src/data.rs b/enclave/safetrace/enclave/src/data.rs index f2a7f90..26adc1f 100644 --- a/enclave/safetrace/enclave/src/data.rs +++ b/enclave/safetrace/enclave/src/data.rs @@ -1,24 +1,161 @@ -use serde::{Serialize, Deserialize}; +// use serde::{Serialize, Deserialize}; // use std::{slice}; +// use std::string::String; +use enigma_tools_t::common::errors_t::{EnclaveError, EnclaveError::*, FailedTaskError::*, EnclaveSystemError::*}; +use enigma_crypto::{symmetric::decrypt}; +use enigma_types::{DhKey, PubKey, EnclaveReturn}; use std::string::String; -use errors_t::EnclaveError; -use types::{PubKey, DhKey}; +use std::string::ToString; +use std::vec::Vec; +use std::str; +use serde_json::{Value}; +use serde::{Deserialize, Serialize}; +use sgx_tseal::{SgxSealedData}; +use sgx_types::marker::ContiguousMemory; +use std::untrusted::fs::File; +use std::io::{Read, Write, self}; + + +use sgx_types::sgx_sealed_data_t; + +pub const SEAL_LOG_SIZE: usize = 4096; // Structs #[derive(Serialize, Deserialize, Clone, Debug)] pub struct GeolocationTime { - lat: i32, - lng: i32, + #[serde(default)] + lat: f32, + lng: f32, startTS: i32, - endTS: i32 + endTS: i32, } #[derive(Serialize, Deserialize, Clone, Debug)] -pub struct Request { - encryptedUserId: String, - encryptedData: String, - userPubKey: String +pub struct UserLocations { + pub locations: Vec, + pub user_id: String, +} + +#[derive(Serialize, Deserialize, Clone, Default, Debug)] +pub struct UserLocationsArray { + key: u32, + rand: [u8; 16], + vec: Vec +} + +pub fn decrypt_userid(userid: &[u8], key: &DhKey) -> Result, EnclaveError> { + if userid.is_empty(){ + Err(FailedTaskError(InputError { message: "encryptedUserId is empty".to_string()})) + } else { + Ok(decrypt(userid, key)?) + } +} + +pub fn decrypt_data(data: &[u8], key: &DhKey) -> Result, EnclaveError> { + if data.is_empty(){ + Err(FailedTaskError(InputError { message: "encryptedData is empty".to_string()})) + } else { + Ok(decrypt(data, key)?) + } +} + +#[no_mangle] +pub fn create_sealeddata_for_serializable(data: &UserLocations, sealed_log_out: &mut [u8; SEAL_LOG_SIZE]) -> enigma_types::EnclaveReturn { + + let encoded_vec = serde_json::to_vec(&data).unwrap(); + let encoded_slice = encoded_vec.as_slice(); + println!("Length of encoded slice: {}", encoded_slice.len()); + println!("Encoded slice: {:?}", encoded_slice); + + let aad: [u8; 0] = [0_u8; 0]; + let result = SgxSealedData::<[u8]>::seal_data(&aad, encoded_slice); + let sealed_data = match result { + Ok(x) => x, + Err(ret) => { return EnclaveReturn::SgxError; }, + }; + + let sealed_log = sealed_log_out.as_mut_ptr(); + + let opt = to_sealed_log_for_slice(&sealed_data, sealed_log, SEAL_LOG_SIZE as u32); + if opt.is_none() { + return EnclaveReturn::SgxError; + } + + println!("{:?}", data); + + EnclaveReturn::Success +} + +// pub fn unsealeddata_for_serializable(sealed_log_in: &mut [u8; SEAL_LOG_SIZE]) -> Result { +// let sealed_log = sealed_log_in.as_mut_ptr(); +// let opt = from_sealed_log_for_slice::(sealed_log, SEAL_LOG_SIZE as u32); +// let sealed_data = match opt { +// Some(x) => x, +// None => { +// panic!() +// }, +// }; + +// let result = opt.unseal_data(); +// let unsealed_data = match result { +// Ok(x) => Some(x), +// Err(ret) => { +// panic!(ret); +// }, +// }; + +// let encoded_slice = unsealed_data.get_decrypt_txt(); +// println!("Length of encoded slice: {}", encoded_slice.len()); +// println!("Encoded slice: {:?}", encoded_slice); +// let data: UserLocations = serde_json::from_slice(encoded_slice).unwrap(); + +// println!("{:?}", data); + +// Ok(data) +// } + + +fn to_sealed_log_for_slice(sealed_data: &SgxSealedData<[T]>, sealed_log: * mut u8, sealed_log_size: u32) -> Option<* mut sgx_sealed_data_t> { + unsafe { + sealed_data.to_raw_sealed_data_t(sealed_log as * mut sgx_sealed_data_t, sealed_log_size) + } +} + +fn from_sealed_log_for_slice<'a, T: Copy + ContiguousMemory>(sealed_log: * mut u8, sealed_log_size: u32) -> Option> { + unsafe { + SgxSealedData::<[T]>::from_raw_sealed_data_t(sealed_log as * mut sgx_sealed_data_t, sealed_log_size) + } +} + + +// file system +pub fn save_sealed_data(path: &str, sealed_data: &[u8]) { + let opt = File::create(path); + if opt.is_ok() { + debug_println!("Created file => {} ", path); + let mut file = opt.unwrap(); + let result = file.write_all(&sealed_data); + if result.is_ok() { + debug_println!("success writting to file! "); + } else { + debug_println!("error writting to file! "); + } + } +} + +pub fn load_sealed_data(path: &str, sealed_data: &mut [u8]) { + let opt = File::open(path); + if opt.is_ok() { + debug_println!("Created file => {} ", path); + let mut file = opt.unwrap(); + let result = file.read(sealed_data); + if result.is_ok() { + debug_println!("success writting to file! "); + } else { + debug_println!("error writting to file! "); + } + } } pub fn ecall_add_personal_data_internal( @@ -27,33 +164,43 @@ pub fn ecall_add_personal_data_internal( userPubKey: &PubKey, dhKey: &DhKey) -> Result<(), EnclaveError> { - println!("Add personal data inside the enclave"); - println!("{:?}", dhKey); - println!("Received UserPub Key Again: {:?}", userPubKey.to_vec()); + // let decrypted_userid = decrypt_userid(encryptedUserId, &dhKey)?; + // let decrypted_data = decrypt_data(encryptedData, &dhKey)?; + + // // //let userid = u8_to_string(decrypt_userid)?; + // let userid = match str::from_utf8(&decrypted_userid) { + // Ok(v) => v, + // Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + // }; + // // let userid = std::str::from_utf8(decrypted_userid)?; - // // let str_slice = unsafe { slice::from_raw_parts(data_json, some_len) }; + // let mut inputData: Vec = serde_json::from_slice(&decrypted_data).unwrap(); + // let userData = UserLocations { + // user_id: userid.to_string(), + // locations: inputData, + // }; - // // Input sanitised in EngimaJS to object type - // let mut request: Request = serde_json::from_slice(str_slice).unwrap(); + // let mut sealed_log_in = [0u8; SEAL_LOG_SIZE]; - // println!("EncryptedUserId: {:?}", request.encryptedUserId); + // create_sealeddata_for_serializable(&userData, &mut sealed_log_in); + // let p = String::from("data.sealed"); + // save_sealed_data(&p, &sealed_log_in); - // let inputkey = request.userPubKey; + // println!("{:?}", userData); + let p = String::from("data.sealed"); + let mut sealed_log_out: [u8; SEAL_LOG_SIZE] = [0; SEAL_LOG_SIZE]; + load_sealed_data(&p, &mut sealed_log_out); + // unseal data + // let unsealed_data = SecretKeyStorage::unseal_key(&mut sealed_log_out).unwrap(); + // let unsealed_data = unsealeddata_for_serializable(&mut sealed_log_out)?; - // Read from the state - // let mut data = Self::get_data(); - // Append - // data.append(&mut array); - // Write back to the state - // write_state!(DATASET => data); + // println!("{:?}", unsealed_data); - // Ocall to normal world for output - //println!("Received Data: {:?}", &request); Ok(()) } \ No newline at end of file diff --git a/enclave/safetrace/enclave/src/keys_t.rs b/enclave/safetrace/enclave/src/keys_t.rs index 266a6ec..ccf669f 100644 --- a/enclave/safetrace/enclave/src/keys_t.rs +++ b/enclave/safetrace/enclave/src/keys_t.rs @@ -1,203 +1,13 @@ use crate::SIGNING_KEY; -use types::{PubKey, DhKey, SymmetricKey}; +use enigma_tools_t::common::errors_t::EnclaveError; +use enigma_tools_m::utils::LockExpectMutex; +use enigma_crypto::asymmetric::KeyPair; +use enigma_tools_m::primitives::km_primitives::UserMessage; +use enigma_types::{DhKey, PubKey}; use std::collections::HashMap; -use std::{sync::SgxMutex as Mutex, sync::SgxMutexGuard as MutexGuard, vec::Vec}; -use serde::{Deserialize, Serialize}; -use secp256k1::{PublicKey, SecretKey, SharedSecret}; -use errors_t::{CryptoError, EnclaveError, ToolsError::MessagingError}; -use hash::{Keccak256, prepare_hash_multiple}; +use std::{sync::SgxMutex, vec::Vec}; -//use ring::aead::{self, Nonce, Aad}; -//use std::{borrow::ToOwned}; - - -#[derive(Debug)] -pub struct KeyPair { - pubkey: PublicKey, - privkey: SecretKey, -} - -impl KeyPair { - /// This will generate a fresh pair of Public and Private keys. - /// it will use the available randomness from [crate::rand] - - pub fn new() -> Result { - use sgx_trts::trts::rsgx_read_rand; - // This loop is important to make sure that the resulting public key isn't a point in infinity(at the curve). - // So if the Resulting public key is bad we need to generate a new random private key and try again until it succeeds. - loop { - let mut me = [0u8; 32]; - rsgx_read_rand(&mut me); - if let Ok(privkey) = SecretKey::parse(&me) { - let pubkey = PublicKey::from_secret_key(&privkey); - return Ok(KeyPair { privkey, pubkey }); - } - } - } - - pub fn from_slice(privkey: &[u8; 32]) -> Result { - let privkey = SecretKey::parse(&privkey) - .map_err(|e| CryptoError::KeyError { key_type: "Private Key", err: Some(e) })?; - let pubkey = PublicKey::from_secret_key(&privkey); - - Ok(KeyPair { privkey, pubkey }) - } - - /// This function does an ECDH(point multiplication) between one's private key and the other one's public key. - /// - pub fn derive_key(&self, _pubarr: &PubKey) -> Result { - let mut pubarr: [u8; 65] = [0; 65]; - pubarr[0] = 4; - pubarr[1..].copy_from_slice(&_pubarr[..]); - - let pubkey = PublicKey::parse(&pubarr) - .map_err(|e| CryptoError::KeyError { key_type: "Private Key", err: Some(e) })?; - - let shared = SharedSecret::new(&pubkey, &self.privkey) - .map_err(|_| CryptoError::DerivingKeyError { self_key: self.get_pubkey(), other_key: *_pubarr })?; - - let mut result = [0u8; 32]; - result.copy_from_slice(shared.as_ref()); - Ok(result) - } - - fn pubkey_object_to_pubkey(key: &PublicKey) -> PubKey { - let mut sliced_pubkey: [u8; 64] = [0; 64]; - sliced_pubkey.clone_from_slice(&key.serialize()[1..65]); - sliced_pubkey - } - - pub fn get_privkey(&self) -> [u8; 32] { self.privkey.serialize() } - - /// Get the Public Key and slice the first byte - /// The first byte represents if the key is compressed or not. - /// Because we use uncompressed Keys That start with `0x04` we can slice it out. - /// - /// We should move to compressed keys in the future, this will save 31 bytes on each pubkey. - /// - /// See More: - /// `https://tools.ietf.org/html/rfc5480#section-2.2` - /// `https://docs.rs/libsecp256k1/0.1.13/src/secp256k1/lib.rs.html#146` - pub fn get_pubkey(&self) -> PubKey { - KeyPair::pubkey_object_to_pubkey(&self.pubkey) - } - - /// Sign a message using the Private Key. - /// # Examples - /// Simple Message signing: - /// ``` - /// use enigma_crypto::KeyPair; - /// let keys = KeyPair::new().unwrap(); - /// let msg = b"Sign this"; - /// let sig = keys.sign(msg); - /// ``` - /// - /// The function returns a 65 bytes slice that contains: - /// 1. 32 Bytes, ECDSA `r` variable. - /// 2. 32 Bytes ECDSA `s` variable. - /// 3. 1 Bytes ECDSA `v` variable aligned to the right for Ethereum compatibility - pub fn sign(&self, message: &[u8]) -> Result<[u8; 65], CryptoError> { - let hashed_msg = message.keccak256(); - let message_to_sign = secp256k1::Message::parse(&hashed_msg); - - let (sig, recovery) = secp256k1::sign(&message_to_sign, &self.privkey) - .map_err(|_| CryptoError::SigningError { hashed_msg: *hashed_msg })?; - - let v: u8 = recovery.into(); - let mut returnvalue = [0u8; 65]; - returnvalue[..64].copy_from_slice(&sig.serialize()); - returnvalue[64] = v + 27; - Ok(returnvalue) - } - -} - - -/// A struct to represent the UserMessage for the key exchange. -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] -pub struct UserMessage { - pub(crate) pubkey: Vec, -} - -impl UserMessage { - // The reason for the prefix is that I(@elichai) don't feel comfortable signing a plain public key. - // Because ECDSA signature contains multiplication of curve points, so I'm not sure if signing on a valid curve point has any side effect. - const PREFIX: &'static [u8; 19] = b"Enigma User Message"; - - /// Generate a new UserMessage struct with the provided public key. - pub fn new(pubkey: PubKey) -> Self { - let pubkey = pubkey.to_vec(); - Self { pubkey } - } - - /// This should serialize the struct for it to be signed, using [`enigma_crypto::hash::prepare_hash_multiple()`] - /// it will add a prefix to the data, `b"Enigma User Message"`. - pub fn to_sign(&self) -> Vec { - let to_sign = [&Self::PREFIX[..], &self.pubkey]; - prepare_hash_multiple(&to_sign) - } - - /// This will serialize the Message using MessagePack. - pub fn into_message(self) -> Result, EnclaveError> { - //let mut buf = Vec::new(); - //let val = serde_json::to_value(self).map_err(|_| MessagingError { err: "Couldn't convert UserMesssage to Value" })?; - //val.serialize(&mut Serializer::new(&mut buf)).map_err(|_| MessagingError { err: "Couldn't serialize UserMesssage" })?;; - let val = serde_json::to_vec(&self).map_err(|_| MessagingError { err: "Couldn't convert UserMesssage to Value" })?; - Ok(val) - } - - // /// This will deserialize the Message using MessagePack. - // pub fn from_message(msg: &[u8]) -> Result { - // let mut des = Deserializer::new(&msg[..]); - // let res: serde_json::Value = Deserialize::deserialize(&mut des) - // .map_err(|_| MessagingError { err: "Couldn't Deserialize UserMesssage"})?;; - // let msg: Self = serde_json::from_value(res) - // .map_err(|_| MessagingError { err: "Couldn't convert Value to UserMesssage"})?; - // Ok(msg) - // } - - // /// Will return the DH public key from the message. - // pub fn get_pubkey(&self) -> PubKey { - // let mut pubkey = [0u8; 64]; - // pubkey.copy_from_slice(&self.pubkey[..]); - // pubkey - // } -} - - -// const IV_SIZE: usize = 96/8; -// static AES_MODE: &aead::Algorithm = &aead::AES_256_GCM; -// type IV = [u8; IV_SIZE]; - -// pub fn decrypt(cipheriv: &[u8], key: &SymmetricKey) -> Result, CryptoError> { -// if cipheriv.len() < IV_SIZE { -// return Err(CryptoError::ImproperEncryption); -// } -// let aes_decrypt = aead::OpeningKey::new(&AES_MODE, key) -// .map_err(|_| CryptoError::KeyError { key_type: "Decryption", err: None })?; - -// let (ciphertext, iv) = cipheriv.split_at(cipheriv.len()-12); -// let nonce = aead::Nonce::try_assume_unique_for_key(&iv).unwrap(); // This Cannot fail because split_at promises that iv.len()==12 -// let mut ciphertext = ciphertext.to_owned(); -// let decrypted_data = aead::open_in_place(&aes_decrypt, nonce, Aad::empty(), 0, &mut ciphertext); -// let decrypted_data = decrypted_data.map_err(|_| CryptoError::DecryptionError)?; - -// Ok(decrypted_data.to_vec()) -// } - - -/// A trait that is basically a shortcut for `mutex.lock().expect(format!("{} mutex is posion", name))` -/// you instead call `mutex.lock_expect(name)` and it will act the same. -pub trait LockExpectMutex { - /// See trait documentation. a shortcut for `lock()` and `expect()` - fn lock_expect(&self, name: &str) -> MutexGuard; -} - -impl LockExpectMutex for Mutex { - fn lock_expect(&self, name: &str) -> MutexGuard { self.lock().unwrap_or_else(|_| panic!("{} mutex is poison", name)) } -} - -lazy_static! { pub static ref DH_KEYS: Mutex, DhKey>> = Mutex::new(HashMap::new()); } +lazy_static! { pub static ref DH_KEYS: SgxMutex, DhKey>> = SgxMutex::new(HashMap::new()); } pub(crate) unsafe fn ecall_get_user_key_internal(sig: &mut [u8; 65], user_pubkey: &PubKey) -> Result, EnclaveError> { let keys = KeyPair::new()?; diff --git a/enclave/safetrace/enclave/src/lib.rs b/enclave/safetrace/enclave/src/lib.rs index f0f5d3f..37d4bc2 100644 --- a/enclave/safetrace/enclave/src/lib.rs +++ b/enclave/safetrace/enclave/src/lib.rs @@ -17,72 +17,92 @@ #![crate_name = "safetraceenclave"] #![crate_type = "staticlib"] +#![no_std] #![cfg_attr(not(target_env = "sgx"), no_std)] #![cfg_attr(target_env = "sgx", feature(rustc_private))] +extern crate enigma_runtime_t; +#[macro_use] +extern crate enigma_tools_t; +extern crate enigma_crypto; +extern crate enigma_tools_m; +extern crate enigma_types; + extern crate sgx_types; #[cfg(not(target_env = "sgx"))] #[macro_use] extern crate sgx_tstd as std; + extern crate sgx_rand; -extern crate sgx_trts; +// extern crate sgx_trts; extern crate sgx_tseal; #[macro_use] extern crate lazy_static; +extern crate serde; +// #[macro_use] +extern crate serde_json; + // extern crate sgx_serialize; // #[macro_use] // extern crate sgx_serialize_derive; -use sgx_types::*; use std::{slice}; -extern crate serde; -extern crate serde_json; -extern crate secp256k1; -extern crate tiny_keccak; -extern crate sha2; -extern crate rustc_hex; -extern crate arrayvec; -//extern crate ring; +// extern crate serde; +// extern crate secp256k1; +// extern crate tiny_keccak; +// extern crate sha2; +// extern crate rustc_hex; +// extern crate arrayvec; +// extern crate ring; -#[macro_use] -mod macros; -mod errors_t; +// #[macro_use] +// mod macros; +// mod errors_t; mod data; mod keys_t; -mod storage; -mod types; -mod hash; -mod traits; +// // mod storage; +// mod types; +// mod hash; +// mod traits; -use keys_t::{ecall_get_user_key_internal, KeyPair, DH_KEYS, LockExpectMutex}; +use sgx_types::*; +use keys_t::{ecall_get_user_key_internal}; use data::ecall_add_personal_data_internal; -use storage::*; -use types::{PubKey, DhKey, EnclaveReturn}; -use errors_t::{EnclaveError, CryptoError}; -use traits::SliceCPtr; +// use storage::*; +use enigma_types::{PubKey, DhKey, EnclaveReturn}; +use enigma_tools_t::{ + common::errors_t::{EnclaveError}, + storage_t, + quote_t, +}; +use enigma_tools_m::utils::EthereumAddress; + +use enigma_tools_m::utils::{LockExpectMutex}; +use enigma_crypto::{asymmetric, CryptoError}; + + + +// use traits::SliceCPtr; + +use enigma_tools_t::{esgx::ocalls_t}; lazy_static! { - pub(crate) static ref SIGNING_KEY: KeyPair = get_sealed_keys_wrapper(); + pub(crate) static ref SIGNING_KEY: asymmetric::KeyPair = get_sealed_keys_wrapper(); } -extern "C" { - fn ocall_save_to_memory(ptr: *mut u64, data_ptr: *const u8, data_len: usize) -> sgx_status_t; +#[no_mangle] +pub extern "C" fn ecall_get_registration_quote(target_info: &sgx_target_info_t, real_report: &mut sgx_report_t) -> sgx_status_t { + quote_t::create_report_with_data(&target_info, real_report, &SIGNING_KEY.get_pubkey().address()) } +#[no_mangle] +pub extern "C" fn ecall_get_signing_address(pubkey: &mut [u8; 20]) { pubkey.copy_from_slice(&SIGNING_KEY.get_pubkey().address()); } -// TODO: Replace u64 with *const u8, and pass it via the ocall using *const *const u8 -pub fn save_to_untrusted_memory(data: &[u8]) -> Result { - let mut ptr = 0u64; - match unsafe { ocall_save_to_memory(&mut ptr as *mut u64, data.as_c_ptr(), data.len()) } { - sgx_status_t::SGX_SUCCESS => Ok(ptr), - e => Err(e.into()), - } -} -fn get_sealed_keys_wrapper() -> KeyPair { +fn get_sealed_keys_wrapper() -> asymmetric::KeyPair { // // Get Home path via Ocall // let mut path_buf = get_home_path().unwrap(); // // add the filename to the path: `keypair.sealed` @@ -90,7 +110,7 @@ fn get_sealed_keys_wrapper() -> KeyPair { // let sealed_path = path_buf.to_str().unwrap(); // TODO: Decide what to do if failed to obtain keys. - match get_sealed_keys("keypair.sealed") { + match storage_t::get_sealed_keys("keypair.sealed") { Ok(key) => key, Err(err) => panic!("Failed obtaining keys: {:?}", err), } @@ -103,7 +123,7 @@ pub unsafe extern "C" fn ecall_get_user_key(sig: &mut [u8; 65], user_pubkey: &[u Ok(msg) => msg, Err(e) => return e.into(), }; - *serialized_ptr = match save_to_untrusted_memory(&msg[..]) { + *serialized_ptr = match ocalls_t::save_to_untrusted_memory(&msg[..]) { Ok(ptr) => ptr, Err(e) => return e.into(), }; @@ -111,7 +131,7 @@ pub unsafe extern "C" fn ecall_get_user_key(sig: &mut [u8; 65], user_pubkey: &[u } fn get_io_key(user_key: &PubKey) -> Result { - let io_key = DH_KEYS + let io_key = keys_t::DH_KEYS .lock_expect("User DH Key") .remove(&user_key[..]) .ok_or(CryptoError::MissingKeyError { key_type: "DH Key" })?; From 642466c86fad4785e374c3e2ccf54c5868d285e7 Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Tue, 31 Mar 2020 12:56:32 -0500 Subject: [PATCH 02/11] MAINT: pointing to develop branch of core modules --- enclave/safetrace/app/Cargo.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/enclave/safetrace/app/Cargo.toml b/enclave/safetrace/app/Cargo.toml index 51c1f06..970d16a 100644 --- a/enclave/safetrace/app/Cargo.toml +++ b/enclave/safetrace/app/Cargo.toml @@ -5,12 +5,12 @@ authors = ["The Teaclave Authors"] build = "build.rs" [dependencies] -sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } -sgx_urts = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } -enigma-types = { git = "https://github.com/enigmampc/enigma-core.git", features = ["std"] } -enigma-tools-u = { git = "https://github.com/enigmampc/enigma-core.git" } -enigma-tools-m = { git = "https://github.com/enigmampc/enigma-core.git" } -enigma-crypto = { git = "https://github.com/enigmampc/enigma-core.git" } +sgx_types = { git = "https://github.com/baidu/rust-sgx-sdk.git", rev = "v1.0.9" } +sgx_urts = { git = "https://github.com/baidu/rust-sgx-sdk.git", rev = "v1.0.9" } +enigma-types = { git = "https://github.com/enigmampc/enigma-core.git", branch="develop", features = ["std"] } +enigma-tools-u = { git = "https://github.com/enigmampc/enigma-core.git", branch="develop" } +enigma-tools-m = { git = "https://github.com/enigmampc/enigma-core.git", branch="develop" } +enigma-crypto = { git = "https://github.com/enigmampc/enigma-core.git", branch="develop" } futures = { version = "0.1.25", default-features = false } tokio-zmq = "0.9.0" From 3833ebbf3c2ae1a52ef129f24ec93a86274c5740 Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Tue, 31 Mar 2020 13:10:48 -0500 Subject: [PATCH 03/11] BLD: unsealing data (WIP) --- enclave/safetrace/enclave/src/data.rs | 42 +++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/enclave/safetrace/enclave/src/data.rs b/enclave/safetrace/enclave/src/data.rs index 26adc1f..d1befc0 100644 --- a/enclave/safetrace/enclave/src/data.rs +++ b/enclave/safetrace/enclave/src/data.rs @@ -17,7 +17,8 @@ use std::untrusted::fs::File; use std::io::{Read, Write, self}; -use sgx_types::sgx_sealed_data_t; +use sgx_types::{sgx_status_t, sgx_sealed_data_t}; + pub const SEAL_LOG_SIZE: usize = 4096; @@ -87,8 +88,10 @@ pub fn create_sealeddata_for_serializable(data: &UserLocations, sealed_log_out: EnclaveReturn::Success } -// pub fn unsealeddata_for_serializable(sealed_log_in: &mut [u8; SEAL_LOG_SIZE]) -> Result { +// pub fn unsealeddata_for_serializable(sealed_log_in: &mut [u8; SEAL_LOG_SIZE]) -> enigma_types::EnclaveReturn { + // let sealed_log = sealed_log_in.as_mut_ptr(); + // let opt = from_sealed_log_for_slice::(sealed_log, SEAL_LOG_SIZE as u32); // let sealed_data = match opt { // Some(x) => x, @@ -112,9 +115,39 @@ pub fn create_sealeddata_for_serializable(data: &UserLocations, sealed_log_out: // println!("{:?}", data); -// Ok(data) +// EnclaveReturn::Success + // } +#[no_mangle] +pub extern "C" fn verify_sealeddata_for_serializable(sealed_log: * mut u8, sealed_log_size: u32) -> sgx_status_t { + + let opt = from_sealed_log_for_slice::(sealed_log, sealed_log_size); + let sealed_data = match opt { + Some(x) => x, + None => { + return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + }, + }; + + let result = sealed_data.unseal_data(); + let unsealed_data = match result { + Ok(x) => x, + Err(ret) => { + return ret; + }, + }; + + let encoded_slice = unsealed_data.get_decrypt_txt(); + println!("Length of encoded slice: {}", encoded_slice.len()); + println!("Encoded slice: {:?}", encoded_slice); + let data: UserLocations = serde_json::from_slice(encoded_slice).unwrap(); + + println!("{:?}", data); + + sgx_status_t::SGX_SUCCESS +} + fn to_sealed_log_for_slice(sealed_data: &SgxSealedData<[T]>, sealed_log: * mut u8, sealed_log_size: u32) -> Option<* mut sgx_sealed_data_t> { unsafe { @@ -199,6 +232,9 @@ pub fn ecall_add_personal_data_internal( // let unsealed_data = SecretKeyStorage::unseal_key(&mut sealed_log_out).unwrap(); // let unsealed_data = unsealeddata_for_serializable(&mut sealed_log_out)?; + let sealed_log = sealed_log_out.as_mut_ptr(); + verify_sealeddata_for_serializable(sealed_log, SEAL_LOG_SIZE as u32); + // println!("{:?}", unsealed_data); From 8c98ac9624b82f1c59ebae04359e2ce65787de4f Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Tue, 31 Mar 2020 13:12:57 -0500 Subject: [PATCH 04/11] MAINT: remove commented out section - unseal --- enclave/safetrace/enclave/src/data.rs | 31 --------------------------- 1 file changed, 31 deletions(-) diff --git a/enclave/safetrace/enclave/src/data.rs b/enclave/safetrace/enclave/src/data.rs index d1befc0..213783b 100644 --- a/enclave/safetrace/enclave/src/data.rs +++ b/enclave/safetrace/enclave/src/data.rs @@ -88,37 +88,6 @@ pub fn create_sealeddata_for_serializable(data: &UserLocations, sealed_log_out: EnclaveReturn::Success } -// pub fn unsealeddata_for_serializable(sealed_log_in: &mut [u8; SEAL_LOG_SIZE]) -> enigma_types::EnclaveReturn { - -// let sealed_log = sealed_log_in.as_mut_ptr(); - -// let opt = from_sealed_log_for_slice::(sealed_log, SEAL_LOG_SIZE as u32); -// let sealed_data = match opt { -// Some(x) => x, -// None => { -// panic!() -// }, -// }; - -// let result = opt.unseal_data(); -// let unsealed_data = match result { -// Ok(x) => Some(x), -// Err(ret) => { -// panic!(ret); -// }, -// }; - -// let encoded_slice = unsealed_data.get_decrypt_txt(); -// println!("Length of encoded slice: {}", encoded_slice.len()); -// println!("Encoded slice: {:?}", encoded_slice); -// let data: UserLocations = serde_json::from_slice(encoded_slice).unwrap(); - -// println!("{:?}", data); - -// EnclaveReturn::Success - -// } - #[no_mangle] pub extern "C" fn verify_sealeddata_for_serializable(sealed_log: * mut u8, sealed_log_size: u32) -> sgx_status_t { From 21b919d6db22d8fc922b2eb5508b6823bc9bee0e Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Wed, 1 Apr 2020 00:02:27 -0500 Subject: [PATCH 05/11] BLD: initial implementation of find_match (WIP) --- client/index.js | 72 +++++++-- .../app/src/networking/ipc_listener.rs | 73 +++++++-- .../safetrace/app/src/networking/messages.rs | 22 ++- enclave/safetrace/enclave/Cargo.toml | 3 + enclave/safetrace/enclave/Enclave.edl | 6 + enclave/safetrace/enclave/src/data.rs | 141 ++++++++++-------- enclave/safetrace/enclave/src/errors_t.rs | 7 +- enclave/safetrace/enclave/src/keys_t.rs | 2 +- enclave/safetrace/enclave/src/lib.rs | 36 ++++- 9 files changed, 272 insertions(+), 90 deletions(-) diff --git a/client/index.js b/client/index.js index a29ac97..3c562ee 100644 --- a/client/index.js +++ b/client/index.js @@ -47,12 +47,10 @@ function getClientKeys(seed='') { return {privateKey, publicKey}; } -async function add_data(userId, data){ +async function addData(userId, data){ let {publicKey, privateKey} = getClientKeys(); - console.log(publicKey) - try { const getWorkerEncryptionKeyResult = await new Promise((resolve, reject) => { client.request('newTaskEncryptionKey', {userPubKey: publicKey}, @@ -79,10 +77,6 @@ async function add_data(userId, data){ {t: 'bytes', v: encryptedData}, ); - // const a = getClientKeys(); - - // console.log(a.publicKey); - const addPersonalDataResult = await new Promise((resolve, reject) => { client.request('addPersonalData', { encryptedUserId: encryptedUserId, @@ -104,15 +98,73 @@ async function add_data(userId, data){ } else { console.log('Something went wrong. Time to debug...') } - } catch(err) { console.log(err); // Or Throw an error } +} + +async function findMatch(userId){ + + let {publicKey, privateKey} = getClientKeys(); + + try { + const getWorkerEncryptionKeyResult = await new Promise((resolve, reject) => { + client.request('newTaskEncryptionKey', {userPubKey: publicKey}, + (err, response) => { + if (err) { + reject(err); + return; + } + resolve(response); + }); + }); + const {result, id} = getWorkerEncryptionKeyResult; + const {taskPubKey, sig} = result; + // ToDo: verify signature + + // Generate derived key from worker's encryption key and user's private key + const derivedKey = enigma.utils.getDerivedKey(taskPubKey, privateKey); + // Encrypt function and ABI-encoded args + const encryptedUserId = enigma.utils.encryptMessage(derivedKey, userId); + const msg = web3utils.soliditySha3( + {t: 'bytes', v: encryptedUserId}, + ); + + const findMatchResult = await new Promise((resolve, reject) => { + client.request('findMatch', { + encryptedUserId: encryptedUserId, + userPubKey: publicKey}, + (err, response) => { + if (err) { + reject(err); + return; + } + resolve(response); + }); + }); + + console.log(findMatchResult); + console.log(findMatchResult.findMatch) + + // const {findMatch} = findMatchResult; + + // if(findMatch.status == 0) { + // console.log('Find Match operation successful'); + // console.log() + // } else { + // console.log('Something went wrong. Time to debug...') + // } + + } catch(err) { + console.log(err); + // Or Throw an error + } } + let myData = [ { "lat": 40.757339, @@ -128,4 +180,6 @@ let myData = [ }, ] -add_data('myUserId', JSON.stringify(myData)) +// addData('myUserId', JSON.stringify(myData)) + +findMatch('myUserId'); diff --git a/enclave/safetrace/app/src/networking/ipc_listener.rs b/enclave/safetrace/app/src/networking/ipc_listener.rs index 094c161..05f55f1 100644 --- a/enclave/safetrace/app/src/networking/ipc_listener.rs +++ b/enclave/safetrace/app/src/networking/ipc_listener.rs @@ -61,16 +61,29 @@ pub(self) mod handling { esgx::equote as equote_tools, attestation_service::{service::AttestationService, constants::ATTESTATION_SERVICE_URL}, }; + use enigma_types::{EnclaveReturn}; + extern { - fn ecall_add_personal_data( - eid: sgx_enclave_id_t, - ret: *mut sgx_status_t, - encryptedUserId: *const u8, - encryptedUserId_len: usize, - encryptedData: *const u8, - encryptedData_len: usize, - userPubKey: &[u8; 64]) -> sgx_status_t; + fn ecall_add_personal_data( + eid: sgx_enclave_id_t, + ret: *mut sgx_status_t, + encryptedUserId: *const u8, + encryptedUserId_len: usize, + encryptedData: *const u8, + encryptedData_len: usize, + userPubKey: &[u8; 64]) -> sgx_status_t; + } + + extern { + fn ecall_find_match( + eid: sgx_enclave_id_t, + ret: *mut sgx_status_t, + encryptedUserId: *const u8, + encryptedUserId_len: usize, + userPubKey: &[u8; 64], + serialized_ptr: *mut u64 + ) -> sgx_status_t; } type ResponseResult = Result; @@ -127,7 +140,7 @@ pub(self) mod handling { // TODO //#[logfn(DEBUG)] - pub fn add_personal_data( input: IpcInput, eid: sgx_enclave_id_t) -> ResponseResult { + pub fn add_personal_data(input: IpcInputData, eid: sgx_enclave_id_t) -> ResponseResult { let mut ret = sgx_status_t::SGX_SUCCESS; let encrypted_userid = input.encrypted_userid.from_hex()?; @@ -149,8 +162,46 @@ pub(self) mod handling { // TODO //#[logfn(DEBUG)] - pub fn find_match( input: IpcInput, eid: sgx_enclave_id_t) -> ResponseResult { - let result = IpcResults::FindMatch { status: Status::Passed }; + pub fn find_match( input: IpcInputMatch, eid: sgx_enclave_id_t) -> ResponseResult { + + let mut ret = sgx_status_t::SGX_SUCCESS; + let mut serialized_ptr = 0u64; + let encrypted_userid = input.encrypted_userid.from_hex()?; + let mut user_pub_key = [0u8; 64]; + user_pub_key.clone_from_slice(&input.user_pub_key.from_hex()?); + + let status = unsafe { + ecall_find_match( + eid, + &mut ret as *mut sgx_status_t, + encrypted_userid.as_ptr() as * const u8, + encrypted_userid.len(), + &user_pub_key, + &mut serialized_ptr as *mut u64 + ) + }; + + let box_ptr = serialized_ptr as *mut Box<[u8]>; + let part = unsafe { Box::from_raw(box_ptr) }; + + let mut des = Deserializer::new(&part[..]); + let res: Value = Deserialize::deserialize(&mut des).unwrap(); + + println!("HERE"); + println!("{:?}", res); + let matches = serde_json::from_value::>(res)?; + + //let output = res.as_array().unwrap().clone(); + + // // TODO: Should not panic, propagate error instead + // let output_json = match String::from_utf8(output) { + // Ok(v) => v, + // Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + // }; + + //println!("{}", output_json); + + let result = IpcResults::FindMatch { status: Status::Passed, matches: matches}; Ok(IpcResponse::FindMatch { result }) } diff --git a/enclave/safetrace/app/src/networking/messages.rs b/enclave/safetrace/app/src/networking/messages.rs index 72be19e..ba898fd 100644 --- a/enclave/safetrace/app/src/networking/messages.rs +++ b/enclave/safetrace/app/src/networking/messages.rs @@ -11,6 +11,14 @@ pub enum Status { Passed = 0, } +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct GeolocationTime { + lat: f32, + lng: f32, + startTS: i32, + endTS: i32, +} + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct IpcMessageRequest { pub id: String, @@ -46,7 +54,7 @@ pub enum IpcResults { #[serde(rename = "result")] DHKey { taskPubKey: String, sig: String }, AddPersonalData { status: Status }, - FindMatch { status: Status }, + FindMatch { status: Status, matches: Vec }, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -54,17 +62,23 @@ pub enum IpcResults { pub enum IpcRequest { GetEnclaveReport, NewTaskEncryptionKey { userPubKey: String }, - AddPersonalData { input: IpcInput }, - FindMatch { input: IpcInput }, + AddPersonalData { input: IpcInputData }, + FindMatch { input: IpcInputMatch }, } #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct IpcInput { +pub struct IpcInputData { #[serde(rename = "encryptedUserId")] pub encrypted_userid: String, #[serde(rename = "encryptedData")] pub encrypted_data: String, #[serde(rename = "userPubKey")] pub user_pub_key: String, } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct IpcInputMatch { + #[serde(rename = "encryptedUserId")] pub encrypted_userid: String, + #[serde(rename = "userPubKey")] pub user_pub_key: String, +} + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct IpcStatusResult { pub address: String, diff --git a/enclave/safetrace/enclave/Cargo.toml b/enclave/safetrace/enclave/Cargo.toml index b56a194..66ab019 100644 --- a/enclave/safetrace/enclave/Cargo.toml +++ b/enclave/safetrace/enclave/Cargo.toml @@ -2,6 +2,7 @@ name = "safetrace-enclave" version = "1.0.0" authors = ["Enigma MPC"] +edition = "2018" [lib] name = "safetraceenclave" @@ -20,6 +21,8 @@ enigma-runtime-t = { git = "https://github.com/enigmampc/enigma-core.git", branc # rustc-hex = { version = "2.0", default-features = false } serde = { git = "https://github.com/mesalock-linux/serde-sgx.git", rev = "sgx_1.0.9", features=["serde_derive"] } serde_json = { git = "https://github.com/enigmampc/serde-json-sgx.git", rev = "1.0.39-sgx-1.0.9" } +rmp-serde = {git = "https://github.com/enigmampc/msgpack-rust.git", rev = "0.14.0-sgx-1.0.9" } + # serde_cbor = { git = "https://github.com/mesalock-linux/cbor-sgx.git", rev = "sgx_1.0.9", default-features = false, features=["mesalock_sgx"] } lazy_static = {version = "1.4.0", features = ["spin_no_std"] } diff --git a/enclave/safetrace/enclave/Enclave.edl b/enclave/safetrace/enclave/Enclave.edl index cf788d5..4e3ee15 100644 --- a/enclave/safetrace/enclave/Enclave.edl +++ b/enclave/safetrace/enclave/Enclave.edl @@ -49,6 +49,12 @@ enclave { public void ecall_get_signing_address([out] uint8_t arr[20]); + public sgx_status_t ecall_find_match( + [in, size=encryptedUserId_len] const uint8_t* encryptedUserId, + size_t encryptedUserId_len, + [in] uint8_t user_key[64], + [out] uint64_t* serialized_ptr); + }; untrusted { uint64_t ocall_save_to_memory([in, count=data_len] const uint8_t* data_ptr, size_t data_len); diff --git a/enclave/safetrace/enclave/src/data.rs b/enclave/safetrace/enclave/src/data.rs index 213783b..18244cf 100644 --- a/enclave/safetrace/enclave/src/data.rs +++ b/enclave/safetrace/enclave/src/data.rs @@ -8,24 +8,36 @@ use std::string::String; use std::string::ToString; use std::vec::Vec; use std::str; -use serde_json::{Value}; +use serde_json::{Value, json}; use serde::{Deserialize, Serialize}; +use rmp_serde::{Deserializer, Serializer}; + use sgx_tseal::{SgxSealedData}; use sgx_types::marker::ContiguousMemory; use std::untrusted::fs::File; use std::io::{Read, Write, self}; - - use sgx_types::{sgx_status_t, sgx_sealed_data_t}; +pub enum Error { + SliceError, + UnsealError(sgx_status_t), + SerializeError, + Other +} + +// TODO: Do proper mapping, using a generic for now +impl From for EnclaveError { + fn from(other: Error) -> EnclaveError { + EnclaveError::SystemError(MessagingError{ err: "Error unsealing data".to_string() }) + } +} pub const SEAL_LOG_SIZE: usize = 4096; // Structs #[derive(Serialize, Deserialize, Clone, Debug)] pub struct GeolocationTime { - #[serde(default)] lat: f32, lng: f32, startTS: i32, @@ -61,13 +73,12 @@ pub fn decrypt_data(data: &[u8], key: &DhKey) -> Result, EnclaveError> { } } -#[no_mangle] pub fn create_sealeddata_for_serializable(data: &UserLocations, sealed_log_out: &mut [u8; SEAL_LOG_SIZE]) -> enigma_types::EnclaveReturn { let encoded_vec = serde_json::to_vec(&data).unwrap(); let encoded_slice = encoded_vec.as_slice(); - println!("Length of encoded slice: {}", encoded_slice.len()); - println!("Encoded slice: {:?}", encoded_slice); + // println!("Length of encoded slice: {}", encoded_slice.len()); + // println!("Encoded slice: {:?}", encoded_slice); let aad: [u8; 0] = [0_u8; 0]; let result = SgxSealedData::<[u8]>::seal_data(&aad, encoded_slice); @@ -83,38 +94,20 @@ pub fn create_sealeddata_for_serializable(data: &UserLocations, sealed_log_out: return EnclaveReturn::SgxError; } - println!("{:?}", data); - EnclaveReturn::Success } -#[no_mangle] -pub extern "C" fn verify_sealeddata_for_serializable(sealed_log: * mut u8, sealed_log_size: u32) -> sgx_status_t { - - let opt = from_sealed_log_for_slice::(sealed_log, sealed_log_size); - let sealed_data = match opt { - Some(x) => x, - None => { - return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; - }, - }; - - let result = sealed_data.unseal_data(); - let unsealed_data = match result { - Ok(x) => x, - Err(ret) => { - return ret; - }, - }; +pub fn recover_sealeddata_for_serializable(sealed_log: * mut u8, sealed_log_size: u32) -> Result { + let sealed_data = from_sealed_log_for_slice::(sealed_log, sealed_log_size).ok_or(Error::SliceError)?; + let unsealed_data = sealed_data.unseal_data().map_err(|err| Error::UnsealError(err))?; let encoded_slice = unsealed_data.get_decrypt_txt(); - println!("Length of encoded slice: {}", encoded_slice.len()); - println!("Encoded slice: {:?}", encoded_slice); - let data: UserLocations = serde_json::from_slice(encoded_slice).unwrap(); - println!("{:?}", data); + // println!("Length of encoded slice: {}", encoded_slice.len()); + // println!("Encoded slice: {:?}", encoded_slice); + let data: UserLocations = serde_json::from_slice(encoded_slice).unwrap(); - sgx_status_t::SGX_SUCCESS + Ok(data) } @@ -131,7 +124,7 @@ fn from_sealed_log_for_slice<'a, T: Copy + ContiguousMemory>(sealed_log: * mut u } -// file system +// Save sealed data to disk pub fn save_sealed_data(path: &str, sealed_data: &[u8]) { let opt = File::create(path); if opt.is_ok() { @@ -146,6 +139,7 @@ pub fn save_sealed_data(path: &str, sealed_data: &[u8]) { } } +// Load sealed data from disk pub fn load_sealed_data(path: &str, sealed_data: &mut [u8]) { let opt = File::open(path); if opt.is_ok() { @@ -160,7 +154,7 @@ pub fn load_sealed_data(path: &str, sealed_data: &mut [u8]) { } } -pub fn ecall_add_personal_data_internal( +pub fn add_personal_data_internal( encryptedUserId: &[u8], encryptedData: &[u8], userPubKey: &PubKey, @@ -168,44 +162,73 @@ pub fn ecall_add_personal_data_internal( println!("Add personal data inside the enclave"); - // let decrypted_userid = decrypt_userid(encryptedUserId, &dhKey)?; - // let decrypted_data = decrypt_data(encryptedData, &dhKey)?; - - // // //let userid = u8_to_string(decrypt_userid)?; - // let userid = match str::from_utf8(&decrypted_userid) { - // Ok(v) => v, - // Err(e) => panic!("Invalid UTF-8 sequence: {}", e), - // }; + // Decrypt inputs using dhKey + let decrypted_userid = decrypt_userid(encryptedUserId, dhKey)?; + let decrypted_data = decrypt_data(encryptedData, dhKey)?; - // // let userid = std::str::from_utf8(decrypted_userid)?; + // TODO: Should not panic, propagate error instead + let userid = match str::from_utf8(&decrypted_userid) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; - // let mut inputData: Vec = serde_json::from_slice(&decrypted_data).unwrap(); - // let userData = UserLocations { - // user_id: userid.to_string(), - // locations: inputData, - // }; + // Deserialize decrypted input data into expected format + let mut inputData: Vec = serde_json::from_slice(&decrypted_data).unwrap(); - // let mut sealed_log_in = [0u8; SEAL_LOG_SIZE]; + // Construct user data + let userData = UserLocations { + user_id: userid.to_string(), + locations: inputData, + }; - // create_sealeddata_for_serializable(&userData, &mut sealed_log_in); - // let p = String::from("data.sealed"); - // save_sealed_data(&p, &sealed_log_in); + // Seal the data and store it on disk + let mut sealed_log_in = [0u8; SEAL_LOG_SIZE]; + create_sealeddata_for_serializable(&userData, &mut sealed_log_in); + let p = String::from("data.sealed"); + save_sealed_data(&p, &sealed_log_in); - // println!("{:?}", userData); + // Retrieve sealed data let p = String::from("data.sealed"); + let mut sealed_log_out: [u8; SEAL_LOG_SIZE] = [0; SEAL_LOG_SIZE]; + load_sealed_data(&p, &mut sealed_log_out); + + let sealed_log = sealed_log_out.as_mut_ptr(); + let data = recover_sealeddata_for_serializable(sealed_log, SEAL_LOG_SIZE as u32)?; + println!("{:?}", data); + + Ok(()) +} + +pub fn find_match_internal( + encryptedUserId: &[u8], + userPubKey: &PubKey, + dhKey: &DhKey) -> Result, EnclaveError> { + + // Decrypt inputs using dhKey + let decrypted_userid = decrypt_userid(encryptedUserId, dhKey)?; + // TODO: Should not panic, propagate error instead + let userid = match str::from_utf8(&decrypted_userid) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; + + // Retrieve sealed data + let p = String::from("data.sealed"); let mut sealed_log_out: [u8; SEAL_LOG_SIZE] = [0; SEAL_LOG_SIZE]; load_sealed_data(&p, &mut sealed_log_out); - // unseal data - // let unsealed_data = SecretKeyStorage::unseal_key(&mut sealed_log_out).unwrap(); - // let unsealed_data = unsealeddata_for_serializable(&mut sealed_log_out)?; let sealed_log = sealed_log_out.as_mut_ptr(); - verify_sealeddata_for_serializable(sealed_log, SEAL_LOG_SIZE as u32); + let data = recover_sealeddata_for_serializable(sealed_log, SEAL_LOG_SIZE as u32)?; + println!("{:?}", data.locations); - // println!("{:?}", unsealed_data); + let mut results = data.iter().filter(|item| item.user_id != userid).filter(|item| item.lat > 0 ).collect(); + let mut buf = Vec::new(); + //let val = serde_json::to_value(data.locations).map_err(|_| Error::SerializeError)?; + let val = json!([]); + val.serialize(&mut Serializer::new(&mut buf)).map_err(|_| Error::SerializeError)?; - Ok(()) + Ok(buf) } \ No newline at end of file diff --git a/enclave/safetrace/enclave/src/errors_t.rs b/enclave/safetrace/enclave/src/errors_t.rs index 9dc827d..c7bc329 100644 --- a/enclave/safetrace/enclave/src/errors_t.rs +++ b/enclave/safetrace/enclave/src/errors_t.rs @@ -112,7 +112,9 @@ pub enum EnclaveError { used_gas: u64, err: FailedTaskError }, - SystemError(EnclaveSystemError) + SystemError(EnclaveSystemError), + BadUserId, + UnsealError } impl ::std::fmt::Display for EnclaveError { @@ -245,7 +247,8 @@ impl Into for EnclaveError { // KeyProvisionError { .. } => EnclaveReturn::KeyProvisionError, } - } + }, + BadUserId } } } diff --git a/enclave/safetrace/enclave/src/keys_t.rs b/enclave/safetrace/enclave/src/keys_t.rs index ccf669f..3f1ccac 100644 --- a/enclave/safetrace/enclave/src/keys_t.rs +++ b/enclave/safetrace/enclave/src/keys_t.rs @@ -9,7 +9,7 @@ use std::{sync::SgxMutex, vec::Vec}; lazy_static! { pub static ref DH_KEYS: SgxMutex, DhKey>> = SgxMutex::new(HashMap::new()); } -pub(crate) unsafe fn ecall_get_user_key_internal(sig: &mut [u8; 65], user_pubkey: &PubKey) -> Result, EnclaveError> { +pub(crate) unsafe fn get_user_key_internal(sig: &mut [u8; 65], user_pubkey: &PubKey) -> Result, EnclaveError> { let keys = KeyPair::new()?; let req = UserMessage::new(keys.get_pubkey()); *sig = SIGNING_KEY.sign(&req.to_sign())?; diff --git a/enclave/safetrace/enclave/src/lib.rs b/enclave/safetrace/enclave/src/lib.rs index 37d4bc2..b157ba0 100644 --- a/enclave/safetrace/enclave/src/lib.rs +++ b/enclave/safetrace/enclave/src/lib.rs @@ -69,8 +69,8 @@ mod keys_t; // mod traits; use sgx_types::*; -use keys_t::{ecall_get_user_key_internal}; -use data::ecall_add_personal_data_internal; +use keys_t::{get_user_key_internal}; +use data::{add_personal_data_internal, find_match_internal}; // use storage::*; use enigma_types::{PubKey, DhKey, EnclaveReturn}; use enigma_tools_t::{ @@ -119,7 +119,7 @@ fn get_sealed_keys_wrapper() -> asymmetric::KeyPair { #[no_mangle] pub unsafe extern "C" fn ecall_get_user_key(sig: &mut [u8; 65], user_pubkey: &[u8; 64], serialized_ptr: *mut u64) -> EnclaveReturn { println!("Get User Key called inside enclave"); - let msg = match ecall_get_user_key_internal(sig, user_pubkey) { + let msg = match get_user_key_internal(sig, user_pubkey) { Ok(msg) => msg, Err(e) => return e.into(), }; @@ -155,6 +155,34 @@ pub unsafe extern "C" fn ecall_add_personal_data( Err(e) => return e.into(), } - let result = ecall_add_personal_data_internal(encryptedUserId, encryptedData, userPubKey, &io_key); + let result = add_personal_data_internal(encryptedUserId, encryptedData, userPubKey, &io_key); + + EnclaveReturn::Success +} + +#[no_mangle] +pub unsafe extern "C" fn ecall_find_match( + encryptedUserId: *const u8, + encryptedUserId_len: usize, + userPubKey: &[u8; 64], + serialized_ptr: *mut u64) -> EnclaveReturn { + + let encryptedUserId = slice::from_raw_parts(encryptedUserId, encryptedUserId_len); + + let io_key; + match get_io_key(userPubKey) { + Ok(v) => io_key = v, + Err(e) => return e.into(), + } + + let msg = match find_match_internal(encryptedUserId, userPubKey, &io_key) { + Ok(msg) => msg, + Err(e) => return e.into(), + }; + *serialized_ptr = match ocalls_t::save_to_untrusted_memory(&msg[..]) { + Ok(ptr) => ptr, + Err(e) => return e.into(), + }; + EnclaveReturn::Success } \ No newline at end of file From 24c6b77f91f899204b53724b4c1eb6753fafc5b8 Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Wed, 1 Apr 2020 04:26:09 -0500 Subject: [PATCH 06/11] BLD: implementation of find_match in enclave --- .../app/src/networking/ipc_listener.rs | 2 - enclave/safetrace/enclave/src/auto_ffi.rs | 13 ++ enclave/safetrace/enclave/src/data.rs | 160 +++++++++++------- 3 files changed, 108 insertions(+), 67 deletions(-) create mode 100644 enclave/safetrace/enclave/src/auto_ffi.rs diff --git a/enclave/safetrace/app/src/networking/ipc_listener.rs b/enclave/safetrace/app/src/networking/ipc_listener.rs index 05f55f1..b85eeac 100644 --- a/enclave/safetrace/app/src/networking/ipc_listener.rs +++ b/enclave/safetrace/app/src/networking/ipc_listener.rs @@ -187,8 +187,6 @@ pub(self) mod handling { let mut des = Deserializer::new(&part[..]); let res: Value = Deserialize::deserialize(&mut des).unwrap(); - println!("HERE"); - println!("{:?}", res); let matches = serde_json::from_value::>(res)?; //let output = res.as_array().unwrap().clone(); diff --git a/enclave/safetrace/enclave/src/auto_ffi.rs b/enclave/safetrace/enclave/src/auto_ffi.rs new file mode 100644 index 0000000..4e71553 --- /dev/null +++ b/enclave/safetrace/enclave/src/auto_ffi.rs @@ -0,0 +1,13 @@ +/* automatically generated by rust-bindgen */ + +#![allow(dead_code)] +use enigma_types::*; +use sgx_types::*; + +extern "C" { + pub fn ocall_save_to_memory( + retval: *mut u64, + data_ptr: *const u8, + data_len: size_t, + ) -> sgx_status_t; +} diff --git a/enclave/safetrace/enclave/src/data.rs b/enclave/safetrace/enclave/src/data.rs index 18244cf..9182aa7 100644 --- a/enclave/safetrace/enclave/src/data.rs +++ b/enclave/safetrace/enclave/src/data.rs @@ -1,24 +1,30 @@ -// use serde::{Serialize, Deserialize}; -// use std::{slice}; -// use std::string::String; use enigma_tools_t::common::errors_t::{EnclaveError, EnclaveError::*, FailedTaskError::*, EnclaveSystemError::*}; use enigma_crypto::{symmetric::decrypt}; use enigma_types::{DhKey, PubKey, EnclaveReturn}; -use std::string::String; -use std::string::ToString; -use std::vec::Vec; -use std::str; +use std::{ + string::{String,ToString}, + vec::Vec, + str, + collections::HashMap +}; + use serde_json::{Value, json}; use serde::{Deserialize, Serialize}; use rmp_serde::{Deserializer, Serializer}; - use sgx_tseal::{SgxSealedData}; use sgx_types::marker::ContiguousMemory; use std::untrusted::fs::File; use std::io::{Read, Write, self}; use sgx_types::{sgx_status_t, sgx_sealed_data_t}; +pub const DATAFILE: &str = "data.sealed"; +pub const TOVERLAP: i32 = 300; // 5min * 60s minimum overlap +pub const DISTANCE: f64 = 10.0; // in meters +pub const EARTH_RADIUS: f64 = 6371000.0; // in meters +pub const SEAL_LOG_SIZE: usize = 0x100000; // Maximum data can seal in bytes + + pub enum Error { SliceError, UnsealError(sgx_status_t), @@ -33,30 +39,16 @@ impl From for EnclaveError { } } -pub const SEAL_LOG_SIZE: usize = 4096; // Structs #[derive(Serialize, Deserialize, Clone, Debug)] pub struct GeolocationTime { - lat: f32, - lng: f32, + lat: f64, + lng: f64, startTS: i32, endTS: i32, } -#[derive(Serialize, Deserialize, Clone, Debug)] -pub struct UserLocations { - pub locations: Vec, - pub user_id: String, -} - -#[derive(Serialize, Deserialize, Clone, Default, Debug)] -pub struct UserLocationsArray { - key: u32, - rand: [u8; 16], - vec: Vec -} - pub fn decrypt_userid(userid: &[u8], key: &DhKey) -> Result, EnclaveError> { if userid.is_empty(){ Err(FailedTaskError(InputError { message: "encryptedUserId is empty".to_string()})) @@ -73,7 +65,8 @@ pub fn decrypt_data(data: &[u8], key: &DhKey) -> Result, EnclaveError> { } } -pub fn create_sealeddata_for_serializable(data: &UserLocations, sealed_log_out: &mut [u8; SEAL_LOG_SIZE]) -> enigma_types::EnclaveReturn { +//pub fn create_sealeddata_for_serializable(data: &UserLocations, sealed_log_out: &mut [u8; SEAL_LOG_SIZE]) -> enigma_types::EnclaveReturn { +pub fn create_sealeddata_for_serializable(data: HashMap>, sealed_log_out: &mut [u8; SEAL_LOG_SIZE]) -> enigma_types::EnclaveReturn { let encoded_vec = serde_json::to_vec(&data).unwrap(); let encoded_slice = encoded_vec.as_slice(); @@ -97,7 +90,7 @@ pub fn create_sealeddata_for_serializable(data: &UserLocations, sealed_log_out: EnclaveReturn::Success } -pub fn recover_sealeddata_for_serializable(sealed_log: * mut u8, sealed_log_size: u32) -> Result { +pub fn recover_sealeddata_for_serializable(sealed_log: * mut u8, sealed_log_size: u32) -> Result>, Error> { let sealed_data = from_sealed_log_for_slice::(sealed_log, sealed_log_size).ok_or(Error::SliceError)?; let unsealed_data = sealed_data.unseal_data().map_err(|err| Error::UnsealError(err))?; @@ -105,7 +98,8 @@ pub fn recover_sealeddata_for_serializable(sealed_log: * mut u8, sealed_log_size // println!("Length of encoded slice: {}", encoded_slice.len()); // println!("Encoded slice: {:?}", encoded_slice); - let data: UserLocations = serde_json::from_slice(encoded_slice).unwrap(); + + let data: HashMap> = serde_json::from_slice(encoded_slice).unwrap(); Ok(data) } @@ -140,16 +134,35 @@ pub fn save_sealed_data(path: &str, sealed_data: &[u8]) { } // Load sealed data from disk -pub fn load_sealed_data(path: &str, sealed_data: &mut [u8]) { - let opt = File::open(path); - if opt.is_ok() { - debug_println!("Created file => {} ", path); - let mut file = opt.unwrap(); - let result = file.read(sealed_data); - if result.is_ok() { - debug_println!("success writting to file! "); - } else { - debug_println!("error writting to file! "); +pub fn load_sealed_data(path: &str, sealed_data: &mut [u8]) -> Result<(), String> { + let mut file = match File::open(path) { + Err(why) => return Err("Error opening the file".to_string()), + Ok(file) => file, + }; + debug_println!("Created file => {} ", path); + + let result = file.read(sealed_data); + if result.is_ok() { + debug_println!("success reading from file! "); + } else { + debug_println!("error reading from file! "); + } + Ok(()) + +} + +pub fn unseal_data_wrapper() -> Result>, Error> { + let p = DATAFILE; + let mut sealed_log_out = [0u8; SEAL_LOG_SIZE]; + match load_sealed_data(&p, &mut sealed_log_out) { + Ok(_) => { + let sealed_log = sealed_log_out.as_mut_ptr(); + let mut data = recover_sealeddata_for_serializable(sealed_log, SEAL_LOG_SIZE as u32)?; + Ok(data) + }, + Err(err) => { + let mut data = HashMap::new(); + Ok(data) } } } @@ -175,27 +188,21 @@ pub fn add_personal_data_internal( // Deserialize decrypted input data into expected format let mut inputData: Vec = serde_json::from_slice(&decrypted_data).unwrap(); - // Construct user data - let userData = UserLocations { - user_id: userid.to_string(), - locations: inputData, - }; + let mut data = unseal_data_wrapper()?; + //let mut data = HashMap::new(); + + data.insert(userid.to_string(), inputData); // Seal the data and store it on disk let mut sealed_log_in = [0u8; SEAL_LOG_SIZE]; - create_sealeddata_for_serializable(&userData, &mut sealed_log_in); - let p = String::from("data.sealed"); - save_sealed_data(&p, &sealed_log_in); + create_sealeddata_for_serializable(data, &mut sealed_log_in); + let p = DATAFILE; + save_sealed_data(&p, &sealed_log_in); - // Retrieve sealed data - let p = String::from("data.sealed"); - let mut sealed_log_out: [u8; SEAL_LOG_SIZE] = [0; SEAL_LOG_SIZE]; - load_sealed_data(&p, &mut sealed_log_out); - - let sealed_log = sealed_log_out.as_mut_ptr(); - let data = recover_sealeddata_for_serializable(sealed_log, SEAL_LOG_SIZE as u32)?; - println!("{:?}", data); + let mut newdata = unseal_data_wrapper()?; + println!("This is what we got"); + println!("{:?}", newdata); Ok(()) } @@ -214,20 +221,43 @@ pub fn find_match_internal( Err(e) => panic!("Invalid UTF-8 sequence: {}", e), }; - // Retrieve sealed data - let p = String::from("data.sealed"); - let mut sealed_log_out: [u8; SEAL_LOG_SIZE] = [0; SEAL_LOG_SIZE]; - load_sealed_data(&p, &mut sealed_log_out); - - let sealed_log = sealed_log_out.as_mut_ptr(); - let data = recover_sealeddata_for_serializable(sealed_log, SEAL_LOG_SIZE as u32)?; - println!("{:?}", data.locations); - - let mut results = data.iter().filter(|item| item.user_id != userid).filter(|item| item.lat > 0 ).collect(); + let data = unseal_data_wrapper()?; + + let mut results = Vec::new(); + + // This is the algorithm to find overlaps in time and space, defined in time by TOVERLAP (in seconds) + // and in space by DISTANCE (in meters) + // We iterate over all values in the set, excluding the user we are looking for matches. + // For all of them, we iterate over all locations and compare them with all locations from the user + for (key, val) in data.iter() { + if key != &userid { + for d in data[userid].clone() { + for e in val.iter() { + // It's easier to find overlaps in time because it's a direct comparison of integers + // so handle this first: + // Both time intervals have to be larger than the minumum time overlap TOVERLAP + // and both start times + TOVERLAP have to be smaller than the other end times + if d.endTS - d.startTS > TOVERLAP && + e.endTS - e.startTS > TOVERLAP && + d.startTS + TOVERLAP < e.endTS && e.startTS + TOVERLAP < d.endTS { + // We start comparing distance between latitudes. Each degree of lat is aprox + // 111 kms (range varies between 110.567 km at the equator to 111.699 km at the poles) + // The distance between two locations will be equal or larger than the distance between + // their latitudes (or the distance between lats will be smaller than the distance * cos(45)) + if (e.lat - d.lat).abs() * 111000.0 < DISTANCE * 0.71 { + // then we can run a more computationally expensive and precise comparison + if (e.lat.sin()*d.lat.sin()+e.lat.cos()*d.lat.cos()*(e.lng-d.lng).cos()).acos() * EARTH_RADIUS < DISTANCE { + results.push(e); + } + } + } + } + } + } + } let mut buf = Vec::new(); - //let val = serde_json::to_value(data.locations).map_err(|_| Error::SerializeError)?; - let val = json!([]); + let val = serde_json::to_value(results).map_err(|_| Error::SerializeError)?; val.serialize(&mut Serializer::new(&mut buf)).map_err(|_| Error::SerializeError)?; Ok(buf) From 253cecd93166426876115df39eaf795d29684cf4 Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Wed, 1 Apr 2020 06:40:11 -0500 Subject: [PATCH 07/11] BLD: added testResult field --- client/data.js | 33 ++++++ client/index.js | 146 ++++++++++---------------- enclave/safetrace/enclave/src/data.rs | 41 ++++---- 3 files changed, 113 insertions(+), 107 deletions(-) create mode 100644 client/data.js diff --git a/client/data.js b/client/data.js new file mode 100644 index 0000000..71ae004 --- /dev/null +++ b/client/data.js @@ -0,0 +1,33 @@ +module.exports.DataUser1 = [ + { + "lat": 40.757339, + "lng": -73.985992, + "startTS": 1583064000, + "endTS": 1583067600, + "testResult": false, + }, + { + "lat": 40.793840, + "lng": -73.956900, + "startTS": 1583150400, + "endTS": 1583154000, + "testResult": false, + }, +] + +module.exports.DataUser2 = [ + { + "lat": 41.757339, + "lng": -73.985992, + "startTS": 1583064000, + "endTS": 1583067600, + "testResult": true, + }, + { + "lat": 40.793840, + "lng": -73.956900, + "startTS": 1583150400, + "endTS": 1583154000, + "testResult": true, + }, +] \ No newline at end of file diff --git a/client/index.js b/client/index.js index 3c562ee..63eeee8 100644 --- a/client/index.js +++ b/client/index.js @@ -4,6 +4,7 @@ const EthCrypto = require('eth-crypto'); const jaysonBrowserClient = require('jayson/lib/client/browser'); const enigma = require('enigma-js/lib/enigma-js.node'); const web3utils = require('web3-utils'); +const data = require('./data.js'); const JSON_RPC_Server='http://localhost:8080'; @@ -47,39 +48,44 @@ function getClientKeys(seed='') { return {privateKey, publicKey}; } +async function getEncryptionKey(publicKey) { + const getEncryptionKeyResult = await new Promise((resolve, reject) => { + client.request('newTaskEncryptionKey', {userPubKey: publicKey}, + (err, response) => { + if (err) { + reject(err); + return; + } + resolve(response); + }); + }); + + const {result, id} = getEncryptionKeyResult; + const {taskPubKey, sig} = result; + // ToDo: verify signature + return taskPubKey; +} + +function encrypt(taskPubKey, privateKey, variable){ + // Generate derived key from enclave public encryption key and user's private key + const derivedKey = enigma.utils.getDerivedKey(taskPubKey, privateKey); + // Encrypt function and ABI-encoded args + return enigma.utils.encryptMessage(derivedKey, variable); +} + + async function addData(userId, data){ let {publicKey, privateKey} = getClientKeys(); try { - const getWorkerEncryptionKeyResult = await new Promise((resolve, reject) => { - client.request('newTaskEncryptionKey', {userPubKey: publicKey}, - (err, response) => { - if (err) { - reject(err); - return; - } - resolve(response); - }); - }); - - const {result, id} = getWorkerEncryptionKeyResult; - const {taskPubKey, sig} = result; - // ToDo: verify signature - - // Generate derived key from worker's encryption key and user's private key - const derivedKey = enigma.utils.getDerivedKey(taskPubKey, privateKey); - // Encrypt function and ABI-encoded args - const encryptedUserId = enigma.utils.encryptMessage(derivedKey, userId); - const encryptedData = enigma.utils.encryptMessage(derivedKey, data); - const msg = web3utils.soliditySha3( - {t: 'bytes', v: encryptedUserId}, - {t: 'bytes', v: encryptedData}, - ); + let taskPubKey = await getEncryptionKey(publicKey); + let encryptedUserId = encrypt(taskPubKey, privateKey, userId); + let encryptedData = encrypt(taskPubKey, privateKey, data); const addPersonalDataResult = await new Promise((resolve, reject) => { client.request('addPersonalData', { - encryptedUserId: encryptedUserId, + encryptedUserId: encryptedUserId, encryptedData: encryptedData, userPubKey: publicKey}, (err, response) => { @@ -91,17 +97,16 @@ async function addData(userId, data){ }); }); - const {addPersonalData} = addPersonalDataResult; - - if(addPersonalData.status == 0) { - console.log('Personal data added successfully to the enclave.'); - } else { - console.log('Something went wrong. Time to debug...') - } + const {addPersonalData} = addPersonalDataResult; + if(addPersonalData.status == 0) { + console.log('Personal data added successfully to the enclave.'); + } else { + console.log('Something went wrong. Time to debug...') + } } catch(err) { - console.log(err); - // Or Throw an error + console.log(err); + // Or throw an error } } @@ -110,28 +115,8 @@ async function findMatch(userId){ let {publicKey, privateKey} = getClientKeys(); try { - const getWorkerEncryptionKeyResult = await new Promise((resolve, reject) => { - client.request('newTaskEncryptionKey', {userPubKey: publicKey}, - (err, response) => { - if (err) { - reject(err); - return; - } - resolve(response); - }); - }); - - const {result, id} = getWorkerEncryptionKeyResult; - const {taskPubKey, sig} = result; - // ToDo: verify signature - - // Generate derived key from worker's encryption key and user's private key - const derivedKey = enigma.utils.getDerivedKey(taskPubKey, privateKey); - // Encrypt function and ABI-encoded args - const encryptedUserId = enigma.utils.encryptMessage(derivedKey, userId); - const msg = web3utils.soliditySha3( - {t: 'bytes', v: encryptedUserId}, - ); + let taskPubKey = await getEncryptionKey(publicKey); + let encryptedUserId = encrypt(taskPubKey, privateKey, userId); const findMatchResult = await new Promise((resolve, reject) => { client.request('findMatch', { @@ -146,40 +131,25 @@ async function findMatch(userId){ }); }); - console.log(findMatchResult); - console.log(findMatchResult.findMatch) - - // const {findMatch} = findMatchResult; - - // if(findMatch.status == 0) { - // console.log('Find Match operation successful'); - // console.log() - // } else { - // console.log('Something went wrong. Time to debug...') - // } - + if(findMatchResult.findMatch.status == 0) { + console.log('Find Match operation successful'); + if(findMatchResult.findMatch.matches.length){ + console.log('Find matches:'); + console.log(findMatchResult.findMatch.matches); + } else { + console.log('No matches'); + } + } else { + console.log('Something went wrong. Time to debug...') + } } catch(err) { - console.log(err); - // Or Throw an error + console.log(err); + // Or throw an error } } -let myData = [ - { - "lat": 40.757339, - "lng": -73.985992, - "startTS": 1583064000, - "endTS": 1583067600 - }, - { - "lat": 40.793840, - "lng": -73.956900, - "startTS": 1583150400, - "endTS": 1583154000 - }, -] - -// addData('myUserId', JSON.stringify(myData)) - -findMatch('myUserId'); +addData('user1', JSON.stringify(data.DataUser1)); +addData('user2', JSON.stringify(data.DataUser2)); + +findMatch('user1'); diff --git a/enclave/safetrace/enclave/src/data.rs b/enclave/safetrace/enclave/src/data.rs index 9182aa7..57b340e 100644 --- a/enclave/safetrace/enclave/src/data.rs +++ b/enclave/safetrace/enclave/src/data.rs @@ -19,10 +19,10 @@ use std::io::{Read, Write, self}; use sgx_types::{sgx_status_t, sgx_sealed_data_t}; pub const DATAFILE: &str = "data.sealed"; -pub const TOVERLAP: i32 = 300; // 5min * 60s minimum overlap -pub const DISTANCE: f64 = 10.0; // in meters -pub const EARTH_RADIUS: f64 = 6371000.0; // in meters -pub const SEAL_LOG_SIZE: usize = 0x100000; // Maximum data can seal in bytes +pub const TOVERLAP: i32 = 300; // 5min * 60s minimum overlap +pub const DISTANCE: f64 = 10.0; // in meters +pub const EARTH_RADIUS: f64 = 6371000.0; // in meters +pub const SEAL_LOG_SIZE: usize = 4096; // Maximum data can seal in bytes -> match pub enum Error { @@ -47,6 +47,7 @@ pub struct GeolocationTime { lng: f64, startTS: i32, endTS: i32, + testResult: bool } pub fn decrypt_userid(userid: &[u8], key: &DhKey) -> Result, EnclaveError> { @@ -233,21 +234,23 @@ pub fn find_match_internal( if key != &userid { for d in data[userid].clone() { for e in val.iter() { - // It's easier to find overlaps in time because it's a direct comparison of integers - // so handle this first: - // Both time intervals have to be larger than the minumum time overlap TOVERLAP - // and both start times + TOVERLAP have to be smaller than the other end times - if d.endTS - d.startTS > TOVERLAP && - e.endTS - e.startTS > TOVERLAP && - d.startTS + TOVERLAP < e.endTS && e.startTS + TOVERLAP < d.endTS { - // We start comparing distance between latitudes. Each degree of lat is aprox - // 111 kms (range varies between 110.567 km at the equator to 111.699 km at the poles) - // The distance between two locations will be equal or larger than the distance between - // their latitudes (or the distance between lats will be smaller than the distance * cos(45)) - if (e.lat - d.lat).abs() * 111000.0 < DISTANCE * 0.71 { - // then we can run a more computationally expensive and precise comparison - if (e.lat.sin()*d.lat.sin()+e.lat.cos()*d.lat.cos()*(e.lng-d.lng).cos()).acos() * EARTH_RADIUS < DISTANCE { - results.push(e); + if e.testResult { + // It's easier to find overlaps in time because it's a direct comparison of integers + // so handle this first: + // Both time intervals have to be larger than the minumum time overlap TOVERLAP + // and both start times + TOVERLAP have to be smaller than the other end times + if d.endTS - d.startTS > TOVERLAP && + e.endTS - e.startTS > TOVERLAP && + d.startTS + TOVERLAP < e.endTS && e.startTS + TOVERLAP < d.endTS { + // We start comparing distance between latitudes. Each degree of lat is aprox + // 111 kms (range varies between 110.567 km at the equator to 111.699 km at the poles) + // The distance between two locations will be equal or larger than the distance between + // their latitudes (or the distance between lats will be smaller than the distance * cos(45)) + if (e.lat - d.lat).abs() * 111000.0 < DISTANCE * 0.71 { + // then we can run a more computationally expensive and precise comparison + if (e.lat.sin()*d.lat.sin()+e.lat.cos()*d.lat.cos()*(e.lng-d.lng).cos()).acos() * EARTH_RADIUS < DISTANCE { + results.push(e); + } } } } From fa1688af2a8918ac3be84f2e81e572d57c0577cf Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Wed, 1 Apr 2020 07:55:19 -0500 Subject: [PATCH 08/11] BLD: finalizing enclave code --- client/data.js | 8 ++++---- client/index.js | 16 ++++++++++++++-- .../app/src/networking/ipc_listener.rs | 17 +---------------- .../safetrace/app/src/networking/messages.rs | 2 +- enclave/safetrace/enclave/src/data.rs | 13 ++++++------- 5 files changed, 26 insertions(+), 30 deletions(-) diff --git a/client/data.js b/client/data.js index 71ae004..895a6ff 100644 --- a/client/data.js +++ b/client/data.js @@ -2,15 +2,15 @@ module.exports.DataUser1 = [ { "lat": 40.757339, "lng": -73.985992, - "startTS": 1583064000, - "endTS": 1583067600, + "startTS": 1583064001, + "endTS": 1583067601, "testResult": false, }, { "lat": 40.793840, "lng": -73.956900, - "startTS": 1583150400, - "endTS": 1583154000, + "startTS": 1583150401, + "endTS": 1583154001, "testResult": false, }, ] diff --git a/client/index.js b/client/index.js index 63eeee8..2f89015 100644 --- a/client/index.js +++ b/client/index.js @@ -73,6 +73,15 @@ function encrypt(taskPubKey, privateKey, variable){ return enigma.utils.encryptMessage(derivedKey, variable); } +function decrypt(taskPubKey, privateKey, enc_variable){ + // Generate derived key from enclave public encryption key and user's private key + const derivedKey = enigma.utils.getDerivedKey(taskPubKey, privateKey); + // Decrypt function and ABI-encoded args + let outputHex = enigma.utils.decryptMessage(derivedKey, enc_variable); + let outputStr = enigma.utils.hexToAscii(outputHex); + return JSON.parse(outputStr); +} + async function addData(userId, data){ @@ -133,9 +142,12 @@ async function findMatch(userId){ if(findMatchResult.findMatch.status == 0) { console.log('Find Match operation successful'); - if(findMatchResult.findMatch.matches.length){ + + let output = decrypt(taskPubKey, privateKey, findMatchResult.findMatch.encryptedOutput); + + if(output.length){ console.log('Find matches:'); - console.log(findMatchResult.findMatch.matches); + console.log(output); } else { console.log('No matches'); } diff --git a/enclave/safetrace/app/src/networking/ipc_listener.rs b/enclave/safetrace/app/src/networking/ipc_listener.rs index b85eeac..7ee785f 100644 --- a/enclave/safetrace/app/src/networking/ipc_listener.rs +++ b/enclave/safetrace/app/src/networking/ipc_listener.rs @@ -184,22 +184,7 @@ pub(self) mod handling { let box_ptr = serialized_ptr as *mut Box<[u8]>; let part = unsafe { Box::from_raw(box_ptr) }; - let mut des = Deserializer::new(&part[..]); - let res: Value = Deserialize::deserialize(&mut des).unwrap(); - - let matches = serde_json::from_value::>(res)?; - - //let output = res.as_array().unwrap().clone(); - - // // TODO: Should not panic, propagate error instead - // let output_json = match String::from_utf8(output) { - // Ok(v) => v, - // Err(e) => panic!("Invalid UTF-8 sequence: {}", e), - // }; - - //println!("{}", output_json); - - let result = IpcResults::FindMatch { status: Status::Passed, matches: matches}; + let result = IpcResults::FindMatch { status: Status::Passed, encryptedOutput: part.to_hex()}; Ok(IpcResponse::FindMatch { result }) } diff --git a/enclave/safetrace/app/src/networking/messages.rs b/enclave/safetrace/app/src/networking/messages.rs index ba898fd..add5094 100644 --- a/enclave/safetrace/app/src/networking/messages.rs +++ b/enclave/safetrace/app/src/networking/messages.rs @@ -54,7 +54,7 @@ pub enum IpcResults { #[serde(rename = "result")] DHKey { taskPubKey: String, sig: String }, AddPersonalData { status: Status }, - FindMatch { status: Status, matches: Vec }, + FindMatch { status: Status, encryptedOutput: String }, } #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/enclave/safetrace/enclave/src/data.rs b/enclave/safetrace/enclave/src/data.rs index 57b340e..daf8e75 100644 --- a/enclave/safetrace/enclave/src/data.rs +++ b/enclave/safetrace/enclave/src/data.rs @@ -1,5 +1,5 @@ use enigma_tools_t::common::errors_t::{EnclaveError, EnclaveError::*, FailedTaskError::*, EnclaveSystemError::*}; -use enigma_crypto::{symmetric::decrypt}; +use enigma_crypto::{symmetric::decrypt, symmetric::encrypt}; use enigma_types::{DhKey, PubKey, EnclaveReturn}; use std::{ string::{String,ToString}, @@ -39,7 +39,6 @@ impl From for EnclaveError { } } - // Structs #[derive(Serialize, Deserialize, Clone, Debug)] pub struct GeolocationTime { @@ -249,7 +248,7 @@ pub fn find_match_internal( if (e.lat - d.lat).abs() * 111000.0 < DISTANCE * 0.71 { // then we can run a more computationally expensive and precise comparison if (e.lat.sin()*d.lat.sin()+e.lat.cos()*d.lat.cos()*(e.lng-d.lng).cos()).acos() * EARTH_RADIUS < DISTANCE { - results.push(e); + results.push(d.clone()); } } } @@ -259,9 +258,9 @@ pub fn find_match_internal( } } - let mut buf = Vec::new(); - let val = serde_json::to_value(results).map_err(|_| Error::SerializeError)?; - val.serialize(&mut Serializer::new(&mut buf)).map_err(|_| Error::SerializeError)?; + let serialized_results = serde_json::to_string(&results).map_err(|err| Error::SerializeError)?; + let array_u8_results = serialized_results.as_bytes(); + let encrypted_output = encrypt(array_u8_results, dhKey)?; - Ok(buf) + Ok(encrypted_output) } \ No newline at end of file From 38da18bb94e63de7d0e2bd73f3cecc6490bcf6e6 Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Wed, 1 Apr 2020 08:01:02 -0500 Subject: [PATCH 09/11] DOC: added source for matching algo --- enclave/safetrace/enclave/src/data.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/enclave/safetrace/enclave/src/data.rs b/enclave/safetrace/enclave/src/data.rs index daf8e75..359ed5f 100644 --- a/enclave/safetrace/enclave/src/data.rs +++ b/enclave/safetrace/enclave/src/data.rs @@ -245,6 +245,8 @@ pub fn find_match_internal( // 111 kms (range varies between 110.567 km at the equator to 111.699 km at the poles) // The distance between two locations will be equal or larger than the distance between // their latitudes (or the distance between lats will be smaller than the distance * cos(45)) + // Source: + // https://stackoverflow.com/questions/5031268/algorithm-to-find-all-latitude-longitude-locations-within-a-certain-distance-fro if (e.lat - d.lat).abs() * 111000.0 < DISTANCE * 0.71 { // then we can run a more computationally expensive and precise comparison if (e.lat.sin()*d.lat.sin()+e.lat.cos()*d.lat.cos()*(e.lng-d.lng).cos()).acos() * EARTH_RADIUS < DISTANCE { From ca978cfda38548ec11652ebeb2ca3cf1c4938aa0 Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Wed, 1 Apr 2020 08:06:59 -0500 Subject: [PATCH 10/11] MAINT: removing submodule and hello-rust --- .gitmodules | 4 - enclave/hello-rust/Makefile | 163 ------------------ enclave/hello-rust/app/Cargo.toml | 14 -- enclave/hello-rust/app/build.rs | 36 ---- enclave/hello-rust/app/src/main.rs | 74 -------- enclave/hello-rust/bin/readme.txt | 1 - enclave/hello-rust/enclave/Cargo.toml | 41 ----- enclave/hello-rust/enclave/Enclave.config.xml | 12 -- enclave/hello-rust/enclave/Enclave.edl | 28 --- enclave/hello-rust/enclave/Enclave.lds | 9 - .../hello-rust/enclave/Enclave_private.pem | 39 ----- enclave/hello-rust/enclave/Makefile | 32 ---- enclave/hello-rust/enclave/Xargo.toml | 91 ---------- enclave/hello-rust/enclave/src/lib.rs | 130 -------------- .../enclave/x86_64-unknown-linux-sgx.json | 31 ---- enclave/hello-rust/lib/readme.txt | 1 - enclave/hello-rust/rust-toolchain | 1 - enclave/incubator-teaclave-sgx-sdk | 1 - 18 files changed, 708 deletions(-) delete mode 100644 enclave/hello-rust/Makefile delete mode 100644 enclave/hello-rust/app/Cargo.toml delete mode 100644 enclave/hello-rust/app/build.rs delete mode 100644 enclave/hello-rust/app/src/main.rs delete mode 100644 enclave/hello-rust/bin/readme.txt delete mode 100644 enclave/hello-rust/enclave/Cargo.toml delete mode 100644 enclave/hello-rust/enclave/Enclave.config.xml delete mode 100644 enclave/hello-rust/enclave/Enclave.edl delete mode 100644 enclave/hello-rust/enclave/Enclave.lds delete mode 100644 enclave/hello-rust/enclave/Enclave_private.pem delete mode 100644 enclave/hello-rust/enclave/Makefile delete mode 100644 enclave/hello-rust/enclave/Xargo.toml delete mode 100644 enclave/hello-rust/enclave/src/lib.rs delete mode 100644 enclave/hello-rust/enclave/x86_64-unknown-linux-sgx.json delete mode 100644 enclave/hello-rust/lib/readme.txt delete mode 100644 enclave/hello-rust/rust-toolchain delete mode 160000 enclave/incubator-teaclave-sgx-sdk diff --git a/.gitmodules b/.gitmodules index f6be89f..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +0,0 @@ -[submodule "enclave/incubator-teaclave-sgx-sdk"] - path = enclave/incubator-teaclave-sgx-sdk - url = git@github.com:apache/incubator-teaclave-sgx-sdk.git - branch = v1.1.1-testing diff --git a/enclave/hello-rust/Makefile b/enclave/hello-rust/Makefile deleted file mode 100644 index d357ade..0000000 --- a/enclave/hello-rust/Makefile +++ /dev/null @@ -1,163 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -######## SGX SDK Settings ######## - -SGX_SDK ?= $(HOME)/.sgxsdk/sgxsdk -SGX_MODE ?= HW -SGX_ARCH ?= x64 - -ifeq ($(shell getconf LONG_BIT), 32) - SGX_ARCH := x86 -else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) - SGX_ARCH := x86 -endif - -ifeq ($(SGX_ARCH), x86) - SGX_COMMON_CFLAGS := -m32 - SGX_LIBRARY_PATH := $(SGX_SDK)/lib - SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign - SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r -else - SGX_COMMON_CFLAGS := -m64 - SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 - SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign - SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r -endif - -ifeq ($(SGX_DEBUG), 1) -ifeq ($(SGX_PRERELEASE), 1) -$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!) -endif -endif - - -ifeq ($(SGX_DEBUG), 1) - SGX_COMMON_CFLAGS += -O0 -g -else - SGX_COMMON_CFLAGS += -O2 -endif - -######## CUSTOM Settings ######## - -CUSTOM_LIBRARY_PATH := ./lib -CUSTOM_BIN_PATH := ./bin -CUSTOM_EDL_PATH := ../incubator-teaclave-sgx-sdk/edl -CUSTOM_COMMON_PATH := ../incubator-teaclave-sgx-sdk/common - -######## EDL Settings ######## - -Enclave_EDL_Files := enclave/Enclave_t.c enclave/Enclave_t.h app/Enclave_u.c app/Enclave_u.h - -######## APP Settings ######## - -App_Rust_Flags := --release -App_SRC_Files := $(shell find app/ -type f -name '*.rs') $(shell find app/ -type f -name 'Cargo.toml') -App_Include_Paths := -I ./app -I./include -I$(SGX_SDK)/include -I$(CUSTOM_EDL_PATH) -App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) - -App_Rust_Path := ./app/target/release -App_Enclave_u_Object :=app/libEnclave_u.a -App_Name := bin/app - -######## Enclave Settings ######## - -ifneq ($(SGX_MODE), HW) - Trts_Library_Name := sgx_trts_sim - Service_Library_Name := sgx_tservice_sim -else - Trts_Library_Name := sgx_trts - Service_Library_Name := sgx_tservice -endif -Crypto_Library_Name := sgx_tcrypto -KeyExchange_Library_Name := sgx_tkey_exchange -ProtectedFs_Library_Name := sgx_tprotected_fs - -RustEnclave_C_Files := $(wildcard ./enclave/*.c) -RustEnclave_C_Objects := $(RustEnclave_C_Files:.c=.o) -RustEnclave_Include_Paths := -I$(CUSTOM_COMMON_PATH)/inc -I$(CUSTOM_EDL_PATH) -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport -I$(SGX_SDK)/include/epid -I ./enclave -I./include - -RustEnclave_Link_Libs := -L$(CUSTOM_LIBRARY_PATH) -lcompiler-rt-patch -lenclave -RustEnclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(RustEnclave_Include_Paths) -RustEnclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ - -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ - -Wl,--start-group -lsgx_tstdc -l$(Service_Library_Name) -l$(Crypto_Library_Name) $(RustEnclave_Link_Libs) -Wl,--end-group \ - -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ - -Wl,-pie,-eenclave_entry -Wl,--export-dynamic \ - -Wl,--defsym,__ImageBase=0 \ - -Wl,--gc-sections \ - -Wl,--version-script=enclave/Enclave.lds - -RustEnclave_Name := enclave/enclave.so -Signed_RustEnclave_Name := bin/enclave.signed.so - -.PHONY: all -all: $(App_Name) $(Signed_RustEnclave_Name) - -######## EDL Objects ######## - -$(Enclave_EDL_Files): $(SGX_EDGER8R) enclave/Enclave.edl - $(SGX_EDGER8R) --trusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --search-path $(CUSTOM_EDL_PATH) --trusted-dir enclave - $(SGX_EDGER8R) --untrusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --search-path $(CUSTOM_EDL_PATH) --untrusted-dir app - @echo "GEN => $(Enclave_EDL_Files)" - -######## App Objects ######## - -app/Enclave_u.o: $(Enclave_EDL_Files) - @$(CC) $(App_C_Flags) -c app/Enclave_u.c -o $@ - @echo "CC <= $<" - -$(App_Enclave_u_Object): app/Enclave_u.o - $(AR) rcsD $@ $^ - cp $(App_Enclave_u_Object) ./lib - -$(App_Name): $(App_Enclave_u_Object) $(App_SRC_Files) - @cd app && SGX_SDK=$(SGX_SDK) cargo build $(App_Rust_Flags) - @echo "Cargo => $@" - mkdir -p bin - cp $(App_Rust_Path)/app ./bin - -######## Enclave Objects ######## - -enclave/Enclave_t.o: $(Enclave_EDL_Files) - @$(CC) $(RustEnclave_Compile_Flags) -c enclave/Enclave_t.c -o $@ - @echo "CC <= $<" - -$(RustEnclave_Name): enclave compiler-rt enclave/Enclave_t.o - cp ../incubator-teaclave-sgx-sdk/compiler-rt/libcompiler-rt-patch.a ./lib - @$(CXX) enclave/Enclave_t.o -o $@ $(RustEnclave_Link_Flags) - @echo "LINK => $@" - -$(Signed_RustEnclave_Name): $(RustEnclave_Name) - mkdir -p bin - @$(SGX_ENCLAVE_SIGNER) sign -key enclave/Enclave_private.pem -enclave $(RustEnclave_Name) -out $@ -config enclave/Enclave.config.xml - @echo "SIGN => $@" - -.PHONY: enclave -enclave: - $(MAKE) -C ./enclave/ - -.PHONY: compiler-rt -compiler-rt: - $(MAKE) -C ../incubator-teaclave-sgx-sdk/compiler-rt/ 2> /dev/null - -.PHONY: clean -clean: - @rm -f $(App_Name) $(RustEnclave_Name) $(Signed_RustEnclave_Name) enclave/*_t.* app/*_u.* lib/*.a - @cd enclave && cargo clean && rm -f Cargo.lock - @cd app && cargo clean && rm -f Cargo.lock - diff --git a/enclave/hello-rust/app/Cargo.toml b/enclave/hello-rust/app/Cargo.toml deleted file mode 100644 index 68243b4..0000000 --- a/enclave/hello-rust/app/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "app" -version = "1.0.0" -authors = ["The Teaclave Authors"] -build = "build.rs" - -[dependencies] -sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } -sgx_urts = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } - -[patch.'https://github.com/apache/teaclave-sgx-sdk.git'] -sgx_types = { path = "../../incubator-teaclave-sgx-sdk/sgx_types" } -sgx_urts = { path = "../../incubator-teaclave-sgx-sdk/sgx_urts" } - diff --git a/enclave/hello-rust/app/build.rs b/enclave/hello-rust/app/build.rs deleted file mode 100644 index 8ec16f1..0000000 --- a/enclave/hello-rust/app/build.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License.. - -use std::env; - -fn main () { - - let sdk_dir = env::var("SGX_SDK") - .unwrap_or_else(|_| "/opt/intel/sgxsdk".to_string()); - let is_sim = env::var("SGX_MODE") - .unwrap_or_else(|_| "HW".to_string()); - - println!("cargo:rustc-link-search=native=../lib"); - println!("cargo:rustc-link-lib=static=Enclave_u"); - - println!("cargo:rustc-link-search=native={}/lib64", sdk_dir); - match is_sim.as_ref() { - "SW" => println!("cargo:rustc-link-lib=dylib=sgx_urts_sim"), - "HW" => println!("cargo:rustc-link-lib=dylib=sgx_urts"), - _ => println!("cargo:rustc-link-lib=dylib=sgx_urts"), // Treat undefined as HW - } -} diff --git a/enclave/hello-rust/app/src/main.rs b/enclave/hello-rust/app/src/main.rs deleted file mode 100644 index cdb6d39..0000000 --- a/enclave/hello-rust/app/src/main.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License.. - -extern crate sgx_types; -extern crate sgx_urts; -use sgx_types::*; -use sgx_urts::SgxEnclave; - -static ENCLAVE_FILE: &'static str = "enclave.signed.so"; - -extern { - fn say_something(eid: sgx_enclave_id_t, retval: *mut sgx_status_t, - some_string: *const u8, len: usize) -> sgx_status_t; -} - -fn init_enclave() -> SgxResult { - let mut launch_token: sgx_launch_token_t = [0; 1024]; - let mut launch_token_updated: i32 = 0; - // call sgx_create_enclave to initialize an enclave instance - // Debug Support: set 2nd parameter to 1 - let debug = 1; - let mut misc_attr = sgx_misc_attribute_t {secs_attr: sgx_attributes_t { flags:0, xfrm:0}, misc_select:0}; - SgxEnclave::create(ENCLAVE_FILE, - debug, - &mut launch_token, - &mut launch_token_updated, - &mut misc_attr) -} - -fn main() { - let enclave = match init_enclave() { - Ok(r) => { - println!("[+] Init Enclave Successful {}!", r.geteid()); - r - }, - Err(x) => { - println!("[-] Init Enclave Failed {}!", x.as_str()); - return; - }, - }; - - let input_string = String::from("This is a normal world string passed into Enclave!\n"); - let mut retval = sgx_status_t::SGX_SUCCESS; - - let result = unsafe { - say_something(enclave.geteid(), - &mut retval, - input_string.as_ptr() as * const u8, - input_string.len()) - }; - match result { - sgx_status_t::SGX_SUCCESS => {}, - _ => { - println!("[-] ECALL Enclave Failed {}!", result.as_str()); - return; - } - } - println!("[+] say_something success..."); - enclave.destroy(); -} diff --git a/enclave/hello-rust/bin/readme.txt b/enclave/hello-rust/bin/readme.txt deleted file mode 100644 index c5e82d7..0000000 --- a/enclave/hello-rust/bin/readme.txt +++ /dev/null @@ -1 +0,0 @@ -bin \ No newline at end of file diff --git a/enclave/hello-rust/enclave/Cargo.toml b/enclave/hello-rust/enclave/Cargo.toml deleted file mode 100644 index fe13dfd..0000000 --- a/enclave/hello-rust/enclave/Cargo.toml +++ /dev/null @@ -1,41 +0,0 @@ -[package] -name = "Helloworldsampleenclave" -version = "1.0.0" -authors = ["The Teaclave Authors"] - -[lib] -name = "helloworldsampleenclave" -crate-type = ["staticlib"] - -[features] -default = [] - -[target.'cfg(not(target_env = "sgx"))'.dependencies] -sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } -sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git", features = ["backtrace"] } -sgx_trts = { git = "https://github.com/apache/teaclave-sgx-sdk.git" } -[patch.'https://github.com/apache/teaclave-sgx-sdk.git'] -sgx_alloc = { path = "../../incubator-teaclave-sgx-sdk/sgx_alloc" } -sgx_build_helper = { path = "../../incubator-teaclave-sgx-sdk/sgx_build_helper" } -sgx_cov = { path = "../../incubator-teaclave-sgx-sdk/sgx_cov" } -sgx_crypto_helper = { path = "../../incubator-teaclave-sgx-sdk/sgx_crypto_helper" } -sgx_libc = { path = "../../incubator-teaclave-sgx-sdk/sgx_libc" } -sgx_rand = { path = "../../incubator-teaclave-sgx-sdk/sgx_rand" } -sgx_rand_derive = { path = "../../incubator-teaclave-sgx-sdk/sgx_rand_derive" } -sgx_serialize = { path = "../../incubator-teaclave-sgx-sdk/sgx_serialize" } -sgx_serialize_derive = { path = "../../incubator-teaclave-sgx-sdk/sgx_serialize_derive" } -sgx_serialize_derive_internals = { path = "../../incubator-teaclave-sgx-sdk/sgx_serialize_derive_internals" } -sgx_tcrypto = { path = "../../incubator-teaclave-sgx-sdk/sgx_tcrypto" } -sgx_tcrypto_helper = { path = "../../incubator-teaclave-sgx-sdk/sgx_tcrypto_helper" } -sgx_tdh = { path = "../../incubator-teaclave-sgx-sdk/sgx_tdh" } -sgx_tkey_exchange = { path = "../../incubator-teaclave-sgx-sdk/sgx_tkey_exchange" } -sgx_tprotected_fs = { path = "../../incubator-teaclave-sgx-sdk/sgx_tprotected_fs" } -sgx_trts = { path = "../../incubator-teaclave-sgx-sdk/sgx_trts" } -sgx_tse = { path = "../../incubator-teaclave-sgx-sdk/sgx_tse" } -sgx_tseal = { path = "../../incubator-teaclave-sgx-sdk/sgx_tseal" } -sgx_tstd = { path = "../../incubator-teaclave-sgx-sdk/sgx_tstd" } -sgx_tunittest = { path = "../../incubator-teaclave-sgx-sdk/sgx_tunittest" } -sgx_types = { path = "../../incubator-teaclave-sgx-sdk/sgx_types" } -sgx_ucrypto = { path = "../../incubator-teaclave-sgx-sdk/sgx_ucrypto" } -sgx_unwind = { path = "../../incubator-teaclave-sgx-sdk/sgx_unwind" } -sgx_urts = { path = "../../incubator-teaclave-sgx-sdk/sgx_urts" } diff --git a/enclave/hello-rust/enclave/Enclave.config.xml b/enclave/hello-rust/enclave/Enclave.config.xml deleted file mode 100644 index ee4c3f7..0000000 --- a/enclave/hello-rust/enclave/Enclave.config.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - 0 - 0 - 0x40000 - 0x100000 - 1 - 1 - 0 - 0 - 0xFFFFFFFF - diff --git a/enclave/hello-rust/enclave/Enclave.edl b/enclave/hello-rust/enclave/Enclave.edl deleted file mode 100644 index 0263761..0000000 --- a/enclave/hello-rust/enclave/Enclave.edl +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -enclave { - from "sgx_tstd.edl" import *; - from "sgx_stdio.edl" import *; - from "sgx_backtrace.edl" import *; - from "sgx_tstdc.edl" import *; - trusted { - /* define ECALLs here. */ - - public sgx_status_t say_something([in, size=len] const uint8_t* some_string, size_t len); - }; -}; diff --git a/enclave/hello-rust/enclave/Enclave.lds b/enclave/hello-rust/enclave/Enclave.lds deleted file mode 100644 index e3d9d0e..0000000 --- a/enclave/hello-rust/enclave/Enclave.lds +++ /dev/null @@ -1,9 +0,0 @@ -enclave.so -{ - global: - g_global_data_sim; - g_global_data; - enclave_entry; - local: - *; -}; diff --git a/enclave/hello-rust/enclave/Enclave_private.pem b/enclave/hello-rust/enclave/Enclave_private.pem deleted file mode 100644 index 529d07b..0000000 --- a/enclave/hello-rust/enclave/Enclave_private.pem +++ /dev/null @@ -1,39 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ -AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ -ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr -nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b -3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H -ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD -5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW -KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC -1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe -K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z -AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q -ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6 -JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826 -5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02 -wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9 -osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm -WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i -Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9 -xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd -vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD -Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a -cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC -0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ -gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo -gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t -k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz -Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6 -O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5 -afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom -e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G -BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv -fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN -t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9 -yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp -6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg -WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH -NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk= ------END RSA PRIVATE KEY----- diff --git a/enclave/hello-rust/enclave/Makefile b/enclave/hello-rust/enclave/Makefile deleted file mode 100644 index 386291c..0000000 --- a/enclave/hello-rust/enclave/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -Rust_Enclave_Name := libenclave.a -Rust_Enclave_Files := $(wildcard src/*.rs) -Rust_Target_Path := $(CURDIR)/../../incubator-teaclave-sgx-sdk/xargo - -.PHONY: all - -all: $(Rust_Enclave_Name) - -$(Rust_Enclave_Name): $(Rust_Enclave_Files) -ifeq ($(XARGO_SGX), 1) - RUST_TARGET_PATH=$(Rust_Target_Path) xargo build --target x86_64-unknown-linux-sgx --release - cp ./target/x86_64-unknown-linux-sgx/release/libhelloworldsampleenclave.a ../lib/libenclave.a -else - cargo build --release - cp ./target/release/libhelloworldsampleenclave.a ../lib/libenclave.a -endif \ No newline at end of file diff --git a/enclave/hello-rust/enclave/Xargo.toml b/enclave/hello-rust/enclave/Xargo.toml deleted file mode 100644 index e54e1d7..0000000 --- a/enclave/hello-rust/enclave/Xargo.toml +++ /dev/null @@ -1,91 +0,0 @@ -[dependencies] -alloc = {} - -[dependencies.sgx_types] -path = "../../incubator-teaclave-sgx-sdk/sgx_types" -stage = 1 - -[dependencies.sgx_alloc] -path = "../../incubator-teaclave-sgx-sdk/sgx_alloc" -stage = 1 - -[dependencies.sgx_unwind] -path = "../../incubator-teaclave-sgx-sdk/sgx_unwind" -stage = 1 - -[dependencies.sgx_demangle] -path = "../../incubator-teaclave-sgx-sdk/sgx_demangle" -stage = 1 - -[dependencies.panic_abort] -path = "../../incubator-teaclave-sgx-sdk/sgx_panic_abort" -stage = 1 - -[dependencies.sgx_libc] -path = "../../incubator-teaclave-sgx-sdk/sgx_libc" -stage = 2 - -[dependencies.sgx_tkey_exchange] -path = "../../incubator-teaclave-sgx-sdk/sgx_tkey_exchange" -stage = 2 - -[dependencies.sgx_tse] -path = "../../incubator-teaclave-sgx-sdk/sgx_tse" -stage = 2 - -[dependencies.sgx_tcrypto] -path = "../../incubator-teaclave-sgx-sdk/sgx_tcrypto" -stage = 2 - -[dependencies.sgx_trts] -path = "../../incubator-teaclave-sgx-sdk/sgx_trts" -stage = 3 - -[dependencies.sgx_backtrace_sys] -path = "../../incubator-teaclave-sgx-sdk/sgx_backtrace_sys" -stage = 3 - -[dependencies.panic_unwind] -path = "../../incubator-teaclave-sgx-sdk/sgx_panic_unwind" -stage = 3 - -[dependencies.sgx_tdh] -path = "../../incubator-teaclave-sgx-sdk/sgx_tdh" -stage = 4 - -[dependencies.sgx_tseal] -path = "../../incubator-teaclave-sgx-sdk/sgx_tseal" -stage = 4 - -[dependencies.sgx_tprotected_fs] -path = "../../incubator-teaclave-sgx-sdk/sgx_tprotected_fs" -stage = 4 - -[dependencies.std] -path = "../../incubator-teaclave-sgx-sdk/xargo/sgx_tstd" -stage = 5 -features = ["backtrace"] - -[dependencies.sgx_no_tstd] -path = "../../incubator-teaclave-sgx-sdk/sgx_no_tstd" -stage = 5 - -[dependencies.sgx_rand] -path = "../../incubator-teaclave-sgx-sdk/sgx_rand" -stage = 6 - -[dependencies.sgx_serialize] -path = "../../incubator-teaclave-sgx-sdk/sgx_serialize" -stage = 6 - -[dependencies.sgx_tunittest] -path = "../../incubator-teaclave-sgx-sdk/sgx_tunittest" -stage = 6 - -[dependencies.sgx_backtrace] -path = "../../incubator-teaclave-sgx-sdk/sgx_backtrace" -stage = 7 - -[dependencies.sgx_cov] -path = "../../incubator-teaclave-sgx-sdk/sgx_cov" -stage = 7 diff --git a/enclave/hello-rust/enclave/src/lib.rs b/enclave/hello-rust/enclave/src/lib.rs deleted file mode 100644 index f661955..0000000 --- a/enclave/hello-rust/enclave/src/lib.rs +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License.. - -#![crate_name = "helloworldsampleenclave"] -#![crate_type = "staticlib"] - -#![cfg_attr(not(target_env = "sgx"), no_std)] -#![cfg_attr(target_env = "sgx", feature(rustc_private))] - -extern crate sgx_types; -extern crate sgx_trts; -#[cfg(not(target_env = "sgx"))] -#[macro_use] -extern crate sgx_tstd as std; - -use sgx_types::*; -use sgx_types::metadata::*; -use sgx_trts::enclave; -//use sgx_trts::{is_x86_feature_detected, is_cpu_feature_supported}; -use std::string::String; -use std::vec::Vec; -use std::io::{self, Write}; -use std::slice; -use std::backtrace::{self, PrintFormat}; - -#[no_mangle] -pub extern "C" fn say_something(some_string: *const u8, some_len: usize) -> sgx_status_t { - - let str_slice = unsafe { slice::from_raw_parts(some_string, some_len) }; - let _ = io::stdout().write(str_slice); - - // A sample &'static string - let rust_raw_string = "This is a in-Enclave "; - // An array - let word:[u8;4] = [82, 117, 115, 116]; - // An vector - let word_vec:Vec = vec![32, 115, 116, 114, 105, 110, 103, 33]; - - // Construct a string from &'static string - let mut hello_string = String::from(rust_raw_string); - - // Iterate on word array - for c in word.iter() { - hello_string.push(*c as char); - } - - // Rust style convertion - hello_string += String::from_utf8(word_vec).expect("Invalid UTF-8") - .as_str(); - - // Ocall to normal world for output - println!("{}", &hello_string); - - let _ = backtrace::enable_backtrace("enclave.signed.so", PrintFormat::Full); - - let gd = enclave::SgxGlobalData::new(); - println!("gd: {} {} {} {} ", gd.get_static_tcs_num(), gd.get_eremove_tcs_num(), gd.get_dyn_tcs_num(), gd.get_tcs_max_num()); - let (static_num, eremove_num, dyn_num) = get_thread_num(); - println!("static: {} eremove: {} dyn: {}", static_num, eremove_num, dyn_num); - - unsafe { - println!("EDMM: {}, feature: {}", EDMM_supported, g_cpu_feature_indicator); - } - if is_x86_feature_detected!("sgx") { - println!("supported sgx"); - } - - sgx_status_t::SGX_SUCCESS -} - -#[link(name = "sgx_trts")] -extern { - static g_cpu_feature_indicator: uint64_t; - static EDMM_supported: c_int; -} - - -fn get_thread_num() -> (u32, u32, u32) { - let gd = unsafe { - let p = enclave::rsgx_get_global_data(); - &*p - }; - - let mut static_thread_num: u32 = 0; - let mut eremove_thread_num: u32 = 0; - let mut dyn_thread_num: u32 = 0; - let layout_table = &gd.layout_table[0..gd.layout_entry_num as usize]; - unsafe { traversal_layout(&mut static_thread_num, &mut dyn_thread_num, &mut eremove_thread_num, layout_table); } - - unsafe fn traversal_layout(static_num: &mut u32, dyn_num: &mut u32, eremove_num: &mut u32, layout_table: &[layout_t]) - { - for (i, layout) in layout_table.iter().enumerate() { - if !is_group_id!(layout.group.id as u32) { - if (layout.entry.attributes & PAGE_ATTR_EADD) != 0 { - if (layout.entry.content_offset != 0) && (layout.entry.si_flags == SI_FLAGS_TCS) { - if (layout.entry.attributes & PAGE_ATTR_EREMOVE) == 0 { - *static_num += 1; - } else { - *eremove_num += 1; - } - } - } - if (layout.entry.attributes & PAGE_ATTR_POST_ADD) != 0 { - if layout.entry.id == LAYOUT_ID_TCS_DYN as u16 { - *dyn_num += 1; - } - } - } else { - for _ in 0..layout.group.load_times { - traversal_layout(static_num, dyn_num, eremove_num, &layout_table[i - layout.group.entry_count as usize..i]) - } - } - } - } - (static_thread_num, eremove_thread_num, dyn_thread_num) -} \ No newline at end of file diff --git a/enclave/hello-rust/enclave/x86_64-unknown-linux-sgx.json b/enclave/hello-rust/enclave/x86_64-unknown-linux-sgx.json deleted file mode 100644 index 10d37a7..0000000 --- a/enclave/hello-rust/enclave/x86_64-unknown-linux-sgx.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "arch": "x86_64", - "cpu": "x86-64", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "dynamic-linking": true, - "env": "sgx", - "exe-allocation-crate": "alloc_system", - "executables": true, - "has-elf-tls": true, - "has-rpath": true, - "linker-flavor": "gcc", - "linker-is-gnu": true, - "llvm-target": "x86_64-unknown-linux-gnu", - "max-atomic-width": 64, - "os": "linux", - "position-independent-executables": true, - "pre-link-args": { - "gcc": [ - "-Wl,--as-needed", - "-Wl,-z,noexecstack", - "-m64" - ] - }, - "relro-level": "full", - "stack-probes": true, - "target-c-int-width": "32", - "target-endian": "little", - "target-family": "unix", - "target-pointer-width": "64", - "vendor": "mesalock" -} diff --git a/enclave/hello-rust/lib/readme.txt b/enclave/hello-rust/lib/readme.txt deleted file mode 100644 index 7951405..0000000 --- a/enclave/hello-rust/lib/readme.txt +++ /dev/null @@ -1 +0,0 @@ -lib \ No newline at end of file diff --git a/enclave/hello-rust/rust-toolchain b/enclave/hello-rust/rust-toolchain deleted file mode 100644 index 7b9d999..0000000 --- a/enclave/hello-rust/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -nightly-2020-03-12 \ No newline at end of file diff --git a/enclave/incubator-teaclave-sgx-sdk b/enclave/incubator-teaclave-sgx-sdk deleted file mode 160000 index 92e7b1c..0000000 --- a/enclave/incubator-teaclave-sgx-sdk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 92e7b1c196a6e6025d890ebce5e63a3e1a8e98b5 From 23f6156dbf4421e0eb5792ae94bb4708b057fb76 Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Wed, 1 Apr 2020 09:30:13 -0500 Subject: [PATCH 11/11] DOC: updating READMEs --- api-server/README.md | 8 +++++--- enclave/README.md | 40 +++++++--------------------------------- 2 files changed, 12 insertions(+), 36 deletions(-) diff --git a/api-server/README.md b/api-server/README.md index 115d656..0eb0413 100644 --- a/api-server/README.md +++ b/api-server/README.md @@ -69,18 +69,20 @@ The geolocation + datetime data is to be provided in an array in JSON format as "lat": 40.757339, "lng": -73.985992, "startTS": 1583064000, - "endTS": 1583067600 + "endTS": 1583067600, + "testResult": false, }, { "lat": 40.793840, "lng": -73.956900, "startTS": 1583150400, - "endTS": 1583154000 + "endTS": 1583154000, + "testResult": true, }, ] ``` -In the example above, the first datapoint is for Times Square in New York City on March 1st, 2020 from 12pm to 1pm, whereas the second data point is somewhere in Central Park the following day March 2nd, 2020 from 12pm to 1pm. +In the example above, the first datapoint is for Times Square in New York City on March 1st, 2020 from 12pm to 1pm, whereas the second data point is somewhere in Central Park the following day March 2nd, 2020 from 12pm to 1pm. This user did not test positive for Coronavirus the first day, but he tested positive the following day. # Installation diff --git a/enclave/README.md b/enclave/README.md index 2d5c094..0f8b2e1 100644 --- a/enclave/README.md +++ b/enclave/README.md @@ -24,54 +24,28 @@ This folder contains the code that runs inside the enclave using Intel Secure Gu git clone git@github.com:enigmampc/covid-self-reporting.git ``` -2. Move into this `enclave` subfolder: +2. Install the SGX driver and SDK, as per these [instructions](https://github.com/enigmampc/EnigmaBlockchain/blob/master/docs/dev/setup-sgx.md). - ```bash - cd enclave - ``` -3. Initialize the gitsubmodule: +3. Move into the `enclave/safetrace` subfolder: ```bash - cd incubator-teaclave-sgx-sdk - git submodule init - git submodule update + cd enclave/safetrac ``` -4. Install the SGX driver and SDK, as per these [instructions](https://github.com/enigmampc/EnigmaBlockchain/blob/master/docs/dev/setup-sgx.md). - -5. A sample code is temporarily included in this repo as a starting point. You can try it out: +4. Compile the code: ```bash - cd hello-rust make - cd bin - ./app ``` - *Note: This code is very particular, and you need to run `./app` from inside the `bin` folder. If you try to run it from anywhere else (e.g. its parent folder, as in `./bin/app`), you will get the following error, because it expects another file in the same folder from where the command is run:* +5. Run the enclave code: ```bash - [-] Init Enclave Failed SGX_ERROR_ENCLAVE_FILE_ACCESS!`* - ``` - - Which should print something similar to this: - - ```bash - [+] Init Enclave Successful 2! - This is a normal world string passed into Enclave! - This is a in-Enclave Rust string! - gd: 1 0 0 1 - static: 1 eremove: 0 dyn: 0 - EDMM: 0, feature: 9007268796301311 - supported sgx - [+] say_something success... + cd bin + ./safetrace-app ``` ## ToDo -* Use the `hello-rust` folder and scaffolding for the COVID-19 code -* Write the actual Rust code for the application -* Implement Remote Attestation to provide proof of code running in legitimate enclave -* Implement data sealing and unsealing choosing the right configuration so that data is uniquely assigned to this enclave * Sign code and deploy