Update dcap demo using prebuilt dcap lib

This commit is contained in:
Zheng, Qi 2022-02-09 14:48:36 +08:00 committed by Zongmin.Gu
parent ea3135fa3d
commit 04a357021c
11 changed files with 17 additions and 482 deletions

@ -1,4 +1,4 @@
# SGX DCAP Remote Attestation Demo in Rust # SGX DCAP Remote Attestation Demo
This project demonstrates how to do Intel SGX DCAP (Datacenter Attestation This project demonstrates how to do Intel SGX DCAP (Datacenter Attestation
Primitives) remote attestation on Occlum. Occlum provides SGX capabilities to Primitives) remote attestation on Occlum. Occlum provides SGX capabilities to
@ -18,7 +18,7 @@ applications through ioctls on device `/dev/sgx`.
## Run this demo on Occlum ## Run this demo on Occlum
You can run the DCAP quote generation and verification demo, including dcap library build, rust test demo and C test demo on Occlum via You can run the DCAP quote generation and verification demo, including rust test demo and C test demo on Occlum via
``` ```
./run_dcap_quote_on_occlum.sh ./run_dcap_quote_on_occlum.sh
``` ```

@ -1,13 +1,14 @@
CC ?= gcc CC ?= gcc
LD ?= ld LD ?= ld
LIBPATH ?= ../dcap_lib/target/debug LIBPATH ?= /opt/occlum/toolchains/dcap_lib/glibc
INCPATH ?= /opt/occlum/toolchains/dcap_lib/inc
.PHONY: all clean .PHONY: all clean
all: dcap_c_test all: dcap_c_test
dcap_c_test: dcap_c_test.c dcap_c_test: dcap_c_test.c
$(CC) $^ -fPIE -pie -o $@ -L $(LIBPATH) -ldcap_quote -I /opt/intel/sgxsdk/include $(CC) $^ -fPIE -pie -o $@ -L $(LIBPATH) -locclum_dcap -I /opt/intel/sgxsdk/include -I $(INCPATH)
clean: clean:
rm -rf dcap_c_test rm -rf dcap_c_test

@ -3,8 +3,11 @@
#include <string.h> #include <string.h>
#include "sgx_quote_3.h" #include "sgx_quote_3.h"
#include "dcap_quote.h" #include "sgx_urts.h"
#include "sgx_pce.h"
#include "sgx_error.h"
#include "occlum_dcap.h"
void dump_quote_info(sgx_quote3_t *p_quote) void dump_quote_info(sgx_quote3_t *p_quote)
{ {

@ -1,37 +0,0 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "sgx_urts.h"
#include "sgx_report.h"
#include "sgx_qve_header.h"
#include "sgx_pce.h"
#include "sgx_error.h"
#ifdef __cplusplus
extern "C" {
#endif
void *dcap_quote_open(void);
uint32_t dcap_get_quote_size(void *handle);
int32_t dcap_generate_quote(void *handle, uint8_t *quote_buf, const sgx_report_data_t *report_data);
uint32_t dcap_get_supplemental_data_size(void *handle);
int32_t dcap_verify_quote(void *handle,
const uint8_t *quote_buf,
uint32_t quote_size,
uint32_t *collateral_expiration_status,
sgx_ql_qv_result_t *quote_verification_result,
uint32_t supplemental_data_size,
uint8_t *supplemental_data);
void dcap_quote_close(void *handle);
#ifdef __cplusplus
}
#endif

@ -6,11 +6,11 @@ targets:
- target: /bin - target: /bin
copy: copy:
- files: - files:
- ../dcap_lib/target/x86_64-unknown-linux-musl/release/examples/dcap_test - /opt/occlum/toolchains/dcap_lib/musl/dcap_test
- ../c_app/dcap_c_test - ../c_app/dcap_c_test
# copy lib # copy lib
- target: /lib - target: /lib
copy: copy:
- files: - files:
- ../dcap_lib/target/x86_64-unknown-linux-musl/release/libdcap_quote.so - /opt/occlum/toolchains/dcap_lib/musl/libocclum_dcap.so

@ -6,11 +6,11 @@ targets:
- target: /bin - target: /bin
copy: copy:
- files: - files:
- ../dcap_lib/target/release/examples/dcap_test - /opt/occlum/toolchains/dcap_lib/glibc/dcap_test
- ../c_app/dcap_c_test - ../c_app/dcap_c_test
# copy lib # copy lib
- target: /opt/occlum/glibc/lib - target: /opt/occlum/glibc/lib
copy: copy:
- files: - files:
- ../dcap_lib/target/release/libdcap_quote.so - /opt/occlum/toolchains/dcap_lib/glibc/libocclum_dcap.so

@ -1,15 +0,0 @@
[package]
name = "dcap_quote"
version = "0.1.0"
authors = ["Zheng, Qi <huaiqing.zq@antgroup.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
sgx_types = { path = "../../../../deps/rust-sgx-sdk/sgx_types" }
libc = "0.2"
cfg-if = "1.0.0"
[lib]
crate-type = ["cdylib", "rlib", "staticlib"]

@ -1,172 +0,0 @@
extern crate dcap_quote;
use std::str;
use std::io::Result;
use std::convert::TryFrom;
use dcap_quote::*;
use sgx_types::{
sgx_quote_header_t, sgx_report_data_t, sgx_ql_qv_result_t, sgx_report_body_t
};
struct DcapDemo {
dcap_quote: DcapQuote,
quote_size: u32,
quote_buf: Vec<u8>,
req_data: sgx_report_data_t,
supplemental_size: u32,
suppl_buf: Vec<u8>
}
impl DcapDemo {
pub fn new(report_data: &str) -> Self {
let mut dcap = DcapQuote::new();
let quote_size = dcap.get_quote_size();
let supplemental_size = dcap.get_supplemental_data_size();
let quote_buf: Vec<u8> = vec![0; quote_size as usize];
let suppl_buf: Vec<u8> = vec![0; supplemental_size as usize];
let mut req_data = sgx_report_data_t::default();
//fill in the report data array
for (pos, val) in report_data.as_bytes().iter().enumerate() {
req_data.d[pos] = *val;
}
Self {
dcap_quote: dcap,
quote_size: quote_size,
quote_buf: quote_buf,
req_data: req_data,
supplemental_size: supplemental_size,
suppl_buf: suppl_buf
}
}
fn dcap_quote_gen(&mut self) -> Result<i32> {
self.dcap_quote.generate_quote(self.quote_buf.as_mut_ptr(), &mut self.req_data).unwrap();
println!("DCAP generate quote successfully");
Ok( 0 )
}
// Quote has type `sgx_quote3_t` and is structured as
// pub struct sgx_quote3_t {
// pub header: sgx_quote_header_t,
// pub report_body: sgx_report_body_t,
// pub signature_data_len: uint32_t,
// pub signature_data: [uint8_t; 0],
// }
fn dcap_quote_get_report_body(&mut self) -> Result<*const sgx_report_body_t> {
let report_body_offset = std::mem::size_of::<sgx_quote_header_t>();
let report_body: *const sgx_report_body_t
= (self.quote_buf[report_body_offset..]).as_ptr() as _;
Ok(report_body)
}
fn dcap_quote_get_report_data(&mut self) -> Result<*const sgx_report_data_t> {
let report_body_ptr = self.dcap_quote_get_report_body().unwrap();
let report_data_ptr = unsafe { &(*report_body_ptr).report_data };
Ok(report_data_ptr)
}
fn dcap_quote_ver(&mut self) -> Result<sgx_ql_qv_result_t> {
let mut quote_verification_result = sgx_ql_qv_result_t::SGX_QL_QV_RESULT_UNSPECIFIED;
let mut status = 1;
let mut verify_arg = IoctlVerDCAPQuoteArg {
quote_buf: self.quote_buf.as_mut_ptr(),
quote_size: self.quote_size,
collateral_expiration_status: &mut status,
quote_verification_result: &mut quote_verification_result,
supplemental_data_size: self.supplemental_size,
supplemental_data: self.suppl_buf.as_mut_ptr(),
};
self.dcap_quote.verify_quote(&mut verify_arg).unwrap();
println!("DCAP verify quote successfully");
Ok( quote_verification_result )
}
fn dcap_dump_quote_info(&mut self) {
let report_body_ptr = self.dcap_quote_get_report_body().unwrap();
// Dump ISV FAMILY ID
let family_id = unsafe { (*report_body_ptr).isv_family_id };
let (fam_id_l, fam_id_h) = family_id.split_at(8);
let fam_id_l = <&[u8; 8]>::try_from(fam_id_l).unwrap();
let fam_id_l = u64::from_le_bytes(*fam_id_l);
let fam_id_h = <&[u8; 8]>::try_from(fam_id_h).unwrap();
let fam_id_h = u64::from_le_bytes(*fam_id_h);
println!("\nSGX ISV Family ID:");
println!("\t Low 8 bytes: 0x{:016x?}\t", fam_id_l);
println!("\t high 8 bytes: 0x{:016x?}\t", fam_id_h);
// Dump ISV EXT Product ID
let prod_id = unsafe { (*report_body_ptr).isv_ext_prod_id };
let (prod_id_l, prod_id_h) = prod_id.split_at(8);
let prod_id_l = <&[u8; 8]>::try_from(prod_id_l).unwrap();
let prod_id_l = u64::from_le_bytes(*prod_id_l);
let prod_id_h = <&[u8; 8]>::try_from(prod_id_h).unwrap();
let prod_id_h = u64::from_le_bytes(*prod_id_h);
println!("\nSGX ISV EXT Product ID:");
println!("\t Low 8 bytes: 0x{:016x?}\t", prod_id_l);
println!("\t high 8 bytes: 0x{:016x?}\t", prod_id_h);
// Dump CONFIG ID
let conf_id = unsafe { (*report_body_ptr).config_id };
println!("\nSGX CONFIG ID:");
println!("\t{:02x?}", &conf_id[..16]);
println!("\t{:02x?}", &conf_id[16..32]);
println!("\t{:02x?}", &conf_id[32..48]);
println!("\t{:02x?}", &conf_id[48..]);
// Dump CONFIG SVN
let conf_svn = unsafe { (*report_body_ptr).config_svn };
println!("\nSGX CONFIG SVN:\t {:04x?}", conf_svn);
}
}
impl Drop for DcapDemo {
fn drop(&mut self) {
self.dcap_quote.close();
}
}
fn main() {
let report_str = "Dcap demo sample";
let mut dcap_demo = DcapDemo::new(report_str);
println!("Generate quote with report data : {}", report_str);
dcap_demo.dcap_quote_gen().unwrap();
// compare the report data in quote buffer
let report_data_ptr = dcap_demo.dcap_quote_get_report_data().unwrap();
let string = str::from_utf8( unsafe { &(*report_data_ptr).d } ).unwrap();
if report_str == &string[..report_str.len()] {
println!("Report data from Quote: '{}' exactly matches.", string);
} else {
println!("Report data from Quote: '{}' doesn't match !!!", string);
}
dcap_demo.dcap_dump_quote_info();
let result = dcap_demo.dcap_quote_ver().unwrap();
match result {
sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK => {
println!("Succeed to verify the quote!");
},
sgx_ql_qv_result_t::SGX_QL_QV_RESULT_CONFIG_NEEDED |
sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OUT_OF_DATE |
sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OUT_OF_DATE_CONFIG_NEEDED |
sgx_ql_qv_result_t::SGX_QL_QV_RESULT_SW_HARDENING_NEEDED |
sgx_ql_qv_result_t::SGX_QL_QV_RESULT_CONFIG_AND_SW_HARDENING_NEEDED => {
println!("WARN: App: Verification completed with Non-terminal result: {}", result);
},
_ => println!("Error: App: Verification completed with Terminal result: {}", result),
}
}

@ -1,132 +0,0 @@
use libc::*;
use std::ffi::CString;
use sgx_types::{
sgx_report_data_t, sgx_ql_qv_result_t
};
const SGXIOC_GET_DCAP_QUOTE_SIZE: u64 = 0x80047307;
const SGXIOC_GEN_DCAP_QUOTE: u64 = 0xc0187308;
const SGXIOC_GET_DCAP_SUPPLEMENTAL_SIZE: u64 = 0x80047309;
const SGXIOC_VER_DCAP_QUOTE: u64 = 0xc030730a;
cfg_if::cfg_if! {
if #[cfg(target_env = "musl")] {
const IOCTL_GET_DCAP_QUOTE_SIZE: i32 = SGXIOC_GET_DCAP_QUOTE_SIZE as i32;
const IOCTL_GEN_DCAP_QUOTE: i32 = SGXIOC_GEN_DCAP_QUOTE as i32;
const IOCTL_GET_DCAP_SUPPLEMENTAL_SIZE: i32 = SGXIOC_GET_DCAP_SUPPLEMENTAL_SIZE as i32;
const IOCTL_VER_DCAP_QUOTE: i32 = SGXIOC_VER_DCAP_QUOTE as i32;
} else {
const IOCTL_GET_DCAP_QUOTE_SIZE: u64 = SGXIOC_GET_DCAP_QUOTE_SIZE;
const IOCTL_GEN_DCAP_QUOTE: u64 = SGXIOC_GEN_DCAP_QUOTE;
const IOCTL_GET_DCAP_SUPPLEMENTAL_SIZE: u64 = SGXIOC_GET_DCAP_SUPPLEMENTAL_SIZE;
const IOCTL_VER_DCAP_QUOTE: u64 = SGXIOC_VER_DCAP_QUOTE;
}
}
// Copy from occlum/src/libos/src/fs/dev_fs/dev_sgx/mod.rs
//#[allow(dead_code)]
#[repr(C)]
pub struct IoctlGenDCAPQuoteArg {
pub report_data: *const sgx_report_data_t, // Input
pub quote_size: *mut u32, // Input/output
pub quote_buf: *mut u8, // Output
}
// Copy from occlum/src/libos/src/fs/dev_fs/dev_sgx/mod.rs
//#[allow(dead_code)]
#[repr(C)]
pub struct IoctlVerDCAPQuoteArg {
pub quote_buf: *const u8, // Input
pub quote_size: u32, // Input
pub collateral_expiration_status: *mut u32, // Output
pub quote_verification_result: *mut sgx_ql_qv_result_t, // Output
pub supplemental_data_size: u32, // Input (optional)
pub supplemental_data: *mut u8, // Output (optional)
}
pub struct DcapQuote {
fd: c_int,
quote_size: u32,
supplemental_size: u32,
}
impl DcapQuote {
pub fn new() -> Self {
println!("DcapQuote: new");
let path = CString::new("/dev/sgx").unwrap();
let fd = unsafe { libc::open(path.as_ptr(), O_RDONLY) };
if fd > 0 {
Self {
fd: fd,
quote_size: 0,
supplemental_size: 0,
}
} else {
panic!("Open /dev/sgx failed")
}
}
pub fn get_quote_size(&mut self) -> u32 {
println!("DcapQuote: get_quote_size");
let size: u32 = 0;
let ret = unsafe { libc::ioctl(self.fd, IOCTL_GET_DCAP_QUOTE_SIZE, &size) };
if ret < 0 {
panic!("IOCTRL IOCTL_GET_DCAP_QUOTE_SIZE failed");
} else {
self.quote_size = size;
size
}
}
pub fn generate_quote(&mut self, quote_buf: *mut u8, report_data: *const sgx_report_data_t) -> Result<i32, &'static str> {
println!("DcapQuote: generate_quote");
let quote_arg: IoctlGenDCAPQuoteArg = IoctlGenDCAPQuoteArg {
report_data: report_data,
quote_size: &mut self.quote_size,
quote_buf: quote_buf,
};
let ret = unsafe { libc::ioctl(self.fd, IOCTL_GEN_DCAP_QUOTE, &quote_arg) };
if ret < 0 {
Err("IOCTRL IOCTL_GEN_DCAP_QUOTE failed")
} else {
Ok( 0 )
}
}
pub fn get_supplemental_data_size(&mut self) -> u32 {
println!("DcapQuote: get_supplemental_data_size");
let size: u32 = 0;
let ret = unsafe { libc::ioctl(self.fd, IOCTL_GET_DCAP_SUPPLEMENTAL_SIZE, &size) };
if ret < 0 {
panic!("IOCTRL IOCTL_GET_DCAP_SUPPLEMENTAL_SIZE failed");
} else {
self.supplemental_size = size;
size
}
}
pub fn verify_quote(&mut self, verify_arg: *mut IoctlVerDCAPQuoteArg) -> Result<i32, &'static str> {
println!("DcapQuote: verify_quote");
let ret = unsafe { libc::ioctl(self.fd, IOCTL_VER_DCAP_QUOTE, verify_arg) };
if ret < 0 {
println!("ret = {}", ret);
Err("IOCTRL IOCTL_VER_DCAP_QUOTE failed")
} else {
Ok( 0 )
}
}
pub fn close(&mut self) {
println!("DcapQuote: close");
unsafe { libc::close(self.fd) };
}
}

@ -1,109 +0,0 @@
use std::boxed::Box;
use libc::{c_void};
use sgx_types::{
sgx_report_data_t, sgx_ql_qv_result_t
};
mod dcap_quote;
pub use crate::dcap_quote::*;
#[no_mangle]
pub extern "C" fn dcap_quote_open() -> *mut c_void {
Box::into_raw(Box::new(DcapQuote::new())) as *mut c_void
}
#[no_mangle]
pub extern "C" fn dcap_get_quote_size(handle: *mut c_void) -> u32 {
if handle.is_null() {
return 0
}
let dcap = unsafe {
&mut *(handle as *mut DcapQuote)
};
dcap.get_quote_size()
}
#[no_mangle]
pub extern "C" fn dcap_generate_quote(
handle: *mut c_void,
quote_buf: *mut u8,
report_data: *const sgx_report_data_t) -> i32
{
if handle.is_null() {
return -1
}
let dcap = unsafe {
&mut *(handle as *mut DcapQuote)
};
dcap.generate_quote(quote_buf, report_data).unwrap();
0
}
#[no_mangle]
pub extern "C" fn dcap_get_supplemental_data_size(handle: *mut c_void) -> u32 {
if handle.is_null() {
return 0
}
let dcap = unsafe {
&mut *(handle as *mut DcapQuote)
};
dcap.get_supplemental_data_size()
}
#[no_mangle]
pub extern "C" fn dcap_verify_quote(
handle: *mut c_void,
quote_buf: *const u8,
quote_size: u32,
collateral_expiration_status: *mut u32,
quote_verification_result: *mut sgx_ql_qv_result_t,
supplemental_data_size: u32,
supplemental_data: *mut u8) -> i32
{
if handle.is_null() {
return -1
}
let dcap = unsafe {
&mut *(handle as *mut DcapQuote)
};
let mut verify_arg = IoctlVerDCAPQuoteArg {
quote_buf: quote_buf,
quote_size: quote_size,
collateral_expiration_status: collateral_expiration_status,
quote_verification_result: quote_verification_result,
supplemental_data_size: supplemental_data_size,
supplemental_data: supplemental_data,
};
dcap.verify_quote(&mut verify_arg).unwrap();
0
}
#[no_mangle]
pub extern "C" fn dcap_quote_close(handle: *mut c_void) {
if handle.is_null() {
return
}
let dcap = unsafe {
&mut *(handle as *mut DcapQuote)
};
dcap.close();
unsafe {
Box::from_raw(handle);
}
}

@ -10,23 +10,19 @@ if [[ $1 == "musl" ]]; then
bomfile="../dcap-musl.yaml" bomfile="../dcap-musl.yaml"
CC=occlum-gcc CC=occlum-gcc
LD=occlum-ld LD=occlum-ld
CARGO=occlum-cargo LIBPATH="/opt/occlum/toolchains/dcap_lib/musl"
LIBPATH="../dcap_lib/target/x86_64-unknown-linux-musl/release"
else else
echo "*** Build and run glibc dcap demo ***" echo "*** Build and run glibc dcap demo ***"
bomfile="../dcap.yaml" bomfile="../dcap.yaml"
CC=gcc CC=gcc
LD=ld LD=ld
CARGO=cargo LIBPATH="/opt/occlum/toolchains/dcap_lib/glibc"
LIBPATH="../dcap_lib/target/release"
fi fi
pushd dcap_lib INCPATH="/opt/occlum/toolchains/dcap_lib/inc"
$CARGO build --all-targets --release
popd
CC=$CC LD=$LD LIBPATH=$LIBPATH make -C c_app clean CC=$CC LD=$LD LIBPATH=$LIBPATH make -C c_app clean
CC=$CC LD=$LD LIBPATH=$LIBPATH make -C c_app CC=$CC LD=$LD LIBPATH=$LIBPATH INCPATH=$INCPATH make -C c_app
rm -rf ${INSTANCE_DIR} && occlum new ${INSTANCE_DIR} rm -rf ${INSTANCE_DIR} && occlum new ${INSTANCE_DIR}
cd ${INSTANCE_DIR} cd ${INSTANCE_DIR}