From 0a5bad4854606e504d8e384975ed073c03e63d6f Mon Sep 17 00:00:00 2001 From: Lily Sturmann Date: Fri, 29 Jan 2021 12:53:47 -0500 Subject: [PATCH] Implement SGX measure() Signed-off-by: Lily Sturmann --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/backend/sgx/builder.rs | 82 ++++++++++++++++++++++++++++++++ src/backend/sgx/mod.rs | 95 +++++++++----------------------------- 4 files changed, 106 insertions(+), 75 deletions(-) create mode 100644 src/backend/sgx/builder.rs diff --git a/Cargo.lock b/Cargo.lock index 4f71fbba..1f84daa5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -765,7 +765,7 @@ dependencies = [ [[package]] name = "sgx" version = "0.1.0" -source = "git+https://github.com/enarx/sgx?rev=e805b51#e805b514b34dfd206305f95ddff992b7a2462fc2" +source = "git+https://github.com/lkatalin/sgx?branch=hasher#3b6f8ff440b53678493e03952f2c9a270d247b7a" dependencies = [ "bitflags", "cc", diff --git a/Cargo.toml b/Cargo.toml index 1dc5f964..7017c49f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ backend-sgx = ["sgx"] [dependencies] sev = { git = "https://github.com/enarx/sev", features = ["openssl"], optional = true } -sgx = { git = "https://github.com/enarx/sgx", rev = "e805b51", features = ["asm", "crypto"], optional = true } +sgx = { git = "https://github.com/lkatalin/sgx", branch = "hasher", features = ["asm", "crypto"], optional = true } koine = { git = "https://github.com/enarx/koine", optional = true } x86_64 = { version = "0.11", default-features = false, features = ["stable"], optional = true } kvm-bindings = { version = "0.3", optional = true } diff --git a/src/backend/sgx/builder.rs b/src/backend/sgx/builder.rs new file mode 100644 index 00000000..6f90ff77 --- /dev/null +++ b/src/backend/sgx/builder.rs @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 + +use crate::binary::Component; + +use anyhow::Result; +use lset::Span; +use primordial::Page; +use sgx::enclave::{Builder, Segment}; +use sgx::types::{ + page::{Flags, SecInfo}, + tcs::Tcs, +}; + +/// Creates and loads an enclave, then returns the Builder. +pub fn builder(mut shim: Component, mut code: Component) -> Result { + // Calculate the memory layout for the enclave. + let layout = crate::backend::sgx::shim::Layout::calculate(shim.region(), code.region()); + + // Relocate the shim binary. + shim.entry += layout.shim.start; + for seg in shim.segments.iter_mut() { + seg.dst += layout.shim.start; + } + + // Relocate the code binary. + code.entry += layout.code.start; + for seg in code.segments.iter_mut() { + seg.dst += layout.code.start; + } + + // Create SSAs and TCS. + let ssas = vec![Page::default(); 2]; + let tcs = Tcs::new( + shim.entry - layout.enclave.start, + Page::size() * 2, // SSAs after Layout (see below) + ssas.len() as _, + ); + + let internal = vec![ + // TCS + Segment { + si: SecInfo::tcs(), + dst: layout.prefix.start, + src: vec![Page::copy(tcs)], + }, + // Layout + Segment { + si: SecInfo::reg(Flags::R), + dst: layout.prefix.start + Page::size(), + src: vec![Page::copy(layout)], + }, + // SSAs + Segment { + si: SecInfo::reg(Flags::R | Flags::W), + dst: layout.prefix.start + Page::size() * 2, + src: ssas, + }, + // Heap + Segment { + si: SecInfo::reg(Flags::R | Flags::W | Flags::X), + dst: layout.heap.start, + src: vec![Page::default(); Span::from(layout.heap).count / Page::size()], + }, + // Stack + Segment { + si: SecInfo::reg(Flags::R | Flags::W), + dst: layout.stack.start, + src: vec![Page::default(); Span::from(layout.stack).count / Page::size()], + }, + ]; + + let shim_segs: Vec<_> = shim.segments.into_iter().map(Segment::from).collect(); + let code_segs: Vec<_> = code.segments.into_iter().map(Segment::from).collect(); + + // Initiate the enclave building process. + let mut builder = Builder::new(layout.enclave).expect("Unable to create builder"); + builder.load(&internal)?; + builder.load(&shim_segs)?; + builder.load(&code_segs)?; + + Ok(builder) +} diff --git a/src/backend/sgx/mod.rs b/src/backend/sgx/mod.rs index 41c7943f..b7f4412a 100644 --- a/src/backend/sgx/mod.rs +++ b/src/backend/sgx/mod.rs @@ -7,13 +7,11 @@ use crate::sallyport; use crate::syscall::{SYS_ENARX_CPUID, SYS_ENARX_ERESUME, SYS_ENARX_GETATT}; use anyhow::{anyhow, Result}; -use lset::Span; -use primordial::Page; -use sgx::enclave::{Builder, Enclave, Entry, Registers, Segment}; +use sgx::enclave::{Enclave, Entry, Registers, Segment}; use sgx::types::{ page::{Flags, SecInfo}, + sig::{Author, Parameters}, ssa::Exception, - tcs::Tcs, }; use std::arch::x86_64::__cpuid_count; @@ -21,7 +19,10 @@ use std::convert::TryInto; use std::path::Path; use std::sync::{Arc, RwLock}; +use openssl::{bn, rsa}; + mod attestation; +mod builder; mod data; mod shim; @@ -73,78 +74,26 @@ impl crate::backend::Backend for Backend { } /// Create a keep instance on this backend - fn build(&self, mut code: Component, _sock: Option<&Path>) -> Result> { - let mut shim = Component::from_bytes(SHIM)?; - - // Calculate the memory layout for the enclave. - let layout = crate::backend::sgx::shim::Layout::calculate(shim.region(), code.region()); - - // Relocate the shim binary. - shim.entry += layout.shim.start; - for seg in shim.segments.iter_mut() { - seg.dst += layout.shim.start; - } - - // Relocate the code binary. - code.entry += layout.code.start; - for seg in code.segments.iter_mut() { - seg.dst += layout.code.start; - } - - // Create SSAs and TCS. - let ssas = vec![Page::default(); 2]; - let tcs = Tcs::new( - shim.entry - layout.enclave.start, - Page::size() * 2, // SSAs after Layout (see below) - ssas.len() as _, - ); - - let internal = vec![ - // TCS - Segment { - si: SecInfo::tcs(), - dst: layout.prefix.start, - src: vec![Page::copy(tcs)], - }, - // Layout - Segment { - si: SecInfo::reg(Flags::R), - dst: layout.prefix.start + Page::size(), - src: vec![Page::copy(layout)], - }, - // SSAs - Segment { - si: SecInfo::reg(Flags::R | Flags::W), - dst: layout.prefix.start + Page::size() * 2, - src: ssas, - }, - // Heap - Segment { - si: SecInfo::reg(Flags::R | Flags::W | Flags::X), - dst: layout.heap.start, - src: vec![Page::default(); Span::from(layout.heap).count / Page::size()], - }, - // Stack - Segment { - si: SecInfo::reg(Flags::R | Flags::W), - dst: layout.stack.start, - src: vec![Page::default(); Span::from(layout.stack).count / Page::size()], - }, - ]; - - let shim_segs: Vec<_> = shim.segments.into_iter().map(Segment::from).collect(); - let code_segs: Vec<_> = code.segments.into_iter().map(Segment::from).collect(); - - // Initiate the enclave building process. - let mut builder = Builder::new(layout.enclave).expect("Unable to create builder"); - builder.load(&internal)?; - builder.load(&shim_segs)?; - builder.load(&code_segs)?; + fn build(&self, code: Component, _sock: Option<&Path>) -> Result> { + let shim = Component::from_bytes(SHIM)?; + let builder = builder::builder(shim, code)?; Ok(builder.build()?) } - fn measure(&self, mut _code: Component) -> Result { - unimplemented!() + fn measure(&self, code: Component) -> Result { + let shim = Component::from_bytes(SHIM)?; + + let builder = builder::builder(shim, code)?; + + // Use Builder's hasher to get enclave measurement. + let hasher = builder.hasher(); + let vendor = Author::new(0, 0); + let exp = bn::BigNum::from_u32(3u32)?; + let key = rsa::Rsa::generate_with_e(3072, &exp)?; + let sig = hasher.finish(Parameters::default()).sign(vendor, key)?; + let mrenclave = sig.measurement().mrenclave(); + let json = format!(r#"{{ "backend": "sgx", "mrenclave": {:?} }}"#, mrenclave); + Ok(json) } }