Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Safety Rules SGX with Teaclave #2

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Safety Rules SGX with Teaclave #2

wants to merge 13 commits into from

Conversation

zaxguo
Copy link
Owner

@zaxguo zaxguo commented Jul 1, 2020

Motivation

This PR sets up the basic framework to integrate safety rules with SGX using Teaclave Rust SGX SDK.
There are a few notable changes made to enable Libra code to run inside SGX with Teaclave:

  1. Changes of directory structure: ( * means newly added)
    consensus/
    |--Makefile *
    |--safety_rules/
    | -- build.rs *
    |--enclave/ *
    | -- Enclave.edl
    | -- Makefile

File explanation:

  • Makefiles: Teaclave works closely with Intel SGX SDK, which works with C. Hence Teaclave follows the same convention in using Makefiles to invoke functions Intel SGX SDK to process the enclave binary (e.g. take measurement and sign enclave). Two Makefiles are important:
  • consensus/Makefile: this is the main driver Makefile. It drives normal Cargo build to compile the non-enclave code for setting tup ECALLs/OCALLs in Rust API.
  • consensus/enclave/Makefile: this Makefile drives xargo to compile enclave code.
  • build.rs: the build script to make the non-enclave code link against enclave library

  • Enclave.edl: the file specifies each ECALL/OCALL!

  1. Using Xargo: SGX is a different STD environment, which requires the Rust code to be linked against SGX libstd, i.e. sgx_tstd. Xargo is used here to achieve this goal, which automatically swaps the Rust STD with sgx_tstd at compile time. The usage of Xargo can be found in enclave/Makefile.

  2. Updating dependencies for enclave code: Virtual Cargo.toml files are added to handle the proper dependencies needed by enclave code.
    To work with SGX, all dependencies that rely on libc must be substituted with respective SGX-supported ones, e.g. serde -> serde-sgx. However due to Cargo limitation, one crate cannot have different source paths, even with conditional compilation (Conditional compilation of dependency feature based on target doesn't work rust-lang/cargo#2524) -- this makes in-place dependency modification of the crates impossible.

Virtual Cargo.toml solve this by pointing its library path to the original crate, while having a completely substituted dependency graph. A good example is the pair of common/lcs/Cargo.toml with its virtual one: sgx-deps/lcs/Cargo.toml.

  • All future virtual Cargo.tomls for SGX will be put under sgx-deps/ and enclave code use them to compile. This is demonstrated in enclave/Cargo.toml which relies on modified lcs in sgx-deps/lcs.

  • Additional code snippet must be added to the original crate's lib.rs to work with Xargo, shown below:

#![cfg_attr(
    all(target_env = "sgx", target_vendor = "mesalock"),
    feature(rustc_private)
)]

This allows Xargo to read the SGX libstd (e.g. sgx_tstd) from sysroot. Otherwise it will fetch from crates.io, although it's unclear what can go wrong if SGX libstds are fetched from crates.io.

  1. What third-party dependencies are supported?
  • Those that support no_std (i.e. allows default-features=off) and do not rely on libc should compile out-of-box.
  • Those that support no_std but rely on libc might compile so long as sgx_trts implements its respective backend (e.g. libc::iovec is supported by sgx_trts).
  • Those that rely on Rust libstd but not libc might compile with minor code changes (e.g. SGX libstd asks the user to modify std::Mutex into std::SgxMutex manually so the user is aware of this)
  • Those that rely on Rust libstd and libc might compile with moderate code changes (i.e. need to handle both SGX version of libc and std)
  • Those that rely UNSUPPORTED features of SGX libstd (i.e. sgx_tstd) and SGX libc (i.e. sgx_trts) do not compile.
  1. To embed inside currently LSR, the framework needs to setup a new SafetyRulesSGX which implements TSafetyRules traits. I leave this out since this is implemented in the Fortanix PR. (Safety Rules SGX with Fortanix (obsolete) #1)

  2. The enormous insertions are caused by adding teaclave as a subtree in sgx-sdk/ in commit 5eb3fe5. Simply ignore it.

Have you read the Contributing Guidelines on pull requests?

Yea

Test Plan

safety rules test suites

Related PRs

None

@zaxguo
Copy link
Owner Author

zaxguo commented Jul 4, 2020

  • Note: Virtual Cargo.toml is not working due to compiler bug:
   Compiling libra-crypto-sgx v0.1.0 (/root/libra/sgx-deps/crypto/crypto)
     Running `rustc --crate-name libra_crypto_sgx --edition=2018 sgx-deps/crypto/crypto/../../../crypto/crypto/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="fiat_u64_backend"' --cfg 'feature="std"' -C metadata=2abde04a8a907454 -C extra-filename=-2abde04a8a907454 --out-dir /root/libra/target/x86_64-unknown-linux-sgx/release/deps --target x86_64-unknown-linux-sgx -L dependency=/root/libra/target/x86_64-unknown-linux-sgx/release/deps -L dependency=/root/libra/target/release/deps --extern aes_gcm=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libaes_gcm-7ae0b99463761f96.rmeta --extern anyhow=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libanyhow-7bec40881e8f2a69.rmeta --extern bytes=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libbytes-b5898f000100a0d9.rmeta --extern curve25519_dalek=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libcurve25519_dalek-5f8eec768d5b9b55.rmeta --extern digest=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libdigest-847d3d4ba1a0ab15.rmeta --extern ed25519_dalek=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libed25519_dalek-061ce9257c7b0366.rmeta --extern hex=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libhex-7ab07dfb4a50f9af.rmeta --extern hmac=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libhmac-73f2759a563acf83.rmeta --extern lcs=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/liblibra_canonical_serialization_sgx-c535a28d7bf61ae4.rmeta --extern libra_crypto_derive=/root/libra/target/release/deps/liblibra_crypto_derive_sgx-0e641a92182123b4.so --extern libra_nibble=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/liblibra_nibble_sgx-e124c664f04a770e.rmeta --extern mirai_annotations=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libmirai_annotations-441655a8fac29971.rmeta --extern once_cell=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libonce_cell-4aeff9923e5c33c7.rmeta --extern rand=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/librand-43074630855ec19c.rmeta --extern rand_core=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/librand_core-e33578d89c6e5912.rmeta --extern serde=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libserde-c0e4b3da85fb6ab9.rmeta --extern serde_name=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libserde_name-94ba8f703c47f70a.rmeta --extern serde_bytes=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libserde_bytes-c082891d450e979f.rmeta --extern sha2=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libsha2-552462fa2b8341fc.rmeta --extern sha3=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libsha3-f37697c1951e4c97.rmeta --extern thiserror=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libthiserror-cd9cfcfa769b7418.rmeta --extern tiny_keccak=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libtiny_keccak-93c88d64c0b16a5c.rmeta --extern x25519_dalek=/root/libra/target/x86_64-unknown-linux-sgx/release/deps/libx25519_dalek-542585517eb5ce2b.rmeta -Z force-unstable-if-unmarked -Z macro-backtrace --sysroot /root/.xargo -L native=/root/libra/target/x86_64-unknown-linux-sgx/release/build/clear_on_drop-4b2ac08fbc780388/out`
  21: rustc_interface::passes::configure_and_expand_inner
  22: rustc_interface::passes::configure_and_expand::{{closure}}
  23: rustc_data_structures::box_region::PinnedGenerator<I,A,R>::new
  24: rustc_interface::passes::configure_and_expand
  25: rustc_interface::queries::Queries::expansion
  26: rustc_interface::interface::run_compiler_in_existing_thread_pool
  27: scoped_tls::ScopedKey<T>::set
  28: rustc_ast::attr::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.44.0-nightly (6dee5f112 2020-04-06) running on x86_64-unknown-linux-gnu

@zaxguo
Copy link
Owner Author

zaxguo commented Jul 5, 2020

Deal with untrusted components -- general approach "trust the untrusted system" b swapping them:

  • Mutex
  • Time
  • FS

Specifically, components that need human auditing:

  • Utc::now(), depend on chrono feature ["clock"], currently unsupported: replacce with SystemTime::now()
  • Mutx as SgxMutex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant