diff --git a/core/Cargo.lock b/core/Cargo.lock index 15448926b..83f01ab2d 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -200,11 +200,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "mc-sgx-core-build" +version = "0.1.0" + [[package]] name = "mc-sgx-core-sys-types" version = "0.1.0" dependencies = [ "bindgen", + "mc-sgx-core-build", ] [[package]] diff --git a/core/Cargo.toml b/core/Cargo.toml index 2147fce63..774a0c827 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,7 +1,8 @@ [workspace] resolver = "2" members = [ - "sys/types", + "sys/types", + "build", ] [profile.dev] diff --git a/core/build/Cargo.toml b/core/build/Cargo.toml new file mode 100644 index 000000000..37e01d337 --- /dev/null +++ b/core/build/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "mc-sgx-core-build" +version = "0.1.0" +edition = "2021" diff --git a/core/build/README.md b/core/build/README.md new file mode 100644 index 000000000..89f19bb98 --- /dev/null +++ b/core/build/README.md @@ -0,0 +1,20 @@ +# Common build logic for SGX libraries + +This crate provides common logic to build and link against the Intel SGX SDK + +## Table of Contents + +- [License](#license) +- [Build Instructions](#build-instructions) +- [Intel SGX SDK](#intel-sgx-sdk) +- [Features](#features) +- [References](#references) + +## License + +Look for the *LICENSE* file at the root of the repo for more information. + +## References + +- +- diff --git a/core/build/src/lib.rs b/core/build/src/lib.rs new file mode 100644 index 000000000..a5e8f6ae0 --- /dev/null +++ b/core/build/src/lib.rs @@ -0,0 +1,34 @@ +// Copyright (c) 2022 The MobileCoin Foundation + +#![doc = include_str!("../README.md")] + +use std::{env, path::PathBuf}; + +static DEFAULT_SGX_SDK_PATH: &str = "/opt/intel/sgxsdk"; + +/// Return the SGX library path. +/// +/// Will first attempt to look at the environment variable `SGX_SDK`, if that +/// isn't present then `/opt/intel/sgxsdk` will be used. +pub fn sgx_library_path() -> String { + env::var("SGX_SDK").unwrap_or_else(|_| DEFAULT_SGX_SDK_PATH.into()) +} + +/// Return the build output path. +pub fn build_output_path() -> PathBuf { + PathBuf::from(env::var("OUT_DIR").expect("Missing env.OUT_DIR")) +} + +/// Return the SGX library suffix +/// +/// Some SGX libraries have a suffix for example `sgx_trts.a` versus +/// `sgx_trts_sim.a`. This will result the suffix based on the presence of the +/// feature `hw`. +pub fn sgx_library_suffix() -> &'static str { + // See https://doc.rust-lang.org/cargo/reference/features.html#build-scripts + // for description of `CARGO_FEATURE_` + match env::var("CARGO_FEATURE_HW") { + Ok(_) => "", + _ => "_sim", + } +} diff --git a/core/sys/types/Cargo.toml b/core/sys/types/Cargo.toml index ab8ffcef4..eeac897a2 100644 --- a/core/sys/types/Cargo.toml +++ b/core/sys/types/Cargo.toml @@ -5,3 +5,4 @@ edition = "2021" [build-dependencies] bindgen = "0.60.1" +mc-sgx-core-build = { path = "../../build" } diff --git a/core/sys/types/build.rs b/core/sys/types/build.rs index e7f8b22ed..161e1831f 100644 --- a/core/sys/types/build.rs +++ b/core/sys/types/build.rs @@ -2,9 +2,6 @@ //! Builds the FFI type bindings for the common SGX SDK types use bindgen::{callbacks::ParseCallbacks, Builder}; -use std::{env, path::PathBuf}; - -static DEFAULT_SGX_SDK_PATH: &str = "/opt/intel/sgxsdk"; #[derive(Debug)] struct Callbacks; @@ -18,17 +15,14 @@ impl ParseCallbacks for Callbacks { } } -fn sgx_library_path() -> String { - env::var("SGX_SDK").unwrap_or_else(|_| DEFAULT_SGX_SDK_PATH.into()) -} - fn main() { + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); let bindings = Builder::default() .header_contents( "core_types.h", "#include \n#include ", ) - .clang_arg(&format!("-I{}/include", sgx_library_path())) + .clang_arg(&format!("-I{}/include", sgx_library_path)) .newtype_enum("_status_t") .blocklist_function("*") .allowlist_type("_status_t") @@ -38,7 +32,7 @@ fn main() { .generate() .expect("Unable to generate bindings"); - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + let out_path = mc_sgx_core_build::build_output_path(); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); diff --git a/trusted/trts/sys/Cargo.toml b/trusted/trts/sys/Cargo.toml index 2f6230578..eb2f0f263 100644 --- a/trusted/trts/sys/Cargo.toml +++ b/trusted/trts/sys/Cargo.toml @@ -13,3 +13,4 @@ mc-sgx-core-sys-types = { path = "../../../core/sys/types" } [build-dependencies] bindgen = "0.60.1" cargo-emit = "0.2.1" +mc-sgx-core-build = { path = "../../../core/build" } diff --git a/trusted/trts/sys/build.rs b/trusted/trts/sys/build.rs index ffb71ce37..f9c020600 100644 --- a/trusted/trts/sys/build.rs +++ b/trusted/trts/sys/build.rs @@ -2,35 +2,25 @@ //! Builds the FFI function bindings for trts (trusted runtime system) of the //! Intel SGX SDK -extern crate bindgen; +use bindgen::Builder; use cargo_emit::{rustc_link_lib, rustc_link_search}; -use std::{env, path::PathBuf}; - -static DEFAULT_SGX_SDK_PATH: &str = "/opt/intel/sgxsdk"; - -#[cfg(feature = "hw")] -const SGX_SUFFIX: &str = ""; -#[cfg(not(feature = "hw"))] -const SGX_SUFFIX: &str = "_sim"; - -fn sgx_library_path() -> String { - env::var("SGX_SDK").unwrap_or_else(|_| DEFAULT_SGX_SDK_PATH.into()) -} fn main() { - rustc_link_lib!(&format!("sgx_trts{}", SGX_SUFFIX)); - rustc_link_search!(&format!("{}/lib64", sgx_library_path())); + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); + let sgx_suffix = mc_sgx_core_build::sgx_library_suffix(); + rustc_link_lib!(&format!("sgx_trts{}", sgx_suffix)); + rustc_link_search!(&format!("{}/lib64", &sgx_library_path)); - let bindings = bindgen::Builder::default() + let bindings = Builder::default() .header_contents("trts.h", "#include ") - .clang_arg(&format!("-I{}/include", sgx_library_path())) + .clang_arg(&format!("-I{}/include", &sgx_library_path)) .blocklist_type("*") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .ctypes_prefix("core::ffi") .generate() .expect("Unable to generate bindings"); - let out_path = PathBuf::from(env::var("OUT_DIR").expect("Missing env.OUT_DIR")); + let out_path = mc_sgx_core_build::build_output_path(); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); diff --git a/untrusted/Cargo.lock b/untrusted/Cargo.lock index d4ba9b22a..a00c5ad53 100644 --- a/untrusted/Cargo.lock +++ b/untrusted/Cargo.lock @@ -462,11 +462,16 @@ dependencies = [ "syn", ] +[[package]] +name = "mc-sgx-core-build" +version = "0.1.0" + [[package]] name = "mc-sgx-core-sys-types" version = "0.1.0" dependencies = [ "bindgen 0.60.1", + "mc-sgx-core-build", ] [[package]] @@ -493,6 +498,7 @@ version = "0.1.0" dependencies = [ "bindgen 0.60.1", "cargo-emit", + "mc-sgx-core-build", "mc-sgx-core-sys-types", "mc-sgx-urts-sys-types", "test_enclave", @@ -504,6 +510,7 @@ version = "0.1.0" dependencies = [ "bindgen 0.60.1", "cargo-emit", + "mc-sgx-core-build", "test_enclave", ] @@ -857,6 +864,7 @@ dependencies = [ "bindgen 0.60.1", "cargo-emit", "cc", + "mc-sgx-core-build", "mc-sgx-core-sys-types", "mc-sgx-urts-sys-types", "rand", diff --git a/untrusted/test_enclave/Cargo.toml b/untrusted/test_enclave/Cargo.toml index d15a958d6..99adafad7 100644 --- a/untrusted/test_enclave/Cargo.toml +++ b/untrusted/test_enclave/Cargo.toml @@ -17,3 +17,4 @@ cc = "1.0.73" bindgen = "0.60.1" rsa = "0.6.1" rand = "0.8.5" +mc-sgx-core-build = { path = "../../core/build" } diff --git a/untrusted/test_enclave/build.rs b/untrusted/test_enclave/build.rs index 9600c614f..0316c8ae7 100644 --- a/untrusted/test_enclave/build.rs +++ b/untrusted/test_enclave/build.rs @@ -1,7 +1,7 @@ // Copyright (c) 2022 The MobileCoin Foundation #![doc = include_str!("README.md")] -use bindgen; +use bindgen::Builder; use cargo_emit::rerun_if_changed; use cc::Build; use rand; @@ -24,17 +24,11 @@ struct EdgerFiles { untrusted: PathBuf, } -const DEFAULT_SGX_SDK_PATH: &str = "/opt/intel/sgxsdk"; const EDGER_FILE: &str = "src/enclave.edl"; const ENCLAVE_FILE: &str = "src/enclave.c"; const ENCLAVE_LINKER_SCRIPT: &str = "src/enclave.lds"; const ENCLAVE_CONFIG: &str = "src/config.xml"; -#[cfg(feature = "hw")] -const SGX_SUFFIX: &str = ""; -#[cfg(not(feature = "hw"))] -const SGX_SUFFIX: &str = "_sim"; - fn main() { let root_dir = root_dir(); let edger_files = build_enclave_definitions(root_dir.join(EDGER_FILE)); @@ -47,19 +41,6 @@ fn main() { build_untrusted_bindings(untrusted_header); } -/// Provide the base path for the Intel SGX SDK. Will use the environment -/// variable `SGX_SDK`. If this isn't set it will default to -/// `/opt/intel/sgxsdk`. -fn sgx_library_path() -> String { - env::var("SGX_SDK").unwrap_or_else(|_| DEFAULT_SGX_SDK_PATH.into()) -} - -/// The value of the environment variable `OUT_DIR`, this must be set. -/// See https://doc.rust-lang.org/cargo/reference/environment-variables.html -fn out_dir() -> PathBuf { - env::var("OUT_DIR").expect("Missing env.OUT_DIR").into() -} - /// The root dir of this crate. Will be the value of `CARGO_MANIFEST_DIR` /// See https://doc.rust-lang.org/cargo/reference/environment-variables.html fn root_dir() -> PathBuf { @@ -89,8 +70,9 @@ fn build_enclave_definitions>(edl_file: P) -> EdgerFiles { .to_str() .expect("Invalid UTF-8 in edl path")); - let mut command = Command::new(&format!("{}/bin/x64/sgx_edger8r", sgx_library_path())); - let out_dir = out_dir(); + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); + let mut command = Command::new(&format!("{}/bin/x64/sgx_edger8r", sgx_library_path)); + let out_dir = mc_sgx_core_build::build_output_path(); command .current_dir(&out_dir) .arg(edl_file.as_ref().as_os_str()); @@ -129,6 +111,8 @@ where .expect("Invalid UTF-8 in enclave C file")); } + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); + // This `Build` builds a static library. If we don't omit the // `cargo_metadata` then this static library will be linked into // the consuming crate. The enclave binary is meant to be a stand alone, @@ -138,12 +122,12 @@ where // be directly linked in. Build::new() .files(files) - .include(format!("{}/include", sgx_library_path())) - .include(format!("{}/include/tlibc", sgx_library_path())) + .include(format!("{}/include", sgx_library_path)) + .include(format!("{}/include/tlibc", sgx_library_path)) .cargo_metadata(false) .compile("enclave"); - let static_enclave = out_dir().join("libenclave.a"); + let static_enclave = mc_sgx_core_build::build_output_path().join("libenclave.a"); let dynamic_enclave = build_dynamic_enclave_binary(static_enclave); sign_enclave_binary(dynamic_enclave) } @@ -165,9 +149,11 @@ where fn build_dynamic_enclave_binary>(static_enclave: P) -> PathBuf { let mut dynamic_enclave = PathBuf::from(static_enclave.as_ref()); dynamic_enclave.set_extension("so"); - let trts = format!("-lsgx_trts{}", SGX_SUFFIX); - let tservice = format!("-lsgx_tservice{}", SGX_SUFFIX); + let sgx_suffix = mc_sgx_core_build::sgx_library_suffix(); + let trts = format!("-lsgx_trts{}", sgx_suffix); + let tservice = format!("-lsgx_tservice{}", sgx_suffix); + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); let mut command = Command::new(ld_linker()); command .arg("-o") @@ -177,11 +163,8 @@ fn build_dynamic_enclave_binary>(static_enclave: P) -> PathBuf { .expect("Invalid UTF-8 in static enclave path"), ) .args(&["-z", "relro", "-z", "now", "-z", "noexecstack"]) - .arg(&format!( - "-L{}/lib64/cve_2020_0551_load", - sgx_library_path() - )) - .arg(&format!("-L{}/lib64", sgx_library_path())) + .arg(&format!("-L{}/lib64/cve_2020_0551_load", sgx_library_path)) + .arg(&format!("-L{}/lib64", sgx_library_path)) .arg("--no-undefined") .arg("--nostdlib") .arg("--start-group") @@ -223,7 +206,8 @@ fn sign_enclave_binary>(unsigned_enclave: P) -> PathBuf { let signing_key = get_signing_key(); - let mut command = Command::new(format!("{}/bin/x64/sgx_sign", sgx_library_path())); + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); + let mut command = Command::new(format!("{}/bin/x64/sgx_sign", sgx_library_path)); command .arg("sign") .arg("-enclave") @@ -247,7 +231,7 @@ fn sign_enclave_binary>(unsigned_enclave: P) -> PathBuf { /// Due to the time to create a key file, this will favor returning an already /// built signing key and only generate one as needed. fn get_signing_key() -> PathBuf { - let key_file = out_dir().join("signing_key.pem"); + let key_file = mc_sgx_core_build::build_output_path().join("signing_key.pem"); if !key_file.exists() { // The 3072 bit size and exponent of 3 are a restriction of `sgx_sign` let bit_size = 3072; @@ -275,13 +259,14 @@ fn get_signing_key() -> PathBuf { /// # Returns /// The full path to resultant untrusted library. fn build_untrusted_library>(untrusted_file: P) -> PathBuf { + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); Build::new() .file(untrusted_file) - .include(format!("{}/include", sgx_library_path())) - .include(format!("{}/include/tlibc", sgx_library_path())) + .include(format!("{}/include", sgx_library_path)) + .include(format!("{}/include/tlibc", sgx_library_path)) .compile("untrusted"); - let mut untrusted_object = out_dir(); + let mut untrusted_object = mc_sgx_core_build::build_output_path(); untrusted_object.set_file_name("untrusted.a"); untrusted_object } @@ -296,9 +281,10 @@ fn build_untrusted_library>(untrusted_file: P) -> PathBuf { /// /// * `header` - The untrusted header file generated from `edger8r` fn build_untrusted_bindings>(header: P) { - let bindings = bindgen::Builder::default() + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); + let bindings = Builder::default() .header(header.as_ref().to_str().unwrap()) - .clang_arg(format!("-I{}/include", sgx_library_path())) + .clang_arg(format!("-I{}/include", sgx_library_path)) .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .blocklist_type("*") // limit to only the functions needed @@ -307,6 +293,6 @@ fn build_untrusted_bindings>(header: P) { .expect("Unable to generate bindings"); bindings - .write_to_file(out_dir().join("bindings.rs")) + .write_to_file(mc_sgx_core_build::build_output_path().join("bindings.rs")) .expect("Couldn't write bindings!"); } diff --git a/untrusted/urts/sys/Cargo.toml b/untrusted/urts/sys/Cargo.toml index ff92fbefe..f27ed2e27 100644 --- a/untrusted/urts/sys/Cargo.toml +++ b/untrusted/urts/sys/Cargo.toml @@ -14,6 +14,7 @@ mc-sgx-core-sys-types = { path = "../../../core/sys/types" } [build-dependencies] bindgen = "0.60.1" cargo-emit = "0.2.1" +mc-sgx-core-build = { path = "../../../core/build" } [dev-dependencies] test_enclave = { path = "../../test_enclave" } diff --git a/untrusted/urts/sys/build.rs b/untrusted/urts/sys/build.rs index 314ff67fc..716794d4d 100644 --- a/untrusted/urts/sys/build.rs +++ b/untrusted/urts/sys/build.rs @@ -1,35 +1,25 @@ // Copyright (c) 2022 The MobileCoin Foundation //! Builds the FFI bindings for the untrusted side of the Intel SGX SDK -extern crate bindgen; +use bindgen::Builder; use cargo_emit::{rustc_link_lib, rustc_link_search}; -use std::{env, path::PathBuf}; - -static DEFAULT_SGX_SDK_PATH: &str = "/opt/intel/sgxsdk"; - -#[cfg(feature = "hw")] -const SGX_SUFFIX: &str = ""; -#[cfg(not(feature = "hw"))] -const SGX_SUFFIX: &str = "_sim"; - -fn sgx_library_path() -> String { - env::var("SGX_SDK").unwrap_or_else(|_| DEFAULT_SGX_SDK_PATH.into()) -} fn main() { - rustc_link_lib!(&format!("sgx_urts{}", SGX_SUFFIX)); - rustc_link_lib!(&format!("sgx_launch{}", SGX_SUFFIX)); - rustc_link_search!(&format!("{}/lib64", sgx_library_path())); + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); + let sgx_suffix = mc_sgx_core_build::sgx_library_suffix(); + rustc_link_lib!(&format!("sgx_urts{}", sgx_suffix)); + rustc_link_lib!(&format!("sgx_launch{}", sgx_suffix)); + rustc_link_search!(&format!("{}/lib64", sgx_library_path)); - let bindings = bindgen::Builder::default() + let bindings = Builder::default() .header_contents("urts.h", "#include ") - .clang_arg(&format!("-I{}/include", sgx_library_path())) + .clang_arg(&format!("-I{}/include", sgx_library_path)) .blocklist_type("*") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .generate() .expect("Unable to generate bindings"); - let out_path = PathBuf::from(env::var("OUT_DIR").expect("Missing env.OUT_DIR")); + let out_path = mc_sgx_core_build::build_output_path(); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); diff --git a/untrusted/urts/sys/types/Cargo.toml b/untrusted/urts/sys/types/Cargo.toml index 6c54a82db..2cd177d83 100644 --- a/untrusted/urts/sys/types/Cargo.toml +++ b/untrusted/urts/sys/types/Cargo.toml @@ -7,11 +7,10 @@ edition = "2021" sw = [] default = ["sw"] -[dependencies] +[dev-dependencies] +test_enclave = { path = "../../../test_enclave" } [build-dependencies] bindgen = "0.60.1" cargo-emit = "0.2.1" - -[dev-dependencies] -test_enclave = { path = "../../../test_enclave" } +mc-sgx-core-build = { path = "../../../../core/build" } \ No newline at end of file diff --git a/untrusted/urts/sys/types/build.rs b/untrusted/urts/sys/types/build.rs index b6f1c1680..e511e9e6d 100644 --- a/untrusted/urts/sys/types/build.rs +++ b/untrusted/urts/sys/types/build.rs @@ -4,8 +4,6 @@ use bindgen::{callbacks::ParseCallbacks, Builder}; use std::{env, path::PathBuf}; -static DEFAULT_SGX_SDK_PATH: &str = "/opt/intel/sgxsdk"; - #[derive(Debug)] struct Callbacks; @@ -19,14 +17,11 @@ impl ParseCallbacks for Callbacks { } } -fn sgx_library_path() -> String { - env::var("SGX_SDK").unwrap_or_else(|_| DEFAULT_SGX_SDK_PATH.into()) -} - fn main() { + let sgx_library_path = mc_sgx_core_build::sgx_library_path(); let bindings = Builder::default() .header_contents("urts_types.h", "#include ") - .clang_arg(&format!("-I{}/include", sgx_library_path())) + .clang_arg(&format!("-I{}/include", sgx_library_path)) .blocklist_function("*") .allowlist_type("sgx_enclave_id_t") .allowlist_type("sgx_launch_token_t")