[dcap] Do not panic in dcap library

This commit is contained in:
Zheng, Qi 2023-05-26 17:14:29 +08:00 committed by volcano
parent 9089764b64
commit 198515ab90
7 changed files with 75 additions and 63 deletions

@ -7,8 +7,8 @@ use occlum_dcap::*;
pub const MAX_REPORT_DATA_SIZE: usize = 64; pub const MAX_REPORT_DATA_SIZE: usize = 64;
fn maa_get_quote_base64(user_data: &[u8]) -> Result<String, &'static str> { fn maa_get_quote_base64(user_data: &[u8]) -> Result<String, &'static str> {
let mut dcap = DcapQuote::new(); let mut dcap = DcapQuote::new().unwrap();
let quote_size = dcap.get_quote_size(); let quote_size = dcap.get_quote_size().unwrap();
let mut quote_buf: Vec<u8> = vec![0; quote_size as usize]; let mut quote_buf: Vec<u8> = vec![0; quote_size as usize];
let mut report_data = sgx_report_data_t::default(); let mut report_data = sgx_report_data_t::default();
@ -25,10 +25,13 @@ fn maa_get_quote_base64(user_data: &[u8]) -> Result<String, &'static str> {
report_data.d[i] = user_data[i]; report_data.d[i] = user_data[i];
} }
dcap.generate_quote(quote_buf.as_mut_ptr(), &mut report_data).unwrap(); let ret = dcap.generate_quote(quote_buf.as_mut_ptr(), &mut report_data).unwrap();
dcap.close(); dcap.close();
let quote = base64::encode(&quote_buf); if ret < 0 {
return Err("DCAP generate quote failed");
}
let quote = base64::encode(&quote_buf);
Ok(quote) Ok(quote)
} }

@ -7,8 +7,8 @@ use occlum_dcap::*;
pub const MAX_REPORT_DATA_SIZE: usize = 64; pub const MAX_REPORT_DATA_SIZE: usize = 64;
fn maa_get_quote_base64(user_data: &[u8]) -> Result<String, &'static str> { fn maa_get_quote_base64(user_data: &[u8]) -> Result<String, &'static str> {
let mut dcap = DcapQuote::new(); let mut dcap = DcapQuote::new().unwrap();
let quote_size = dcap.get_quote_size(); let quote_size = dcap.get_quote_size().unwrap();
let mut quote_buf: Vec<u8> = vec![0; quote_size as usize]; let mut quote_buf: Vec<u8> = vec![0; quote_size as usize];
let mut report_data = sgx_report_data_t::default(); let mut report_data = sgx_report_data_t::default();
@ -25,10 +25,13 @@ fn maa_get_quote_base64(user_data: &[u8]) -> Result<String, &'static str> {
report_data.d[i] = user_data[i]; report_data.d[i] = user_data[i];
} }
dcap.generate_quote(quote_buf.as_mut_ptr(), &mut report_data).unwrap(); let ret = dcap.generate_quote(quote_buf.as_mut_ptr(), &mut report_data).unwrap();
dcap.close(); dcap.close();
let quote = base64::encode(&quote_buf); if ret < 0 {
return Err("DCAP generate quote failed");
}
let quote = base64::encode(&quote_buf);
Ok(quote) Ok(quote)
} }

@ -18,14 +18,6 @@ fn main() -> Result<(), Box<dyn Error>> {
const IMAGE_CONFIG_FILE: &str = "/etc/image_config.json"; const IMAGE_CONFIG_FILE: &str = "/etc/image_config.json";
let image_config = load_config(IMAGE_CONFIG_FILE)?; let image_config = load_config(IMAGE_CONFIG_FILE)?;
// Get the MAC of Occlum.json.protected file
let occlum_json_mac = {
let mut mac: sgx_aes_gcm_128bit_tag_t = Default::default();
parse_str_to_bytes(&image_config.occlum_json_mac, &mut mac)?;
mac
};
let occlum_json_mac_ptr = &occlum_json_mac as *const sgx_aes_gcm_128bit_tag_t;
// Get the key of FS image if needed // Get the key of FS image if needed
let key = match &image_config.image_type[..] { let key = match &image_config.image_type[..] {
"encrypted" => { "encrypted" => {
@ -65,8 +57,9 @@ fn main() -> Result<(), Box<dyn Error>> {
const SYS_MOUNT_FS: i64 = 363; const SYS_MOUNT_FS: i64 = 363;
// User can provide valid path for runtime mount and boot // User can provide valid path for runtime mount and boot
// Otherwise, just pass null pointer to do general mount and boot // Otherwise, just pass null pointer to do general mount and boot
let rootfs_config: *const i8 = std::ptr::null(); let root_config_path: *const i8 = std::ptr::null();
let ret = unsafe { syscall(SYS_MOUNT_FS, key_ptr, rootfs_config) }; let ret = unsafe { syscall(
SYS_MOUNT_FS, key_ptr, root_config_path) };
if ret < 0 { if ret < 0 {
return Err(Box::new(std::io::Error::last_os_error())); return Err(Box::new(std::io::Error::last_os_error()));
} }
@ -82,13 +75,10 @@ fn main() -> Result<(), Box<dyn Error>> {
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
type sgx_key_128bit_t = [u8; 16]; type sgx_key_128bit_t = [u8; 16];
#[allow(non_camel_case_types)]
type sgx_aes_gcm_128bit_tag_t = [u8; 16];
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
struct ImageConfig { struct ImageConfig {
occlum_json_mac: String,
image_type: String, image_type: String,
} }

@ -15,9 +15,9 @@ struct DcapDemo {
impl DcapDemo { impl DcapDemo {
pub fn new(report_data: &str) -> Self { pub fn new(report_data: &str) -> Self {
let mut dcap = DcapQuote::new(); let mut dcap = DcapQuote::new().unwrap();
let quote_size = dcap.get_quote_size(); let quote_size = dcap.get_quote_size().unwrap();
let supplemental_size = dcap.get_supplemental_data_size(); let supplemental_size = dcap.get_supplemental_data_size().unwrap();
let quote_buf: Vec<u8> = vec![0; quote_size as usize]; let quote_buf: Vec<u8> = vec![0; quote_size as usize];
let suppl_buf: Vec<u8> = vec![0; supplemental_size as usize]; let suppl_buf: Vec<u8> = vec![0; supplemental_size as usize];
let mut req_data = sgx_report_data_t::default(); let mut req_data = sgx_report_data_t::default();
@ -37,12 +37,15 @@ impl DcapDemo {
} }
} }
fn dcap_quote_gen(&mut self) -> Result<i32> { fn dcap_quote_gen(&mut self) -> i32 {
self.dcap_quote.generate_quote(self.quote_buf.as_mut_ptr(), &mut self.req_data).unwrap(); let ret = self.dcap_quote.generate_quote(self.quote_buf.as_mut_ptr(), &mut self.req_data).unwrap();
if ret < 0 {
println!("DCAP generate quote failed");
} else {
println!("DCAP generate quote successfully"); println!("DCAP generate quote successfully");
}
Ok( 0 ) ret
} }
// Quote has type `sgx_quote3_t` and is structured as // Quote has type `sgx_quote3_t` and is structured as
@ -68,7 +71,7 @@ impl DcapDemo {
Ok(report_data_ptr) Ok(report_data_ptr)
} }
fn dcap_quote_ver(&mut self) -> Result<sgx_ql_qv_result_t> { fn dcap_quote_verify(&mut self) -> sgx_ql_qv_result_t {
let mut quote_verification_result = sgx_ql_qv_result_t::SGX_QL_QV_RESULT_UNSPECIFIED; let mut quote_verification_result = sgx_ql_qv_result_t::SGX_QL_QV_RESULT_UNSPECIFIED;
let mut status = 1; let mut status = 1;
@ -81,10 +84,14 @@ impl DcapDemo {
supplemental_data: self.suppl_buf.as_mut_ptr(), supplemental_data: self.suppl_buf.as_mut_ptr(),
}; };
self.dcap_quote.verify_quote(&mut verify_arg).unwrap(); let ret = self.dcap_quote.verify_quote(&mut verify_arg).unwrap();
if ret < 0 {
println!("DCAP verify quote failed");
} else {
println!("DCAP verify quote successfully"); println!("DCAP verify quote successfully");
}
Ok( quote_verification_result ) quote_verification_result
} }
fn dcap_dump_quote_info(&mut self) { fn dcap_dump_quote_info(&mut self) {
@ -137,7 +144,7 @@ fn main() {
let mut dcap_demo = DcapDemo::new(report_str); let mut dcap_demo = DcapDemo::new(report_str);
println!("Generate quote with report data : {}", report_str); println!("Generate quote with report data : {}", report_str);
dcap_demo.dcap_quote_gen().unwrap(); dcap_demo.dcap_quote_gen();
// compare the report data in quote buffer // compare the report data in quote buffer
let report_data_ptr = dcap_demo.dcap_quote_get_report_data().unwrap(); let report_data_ptr = dcap_demo.dcap_quote_get_report_data().unwrap();
@ -151,7 +158,7 @@ fn main() {
dcap_demo.dcap_dump_quote_info(); dcap_demo.dcap_dump_quote_info();
let result = dcap_demo.dcap_quote_ver().unwrap(); let result = dcap_demo.dcap_quote_verify();
match result { match result {
sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK => { sgx_ql_qv_result_t::SGX_QL_QV_RESULT_OK => {
println!("Succeed to verify the quote!"); println!("Succeed to verify the quote!");

@ -6,7 +6,11 @@ pub use crate::occlum_dcap::*;
#[no_mangle] #[no_mangle]
pub extern "C" fn dcap_quote_open() -> *mut c_void { pub extern "C" fn dcap_quote_open() -> *mut c_void {
Box::into_raw(Box::new(DcapQuote::new())) as *mut c_void if let Ok(fd) = DcapQuote::new() {
Box::into_raw(Box::new(fd)) as *mut c_void
} else {
std::ptr::null_mut::<u8>() as *mut c_void
}
} }
#[no_mangle] #[no_mangle]
@ -19,7 +23,7 @@ pub extern "C" fn dcap_get_quote_size(handle: *mut c_void) -> u32 {
&mut *(handle as *mut DcapQuote) &mut *(handle as *mut DcapQuote)
}; };
dcap.get_quote_size() dcap.get_quote_size().unwrap_or(0)
} }
#[no_mangle] #[no_mangle]
@ -36,9 +40,7 @@ pub extern "C" fn dcap_generate_quote(
&mut *(handle as *mut DcapQuote) &mut *(handle as *mut DcapQuote)
}; };
dcap.generate_quote(quote_buf, report_data).unwrap(); dcap.generate_quote(quote_buf, report_data).unwrap_or(-1)
0
} }
#[no_mangle] #[no_mangle]
@ -51,7 +53,7 @@ pub extern "C" fn dcap_get_supplemental_data_size(handle: *mut c_void) -> u32 {
&mut *(handle as *mut DcapQuote) &mut *(handle as *mut DcapQuote)
}; };
dcap.get_supplemental_data_size() dcap.get_supplemental_data_size().unwrap_or(0)
} }
#[no_mangle] #[no_mangle]
@ -81,9 +83,7 @@ pub extern "C" fn dcap_verify_quote(
supplemental_data: supplemental_data, supplemental_data: supplemental_data,
}; };
dcap.verify_quote(&mut verify_arg).unwrap(); dcap.verify_quote(&mut verify_arg).unwrap_or(-1)
0
} }

@ -20,7 +20,6 @@ cfg_if::cfg_if! {
} }
} }
// Copy from occlum/src/libos/src/fs/dev_fs/dev_sgx/mod.rs // Copy from occlum/src/libos/src/fs/dev_fs/dev_sgx/mod.rs
//#[allow(dead_code)] //#[allow(dead_code)]
#[repr(C)] #[repr(C)]
@ -49,32 +48,36 @@ pub struct DcapQuote {
} }
impl DcapQuote { impl DcapQuote {
pub fn new() -> Self { pub fn new() -> Result<Self, Error> {
let path = CString::new("/dev/sgx").unwrap(); let path = CString::new("/dev/sgx").unwrap();
let fd = unsafe { libc::open(path.as_ptr(), O_RDONLY) }; let fd = unsafe { libc::open(path.as_ptr(), O_RDONLY) };
if fd > 0 { if fd > 0 {
Self { Ok(Self {
fd: fd, fd: fd,
quote_size: 0, quote_size: 0,
supplemental_size: 0, supplemental_size: 0,
} })
} else { } else {
panic!("Open /dev/sgx failed") let os_err = Error::last_os_error();
println!("OS error: {os_err:?}");
Err(os_err)
} }
} }
pub fn get_quote_size(&mut self) -> u32 { pub fn get_quote_size(&mut self) -> Result<u32, Error> {
let size: u32 = 0; let size: u32 = 0;
let ret = unsafe { libc::ioctl(self.fd, IOCTL_GET_DCAP_QUOTE_SIZE, &size) }; let ret = unsafe { libc::ioctl(self.fd, IOCTL_GET_DCAP_QUOTE_SIZE, &size) };
if ret < 0 { if ret < 0 {
panic!("IOCTRL IOCTL_GET_DCAP_QUOTE_SIZE failed"); let os_err = Error::last_os_error();
println!("OS error: {os_err:?}");
Err(os_err)
} else { } else {
self.quote_size = size; self.quote_size = size;
size Ok(size)
} }
} }
pub fn generate_quote(&mut self, quote_buf: *mut u8, report_data: *const sgx_report_data_t) -> Result<i32, &'static str> { pub fn generate_quote(&mut self, quote_buf: *mut u8, report_data: *const sgx_report_data_t) -> Result<i32, Error> {
let quote_arg: IoctlGenDCAPQuoteArg = IoctlGenDCAPQuoteArg { let quote_arg: IoctlGenDCAPQuoteArg = IoctlGenDCAPQuoteArg {
report_data: report_data, report_data: report_data,
quote_size: &mut self.quote_size, quote_size: &mut self.quote_size,
@ -83,28 +86,33 @@ impl DcapQuote {
let ret = unsafe { libc::ioctl(self.fd, IOCTL_GEN_DCAP_QUOTE, &quote_arg) }; let ret = unsafe { libc::ioctl(self.fd, IOCTL_GEN_DCAP_QUOTE, &quote_arg) };
if ret < 0 { if ret < 0 {
Err("IOCTRL IOCTL_GEN_DCAP_QUOTE failed") let os_err = Error::last_os_error();
println!("OS error: {os_err:?}");
Err(os_err)
} else { } else {
Ok(0) Ok(0)
} }
} }
pub fn get_supplemental_data_size(&mut self) -> u32 { pub fn get_supplemental_data_size(&mut self) -> Result<u32, Error> {
let size: u32 = 0; let size: u32 = 0;
let ret = unsafe { libc::ioctl(self.fd, IOCTL_GET_DCAP_SUPPLEMENTAL_SIZE, &size) }; let ret = unsafe { libc::ioctl(self.fd, IOCTL_GET_DCAP_SUPPLEMENTAL_SIZE, &size) };
if ret < 0 { if ret < 0 {
panic!("IOCTRL IOCTL_GET_DCAP_SUPPLEMENTAL_SIZE failed"); let os_err = Error::last_os_error();
println!("OS error: {os_err:?}");
Err(os_err)
} else { } else {
self.supplemental_size = size; self.supplemental_size = size;
size Ok(size)
} }
} }
pub fn verify_quote(&mut self, verify_arg: *mut IoctlVerDCAPQuoteArg) -> Result<i32, &'static str> { pub fn verify_quote(&mut self, verify_arg: *mut IoctlVerDCAPQuoteArg) -> Result<i32, Error> {
let ret = unsafe { libc::ioctl(self.fd, IOCTL_VER_DCAP_QUOTE, verify_arg) }; let ret = unsafe { libc::ioctl(self.fd, IOCTL_VER_DCAP_QUOTE, verify_arg) };
if ret < 0 { if ret < 0 {
println!("ret = {}", ret); let os_err = Error::last_os_error();
Err("IOCTRL IOCTL_VER_DCAP_QUOTE failed") println!("OS error: {os_err:?}");
Err(os_err)
} else { } else {
Ok(0) Ok(0)
} }

@ -1,4 +1,5 @@
pub use std::boxed::Box; pub use std::boxed::Box;
pub use std::io::Error;
pub use libc::{open, ioctl, close, c_void, c_int, O_RDONLY}; pub use libc::{open, ioctl, close, c_void, c_int, O_RDONLY};
// Defined in "occlum/deps/rust-sgx-sdk/sgx_types" // Defined in "occlum/deps/rust-sgx-sdk/sgx_types"