1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
//! Oasis Core runtime SDK.
//!
//! # Examples
//!
//! To create a minimal runtime that doesn't expose any APIs to the
//! outside world, you need to call the `start_runtime` function:
//! ```rust,ignore
//! oasis_core_runtime::start_runtime(Some(Box::new(reg)), config);
//! ```
//!
//! This will start the required services needed to communicate with
//! the worker host.
#![feature(test)]
#![feature(arbitrary_self_types)]
#![feature(const_option)]
use lazy_static::lazy_static;
#[cfg(target_env = "sgx")]
use sgx_isa::{AttributesFlags, Report};
#[cfg_attr(test, macro_use)]
extern crate base64_serde;
#[macro_use]
pub mod common;
pub mod app;
mod attestation;
pub mod cache;
pub mod config;
pub mod consensus;
pub mod dispatcher;
pub mod enclave_rpc;
pub mod future;
pub mod host;
pub mod identity;
pub mod init;
pub mod policy;
pub mod protocol;
pub mod storage;
pub mod transaction;
pub mod types;
use common::{
sgx::{EnclaveIdentity, MrSigner},
version::{Version, PROTOCOL_VERSION},
};
// Validate features.
#[cfg(all(target_env = "sgx", feature = "debug-mock-sgx"))]
compile_error!("the debug-mock-sgx feature can only be enabled on non-sgx targets");
#[cfg(all(target_env = "sgx", feature = "tdx"))]
compile_error!("the tdx feature can only be enabled on non-sgx targets");
#[cfg(all(feature = "tdx", feature = "debug-mock-sgx"))]
compile_error!("the tdx feature can't be enabled together with debug-mock-sgx");
lazy_static! {
pub static ref BUILD_INFO: BuildInfo = {
// Determine TEE type.
let tee_type = if cfg!(any(target_env = "sgx", feature = "debug-mock-sgx")) {
TeeType::Sgx
} else if cfg!(feature = "tdx") {
TeeType::Tdx
} else {
TeeType::None
};
// Determine build security.
#[allow(clippy::let_and_return)]
let is_secure = match tee_type {
TeeType::Sgx => {
// SGX build security depends on how it was built.
//
// Optimistically start out as "it could be secure", and any single insecure build time
// option will propagate failure.
let maybe_secure = true;
// Quote signature verification MUST be enabled.
let maybe_secure = maybe_secure && option_env!("OASIS_UNSAFE_SKIP_AVR_VERIFY").is_none();
// Disallow debug enclaves MUST be enabled.
let maybe_secure = maybe_secure && option_env!("OASIS_UNSAFE_ALLOW_DEBUG_ENCLAVES").is_none();
// Attestation `OutOfDate` and `ConfigurationNeeded` responses MUST count as attestation
// failure.
//
// Rationale: This is how remote attestation signifies that the host environment is
// insecure (eg: SMT is enabled when it should not be).
let maybe_secure = maybe_secure && option_env!("OASIS_UNSAFE_LAX_AVR_VERIFY").is_none();
// The enclave MUST NOT be a debug one.
#[cfg(target_env = "sgx")]
let maybe_secure = maybe_secure && !Report::for_self().attributes.flags.contains(AttributesFlags::DEBUG);
// The enclave MUST NOT be signed by a test key,
let enclave_identity = EnclaveIdentity::current().unwrap();
let fortanix_mrsigner = MrSigner::from("9affcfae47b848ec2caf1c49b4b283531e1cc425f93582b36806e52a43d78d1a");
let maybe_secure = maybe_secure && (enclave_identity.mr_signer != fortanix_mrsigner);
maybe_secure
}
TeeType::Tdx => {
// TDX build security depends on how it was built.
//
// Optimistically start out as "it could be secure", and any single insecure build time
// option will propagate failure.
let maybe_secure = true;
// Quote signature verification MUST be enabled.
let maybe_secure = maybe_secure && option_env!("OASIS_UNSAFE_SKIP_AVR_VERIFY").is_none();
// Disallow debug enclaves MUST be enabled.
let maybe_secure = maybe_secure && option_env!("OASIS_UNSAFE_ALLOW_DEBUG_ENCLAVES").is_none();
// Attestation `OutOfDate` and `ConfigurationNeeded` responses MUST count as attestation
// failure.
//
// Rationale: This is how remote attestation signifies that the host environment is
// insecure (eg: SMT is enabled when it should not be).
let maybe_secure = maybe_secure && option_env!("OASIS_UNSAFE_LAX_AVR_VERIFY").is_none();
// TODO: Debug TD attributes.
maybe_secure
}
TeeType::None => {
// Non-TEE builds are insecure by definition.
false
}
};
BuildInfo {
tee_type,
protocol_version: PROTOCOL_VERSION,
is_secure,
}
};
}
/// TEE type this build is for.
#[derive(Debug, Default, PartialEq, Eq)]
pub enum TeeType {
#[default]
None,
Sgx,
Tdx,
}
/// Runtime build information.
#[derive(Debug)]
pub struct BuildInfo {
/// TEE type this build is for.
pub tee_type: TeeType,
/// Supported runtime protocol version.
pub protocol_version: Version,
/// True iff the build can provide integrity and confidentiality.
pub is_secure: bool,
}
// Re-exports.
pub use self::{
enclave_rpc::{demux::Demux as RpcDemux, dispatcher::Dispatcher as RpcDispatcher},
init::start_runtime,
protocol::Protocol,
transaction::dispatcher::Dispatcher as TxnDispatcher,
};
// Re-export the cbor crate.
pub use cbor;