From 4a8aa82533266a3b86352f67db5ca8f88d171482 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Thu, 1 Jun 2023 05:13:42 +0900 Subject: [PATCH 01/18] add RA simulation support Signed-off-by: Jun Kimura --- Cargo.lock | 187 ++++++++++-- Makefile | 6 +- app/Cargo.toml | 11 +- app/src/cli.rs | 5 +- app/src/commands.rs | 10 +- app/src/commands/attestation.rs | 274 ++++++++++++++++++ app/src/commands/enclave.rs | 121 +------- enclave-modules/ecall-handler/Cargo.toml | 6 + .../enclave_manage/{ias.rs => attestation.rs} | 47 ++- .../src/enclave_manage/errors.rs | 20 +- .../src/enclave_manage/init_enclave.rs | 2 +- .../ecall-handler/src/enclave_manage/mod.rs | 4 +- .../src/enclave_manage/router.rs | 12 +- enclave-modules/environment/src/lib.rs | 5 + enclave-modules/remote-attestation/Cargo.toml | 7 +- .../remote-attestation/src/attestation.rs | 5 +- enclave-modules/remote-attestation/src/lib.rs | 3 + .../remote-attestation/src/simulate.rs | 167 +++++++++++ enclave-modules/runtime/Cargo.toml | 6 + enclave/Cargo.lock | 1 + enclave/Cargo.toml | 3 + modules/attestation-report/src/report.rs | 39 ++- modules/ecall-commands/Cargo.toml | 2 + modules/ecall-commands/src/enclave_manage.rs | 38 ++- modules/ecall-commands/src/errors.rs | 2 +- modules/ecall-commands/src/lib.rs | 2 + modules/enclave-api/Cargo.toml | 1 + modules/enclave-api/src/api/command.rs | 17 ++ modules/service/Cargo.toml | 5 + modules/types/src/time.rs | 1 - tests/integration/Cargo.toml | 4 + tools/cgen/Cargo.toml | 4 + 32 files changed, 819 insertions(+), 198 deletions(-) create mode 100644 app/src/commands/attestation.rs rename enclave-modules/ecall-handler/src/enclave_manage/{ias.rs => attestation.rs} (51%) create mode 100644 enclave-modules/remote-attestation/src/simulate.rs diff --git a/Cargo.lock b/Cargo.lock index 008e7509..1081511a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -326,6 +326,12 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bech32" version = "0.9.1" @@ -859,9 +865,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "context" @@ -1007,7 +1013,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.6", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle 2.4.1", "zeroize", ] @@ -1071,7 +1077,7 @@ checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" dependencies = [ "byteorder 1.4.3", "digest 0.9.0", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle-ng", "zeroize", ] @@ -1187,6 +1193,17 @@ dependencies = [ "const-oid", ] +[[package]] +name = "der" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "derivation-path" version = "0.2.0" @@ -1250,6 +1267,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.2", + "const-oid", "crypto-common", "subtle 2.4.1", ] @@ -1318,6 +1336,7 @@ version = "0.1.0" dependencies = [ "attestation-report", "commitments", + "enclave-environment", "flex-error", "lcp-proto", "lcp-types", @@ -1332,10 +1351,10 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", + "der 0.6.1", "elliptic-curve", "rfc6979", - "signature", + "signature 1.6.4", ] [[package]] @@ -1345,7 +1364,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" dependencies = [ "serde", - "signature", + "signature 1.6.4", ] [[package]] @@ -1356,7 +1375,7 @@ checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" dependencies = [ "curve25519-dalek-ng", "hex", - "rand_core 0.6.3", + "rand_core 0.6.4", "sha2 0.9.9", "zeroize", ] @@ -1402,12 +1421,12 @@ checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", - "der", + "der 0.6.1", "digest 0.10.6", "ff", "generic-array 0.14.6", "group", - "rand_core 0.6.3", + "rand_core 0.6.4", "sec1", "subtle 2.4.1", "zeroize", @@ -1431,6 +1450,15 @@ dependencies = [ "store", ] +[[package]] +name = "enclave-environment" +version = "0.1.0" +dependencies = [ + "light-client", + "light-client-registry", + "store", +] + [[package]] name = "encode_unicode" version = "0.3.6" @@ -1528,7 +1556,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle 2.4.1", ] @@ -1763,7 +1791,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle 2.4.1", ] @@ -2253,7 +2281,7 @@ dependencies = [ "serde_derive", "serde_json", "sha2 0.10.6", - "signature", + "signature 1.6.4", "strum", "subtle-encoding", "tendermint 0.28.0", @@ -2586,6 +2614,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "lazycell" @@ -2608,12 +2639,14 @@ dependencies = [ "host", "host-environment", "log 0.4.17", + "rsa", "serde", "serde_json", "service", "settings", "sgx_types", "sgx_urts", + "sha2 0.10.6", "store", "tokio", ] @@ -2691,6 +2724,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + [[package]] name = "librocksdb-sys" version = "0.8.0+7.4.4" @@ -3016,6 +3055,23 @@ dependencies = [ "serde", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" +dependencies = [ + "byteorder 1.4.3", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -3037,6 +3093,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.1" @@ -3057,6 +3124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -3365,6 +3433,15 @@ dependencies = [ "base64 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -3403,6 +3480,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.6", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.6", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.25" @@ -3631,7 +3729,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -3661,7 +3759,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86 0.2.16", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -3699,9 +3797,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom 0.2.7", ] @@ -3969,6 +4067,28 @@ dependencies = [ "url", ] +[[package]] +name = "rsa" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +dependencies = [ + "byteorder 1.4.3", + "const-oid", + "digest 0.10.6", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature 2.1.0", + "spki", + "subtle 2.4.1", + "zeroize", +] + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -4257,7 +4377,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct", - "der", + "der 0.6.1", "generic-array 0.14.6", "subtle 2.4.1", "zeroize", @@ -4382,6 +4502,7 @@ version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" dependencies = [ + "indexmap", "itoa", "ryu", "serde", @@ -4701,7 +4822,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ "digest 0.10.6", - "rand_core 0.6.3", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.6", + "rand_core 0.6.4", ] [[package]] @@ -4733,9 +4864,9 @@ checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "smallvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" @@ -4753,6 +4884,16 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.6", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -4922,7 +5063,7 @@ dependencies = [ "serde_json", "serde_repr", "sha2 0.9.9", - "signature", + "signature 1.6.4", "subtle 2.4.1", "subtle-encoding", "tendermint-proto 0.28.0", @@ -4951,7 +5092,7 @@ dependencies = [ "serde_json", "serde_repr", "sha2 0.10.6", - "signature", + "signature 1.6.4", "subtle 2.4.1", "subtle-encoding", "tendermint-proto 0.29.0", diff --git a/Makefile b/Makefile index ab3fcc98..917e1b35 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,11 @@ else SGX_ENCLAVE_MODE = "Development Mode" SGX_ENCLAVE_CONFIG = "enclave/Enclave.config.xml" SGX_SIGN_KEY = "enclave/Enclave_private.pem" - CARGO_FEATURES = --features=default + ifeq ($(SGX_MODE), HW) + CARGO_FEATURES = --features=default + else + CARGO_FEATURES = --features=default,sgx-sw + endif endif ######## CUSTOM Settings ######## diff --git a/app/Cargo.toml b/app/Cargo.toml index a00efe74..ab76efb8 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -19,7 +19,9 @@ anyhow = { version = "1.0.56" } clap = { version = "3.2", features = ["derive"] } dirs = "4.0" serde = { version = "1.0", default-features = false, features = ["alloc"] } -serde_json = { version = "1.0", default-features = false, features = ["alloc"] } +serde_json = { version = "1.0", default-features = false, features = ["alloc", "preserve_order"] } +rsa = { version = "0.9.2", features = ["pem"], optional = true } +sha2 = { version = "0.10.6", default-features = false, features = ["oid"], optional = true } host = { path = "../modules/host" } host-environment = { path = "../modules/host-environment" } @@ -32,3 +34,10 @@ store = { path = "../modules/store", features = ["rocksdbstore"] } [features] default = [] +sgx-sw = [ + "rsa", + "sha2", + "enclave-api/sgx-sw", + "ecall-commands/sgx-sw", + "service/sgx-sw" +] diff --git a/app/src/cli.rs b/app/src/cli.rs index b21fea44..45166010 100644 --- a/app/src/cli.rs +++ b/app/src/cli.rs @@ -1,13 +1,12 @@ +use crate::{commands::CliCmd, opts::Opts}; use anyhow::Result; use clap::Parser; -use crate::{commands::CliCmd, opts::Opts}; - /// Entry point for LCP CLI. #[derive(Debug, Parser)] #[clap( name = env!("CARGO_PKG_NAME"), - version = env!("CARGO_PKG_VERSION"), + version = concat!(env!("CARGO_PKG_VERSION"), "-", env!("SGX_MODE")), author = env!("CARGO_PKG_AUTHORS"), about = env!("CARGO_PKG_DESCRIPTION"), arg_required_else_help = true, diff --git a/app/src/commands.rs b/app/src/commands.rs index 57923330..1842ce51 100644 --- a/app/src/commands.rs +++ b/app/src/commands.rs @@ -1,4 +1,4 @@ -use self::{elc::ELCCmd, enclave::EnclaveCmd, service::ServiceCmd}; +use self::{attestation::AttestationCmd, elc::ELCCmd, enclave::EnclaveCmd, service::ServiceCmd}; use crate::{enclave::build_enclave_loader, opts::Opts}; use anyhow::Result; use clap::Parser; @@ -6,6 +6,7 @@ use host_environment::Environment; use std::sync::{Arc, RwLock}; use store::{host::HostStore, rocksdb::RocksDBStore}; +mod attestation; mod elc; mod enclave; mod service; @@ -15,9 +16,11 @@ mod service; pub enum CliCmd { #[clap(subcommand, display_order = 1, about = "Enclave subcommands")] Enclave(EnclaveCmd), - #[clap(subcommand, display_order = 2, about = "ELC subcommands")] + #[clap(subcommand, display_order = 2, about = "Attestation subcommands")] + Attestation(AttestationCmd), + #[clap(subcommand, display_order = 3, about = "ELC subcommands")] ELC(ELCCmd), - #[clap(subcommand, display_order = 3, about = "Service subcommands")] + #[clap(subcommand, display_order = 4, about = "Service subcommands")] Service(ServiceCmd), } @@ -29,6 +32,7 @@ impl CliCmd { host::set_environment(env).unwrap(); match self { CliCmd::Enclave(cmd) => cmd.run(opts, enclave_loader), + CliCmd::Attestation(cmd) => cmd.run(opts, enclave_loader), CliCmd::Service(cmd) => cmd.run(opts, enclave_loader), CliCmd::ELC(cmd) => cmd.run(opts, enclave_loader), } diff --git a/app/src/commands/attestation.rs b/app/src/commands/attestation.rs new file mode 100644 index 00000000..be7400a6 --- /dev/null +++ b/app/src/commands/attestation.rs @@ -0,0 +1,274 @@ +use crate::opts::Opts; +use anyhow::{bail, Result}; +use attestation_report::EndorsedAttestationVerificationReport; +use clap::Parser; +use ecall_commands::IASRemoteAttestationInput; +use enclave_api::{Enclave, EnclaveCommandAPI, EnclaveProtoAPI}; +use serde_json::json; +use settings::AVR_KEY_PATH; +use std::{ + fs::{read, remove_file, OpenOptions}, + io::Write, + path::PathBuf, +}; +use store::transaction::CommitStore; + +// `enclave` subcommand +#[derive(Debug, Parser)] +pub enum AttestationCmd { + #[clap(display_order = 1, about = "Remote Attestation with IAS")] + IAS(IASRemoteAttestation), + #[clap(display_order = 2, about = "Show the AVR info")] + ShowAVR(ShowAVR), + #[cfg(feature = "sgx-sw")] + #[clap(display_order = 3, about = "Simulate Remote Attestation")] + Simulate(SimulateRemoteAttestation), +} + +impl AttestationCmd { + pub fn run( + &self, + opts: &Opts, + enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>) -> Result>, + ) -> Result<()> + where + S: CommitStore, + Enclave: EnclaveProtoAPI, + { + let home = opts.get_home(); + match self { + AttestationCmd::IAS(cmd) => { + if !home.exists() { + bail!("home directory doesn't exist at {:?}", home); + } + run_ias_remote_attestation(enclave_loader(opts, cmd.enclave.as_ref())?, home, cmd) + } + #[cfg(feature = "sgx-sw")] + AttestationCmd::Simulate(cmd) => { + if !home.exists() { + bail!("home directory doesn't exist at {:?}", home); + } + run_simulate_remote_attestation( + enclave_loader(opts, cmd.enclave.as_ref())?, + home, + cmd, + ) + } + AttestationCmd::ShowAVR(cmd) => { + if !home.exists() { + bail!("home directory doesn't exist at {:?}", home); + } + run_show_avr(opts, home, cmd) + } + } + } +} + +#[derive(Clone, Debug, Parser, PartialEq)] +pub struct IASRemoteAttestation { + /// Path to the enclave binary + #[clap(long = "enclave", help = "Path to the enclave binary")] + pub enclave: Option, + + /// Boolean flag to overwrite an enclave key and AVR if it already exists + #[clap( + long = "force", + help = "Boolean flag to overwrite an enclave key and AVR if it already exists." + )] + pub force: bool, +} + +fn run_ias_remote_attestation, S: CommitStore>( + enclave: E, + home: PathBuf, + cmd: &IASRemoteAttestation, +) -> Result<()> { + let spid = std::env::var("SPID")?; + let ias_key = std::env::var("IAS_KEY")?; + + let avr_path = check_and_get_avr_path(home, cmd.force)?; + match enclave.ias_remote_attestation(IASRemoteAttestationInput { + spid: spid.as_bytes().to_vec(), + ias_key: ias_key.as_bytes().to_vec(), + }) { + Ok(res) => save_avr(&res.report, &avr_path), + Err(e) => bail!("failed to perform IAS Remote Attestation: {:?}!", e), + } +} + +#[derive(Clone, Debug, Parser, PartialEq)] +pub struct ShowAVR { + /// Path to the enclave binary + #[clap(long = "enclave", help = "Path to the enclave binary")] + pub enclave: Option, + #[clap(long = "validate", help = "Check if the AVR is valid for the enclave")] + pub validate: bool, +} + +fn run_show_avr(opts: &Opts, home: PathBuf, cmd: &ShowAVR) -> Result<()> { + let avr_path = home.join(AVR_KEY_PATH); + if !avr_path.exists() { + bail!("AVR not found: {:?}", avr_path.as_path()); + } + let report: EndorsedAttestationVerificationReport = + serde_json::from_slice(read(avr_path)?.as_slice())?; + let avr = report.get_avr()?; + let quote = avr.parse_quote()?; + if cmd.validate { + let enclave_path = cmd.enclave.clone().unwrap_or(opts.default_enclave()); + if !enclave_path.exists() { + bail!("Enclave not found: {:?}", enclave_path.as_path()); + } + let metadata = + host::sgx_get_metadata(cmd.enclave.clone().unwrap_or(opts.default_enclave()))?; + quote.match_metadata(&metadata)?; + } + println!( + "{}", + json! {{ + "mrenclave": format!("0x{}", hex::encode(quote.get_mrenclave().m)), + "enclave_key": format!("0x{}", quote.get_enclave_key_address()?.to_hex_string()), + "timestamp": avr.timestamp + }} + ); + Ok(()) +} + +fn check_and_get_avr_path(home: PathBuf, force: bool) -> Result { + let avr_path = home.join(AVR_KEY_PATH); + if avr_path.exists() { + if force { + remove_file(&avr_path)?; + } else { + bail!( + "Init Key Failed: AVR path {:?} already exists", + avr_path.as_path(), + ); + } + } + Ok(avr_path) +} + +#[cfg(feature = "sgx-sw")] +#[derive(Clone, Debug, Parser, PartialEq)] +pub struct SimulateRemoteAttestation { + /// Path to the enclave binary + #[clap(long = "enclave", help = "Path to the enclave binary")] + pub enclave: Option, + + /// Boolean flag to overwrite an enclave key and AVR if it already exists + #[clap( + long = "force", + help = "Boolean flag to overwrite an enclave key and AVR if it already exists." + )] + pub force: bool, + + #[clap(long = "signing_cert_path", help = "TODO")] + pub signing_cert_path: PathBuf, + + /// Path to a PEM-encoded file that contains PKCS#8 private key + #[clap( + long = "signing_key", + help = "Path to a PEM-encoded file that contains PKCS#8 private key" + )] + pub signing_key_path: PathBuf, + + #[clap(long = "validate_cert", default_value = "true")] + pub validate_cert: bool, + + #[clap( + long = "advisory_ids", + value_delimiter = ',', + help = "Intel security advisory IDs to include in the report" + )] + pub advisory_ids: Vec, + + #[clap( + long = "isv_enclave_quote_status", + default_value = "OK", + help = "Quote status to include in the report" + )] + pub isv_enclave_quote_status: String, +} + +#[cfg(feature = "sgx-sw")] +fn run_simulate_remote_attestation, S: CommitStore>( + enclave: E, + home: PathBuf, + cmd: &SimulateRemoteAttestation, +) -> Result<()> { + use rsa::{ + pkcs1v15::SigningKey, + pkcs8::DecodePrivateKey, + signature::{SignatureEncoding, Signer}, + traits::PublicKeyParts, + RsaPrivateKey, + }; + use sha2::Sha256; + use std::fs; + + let pk = RsaPrivateKey::read_pkcs8_pem_file(&cmd.signing_key_path)?; + let pk_modulus = pk.to_public_key().n().to_bytes_be(); + let signing_key = SigningKey::::new(pk); + let signing_cert = fs::read(&cmd.signing_cert_path)?; + + if cmd.validate_cert { + use std::process::Command; + let ret = Command::new("openssl") + .args([ + "x509", + "-noout", + "-modulus", + "-in", + cmd.signing_cert_path.to_str().unwrap(), + ]) + .output()?; + if !ret.status.success() { + bail!( + "failed to exec openssl command: status={:?} error={:?}", + ret.status, + ret.stderr + ) + } + let output = String::from_utf8(ret.stdout)?; + if let Some(modulus) = output.trim().strip_prefix("Modulus=") { + let modulus = + hex::decode(modulus).map_err(|e| anyhow::anyhow!("hex decode error: {:?}", e))?; + if pk_modulus != modulus { + bail!("modulus mismatch: {:X?} != {:X?}", pk_modulus, modulus) + } + } else { + bail!("unexpected output: {}", output) + } + } + + let avr_path = check_and_get_avr_path(home, cmd.force)?; + let avr = + match enclave.simulate_remote_attestation(ecall_commands::SimulateRemoteAttestationInput { + advisory_ids: cmd.advisory_ids.clone(), + isv_enclave_quote_status: cmd.isv_enclave_quote_status.clone(), + }) { + Ok(res) => res.avr, + Err(e) => bail!("failed to simulate Remote Attestation: {:?}!", e), + }; + + let avr_json = avr.to_canonical_json()?; + let signature = signing_key.sign(avr_json.as_bytes()).to_vec(); + let eavr = EndorsedAttestationVerificationReport { + avr: avr_json, + signature, + signing_cert, + }; + save_avr(&eavr, &avr_path) +} + +fn save_avr(avr: &EndorsedAttestationVerificationReport, path: &PathBuf) -> Result<()> { + let s = serde_json::to_string(avr)?; + // NOTE: Currently, enclave key and AVR file operations are not atomic. + // Therefore, if the service is running in the background, the service may read incomplete data (and its attempt will be failed). + // To solve this problem, consider using the traditional `rename` approach or a File DB such as rocksdb. + let mut f = OpenOptions::new().write(true).create_new(true).open(path)?; + f.write_all(s.as_bytes())?; + f.flush()?; + Ok(()) +} diff --git a/app/src/commands/enclave.rs b/app/src/commands/enclave.rs index 89e873a6..7eae64da 100644 --- a/app/src/commands/enclave.rs +++ b/app/src/commands/enclave.rs @@ -1,17 +1,12 @@ use crate::opts::Opts; use anyhow::{bail, Result}; -use attestation_report::EndorsedAttestationVerificationReport; use clap::Parser; -use ecall_commands::{IASRemoteAttestationInput, InitEnclaveInput}; +use ecall_commands::InitEnclaveInput; use enclave_api::{Enclave, EnclaveCommandAPI, EnclaveProtoAPI}; use log::*; use serde_json::json; -use settings::{AVR_KEY_PATH, SEALED_ENCLAVE_KEY_PATH}; -use std::{ - fs::{read, remove_file, OpenOptions}, - io::Write, - path::PathBuf, -}; +use settings::SEALED_ENCLAVE_KEY_PATH; +use std::{fs::remove_file, path::PathBuf}; use store::transaction::CommitStore; // `enclave` subcommand @@ -21,10 +16,6 @@ pub enum EnclaveCmd { InitKey(InitKey), #[clap(about = "Print metadata of the enclave")] Metadata(Metadata), - #[clap(about = "Perform Remote Attestation with IAS")] - IASRemoteAttestation(IASRemoteAttestation), - #[clap(about = "Show the AVR info")] - ShowAVR(ShowAVR), } impl EnclaveCmd { @@ -52,18 +43,6 @@ impl EnclaveCmd { } run_print_metadata(opts, cmd) } - EnclaveCmd::IASRemoteAttestation(cmd) => { - if !home.exists() { - bail!("home directory doesn't exist at {:?}", home); - } - run_ias_remote_attestation(enclave_loader(opts, cmd.enclave.as_ref())?, home, cmd) - } - EnclaveCmd::ShowAVR(cmd) => { - if !home.exists() { - bail!("home directory doesn't exist at {:?}", home); - } - run_show_avr(opts, home, cmd) - } } } } @@ -122,97 +101,3 @@ fn run_print_metadata(opts: &Opts, cmd: &Metadata) -> Result<()> { ); Ok(()) } - -#[derive(Clone, Debug, Parser, PartialEq)] -pub struct IASRemoteAttestation { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to the enclave binary")] - pub enclave: Option, - - /// Boolean flag to overwrite an enclave key and AVR if it already exists - #[clap( - long = "force", - help = "Boolean flag to overwrite an enclave key and AVR if it already exists." - )] - pub force: bool, -} - -fn run_ias_remote_attestation, S: CommitStore>( - enclave: E, - home: PathBuf, - cmd: &IASRemoteAttestation, -) -> Result<()> { - let spid = std::env::var("SPID")?; - let ias_key = std::env::var("IAS_KEY")?; - - let avr_path = home.join(AVR_KEY_PATH); - if avr_path.exists() { - if cmd.force { - remove_file(&avr_path)?; - } else { - bail!( - "Init Key Failed: AVR path {:?} already exists", - avr_path.as_path(), - ); - } - } - - match enclave.ias_remote_attestation(IASRemoteAttestationInput { - spid: spid.as_bytes().to_vec(), - ias_key: ias_key.as_bytes().to_vec(), - }) { - Ok(res) => { - let s = serde_json::to_string(&res.report)?; - info!("successfully got the AVR"); - // NOTE: Currently, enclave key and AVR file operations are not atomic. - // Therefore, if the service is running in the background, the service may read incomplete data (and its attempt will be failed). - // To solve this problem, consider using the traditional `rename` approach or a File DB such as rocksdb. - let mut f = OpenOptions::new() - .write(true) - .create_new(true) - .open(&avr_path)?; - f.write_all(s.as_bytes())?; - f.flush()?; - Ok(()) - } - Err(e) => bail!("IAS Remote Attestation Failed {:?}!", e), - } -} - -#[derive(Clone, Debug, Parser, PartialEq)] -pub struct ShowAVR { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to the enclave binary")] - pub enclave: Option, - #[clap(long = "validate", help = "Check if the AVR is valid for the enclave")] - pub validate: bool, -} - -fn run_show_avr(opts: &Opts, home: PathBuf, cmd: &ShowAVR) -> Result<()> { - let avr_path = home.join(AVR_KEY_PATH); - if !avr_path.exists() { - bail!("AVR not found: {:?}", avr_path.as_path()); - } - let report: EndorsedAttestationVerificationReport = - serde_json::from_slice(read(avr_path)?.as_slice())?; - let avr = report.get_avr()?; - let quote = avr.parse_quote()?; - if cmd.validate { - let enclave_path = cmd.enclave.clone().unwrap_or(opts.default_enclave()); - if !enclave_path.exists() { - bail!("Enclave not found: {:?}", enclave_path.as_path()); - } - let metadata = - host::sgx_get_metadata(cmd.enclave.clone().unwrap_or(opts.default_enclave()))?; - quote.match_metadata(&metadata)?; - } - println!( - "{}", - json! {{ - "mrenclave": format!("0x{}", hex::encode(quote.get_mrenclave().m)), - "enclave_key": format!("0x{}", quote.get_enclave_key_address()?.to_hex_string()), - "timestamp": avr.timestamp - }} - ); - Ok(()) -} diff --git a/enclave-modules/ecall-handler/Cargo.toml b/enclave-modules/ecall-handler/Cargo.toml index 7aa4c99c..971d2f85 100644 --- a/enclave-modules/ecall-handler/Cargo.toml +++ b/enclave-modules/ecall-handler/Cargo.toml @@ -26,3 +26,9 @@ ecall-commands = { path = "../../modules/ecall-commands", default-features = fal commitments = { path = "../../modules/commitments", default-features = false, features = ["prover"] } light-client = { path = "../../modules/light-client", default-features = false } store = { path = "../../modules/store", default-features = false } + +[features] +sgx-sw = [ + "ecall-commands/sgx-sw", + "enclave-remote-attestation/sgx-sw" +] diff --git a/enclave-modules/ecall-handler/src/enclave_manage/ias.rs b/enclave-modules/ecall-handler/src/enclave_manage/attestation.rs similarity index 51% rename from enclave-modules/ecall-handler/src/enclave_manage/ias.rs rename to enclave-modules/ecall-handler/src/enclave_manage/attestation.rs index 341686da..46e628b8 100644 --- a/enclave-modules/ecall-handler/src/enclave_manage/ias.rs +++ b/enclave-modules/ecall-handler/src/enclave_manage/attestation.rs @@ -9,28 +9,52 @@ use enclave_remote_attestation::{ use lcp_types::Time; use sgx_types::{sgx_quote_sign_type_t, sgx_spid_t}; -pub fn remote_attestation( +pub(crate) fn ias_remote_attestation( input: IASRemoteAttestationInput, params: CommandParams, ) -> Result { - let spid = decode_spid(&input.spid)?; + input.validate()?; + let key_manager = KeyManager::new(params.home); + let pub_key = key_manager + .get_enclave_key() + .ok_or(Error::enclave_key_not_found())? + .get_pubkey(); + let report = { + let spid = decode_spid(&input.spid)?; + let report = create_attestation_report( + pub_key.as_report_data(), + sgx_quote_sign_type_t::SGX_UNLINKABLE_SIGNATURE, + spid, + &input.ias_key, + )?; + verify_report(&report, Time::now())?; + report + }; + validate_quote_status(&report.get_avr()?)?; + Ok(IASRemoteAttestationResult { report }) +} + +#[cfg(feature = "sgx-sw")] +pub(crate) fn simulate_remote_attestation( + input: ecall_commands::SimulateRemoteAttestationInput, + params: CommandParams, +) -> Result { + input.validate()?; let key_manager = KeyManager::new(params.home); let pub_key = key_manager .get_enclave_key() .ok_or(Error::enclave_key_not_found())? .get_pubkey(); - let report = create_attestation_report( + + let avr = enclave_remote_attestation::simulate::create_attestation_report( pub_key.as_report_data(), sgx_quote_sign_type_t::SGX_UNLINKABLE_SIGNATURE, - spid, - &input.ias_key, + input.advisory_ids, + input.isv_enclave_quote_status, )?; - - verify_report(&report, Time::now())?; - validate_quote_status(&report.get_avr()?)?; - - Ok(IASRemoteAttestationResult { report }) + validate_quote_status(&avr)?; + Ok(ecall_commands::SimulateRemoteAttestationResult { avr }) } fn decode_spid(hex: &[u8]) -> Result { @@ -39,7 +63,8 @@ fn decode_spid(hex: &[u8]) -> Result { let hex = &hex.trim(); if hex.len() < 16 * 2 { - Err(Error::invalid_sp_id_length(hex.len())) + // Err(Error::invalid_sp_id_length(hex.len())) + panic!("invalid"); } else { let decoded_vec = hex::decode(hex).unwrap(); spid.id.copy_from_slice(&decoded_vec[..16]); diff --git a/enclave-modules/ecall-handler/src/enclave_manage/errors.rs b/enclave-modules/ecall-handler/src/enclave_manage/errors.rs index 8e0dc222..75dc5c69 100644 --- a/enclave-modules/ecall-handler/src/enclave_manage/errors.rs +++ b/enclave-modules/ecall-handler/src/enclave_manage/errors.rs @@ -28,17 +28,13 @@ define_error! { [enclave_remote_attestation::Error] |_| { "RemoteAttestation error" }, + EcallCommand + [ecall_commands::Error] + |_| { "EcallCommand error" }, + Time [lcp_types::TimeError] - |_| { "Time error" }, - - InvalidSpIdLength - { - length: usize - } - |e| { - format_args!("invalid SPID length: expected=32 actual={}", e.length) - } + |_| { "Time error" } } } @@ -59,3 +55,9 @@ impl From for Error { Error::crypto(err) } } + +impl From for Error { + fn from(err: ecall_commands::Error) -> Self { + Error::ecall_command(err) + } +} diff --git a/enclave-modules/ecall-handler/src/enclave_manage/init_enclave.rs b/enclave-modules/ecall-handler/src/enclave_manage/init_enclave.rs index 50094697..06ffcfad 100644 --- a/enclave-modules/ecall-handler/src/enclave_manage/init_enclave.rs +++ b/enclave-modules/ecall-handler/src/enclave_manage/init_enclave.rs @@ -3,7 +3,7 @@ use crate::prelude::*; use crypto::KeyManager; use ecall_commands::{CommandParams, InitEnclaveInput, InitEnclaveResult}; -pub fn init_enclave( +pub(crate) fn init_enclave( _: InitEnclaveInput, params: CommandParams, ) -> Result { diff --git a/enclave-modules/ecall-handler/src/enclave_manage/mod.rs b/enclave-modules/ecall-handler/src/enclave_manage/mod.rs index dece8348..72d242bb 100644 --- a/enclave-modules/ecall-handler/src/enclave_manage/mod.rs +++ b/enclave-modules/ecall-handler/src/enclave_manage/mod.rs @@ -1,8 +1,8 @@ pub use errors::Error; -pub use init_enclave::init_enclave; +// pub use init_enclave::init_enclave; pub use router::dispatch; +mod attestation; mod errors; -mod ias; mod init_enclave; mod router; diff --git a/enclave-modules/ecall-handler/src/enclave_manage/router.rs b/enclave-modules/ecall-handler/src/enclave_manage/router.rs index bf7e5825..b1b4764f 100644 --- a/enclave-modules/ecall-handler/src/enclave_manage/router.rs +++ b/enclave-modules/ecall-handler/src/enclave_manage/router.rs @@ -1,4 +1,6 @@ -use crate::enclave_manage::{ias::remote_attestation, init_enclave, Error}; +use crate::enclave_manage::{ + attestation::ias_remote_attestation, init_enclave::init_enclave, Error, +}; use crate::prelude::*; use ecall_commands::{CommandParams, CommandResult, EnclaveManageCommand, EnclaveManageResult}; @@ -13,8 +15,14 @@ pub fn dispatch( init_enclave(input, params)?, )), IASRemoteAttestation(input) => CommandResult::EnclaveManage( - EnclaveManageResult::IASRemoteAttestation(remote_attestation(input, params)?), + EnclaveManageResult::IASRemoteAttestation(ias_remote_attestation(input, params)?), ), + #[cfg(feature = "sgx-sw")] + SimulateRemoteAttestation(input) => { + CommandResult::EnclaveManage(EnclaveManageResult::SimulateRemoteAttestation( + crate::enclave_manage::attestation::simulate_remote_attestation(input, params)?, + )) + } }; Ok(res) } diff --git a/enclave-modules/environment/src/lib.rs b/enclave-modules/environment/src/lib.rs index 5271bae4..d4e744c1 100644 --- a/enclave-modules/environment/src/lib.rs +++ b/enclave-modules/environment/src/lib.rs @@ -26,3 +26,8 @@ pub use environment_impl::Environment; mod environment; #[cfg(feature = "environment_impl")] mod environment_impl; + +pub const fn is_sgx_hw_mode() -> bool { + let mode = env!("SGX_MODE").as_bytes(); + mode.len() == 2 && mode[0] == 'H' as u8 && mode[1] == 'W' as u8 +} diff --git a/enclave-modules/remote-attestation/Cargo.toml b/enclave-modules/remote-attestation/Cargo.toml index 606bb398..ba585091 100644 --- a/enclave-modules/remote-attestation/Cargo.toml +++ b/enclave-modules/remote-attestation/Cargo.toml @@ -3,8 +3,6 @@ name = "enclave-remote-attestation" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] sgx_types = { rev = "v1.1.6", git = "https://github.com/apache/incubator-teaclave-sgx-sdk" } sgx_tstd = { rev = "v1.1.6", git = "https://github.com/apache/incubator-teaclave-sgx-sdk", features = ["net"] } @@ -34,3 +32,8 @@ crypto = { path = "../../modules/crypto", default-features = false } attestation-report = { path = "../../modules/attestation-report", default-features = false } settings = { path = "../../modules/settings", default-features = false } ocall-commands = { path = "../../modules/ocall-commands", default-features = false } + +[features] +sgx-sw = [ + "sgx_tstd/untrusted_time" +] diff --git a/enclave-modules/remote-attestation/src/attestation.rs b/enclave-modules/remote-attestation/src/attestation.rs index 5c4a2ea2..cbe04db9 100644 --- a/enclave-modules/remote-attestation/src/attestation.rs +++ b/enclave-modules/remote-attestation/src/attestation.rs @@ -18,7 +18,7 @@ use sgx_tstd::{ use sgx_types::{c_int, sgx_spid_t}; use sgx_types::{sgx_quote_nonce_t, sgx_quote_sign_type_t, sgx_report_data_t}; -const REPORT_DATA_SIZE: usize = 32; +pub const REPORT_DATA_SIZE: usize = 32; pub const DEV_HOSTNAME: &str = "api.trustedservices.intel.com"; @@ -33,7 +33,6 @@ pub const SIGRL_SUFFIX: &str = "/sgx/dev/attestation/v4/sigrl/"; pub const REPORT_SUFFIX: &str = "/sgx/dev/attestation/v4/report"; //input: pub_k: &sgx_ec256_public_t, todo: make this the pubkey of the node -#[allow(const_err)] pub fn create_attestation_report( report_data: sgx_report_data_t, sign_type: sgx_quote_sign_type_t, @@ -385,7 +384,7 @@ pub fn make_ias_client_config() -> rustls::ClientConfig { config } -fn as_u32_le(array: &[u8; 4]) -> u32 { +pub(crate) fn as_u32_le(array: &[u8; 4]) -> u32 { ((array[0] as u32) << 0) + ((array[1] as u32) << 8) + ((array[2] as u32) << 16) diff --git a/enclave-modules/remote-attestation/src/lib.rs b/enclave-modules/remote-attestation/src/lib.rs index 5cf35af4..66d05182 100644 --- a/enclave-modules/remote-attestation/src/lib.rs +++ b/enclave-modules/remote-attestation/src/lib.rs @@ -24,3 +24,6 @@ pub use errors::Error; pub mod attestation; mod errors; pub mod report; + +#[cfg(feature = "sgx-sw")] +pub mod simulate; diff --git a/enclave-modules/remote-attestation/src/simulate.rs b/enclave-modules/remote-attestation/src/simulate.rs new file mode 100644 index 00000000..5fc91148 --- /dev/null +++ b/enclave-modules/remote-attestation/src/simulate.rs @@ -0,0 +1,167 @@ +use crate::attestation::REPORT_DATA_SIZE; +use crate::errors::Error; +use crate::prelude::*; +use attestation_report::AttestationVerificationReport; +use crypto::sgx::rand::fill_bytes; +use host_api::remote_attestation::{get_quote, init_quote}; +use itertools::Itertools; +use log::*; +use ocall_commands::{GetQuoteInput, GetQuoteResult, InitQuoteResult}; +use settings::{SigningMethod, SIGNING_METHOD}; +use sgx_tcrypto::rsgx_sha256_slice; +use sgx_tse::{rsgx_create_report, rsgx_verify_report}; +use sgx_types::{sgx_quote_nonce_t, sgx_quote_sign_type_t, sgx_report_data_t}; + +pub fn create_attestation_report( + report_data: sgx_report_data_t, + sign_type: sgx_quote_sign_type_t, + advisory_ids: Vec, + isv_enclave_quote_status: String, +) -> Result { + // Workflow: + // (1) ocall to get the target_info structure and epid_group_id + // (1.5) get sigrl + // (2) call sgx_create_report with target_info+data, produce an sgx_report_t + // (3) ocall to sgx_get_quote to generate (*mut sgx-quote_t, uint32_t) + + // (1) get target_info + epid_group_id + + let InitQuoteResult { + target_info, + epid_group_id, + } = init_quote().map_err(Error::host_api)?; + + trace!("EPID group = {:?}", epid_group_id); + + // (2) Generate the report + // Fill secp256k1 public key into report_data + // this is given as a parameter + + let report = match rsgx_create_report(&target_info, &report_data) { + Ok(r) => { + match SIGNING_METHOD { + SigningMethod::MRENCLAVE => { + trace!( + "Report creation => success. Using MR_SIGNER: {:?}", + r.body.mr_signer.m + ); + } + SigningMethod::MRSIGNER => { + trace!( + "Report creation => success. Got MR_ENCLAVE {:?}", + r.body.mr_signer.m + ); + } + SigningMethod::NONE => { + trace!("Report creation => success. Not using any verification"); + } + } + r + } + Err(e) => { + return Err(Error::sgx_error(e, "Report creation => failed".to_string())); + } + }; + + let mut quote_nonce = sgx_quote_nonce_t { rand: [0; 16] }; + fill_bytes(&mut quote_nonce.rand) + .map_err(|e| Error::sgx_error(e, "failed to fill_bytes".to_string()))?; + trace!("Nonce generated successfully"); + + // (3) Generate the quote + // Args: + // 1. sigrl: ptr + len + // 2. report: ptr 432bytes + // 3. linkable: u32, unlinkable=0, linkable=1 + // 4. spid: sgx_spid_t ptr 16bytes + // 5. sgx_quote_nonce_t ptr 16bytes + // 6. p_sig_rl + sigrl size ( same to sigrl) + // 7. [out]p_qe_report need further check + // 8. [out]p_quote + // 9. quote_size + + let GetQuoteResult { qe_report, quote } = get_quote(GetQuoteInput { + sigrl: vec![], + report, + quote_type: sign_type, + spid: Default::default(), + nonce: quote_nonce, + }) + .map_err(Error::host_api)?; + + // Added 09-28-2018 + // Perform a check on qe_report to verify if the qe_report is valid + match rsgx_verify_report(&qe_report) { + Ok(()) => trace!("rsgx_verify_report passed!"), + Err(e) => { + return Err(Error::sgx_error(e, "rsgx_verify_report failed".to_string())); + } + } + + // Check if the qe_report is produced on the same platform + if target_info.mr_enclave.m != qe_report.body.mr_enclave.m + || target_info.attributes.flags != qe_report.body.attributes.flags + || target_info.attributes.xfrm != qe_report.body.attributes.xfrm + { + return Err(Error::unexpected_report( + "qe_report does not match current target_info!".to_string(), + )); + } + + trace!("QE report check passed"); + + // Check qe_report to defend against replay attack + // The purpose of p_qe_report is for the ISV enclave to confirm the QUOTE + // it received is not modified by the untrusted SW stack, and not a replay. + // The implementation in QE is to generate a REPORT targeting the ISV + // enclave (target info from p_report) , with the lower 32Bytes in + // report.data = SHA256(p_nonce||p_quote). The ISV enclave can verify the + // p_qe_report and report.data to confirm the QUOTE has not be modified and + // is not a replay. It is optional. + + let mut rhs_vec: Vec = quote_nonce.rand.to_vec(); + rhs_vec.extend("e); + let rhs_hash = rsgx_sha256_slice(&rhs_vec[..]).unwrap(); + let lhs_hash = &qe_report.body.report_data.d[..REPORT_DATA_SIZE]; + + trace!("Report rhs hash = {:02X}", rhs_hash.iter().format("")); + trace!("Report lhs hash = {:02X}", lhs_hash.iter().format("")); + + if rhs_hash != lhs_hash { + return Err(Error::unexpected_quote( + format!("Quote is tampered!: {:?} != {:?}", rhs_hash, lhs_hash).to_string(), + )); + } + + create_simulate_avr(quote, advisory_ids, isv_enclave_quote_status) +} + +fn create_simulate_avr( + quote: Vec, + advisory_ids: Vec, + isv_enclave_quote_status: String, +) -> Result { + use chrono::{DateTime, NaiveDateTime, Utc}; + use sgx_tstd::time::SystemTime; + + let now = { + let now = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(); + let now = NaiveDateTime::from_timestamp_millis(now.as_millis() as i64).unwrap(); + DateTime::::from_utc(now, Utc) + }; + // TODO more configurable via simulation command + Ok(AttestationVerificationReport { + id: "23856791181030202675484781740313693463".to_string(), + // TODO refactoring + timestamp: format!("{}000", now.format("%Y-%m-%dT%H:%M:%S%.f%z").to_string().strip_suffix("+0000").unwrap().to_string()), + version: 4, + advisory_url: "https://security-center.intel.com".to_string(), + advisory_ids, + isv_enclave_quote_status, + platform_info_blob: Some("1502006504000F00000F0F020202800E0000000000000000000D00000C000000020000000000000BF154C1BDAEFB9BCA30B8D7F52CD6307340650A5973262D8C99CFA64D783507294F0FE90F467E0208EB14E9E2181C34E521BF8B43D91017D5697C490094E24D5F96".to_string()), + isv_enclave_quote_body: base64::encode(quote), + ..Default::default() + }) +} diff --git a/enclave-modules/runtime/Cargo.toml b/enclave-modules/runtime/Cargo.toml index 00f90800..18ee1d78 100644 --- a/enclave-modules/runtime/Cargo.toml +++ b/enclave-modules/runtime/Cargo.toml @@ -21,3 +21,9 @@ light-client-registry = { path = "../../modules/light-client-registry", default- store = { path = "../../modules/store", default-features = false } ecall-commands = { path = "../../modules/ecall-commands", default-features = false } + +[features] +sgx-sw = [ + "ecall-handler/sgx-sw", + "ecall-commands/sgx-sw" +] diff --git a/enclave/Cargo.lock b/enclave/Cargo.lock index 4cdfcdd8..83420d8f 100644 --- a/enclave/Cargo.lock +++ b/enclave/Cargo.lock @@ -451,6 +451,7 @@ version = "0.1.0" dependencies = [ "attestation-report", "commitments", + "enclave-environment", "flex-error", "lcp-proto", "lcp-types", diff --git a/enclave/Cargo.toml b/enclave/Cargo.toml index 988d0e7d..b75d1251 100644 --- a/enclave/Cargo.toml +++ b/enclave/Cargo.toml @@ -10,6 +10,9 @@ crate-type = ["staticlib"] [features] default = [] +sgx-sw = [ + "enclave-runtime/sgx-sw" +] [dependencies] sgx_tstd = { rev = "v1.1.6", git = "https://github.com/apache/incubator-teaclave-sgx-sdk" } diff --git a/modules/attestation-report/src/report.rs b/modules/attestation-report/src/report.rs index 5440831d..1cd42d9d 100644 --- a/modules/attestation-report/src/report.rs +++ b/modules/attestation-report/src/report.rs @@ -5,6 +5,7 @@ use core::fmt::Debug; use crypto::Address; use lcp_types::Time; use serde::{Deserialize, Serialize}; +use serde_json::json; use sgx_types::{metadata::metadata_t, sgx_measurement_t, sgx_quote_t}; use tendermint::Time as TmTime; @@ -57,22 +58,6 @@ pub struct AttestationVerificationReport { pub advisory_ids: Vec, } -impl TryFrom<&AttestationVerificationReport> for Vec { - type Error = serde_json::Error; - - fn try_from(value: &AttestationVerificationReport) -> Result { - serde_json::to_vec(value) - } -} - -impl TryFrom<&[u8]> for AttestationVerificationReport { - type Error = serde_json::Error; - - fn try_from(value: &[u8]) -> Result { - serde_json::from_slice(value) - } -} - impl AttestationVerificationReport { pub fn parse_quote(&self) -> Result { if self.version != 4 { @@ -99,6 +84,28 @@ impl AttestationVerificationReport { attestation_time, }) } + + pub fn to_canonical_json(&self) -> Result { + if self.version != 4 { + return Err(Error::unexpected_attestation_report_version( + 4, + self.version, + )); + } + Ok(format!( + "{}", + json!({ + "id": self.id, + "timestamp": self.timestamp, + "version": self.version, + "advisoryURL": self.advisory_url, + "advisoryIDs": self.advisory_ids, + "isvEnclaveQuoteStatus": self.isv_enclave_quote_status, + "platformInfoBlob": self.platform_info_blob, + "isvEnclaveQuoteBody": self.isv_enclave_quote_body + }) + )) + } } #[derive(Clone, Debug, PartialEq)] diff --git a/modules/ecall-commands/Cargo.toml b/modules/ecall-commands/Cargo.toml index de64a51a..8df39c59 100644 --- a/modules/ecall-commands/Cargo.toml +++ b/modules/ecall-commands/Cargo.toml @@ -8,6 +8,7 @@ serde = { version = "1.0", default-features = false, features = ["alloc", "deriv serde_json = { version = "1.0", default-features = false, features = ["alloc"] } flex-error = { version = "0.4.4", default-features = false } +enclave-environment = { path = "../../enclave-modules/environment", default-features = false } commitments = { path = "../commitments", default-features = false } lcp-types = { path = "../types", default-features = false } attestation-report = { path = "../attestation-report", default-features = false } @@ -17,3 +18,4 @@ lcp-proto = { path = "../../proto", default-features = false } [features] default = ["std"] std = ["lcp-types/std"] +sgx-sw = [] diff --git a/modules/ecall-commands/src/enclave_manage.rs b/modules/ecall-commands/src/enclave_manage.rs index d39534fc..ea5dc25d 100644 --- a/modules/ecall-commands/src/enclave_manage.rs +++ b/modules/ecall-commands/src/enclave_manage.rs @@ -1,4 +1,4 @@ -use crate::prelude::*; +use crate::{prelude::*, Error}; use attestation_report::EndorsedAttestationVerificationReport; use serde::{Deserialize, Serialize}; @@ -6,6 +6,8 @@ use serde::{Deserialize, Serialize}; pub enum EnclaveManageCommand { InitEnclave(InitEnclaveInput), IASRemoteAttestation(IASRemoteAttestationInput), + #[cfg(feature = "sgx-sw")] + SimulateRemoteAttestation(SimulateRemoteAttestationInput), } #[derive(Serialize, Deserialize, Debug, Default)] @@ -17,10 +19,38 @@ pub struct IASRemoteAttestationInput { pub ias_key: Vec, } +impl IASRemoteAttestationInput { + pub fn validate(&self) -> Result<(), Error> { + if self.spid.len() == 32 && self.ias_key.len() == 32 { + Ok(()) + } else { + Err(Error::invalid_argument( + "either or both of SPID and IAS_KEY are invalid".to_string(), + )) + } + } +} + +#[cfg(feature = "sgx-sw")] +#[derive(Serialize, Deserialize, Debug)] +pub struct SimulateRemoteAttestationInput { + pub advisory_ids: Vec, + pub isv_enclave_quote_status: String, +} + +#[cfg(feature = "sgx-sw")] +impl SimulateRemoteAttestationInput { + pub fn validate(&self) -> Result<(), Error> { + Ok(()) + } +} + #[derive(Serialize, Deserialize, Debug)] pub enum EnclaveManageResult { InitEnclave(InitEnclaveResult), IASRemoteAttestation(IASRemoteAttestationResult), + #[cfg(feature = "sgx-sw")] + SimulateRemoteAttestation(SimulateRemoteAttestationResult), } #[derive(Serialize, Deserialize, Debug)] @@ -32,3 +62,9 @@ pub struct InitEnclaveResult { pub struct IASRemoteAttestationResult { pub report: EndorsedAttestationVerificationReport, } + +#[cfg(feature = "sgx-sw")] +#[derive(Serialize, Deserialize, Debug, Default)] +pub struct SimulateRemoteAttestationResult { + pub avr: attestation_report::AttestationVerificationReport, +} diff --git a/modules/ecall-commands/src/errors.rs b/modules/ecall-commands/src/errors.rs index e3bf8f7a..e4f47eb7 100644 --- a/modules/ecall-commands/src/errors.rs +++ b/modules/ecall-commands/src/errors.rs @@ -2,7 +2,7 @@ use crate::prelude::*; use flex_error::*; define_error! { - #[derive(Debug, PartialEq, Eq)] + #[derive(Debug, Clone, PartialEq, Eq)] Error { InvalidArgument { descr: String diff --git a/modules/ecall-commands/src/lib.rs b/modules/ecall-commands/src/lib.rs index 7917947f..e5ee5e53 100644 --- a/modules/ecall-commands/src/lib.rs +++ b/modules/ecall-commands/src/lib.rs @@ -24,6 +24,8 @@ pub use enclave_manage::{ EnclaveManageCommand, EnclaveManageResult, IASRemoteAttestationInput, IASRemoteAttestationResult, InitEnclaveInput, InitEnclaveResult, }; +#[cfg(feature = "sgx-sw")] +pub use enclave_manage::{SimulateRemoteAttestationInput, SimulateRemoteAttestationResult}; pub use errors::Error; pub use light_client::{ CommitmentProofPair, InitClientInput, InitClientResult, LightClientCommand, LightClientResult, diff --git a/modules/enclave-api/Cargo.toml b/modules/enclave-api/Cargo.toml index bc20d039..4dff8255 100644 --- a/modules/enclave-api/Cargo.toml +++ b/modules/enclave-api/Cargo.toml @@ -21,3 +21,4 @@ host-environment = { path = "../host-environment" } [features] default = ["rocksdb"] rocksdb = ["store/rocksdbstore"] +sgx-sw = ["ecall-commands/sgx-sw"] diff --git a/modules/enclave-api/src/api/command.rs b/modules/enclave-api/src/api/command.rs index 092d44e8..8e7304bd 100644 --- a/modules/enclave-api/src/api/command.rs +++ b/modules/enclave-api/src/api/command.rs @@ -34,6 +34,23 @@ pub trait EnclaveCommandAPI: EnclavePrimitiveAPI { } } + /// simulate_remote_attestation simulates Remote Attestation + #[cfg(feature = "sgx-sw")] + fn simulate_remote_attestation( + &self, + input: ecall_commands::SimulateRemoteAttestationInput, + ) -> Result { + match self.execute_command( + Command::EnclaveManage(EnclaveManageCommand::SimulateRemoteAttestation(input)), + None, + )? { + CommandResult::EnclaveManage(EnclaveManageResult::SimulateRemoteAttestation(res)) => { + Ok(res) + } + _ => unreachable!(), + } + } + /// init_client initializes an ELC instance with given states fn init_client(&self, input: InitClientInput) -> Result { let update_key = Some(input.any_client_state.type_url.clone()); diff --git a/modules/service/Cargo.toml b/modules/service/Cargo.toml index eda44a2a..bd41d6b0 100644 --- a/modules/service/Cargo.toml +++ b/modules/service/Cargo.toml @@ -17,3 +17,8 @@ lcp-proto = { path = "../../proto", default-features = false } attestation-report = { path = "../attestation-report" } settings = { path = "../settings" } store = { path = "../store", features = ["rocksdbstore"] } + +[features] +sgx-sw = [ + "enclave-api/sgx-sw" +] diff --git a/modules/types/src/time.rs b/modules/types/src/time.rs index d047f65b..66884aa6 100644 --- a/modules/types/src/time.rs +++ b/modules/types/src/time.rs @@ -23,7 +23,6 @@ impl Time { #[cfg(feature = "sgx")] pub fn now() -> Self { use sgx_tstd::time::{SystemTime, UNIX_EPOCH}; - use sgx_tstd::untrusted::time::SystemTimeEx; let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); Time(TmTime::from_unix_timestamp(now.as_secs() as i64, now.subsec_nanos()).unwrap()) } diff --git a/tests/integration/Cargo.toml b/tests/integration/Cargo.toml index eb525c9c..19ac24df 100644 --- a/tests/integration/Cargo.toml +++ b/tests/integration/Cargo.toml @@ -33,3 +33,7 @@ relay-tendermint = { path = "../../modules/relay/tendermint" } [features] default = [] +sgx-sw = [ + "enclave-api/sgx-sw", + "ecall-commands/sgx-sw" +] diff --git a/tools/cgen/Cargo.toml b/tools/cgen/Cargo.toml index ac448ea7..0b3d8012 100644 --- a/tools/cgen/Cargo.toml +++ b/tools/cgen/Cargo.toml @@ -35,3 +35,7 @@ relay-tendermint = { path = "../../modules/relay/tendermint" } [features] default = [] +sgx-sw = [ + "enclave-api/sgx-sw", + "ecall-commands/sgx-sw" +] From a2d5fa5eeea7f74fe2541e7d81e2a98fb71079fb Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 6 Jun 2023 12:09:20 +0900 Subject: [PATCH 02/18] remove unused function Signed-off-by: Jun Kimura --- enclave-modules/environment/src/lib.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/enclave-modules/environment/src/lib.rs b/enclave-modules/environment/src/lib.rs index d4e744c1..5271bae4 100644 --- a/enclave-modules/environment/src/lib.rs +++ b/enclave-modules/environment/src/lib.rs @@ -26,8 +26,3 @@ pub use environment_impl::Environment; mod environment; #[cfg(feature = "environment_impl")] mod environment_impl; - -pub const fn is_sgx_hw_mode() -> bool { - let mode = env!("SGX_MODE").as_bytes(); - mode.len() == 2 && mode[0] == 'H' as u8 && mode[1] == 'W' as u8 -} From a85749d26dc143d81585129d5a0418032e07f12a Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 6 Jun 2023 12:09:36 +0900 Subject: [PATCH 03/18] remove unused dependency Signed-off-by: Jun Kimura --- Cargo.lock | 10 ---------- enclave/Cargo.lock | 1 - modules/ecall-commands/Cargo.toml | 1 - 3 files changed, 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1081511a..6973c229 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1336,7 +1336,6 @@ version = "0.1.0" dependencies = [ "attestation-report", "commitments", - "enclave-environment", "flex-error", "lcp-proto", "lcp-types", @@ -1450,15 +1449,6 @@ dependencies = [ "store", ] -[[package]] -name = "enclave-environment" -version = "0.1.0" -dependencies = [ - "light-client", - "light-client-registry", - "store", -] - [[package]] name = "encode_unicode" version = "0.3.6" diff --git a/enclave/Cargo.lock b/enclave/Cargo.lock index 83420d8f..4cdfcdd8 100644 --- a/enclave/Cargo.lock +++ b/enclave/Cargo.lock @@ -451,7 +451,6 @@ version = "0.1.0" dependencies = [ "attestation-report", "commitments", - "enclave-environment", "flex-error", "lcp-proto", "lcp-types", diff --git a/modules/ecall-commands/Cargo.toml b/modules/ecall-commands/Cargo.toml index 8df39c59..6aec3c8b 100644 --- a/modules/ecall-commands/Cargo.toml +++ b/modules/ecall-commands/Cargo.toml @@ -8,7 +8,6 @@ serde = { version = "1.0", default-features = false, features = ["alloc", "deriv serde_json = { version = "1.0", default-features = false, features = ["alloc"] } flex-error = { version = "0.4.4", default-features = false } -enclave-environment = { path = "../../enclave-modules/environment", default-features = false } commitments = { path = "../commitments", default-features = false } lcp-types = { path = "../types", default-features = false } attestation-report = { path = "../attestation-report", default-features = false } From b67c9992c5354bb64307752e1a212772c2076b41 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 6 Jun 2023 13:10:41 +0900 Subject: [PATCH 04/18] ci: fix CI error Signed-off-by: Jun Kimura --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b9211633..024b2987 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: ./enclave - uses: actions-rs/cargo@v1 - run: make lint-tools - - run: make lint + - run: export SGX_MODE=HW && make lint relayer: runs-on: ubuntu-latest @@ -57,6 +57,7 @@ jobs: "source /opt/sgxsdk/environment && \ source /root/.cargo/env && \ export SGX_MODE=SW && \ + sed -i -e 's#deb https://download.01.org/intel-sgx/sgx_repo/ubuntu.*##g' /etc/apt/sources.list && \ apt update -y && apt install -y libclang-dev && \ make && make test integration-test cgen" - run: sudo chown -R runner:docker . ${HOME}/.cargo From 75eff92882fa0398c1345c3ba290d7771873db0c Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 6 Jun 2023 13:35:16 +0900 Subject: [PATCH 05/18] enable nightly option Signed-off-by: Jun Kimura --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 917e1b35..1ead4e76 100644 --- a/Makefile +++ b/Makefile @@ -199,7 +199,7 @@ lint-tools: .PHONY: lint lint: @cargo check --locked --tests $(CARGO_TARGET) - @cargo udeps --locked --lib --tests --quiet $(CARGO_TARGET) + @cargo +nightly udeps --locked --lib --tests --quiet $(CARGO_TARGET) ######## Tools ######## From e5486f8abadd6cb577363c72a4eeca82a865a3a9 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 6 Jun 2023 17:10:42 +0900 Subject: [PATCH 06/18] environment: fix feature option Signed-off-by: Jun Kimura --- enclave-modules/environment/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enclave-modules/environment/Cargo.toml b/enclave-modules/environment/Cargo.toml index bed7a06d..0872bb8c 100644 --- a/enclave-modules/environment/Cargo.toml +++ b/enclave-modules/environment/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] light-client = { path = "../../modules/light-client", default-features = false } -light-client-registry = { path = "../../modules/light-client-registry", default-features = false } +light-client-registry = { path = "../../modules/light-client-registry", default-features = false, features = ["sgx"] } store = { path = "../../modules/store", default-features = false } enclave-store = { path = "../store", optional = true } From 4dff7ada796374b9839e805062c484ff138a379d Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 6 Jun 2023 17:18:37 +0900 Subject: [PATCH 07/18] ecall-handler: remove unnecessary input check Signed-off-by: Jun Kimura --- .../src/enclave_manage/attestation.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/enclave-modules/ecall-handler/src/enclave_manage/attestation.rs b/enclave-modules/ecall-handler/src/enclave_manage/attestation.rs index 46e628b8..157d3de0 100644 --- a/enclave-modules/ecall-handler/src/enclave_manage/attestation.rs +++ b/enclave-modules/ecall-handler/src/enclave_manage/attestation.rs @@ -21,7 +21,7 @@ pub(crate) fn ias_remote_attestation( .get_pubkey(); let report = { - let spid = decode_spid(&input.spid)?; + let spid = decode_spid(&input.spid); let report = create_attestation_report( pub_key.as_report_data(), sgx_quote_sign_type_t::SGX_UNLINKABLE_SIGNATURE, @@ -57,17 +57,14 @@ pub(crate) fn simulate_remote_attestation( Ok(ecall_commands::SimulateRemoteAttestationResult { avr }) } -fn decode_spid(hex: &[u8]) -> Result { +// CONTRACT: `hex` length must be 32 +fn decode_spid(hex: &[u8]) -> sgx_spid_t { + assert!(hex.len() == 32); let mut spid = sgx_spid_t::default(); let hex = String::from_utf8_lossy(hex); let hex = &hex.trim(); - if hex.len() < 16 * 2 { - // Err(Error::invalid_sp_id_length(hex.len())) - panic!("invalid"); - } else { - let decoded_vec = hex::decode(hex).unwrap(); - spid.id.copy_from_slice(&decoded_vec[..16]); - Ok(spid) - } + let decoded_vec = hex::decode(hex).unwrap(); + spid.id.copy_from_slice(&decoded_vec[..16]); + spid } From 46ba4e4e137669d94e3c71533bc489b22f48fe9c Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 6 Jun 2023 17:34:36 +0900 Subject: [PATCH 08/18] refer to feature flag instead of env! Signed-off-by: Jun Kimura --- .github/workflows/test.yml | 2 +- app/src/cli.rs | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 024b2987..c90f5042 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: ./enclave - uses: actions-rs/cargo@v1 - run: make lint-tools - - run: export SGX_MODE=HW && make lint + - run: make lint relayer: runs-on: ubuntu-latest diff --git a/app/src/cli.rs b/app/src/cli.rs index 45166010..5d8b3663 100644 --- a/app/src/cli.rs +++ b/app/src/cli.rs @@ -4,21 +4,23 @@ use clap::Parser; /// Entry point for LCP CLI. #[derive(Debug, Parser)] -#[clap( +#[cfg_attr(feature = "sgx-sw", clap( name = env!("CARGO_PKG_NAME"), - version = concat!(env!("CARGO_PKG_VERSION"), "-", env!("SGX_MODE")), + version = concat!(env!("CARGO_PKG_VERSION"), "-sw"), author = env!("CARGO_PKG_AUTHORS"), about = env!("CARGO_PKG_DESCRIPTION"), arg_required_else_help = true, -)] +))] +#[cfg_attr(not(feature = "sgx-sw"), clap( + name = env!("CARGO_PKG_NAME"), + version = env!("CARGO_PKG_VERSION"), + author = env!("CARGO_PKG_AUTHORS"), + about = env!("CARGO_PKG_DESCRIPTION"), + arg_required_else_help = true, +))] pub struct Cli { #[clap(flatten)] pub opts: Opts, - - /// Subcommand to execute. - /// - /// The `command` option will delegate option parsing to the command type, - /// starting at the first free argument. #[clap(subcommand)] pub command: CliCmd, } From f1470f86a569c91acbf26f46db0a0f62425938e2 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 6 Jun 2023 19:29:49 +0900 Subject: [PATCH 09/18] remote-attestation: fix quote Signed-off-by: Jun Kimura --- enclave-modules/remote-attestation/src/simulate.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/enclave-modules/remote-attestation/src/simulate.rs b/enclave-modules/remote-attestation/src/simulate.rs index 5fc91148..c5e83755 100644 --- a/enclave-modules/remote-attestation/src/simulate.rs +++ b/enclave-modules/remote-attestation/src/simulate.rs @@ -155,13 +155,20 @@ fn create_simulate_avr( Ok(AttestationVerificationReport { id: "23856791181030202675484781740313693463".to_string(), // TODO refactoring - timestamp: format!("{}000", now.format("%Y-%m-%dT%H:%M:%S%.f%z").to_string().strip_suffix("+0000").unwrap().to_string()), + timestamp: format!( + "{}000", + now.format("%Y-%m-%dT%H:%M:%S%.f%z") + .to_string() + .strip_suffix("+0000") + .unwrap() + .to_string() + ), version: 4, advisory_url: "https://security-center.intel.com".to_string(), advisory_ids, isv_enclave_quote_status, - platform_info_blob: Some("1502006504000F00000F0F020202800E0000000000000000000D00000C000000020000000000000BF154C1BDAEFB9BCA30B8D7F52CD6307340650A5973262D8C99CFA64D783507294F0FE90F467E0208EB14E9E2181C34E521BF8B43D91017D5697C490094E24D5F96".to_string()), - isv_enclave_quote_body: base64::encode(quote), + platform_info_blob: None, + isv_enclave_quote_body: base64::encode("e.as_slice()[..432]), ..Default::default() }) } From beb110ede1be5c3fc9db6408a480c4351070cf4b Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 6 Jun 2023 19:38:29 +0900 Subject: [PATCH 10/18] tests: use `compose` subcommand instead Signed-off-by: Jun Kimura --- tests/e2e/cases/tm2tm/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/cases/tm2tm/Makefile b/tests/e2e/cases/tm2tm/Makefile index 9dfeddc6..c50a2da0 100644 --- a/tests/e2e/cases/tm2tm/Makefile +++ b/tests/e2e/cases/tm2tm/Makefile @@ -1,5 +1,5 @@ DOCKER ?= docker -DOCKER_COMPOSE ?= docker-compose +DOCKER_COMPOSE ?= docker compose DOCKER_REPO ?= "" DOCKER_TAG ?= latest DOCKER_BUILD ?= $(DOCKER) build --rm --no-cache --pull @@ -17,7 +17,7 @@ network: network-down: TAG=${DOCKER_TAG} $(DOCKER_COMPOSE) \ -f ../docker-compose-test.yaml \ - down --volume --remove-orphans + down --volumes --remove-orphans .PHONY: test test: From 248f679d7a06efff7a01a832f0f5a394f1e6805f Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 7 Jun 2023 09:28:21 +0900 Subject: [PATCH 11/18] types: fix missing trait Signed-off-by: Jun Kimura --- modules/types/src/time.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/types/src/time.rs b/modules/types/src/time.rs index 66884aa6..d047f65b 100644 --- a/modules/types/src/time.rs +++ b/modules/types/src/time.rs @@ -23,6 +23,7 @@ impl Time { #[cfg(feature = "sgx")] pub fn now() -> Self { use sgx_tstd::time::{SystemTime, UNIX_EPOCH}; + use sgx_tstd::untrusted::time::SystemTimeEx; let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); Time(TmTime::from_unix_timestamp(now.as_secs() as i64, now.subsec_nanos()).unwrap()) } From 8272125c5bd48fdc43dcd6ca4d47e8adb39d094f Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 7 Jun 2023 09:33:36 +0900 Subject: [PATCH 12/18] go: introduce an option enables custom root cert for RA Signed-off-by: Jun Kimura --- go/sgx/ias/cert.go | 33 +++++++++++++++++++++++++-------- go/sgx/ias/cert_env.go | 31 +++++++++++++++++++++++++++++++ go/sgx/ias/cert_static.go | 7 +++++++ go/sgx/ias/sgx.go | 6 +++--- go/simapp/Dockerfile | 2 +- 5 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 go/sgx/ias/cert_env.go create mode 100644 go/sgx/ias/cert_static.go diff --git a/go/sgx/ias/cert.go b/go/sgx/ias/cert.go index 294142ea..c6315be3 100644 --- a/go/sgx/ias/cert.go +++ b/go/sgx/ias/cert.go @@ -2,15 +2,15 @@ package ias import ( "crypto/x509" + "fmt" "github.com/oasisprotocol/oasis-core/go/common/sgx/ias" ) -var intelTrustRoots = x509.NewCertPool() - -func init() { - intelTrustRoots.AddCert(GetIASRootCert()) -} +var ( + trustRARoots = x509.NewCertPool() + trustRARootCert *x509.Certificate +) const iasTrustRootCert = `-----BEGIN CERTIFICATE----- MIIFSzCCA7OgAwIBAgIJANEHdl0yo7CUMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNV @@ -44,10 +44,27 @@ DD+gT9sSpssq0ascmvH49MOgjt1yoysLtdCtJW/9FZpoOypaHx0R+mJTLwPXVMrv DaVzWh5aiEx+idkSGMnX -----END CERTIFICATE-----` -func GetIASRootCert() *x509.Certificate { - iasRootCert, _, err := ias.CertFromPEM([]byte(iasTrustRootCert)) +func initIAS() { + rootCert, _, err := ias.CertFromPEM([]byte(iasTrustRootCert)) if err != nil { panic(err) + } else if rootCert == nil { + panic(fmt.Sprintf("invalid rootCert: %v", iasTrustRootCert)) + } + setRARootCert(rootCert) +} + +func GetRARootCert() *x509.Certificate { + if trustRARootCert == nil { + panic("`trustRARootCert` is not initialized") + } + return trustRARootCert +} + +func setRARootCert(rootCert *x509.Certificate) { + if trustRARootCert != nil { + panic("`trustRARootCert` is already initialized") } - return iasRootCert + trustRARootCert = rootCert + trustRARoots.AddCert(trustRARootCert) } diff --git a/go/sgx/ias/cert_env.go b/go/sgx/ias/cert_env.go new file mode 100644 index 00000000..eab2476a --- /dev/null +++ b/go/sgx/ias/cert_env.go @@ -0,0 +1,31 @@ +//go:build customcert + +package ias + +import ( + "fmt" + "os" + + "github.com/oasisprotocol/oasis-core/go/common/sgx/ias" +) + +const envRARootCert = "LCP_RA_ROOT_CERT" + +func init() { + cert := os.Getenv(envRARootCert) + if len(cert) == 0 { + initIAS() + } else { + initFromEnv(cert) + } +} + +func initFromEnv(cert string) { + rootCert, _, err := ias.CertFromPEM([]byte(cert)) + if err != nil { + panic(err) + } else if rootCert == nil { + panic(fmt.Sprintf("invalid rootCert: %v", cert)) + } + setRARootCert(rootCert) +} diff --git a/go/sgx/ias/cert_static.go b/go/sgx/ias/cert_static.go new file mode 100644 index 00000000..6a3575d1 --- /dev/null +++ b/go/sgx/ias/cert_static.go @@ -0,0 +1,7 @@ +//go:build !customcert + +package ias + +func init() { + initIAS() +} diff --git a/go/sgx/ias/sgx.go b/go/sgx/ias/sgx.go index 21eb5c47..67bd97bf 100644 --- a/go/sgx/ias/sgx.go +++ b/go/sgx/ias/sgx.go @@ -22,14 +22,14 @@ func (avr AttestationVerificationReport) GetTimestamp() time.Time { } func VerifyReport(report string, signature []byte, signingCertDer []byte, currentTime time.Time) error { - iasRootCert := GetIASRootCert() + rootCert := GetRARootCert() signingCert, err := x509.ParseCertificate(signingCertDer) if err != nil { return err } chains, err := signingCert.Verify(x509.VerifyOptions{ - Roots: intelTrustRoots, + Roots: trustRARoots, CurrentTime: currentTime, }) if err != nil { @@ -40,7 +40,7 @@ func VerifyReport(report string, signature []byte, signingCertDer []byte, curren return fmt.Errorf("unexpected chains length: %v", l) } else if l := len(chains[0]); l != 2 { return fmt.Errorf("unexpected certs length: %v", l) - } else if !iasRootCert.Equal(chains[0][1]) { + } else if !rootCert.Equal(chains[0][1]) { return fmt.Errorf("unexpected root cert: %v", chains[0][1]) } diff --git a/go/simapp/Dockerfile b/go/simapp/Dockerfile index 58e698ea..59b60ec0 100644 --- a/go/simapp/Dockerfile +++ b/go/simapp/Dockerfile @@ -3,7 +3,7 @@ FROM golang:1.18.6-bullseye COPY . /root/ WORKDIR /root/go/simapp -RUN go build -mod readonly -o /usr/bin/simd ./simd +RUN go build -tags customcert -mod readonly -o /usr/bin/simd ./simd RUN apt-get update -y && apt-get install -y jq WORKDIR /root/go/simapp From 6a8c56537246e55e799939a3c2653fcc9eda1b29 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 7 Jun 2023 15:11:52 +0900 Subject: [PATCH 13/18] tests: enable to use a custom cert for development Signed-off-by: Jun Kimura --- tests/e2e/cases/docker-compose-test.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/e2e/cases/docker-compose-test.yaml b/tests/e2e/cases/docker-compose-test.yaml index 54185a40..a0ab5752 100644 --- a/tests/e2e/cases/docker-compose-test.yaml +++ b/tests/e2e/cases/docker-compose-test.yaml @@ -8,6 +8,8 @@ services: tendermint-chain0: container_name: tendermint-chain0 image: tendermint-chain0:${TAG} + environment: + - LCP_RA_ROOT_CERT=${LCP_RA_ROOT_CERT} ports: - 26656:26656 - 26657:26657 @@ -23,6 +25,8 @@ services: tendermint-chain1: container_name: tendermint-chain1 image: tendermint-chain1:${TAG} + environment: + - LCP_RA_ROOT_CERT=${LCP_RA_ROOT_CERT} ports: - 26566:26656 - 26557:26657 From 3907b9b1dac85c3b5bef4020d9adbd431eae9f0a Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 7 Jun 2023 15:48:33 +0900 Subject: [PATCH 14/18] remove unused comment Signed-off-by: Jun Kimura --- enclave-modules/ecall-handler/src/enclave_manage/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/enclave-modules/ecall-handler/src/enclave_manage/mod.rs b/enclave-modules/ecall-handler/src/enclave_manage/mod.rs index 72d242bb..be234fbc 100644 --- a/enclave-modules/ecall-handler/src/enclave_manage/mod.rs +++ b/enclave-modules/ecall-handler/src/enclave_manage/mod.rs @@ -1,5 +1,4 @@ pub use errors::Error; -// pub use init_enclave::init_enclave; pub use router::dispatch; mod attestation; From 6b8c07098488733b636f9e4d7e5e576bee38fe42 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 7 Jun 2023 16:08:26 +0900 Subject: [PATCH 15/18] attestation: only allow DER as cert encoding Signed-off-by: Jun Kimura --- app/src/commands/attestation.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/src/commands/attestation.rs b/app/src/commands/attestation.rs index be7400a6..8d561e51 100644 --- a/app/src/commands/attestation.rs +++ b/app/src/commands/attestation.rs @@ -163,7 +163,11 @@ pub struct SimulateRemoteAttestation { )] pub force: bool, - #[clap(long = "signing_cert_path", help = "TODO")] + /// Path to a der-encoded file that contains X.509 certificate + #[clap( + long = "signing_cert_path", + help = "Path to a der-encoded file that contains X.509 certificate" + )] pub signing_cert_path: PathBuf, /// Path to a PEM-encoded file that contains PKCS#8 private key @@ -173,9 +177,15 @@ pub struct SimulateRemoteAttestation { )] pub signing_key_path: PathBuf, - #[clap(long = "validate_cert", default_value = "true")] + /// Validate a signing certificate using openssl command + #[clap( + long = "validate_cert", + default_value = "true", + help = "Validate a signing certificate using openssl command" + )] pub validate_cert: bool, + /// Intel security advisory IDs to include in the report #[clap( long = "advisory_ids", value_delimiter = ',', @@ -183,6 +193,7 @@ pub struct SimulateRemoteAttestation { )] pub advisory_ids: Vec, + /// Quote status to include in the report #[clap( long = "isv_enclave_quote_status", default_value = "OK", @@ -219,6 +230,8 @@ fn run_simulate_remote_attestation, S: CommitStore>( "x509", "-noout", "-modulus", + "-inform", + "der", "-in", cmd.signing_cert_path.to_str().unwrap(), ]) From 96949f1132e8acc4aeb42b12544aba4d001198e3 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 7 Jun 2023 18:35:38 +0900 Subject: [PATCH 16/18] add certs for testing Signed-off-by: Jun Kimura --- tests/Makefile | 12 +++++++++++ tests/certs/root.crt | 27 ++++++++++++++++++++++++ tests/certs/root.csr | 23 +++++++++++++++++++++ tests/certs/root.key | 40 ++++++++++++++++++++++++++++++++++++ tests/certs/signing.crt | 24 ++++++++++++++++++++++ tests/certs/signing.crt.der | Bin 0 -> 1028 bytes tests/certs/signing.csr | 17 +++++++++++++++ tests/certs/signing.key | 28 +++++++++++++++++++++++++ 8 files changed, 171 insertions(+) create mode 100644 tests/Makefile create mode 100644 tests/certs/root.crt create mode 100644 tests/certs/root.csr create mode 100644 tests/certs/root.key create mode 100644 tests/certs/signing.crt create mode 100644 tests/certs/signing.crt.der create mode 100644 tests/certs/signing.csr create mode 100644 tests/certs/signing.key diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 00000000..e73b7ca6 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,12 @@ +OPENSSL ?= openssl +CERTS_DIR ?= ./certs + +.PHONY: gencerts +gencerts: + $(OPENSSL) req -noenc -newkey rsa:3072 -pkeyopt rsa_keygen_pubexp:65537 -keyout $(CERTS_DIR)/root.key -out $(CERTS_DIR)/root.csr -subj "/C=US/ST=CA/L=Santa Clara/O=Example/CN=Test for Intel SGX Attestation Report Signing CA" + $(OPENSSL) x509 -req -in $(CERTS_DIR)/root.csr -signkey $(CERTS_DIR)/root.key -days 10000 -out $(CERTS_DIR)/root.crt + $(OPENSSL) verify -CAfile $(CERTS_DIR)/root.crt $(CERTS_DIR)/root.crt + $(OPENSSL) req -noenc -newkey rsa:2048 -pkeyopt rsa_keygen_pubexp:65537 -keyout $(CERTS_DIR)/signing.key -out $(CERTS_DIR)/signing.csr -subj "/C=US/ST=CA/L=Santa Clara/O=Example/CN=Test for Intel SGX Attestation Report Signing" + $(OPENSSL) x509 -req -in $(CERTS_DIR)/signing.csr -CA $(CERTS_DIR)/root.crt -CAkey $(CERTS_DIR)/root.key -CAcreateserial -days 10000 -out $(CERTS_DIR)/signing.crt + $(OPENSSL) verify -CAfile $(CERTS_DIR)/root.crt $(CERTS_DIR)/signing.crt + $(OPENSSL) x509 -in $(CERTS_DIR)/signing.crt -inform PEM -out $(CERTS_DIR)/signing.crt.der -outform DER diff --git a/tests/certs/root.crt b/tests/certs/root.crt new file mode 100644 index 00000000..34b87f43 --- /dev/null +++ b/tests/certs/root.crt @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEgzCCAusCFG+3OZnTUpJYa9qyvcduh1L4IEzDMA0GCSqGSIb3DQEBCwUAMH0x +CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UEBwwLU2FudGEgQ2xhcmEx +EDAOBgNVBAoMB0V4YW1wbGUxOTA3BgNVBAMMMFRlc3QgZm9yIEludGVsIFNHWCBB +dHRlc3RhdGlvbiBSZXBvcnQgU2lnbmluZyBDQTAgFw0yMzA2MDcwOTQyMjdaGA8y +MDUwMTAyMzA5NDIyN1owfTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRQwEgYD +VQQHDAtTYW50YSBDbGFyYTEQMA4GA1UECgwHRXhhbXBsZTE5MDcGA1UEAwwwVGVz +dCBmb3IgSW50ZWwgU0dYIEF0dGVzdGF0aW9uIFJlcG9ydCBTaWduaW5nIENBMIIB +ojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA23A8X/1ulaVlgl1kPvzaTcZe +6AXN6UKAQ5CM681y7Q5Afexiep4UkvfLV8Dunxi6c0Ew9EWEGkHTqiWOd0eAE2JP +PUz6KiHvE/8m6tGy/wdaEcb9912knDtoiC/JG1mjhaenHswuGHIBRhVEmD2jUfjL +eClk4P/KglVicuOVunWsw+9yMZtXVMSghFoadmFNsk5Ez/jJ4VIXedzmoxGyS3j+ +UlBtpexetgPiqd0srXz0TAXK/49+Nld94AFgL6/FRz6slu7pd+wE+NWXVkcVosPA +hbAj3fdz4IWec3gW78lvmyIH2jPTumrMX7sjX9Ia8ozecE+Y+SOsBgS5YN8F0zdM +733PZ2/3K9LLaoqTKvNn7IfiOqR70J+6OmXw0SZuZlFVkwjjmLbvQnz/EwG3HzI7 +TdRmlucO9pgfRC+Gpp+nY4QnJ9Thn7MO5oNTD24+n1BvHmDHS8dH0U8tnfTeBjMD +e4AmOtijbazgiQe4/OVrS9KVFozTfUA+FNMq8EZFAgMBAAEwDQYJKoZIhvcNAQEL +BQADggGBAAr0m/G0TsrvAZ/2F1cm9I0r0z1VXDsodFKzm8t7YM08thujEMOu7HXy +C+nwxO2x2A3BglURVXru9dVYOrJwwx5OIGSqkyCh0I6o9RNwCxlWXUwA3GbpGBlD +pMKDnn4sgjgjLYy8koo27OtkF6UepOnF9hSJvNUELv+ac5T9pJ429DDWvOWli3v4 +uCtdAoz6at1XMcxlJng22wPGzLbewcI2D3mlcvQaBtqQ32PCw/t5d6owKPuB6hHj +Ibn+Y4LPenLnlgARdX0DKcsKo8b0KBy1NM8OF4dwZh+TX0wIlBOlRF4zK77AodVr +jS9Z91QHl9052BFQJCfRwyxO58tICH786tc7BwMRHWQtjvPj5nKJTd2QfspsSz0S +W8bMAL5qBdWfV3Yp90j9R3AUHXpDOZD7skf8FiDJ9SY+DvLtV1kI/M+M522GxYH/ +mFVlUxsmOOd7dBPASpx5IC0T6LznZmLuWrMVfPABhdOlHBHga8m2mQoX3gsonWIo +uHoP9++ySw== +-----END CERTIFICATE----- diff --git a/tests/certs/root.csr b/tests/certs/root.csr new file mode 100644 index 00000000..dcabdfc3 --- /dev/null +++ b/tests/certs/root.csr @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDwjCCAioCAQAwfTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRQwEgYDVQQH +DAtTYW50YSBDbGFyYTEQMA4GA1UECgwHRXhhbXBsZTE5MDcGA1UEAwwwVGVzdCBm +b3IgSW50ZWwgU0dYIEF0dGVzdGF0aW9uIFJlcG9ydCBTaWduaW5nIENBMIIBojAN +BgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA23A8X/1ulaVlgl1kPvzaTcZe6AXN +6UKAQ5CM681y7Q5Afexiep4UkvfLV8Dunxi6c0Ew9EWEGkHTqiWOd0eAE2JPPUz6 +KiHvE/8m6tGy/wdaEcb9912knDtoiC/JG1mjhaenHswuGHIBRhVEmD2jUfjLeClk +4P/KglVicuOVunWsw+9yMZtXVMSghFoadmFNsk5Ez/jJ4VIXedzmoxGyS3j+UlBt +pexetgPiqd0srXz0TAXK/49+Nld94AFgL6/FRz6slu7pd+wE+NWXVkcVosPAhbAj +3fdz4IWec3gW78lvmyIH2jPTumrMX7sjX9Ia8ozecE+Y+SOsBgS5YN8F0zdM733P +Z2/3K9LLaoqTKvNn7IfiOqR70J+6OmXw0SZuZlFVkwjjmLbvQnz/EwG3HzI7TdRm +lucO9pgfRC+Gpp+nY4QnJ9Thn7MO5oNTD24+n1BvHmDHS8dH0U8tnfTeBjMDe4Am +OtijbazgiQe4/OVrS9KVFozTfUA+FNMq8EZFAgMBAAGgADANBgkqhkiG9w0BAQsF +AAOCAYEABzvjnqcnzpRMFcq4RqI56VIzBHZvgUYpqjd+2ubtt3mQNEeBDjC6HYFH ++GSDhP6nW+ym7LvZQKgngLPvgj7l150j34WX39C0y743GSpnyB8+hm4QwtqkOfcQ +KkrfY0gjwzZGPB7A8Um7yu1NfNfRBEx6VF9YDlLgi6QpW0rnUZyN7wW8xNkPaDnL +O4Rsm7w93KP8S43F0fytaRSOew3WL1S+Q6ck8SchQvFFyTCsZBmoVOuiMtfUWbK+ +Yr79yc55awOp/cyodsOKL7VG+pNg9saBJYHHQHeo5sL8eBfHAsjHbHd1xSYKQIGC +y9k7UWi5OIO2yrmZy6F3jJ4ynjWenmVme3zBEb0HhV3WMO4LFPkY/hmIv7qyK9Rr +avS02xR1aARk2BhykCXBs2KkoOkBUKb0JZFwKd8m5iVnR2j954RE9ATINONjIKAi +9RIYqWg5/heWrPWf5OmfC0f2aHKENDwHREB46n4c6rzrN70df/vU7BtYusY+RR6Z +G4SvibuB +-----END CERTIFICATE REQUEST----- diff --git a/tests/certs/root.key b/tests/certs/root.key new file mode 100644 index 00000000..5b800bf6 --- /dev/null +++ b/tests/certs/root.key @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +MIIG/QIBADANBgkqhkiG9w0BAQEFAASCBucwggbjAgEAAoIBgQDbcDxf/W6VpWWC +XWQ+/NpNxl7oBc3pQoBDkIzrzXLtDkB97GJ6nhSS98tXwO6fGLpzQTD0RYQaQdOq +JY53R4ATYk89TPoqIe8T/ybq0bL/B1oRxv33XaScO2iIL8kbWaOFp6cezC4YcgFG +FUSYPaNR+Mt4KWTg/8qCVWJy45W6dazD73Ixm1dUxKCEWhp2YU2yTkTP+MnhUhd5 +3OajEbJLeP5SUG2l7F62A+Kp3SytfPRMBcr/j342V33gAWAvr8VHPqyW7ul37AT4 +1ZdWRxWiw8CFsCPd93PghZ5zeBbvyW+bIgfaM9O6asxfuyNf0hryjN5wT5j5I6wG +BLlg3wXTN0zvfc9nb/cr0stqipMq82fsh+I6pHvQn7o6ZfDRJm5mUVWTCOOYtu9C +fP8TAbcfMjtN1GaW5w72mB9EL4amn6djhCcn1OGfsw7mg1MPbj6fUG8eYMdLx0fR +Ty2d9N4GMwN7gCY62KNtrOCJB7j85WtL0pUWjNN9QD4U0yrwRkUCAwEAAQKCAYAJ +/83uGG8lu3A9QqwXsOLYUlUbsNYE9M5bWQOLsP4COAwvk/bmopW9hU3ObVPb5Pif +QCxIctl8VWpDsZ64DmzgFT9j0I8bhK/Vz+J+86uUWPCqNWpE6Rvs4/0iElfEgTvR +3ywFNUvwoIZ9bwJdujAbKZSvk7Oz2AJ3/wcmxPpn6uBPdMJvaPMPp9hIdHWjvGpA +TE/XUHCPx3Nn6DolpwY8AuLhFXNycRHdkx6mdS+WjGzYzcosbCZV0hW1JsLlpJZc +wyJVY+W6sfVLRXXDlFYpGoFT4xW2vmxusX3fq21n3oSICUMpg0ogGaOBJJuIYsEC +dYzLsioAANtW249+qQ2CRM2SN6u+zyCqumCd9HQ/T9udu6Ll1YoO3D0wdu5fRV6w +y2FVEUlue8eRSOQf7zgO/qdpQRqxjAvBqQmrAIn3iAbWqCoYv+puIzMxjhMdrZK4 +FTaegEyXxWN0jgE9yB1CPy8kaLfsLM8e5pAVQLH3rokBTMA+7fnHdGcr8ey4H6kC +gcEA374I6lV5Bt1Qb/2BOigbQAXpvzlrDlNAVVydmBUzEswjkjNKZojaJnMh4HaY +drqyIomDX7gdtJ8mVXDzEbWgfVdTaRozcdEQgkPZDiW0kO9/upradP6i9Mgbui/m +aAiVZdCrAztRlNSPKCupjf+PGuNYl8OgPNLLUXqIDhBCbgOyg1/3ZTVcXTLl8Ifu +OF/86Oy+fmDqT0coiU+wLlpoJkFSFUsy3xRCcWnJWRzd59vBxJRliNeYaG2hXwb7 +5laJAoHBAPsTWdn4WJ/AharDtPb5BUcYK+zJCsBp6m/vyBKl1Ezqm/i7PNJdyDKr +ksDaigcz8ndNK/S0f80JLO0ekJskkE1tBCg9Y2sEU6InAe8f+k5Yx4FUzNb7cmTF +0rBcM5m7It5aWHo978gtT3ZxokHGr7LYGjzgh6Y+ypKyy0fZYP4QogeUAPrTm5g/ +Q8ZTqm8xtk3nF0GNWr2kIMcXMnakCVxjq/TWNfHU7H/WBH5t1K9V1k6jpfgdULuC +USzXinaC3QKBwCvwH8QVAO1uLMuxVt1a3u8Vui+JURLBGpMo2vHwx9TbLekaFXRJ +T73ZQj/YSlyWkUDjDF+RwpOj5V1GDxXdOyUiLwkm0g955OoP9OIoWWtU/RpiKqBr +GQlE+tz3ZyHq/Zu+/LZnwb+ednaHDIcMNsgq+UzkZ+VJ6A+aJnnMi58bLsVJ5UWE +0xyiUDGKICgGAZ6kT0x2L81dxgIhGhIgQu+wSDRSTi0sx1eKVLYhSxqrN0QpeD8F +R7LKRLRqpLE5MQKBwQDBAiM0WKFoTUtz9naK1Oult4Msx2+ocsNxwVaAX1JQvpmg +H++ll8pqiVKLRnSNDPX7mCuONaN5LvCGZ9SqLvVvT7q+ZFKk1fKk2G+4L1DwIXdc +iJ/fM/TAWwKX6IkSSLWJUNJrRmmp7IsFdl1RSzeNuGqTGdetiN+Y3jE+znCtXoPw +Z2pJZ5pY82lacL64M/L8+AT8s3lqB13bLo3wfjFkAIsT8AgQG6qiqxdRSYUSNF5G +na7ciUyimI9mdVtPt1ECgcARwNFuheZ5rvg54Jfu7EKE13UokGvn9Q6z8S/ISwfV +HxoJ3+2LbWdIJutNMGDv2F4L3Ct62/gbQpMp0RIknyaBRaVzvuh5oW5pzyRPCzED +fqsxYY64d0IdweqPFWLiACMRjBQqjtqbsod2IlcoG5xgoNcIWjeJbH/LlSU86Q4L +QqPbJ7gW5L7sNrkKsuuzZd9M5ikSuZS0VSmj6eDtp/m1Jk11+Bqtx0AwvEGtP7vh +vT6xdxiyB4Sa+o6V5YbOik4= +-----END PRIVATE KEY----- diff --git a/tests/certs/signing.crt b/tests/certs/signing.crt new file mode 100644 index 00000000..b21e0da7 --- /dev/null +++ b/tests/certs/signing.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEADCCAmgCFBubGPb+EfC05/S/6Aw4dX09a1nEMA0GCSqGSIb3DQEBCwUAMH0x +CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UEBwwLU2FudGEgQ2xhcmEx +EDAOBgNVBAoMB0V4YW1wbGUxOTA3BgNVBAMMMFRlc3QgZm9yIEludGVsIFNHWCBB +dHRlc3RhdGlvbiBSZXBvcnQgU2lnbmluZyBDQTAgFw0yMzA2MDcwOTQyMjdaGA8y +MDUwMTAyMzA5NDIyN1owejELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRQwEgYD +VQQHDAtTYW50YSBDbGFyYTEQMA4GA1UECgwHRXhhbXBsZTE2MDQGA1UEAwwtVGVz +dCBmb3IgSW50ZWwgU0dYIEF0dGVzdGF0aW9uIFJlcG9ydCBTaWduaW5nMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkNMKASzEqPmh//fz0QPZcz8805Dp +SBqZ6ZW0dCiBTFzp3NgU03wsC23wgqVR9LAWfDVbaPiOOLhw99NBQizHcXwuKgA0 +2ISpUyu7bQwFhHKWM7YRv14uKcXtdralZOL6uPo5RHZXCTkslxSy29r/Cyg63zxq +vTZjuPpd40W1St2/wH8C1/OXW/ugG3y4bZME01qkHj1nJQLjYav8oHhH93Cu4vni +S0ZAifVa+l9BHRj+jy7X8lOTFbUUSjXgL6rN2GQD5Dtso5fTwj2ukVmYYumfjctv +Fj1KJ1c/3Vx9291d8dmBQNxFZ+eleeGOPZKpgrKEj79WGTE1oHqApxBPbwIDAQAB +MA0GCSqGSIb3DQEBCwUAA4IBgQC39YvP2YVKBbODxkdMG4FQRSAcywdml2GY+ah6 +7sbLF/34i64JzvahLaWo+gl091ivkkUa//fgvGj/BBQq7oLmEJ1K8jsHWR8F3NYQ +HHSIIf8+vgpqGyox8miwZMrbVkMqIlxiqPnDcLWhiRfeXcwqc3qlfPgtHfGPx3YH +lUXZTQLWNffBXXWYxPz5DX5OeMJjlV1VxFd+3xrNltR4klSrGrQLRqyZe7r5AndZ +3b9g86xN7eospyhoAGtSOLw0Ml7j3F4zVXkhoPYTVayhi3q71r4AqfaLLdbYGaXM +hezqo51l06iRaMkFL49enpDXnCRbd1yJtZZXwe17cItDRNB7k6GrpibuLFfbd2go +YR/Rv+lCY/sR5IFwrKuWoxwTvd7pIzYbl9oRurbvpU3srCvNOkQO1oPxP6PpwuSc +px7KCha3QtKrJfMGOQ/siGUXMiseT8hQAj5P4DaPV6xFTbYqHEUx6uW5vFzv5QPh +Cd6Xh3MeUz6Xw2UMbpR2JahkrSM= +-----END CERTIFICATE----- diff --git a/tests/certs/signing.crt.der b/tests/certs/signing.crt.der new file mode 100644 index 0000000000000000000000000000000000000000..506f353583978cd9229b94af566678ab07003c7f GIT binary patch literal 1028 zcmXqLVqq|7V#;6=k)AE_?VsR>EziH~f5Br>T5FpfdBlL1jZ>@5qwPB{BO^B}gF&q! zw*e;`b0`a&FjHtSjKjgh({&fDR{EzRuM1L2l}hd-bi77Vx6;i`sG8m>n29dNP0QH_jJCPt(SVZ{oR<_+jnC> z-fVQZczUb`Ix(pbYp<4g3M|5wCRa6ey*r`ckHzI-yhxUIM01ssJnE77?v?P0s}8dVR8HkCbPeg-41isQi@4h@$+!O z)`gwo_hQdz6;~~-`JpTOvHy4(`&8GPzD(ClzaNY(opI#PPu@DeibKg$V?&RG*WH&o zJMBuvq>$B8Te#iU%&gw^lc_xN?*4?&Ykc3n(pj#N!H^wfvB$(H?(v;Cb~2 z*DUO=+I?*w!^&^ny4P+jRk8~Pg^V_y!YNqWi#pNw*+@>d%x88 z%^K~qRxW(knm^hvetGE0oaJ(-xWu+QU0SXBnaz^_O-HJ@k+z)wi2x=${|9FM;cHxd ow`s|^8oqkEb5G3sr_2vI?@eznmJ7C Date: Wed, 7 Jun 2023 19:13:20 +0900 Subject: [PATCH 17/18] tests: simulate RA if SGX_MODE=SW Signed-off-by: Jun Kimura --- Makefile | 2 +- tests/integration/src/lib.rs | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1ead4e76..2d361801 100644 --- a/Makefile +++ b/Makefile @@ -223,7 +223,7 @@ test: .PHONY: integration-test integration-test: $(Signed_RustEnclave_Name) bin/gaiad - @PATH=${PATH}:$(CURDIR)/bin cargo test $(CARGO_TARGET) --package integration-test + @PATH=${PATH}:$(CURDIR)/bin cargo test $(CARGO_TARGET) --package integration-test $(CARGO_FEATURES) .PHONY: test-nodes test-setup-nodes: bin/gaiad diff --git a/tests/integration/src/lib.rs b/tests/integration/src/lib.rs index 37a61251..60a5db47 100644 --- a/tests/integration/src/lib.rs +++ b/tests/integration/src/lib.rs @@ -6,7 +6,7 @@ mod tests { use anyhow::{anyhow, bail}; use ecall_commands::{ CommitmentProofPair, IASRemoteAttestationInput, InitClientInput, InitEnclaveInput, - UpdateClientInput, VerifyMembershipInput, + SimulateRemoteAttestationInput, UpdateClientInput, VerifyMembershipInput, }; use enclave_api::{Enclave, EnclaveCommandAPI}; use host_environment::Environment; @@ -114,6 +114,16 @@ mod tests { bail!("IAS Remote Attestation Failed {:?}!", e); } }; + } else { + let _ = match enclave.simulate_remote_attestation(SimulateRemoteAttestationInput { + advisory_ids: vec![], + isv_enclave_quote_status: "OK".to_string(), + }) { + Ok(res) => res.avr, + Err(e) => { + bail!("Simulate Remote Attestation Failed {:?}!", e); + } + }; } // XXX use non-latest height here From 9c899a15727ff239501e2c6e930e0436e64c3b78 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 7 Jun 2023 19:39:16 +0900 Subject: [PATCH 18/18] tests: fix compile error in HW mode Signed-off-by: Jun Kimura --- tests/integration/src/lib.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/integration/src/lib.rs b/tests/integration/src/lib.rs index 60a5db47..c7f693e8 100644 --- a/tests/integration/src/lib.rs +++ b/tests/integration/src/lib.rs @@ -6,7 +6,7 @@ mod tests { use anyhow::{anyhow, bail}; use ecall_commands::{ CommitmentProofPair, IASRemoteAttestationInput, InitClientInput, InitEnclaveInput, - SimulateRemoteAttestationInput, UpdateClientInput, VerifyMembershipInput, + UpdateClientInput, VerifyMembershipInput, }; use enclave_api::{Enclave, EnclaveCommandAPI}; use host_environment::Environment; @@ -89,8 +89,7 @@ mod tests { mut rly: Relayer, enclave: &Enclave, ) -> Result<(), anyhow::Error> { - let simulate = std::env::var("SGX_MODE").map_or(false, |m| m == "SW"); - if simulate { + if cfg!(feature = "sgx-sw") { info!("this test is running in SW mode"); } else { info!("this test is running in HW mode"); @@ -103,8 +102,7 @@ mod tests { } }; - let simulate = std::env::var("SGX_MODE").map_or(false, |m| m == "SW"); - if !simulate { + if cfg!(not(feature = "sgx-sw")) { let _ = match enclave.ias_remote_attestation(IASRemoteAttestationInput { spid: std::env::var("SPID").unwrap().as_bytes().to_vec(), ias_key: std::env::var("IAS_KEY").unwrap().as_bytes().to_vec(), @@ -115,10 +113,13 @@ mod tests { } }; } else { - let _ = match enclave.simulate_remote_attestation(SimulateRemoteAttestationInput { - advisory_ids: vec![], - isv_enclave_quote_status: "OK".to_string(), - }) { + #[cfg(feature = "sgx-sw")] + let _ = match enclave.simulate_remote_attestation( + ecall_commands::SimulateRemoteAttestationInput { + advisory_ids: vec![], + isv_enclave_quote_status: "OK".to_string(), + }, + ) { Ok(res) => res.avr, Err(e) => { bail!("Simulate Remote Attestation Failed {:?}!", e);