diff --git a/src/libos/Makefile b/src/libos/Makefile index 65f066f2..6d69932e 100644 --- a/src/libos/Makefile +++ b/src/libos/Makefile @@ -56,7 +56,7 @@ LIBOS_CORE_RS_A := $(BUILD_DIR)/lib/libocclum_libos_core_rs.a LIBCOMPILER_RT_PATCH_A := $(BUILD_DIR)/lib/libcompiler-rt-patch.a # All source code -RUST_SRCS := $(wildcard src/*.rs src/*/*.rs src/*/*/*.rs src/*/*/*/*.rs) +RUST_SRCS := $(wildcard src/*.rs src/*/*.rs src/*/*/*.rs src/*/*/*/*.rs src/*/*/*/*/*.rs) RUST_TARGET_DIR := $(BUILD_DIR)/src/libos/cargo-target RUST_OUT_DIR := $(BUILD_DIR)/lib EDL_C_SRCS := $(addprefix $(BUILD_DIR)/src/libos/,src/Enclave_t.c src/Enclave_t.h) diff --git a/src/libos/src/fs/dev_fs/dev_sgx/attestation/mod.rs b/src/libos/src/fs/dev_fs/dev_sgx/attestation/mod.rs index ebbbc428..92072632 100644 --- a/src/libos/src/fs/dev_fs/dev_sgx/attestation/mod.rs +++ b/src/libos/src/fs/dev_fs/dev_sgx/attestation/mod.rs @@ -7,11 +7,13 @@ use sgx_types::*; mod sgx_attestation_agent; mod sgx_quote; +mod sgx_report; pub use sgx_types::{ - sgx_epid_group_id_t, sgx_quote_nonce_t, sgx_quote_sign_type_t, sgx_quote_t, sgx_report_data_t, - sgx_spid_t, sgx_target_info_t, + sgx_create_report, sgx_epid_group_id_t, sgx_quote_nonce_t, sgx_quote_sign_type_t, sgx_quote_t, + sgx_report_data_t, sgx_self_target, sgx_spid_t, sgx_target_info_t, sgx_verify_report, }; pub use self::sgx_attestation_agent::SgxAttestationAgent; pub use self::sgx_quote::SgxQuote; +pub use self::sgx_report::{create_report, get_self_target, verify_report}; diff --git a/src/libos/src/fs/dev_fs/dev_sgx/attestation/sgx_report.rs b/src/libos/src/fs/dev_fs/dev_sgx/attestation/sgx_report.rs new file mode 100644 index 00000000..c378ce73 --- /dev/null +++ b/src/libos/src/fs/dev_fs/dev_sgx/attestation/sgx_report.rs @@ -0,0 +1,41 @@ +use super::*; + +use std::ptr; + +pub fn get_self_target() -> Result { + let mut self_target = sgx_target_info_t::default(); + let sgx_status = unsafe { sgx_self_target(&mut self_target) }; + match sgx_status { + sgx_status_t::SGX_SUCCESS => Ok(self_target), + _ => return_errno!(EINVAL, "unexpected SGX error"), + } +} + +pub fn create_report( + target_info: Option<&sgx_target_info_t>, + report_data: Option<&sgx_report_data_t>, +) -> Result { + let mut report = sgx_report_t::default(); + let sgx_status = unsafe { + sgx_create_report( + target_info.map_or(ptr::null(), |t| t), + report_data.map_or(ptr::null(), |t| t), + &mut report, + ) + }; + match sgx_status { + sgx_status_t::SGX_SUCCESS => Ok(report), + sgx_status_t::SGX_ERROR_INVALID_PARAMETER => return_errno!(EINVAL, "invalid paramters"), + _ => return_errno!(EINVAL, "unexpected SGX error"), + } +} + +pub fn verify_report(report: &sgx_report_t) -> Result<()> { + let sgx_status = unsafe { sgx_verify_report(report) }; + match sgx_status { + sgx_status_t::SGX_SUCCESS => Ok(()), + sgx_status_t::SGX_ERROR_MAC_MISMATCH => return_errno!(EINVAL, "report MAC mismatch"), + sgx_status_t::SGX_ERROR_INVALID_PARAMETER => return_errno!(EINVAL, "invalid report"), + _ => return_errno!(EINVAL, "unexpected SGX error"), + } +} diff --git a/src/libos/src/fs/dev_fs/dev_sgx/consts.rs b/src/libos/src/fs/dev_fs/dev_sgx/consts.rs index 12c2b644..6247f4e5 100644 --- a/src/libos/src/fs/dev_fs/dev_sgx/consts.rs +++ b/src/libos/src/fs/dev_fs/dev_sgx/consts.rs @@ -17,6 +17,21 @@ pub const SGX_CMD_NUM_GEN_QUOTE: u32 = StructuredIoctlNum::new::(3, SGX_MAGIC_CHAR, StructuredIoctlArgType::Output) + .as_u32(); +/// Ioctl to create a report +pub const SGX_CMD_NUM_CREATE_REPORT: u32 = StructuredIoctlNum::new::( + 4, + SGX_MAGIC_CHAR, + StructuredIoctlArgType::InputOutput, +) +.as_u32(); +/// Ioctl to verify a report +pub const SGX_CMD_NUM_VERIFY_REPORT: u32 = + StructuredIoctlNum::new::(5, SGX_MAGIC_CHAR, StructuredIoctlArgType::Input) + .as_u32(); /// A magical number that distinguishes SGX ioctls for other ioctls const SGX_MAGIC_CHAR: u8 = 's' as u8; diff --git a/src/libos/src/fs/dev_fs/dev_sgx/mod.rs b/src/libos/src/fs/dev_fs/dev_sgx/mod.rs index 5e65b316..9df765c4 100644 --- a/src/libos/src/fs/dev_fs/dev_sgx/mod.rs +++ b/src/libos/src/fs/dev_fs/dev_sgx/mod.rs @@ -60,8 +60,37 @@ impl File for DevSgx { )?; quote.dump_to_buf(quote_output_buf)?; } + SGX_CMD_NUM_SELF_TARGET => { + let arg = nonbuiltin_cmd.arg_mut::()?; + *arg = get_self_target()?; + } + SGX_CMD_NUM_CREATE_REPORT => { + // Prepare the arguments + let arg = nonbuiltin_cmd.arg_mut::()?; + let target_info = if !arg.target_info.is_null() { + Some(unsafe { &*arg.target_info }) + } else { + None + }; + let report_data = if !arg.report_data.is_null() { + Some(unsafe { &*arg.report_data }) + } else { + None + }; + let report = { + if arg.report.is_null() { + return_errno!(EINVAL, "output pointer for report must not be null"); + } + unsafe { &mut *arg.report } + }; + *report = create_report(target_info, report_data)?; + } + SGX_CMD_NUM_VERIFY_REPORT => { + let arg = nonbuiltin_cmd.arg::()?; + verify_report(arg)?; + } _ => { - return_errno!(EINVAL, "unknown ioctl cmd for /dev/sgx"); + return_errno!(ENOSYS, "unknown ioctl cmd for /dev/sgx"); } } Ok(()) @@ -90,3 +119,10 @@ struct IoctlGenQuoteArg { quote_buf_len: u32, // Input quote_buf: *mut u8, // Output } + +#[repr(C)] +struct IoctlCreateReportArg { + target_info: *const sgx_target_info_t, // Input (optional) + report_data: *const sgx_report_data_t, // Input (optional) + report: *mut sgx_report_t, // Output +} diff --git a/test/ioctl/main.c b/test/ioctl/main.c index 059e7957..62c11aa1 100644 --- a/test/ioctl/main.c +++ b/test/ioctl/main.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "test.h" @@ -40,18 +41,27 @@ typedef struct { } quote; // output } sgxioc_gen_quote_arg_t; -#define SGXIOC_IS_EDDM_SUPPORTED _IOR('s', 0, int) +typedef struct { + const sgx_target_info_t* target_info; // input (optinal) + const sgx_report_data_t* report_data; // input (optional) + sgx_report_t* report; // output +} sgxioc_create_report_arg_t; + +#define SGXIOC_IS_EDMM_SUPPORTED _IOR('s', 0, int) #define SGXIOC_GET_EPID_GROUP_ID _IOR('s', 1, sgx_epid_group_id_t) #define SGXIOC_GEN_QUOTE _IOWR('s', 2, sgxioc_gen_quote_arg_t) +#define SGXIOC_SELF_TARGET _IOR('s', 3, sgx_target_info_t) +#define SGXIOC_CREATE_REPORT _IOWR('s', 4, sgxioc_create_report_arg_t) +#define SGXIOC_VERIFY_REPORT _IOW('s', 5, sgx_report_t) // The max number of retries if ioctl returns EBUSY #define IOCTL_MAX_RETRIES 20 typedef int(*sgx_ioctl_test_body_t)(int sgx_fd); -static int do_SGXIOC_IS_EDDM_SUPPORTED(int sgx_fd) { +static int do_SGXIOC_IS_EDMM_SUPPORTED(int sgx_fd) { int is_edmm_supported = 0; - if (ioctl(sgx_fd, SGXIOC_IS_EDDM_SUPPORTED, &is_edmm_supported) < 0) { + if (ioctl(sgx_fd, SGXIOC_IS_EDMM_SUPPORTED, &is_edmm_supported) < 0) { THROW_ERROR("failed to ioctl /dev/sgx"); } if (is_edmm_supported != 0) { @@ -60,7 +70,6 @@ static int do_SGXIOC_IS_EDDM_SUPPORTED(int sgx_fd) { return 0; } - static int do_SGXIOC_GET_EPID_GROUP_ID(int sgx_fd) { int nretries = 0; while (nretries < IOCTL_MAX_RETRIES) { @@ -141,8 +150,49 @@ static int do_sgx_ioctl_test(sgx_ioctl_test_body_t test_body) { return ret; } -int test_sgx_ioctl_SGXIOC_IS_EDDM_SUPPORTED(void) { - return do_sgx_ioctl_test(do_SGXIOC_IS_EDDM_SUPPORTED); +static int do_SGXIOC_SELF_TARGET(int sgx_fd) { + sgx_target_info_t target_info; + if (ioctl(sgx_fd, SGXIOC_SELF_TARGET, &target_info) < 0) { + THROW_ERROR("failed to ioctl /dev/sgx"); + } + return 0; +} + +static int do_SGXIOC_CREATE_AND_VERIFY_REPORT(int sgx_fd) { + sgx_target_info_t target_info; + if (ioctl(sgx_fd, SGXIOC_SELF_TARGET, &target_info) < 0) { + THROW_ERROR("failed to ioctl /dev/sgx"); + } + sgx_report_t report_data; + sgx_report_t report; + + sgxioc_create_report_arg_t args[] = { + { + .target_info = (const sgx_target_info_t*) &target_info, + .report_data = NULL, + .report = &report + }, + { + .target_info = (const sgx_target_info_t*) &target_info, + .report_data = (const sgx_report_data_t*) &report_data, + .report = &report + } + }; + for (int arg_i = 0; arg_i < ARRAY_SIZE(args); arg_i++) { + memset(&report, 0, sizeof(report)); + sgxioc_create_report_arg_t* arg = &args[arg_i]; + if (ioctl(sgx_fd, SGXIOC_CREATE_REPORT, arg) < 0) { + THROW_ERROR("failed to create report"); + } + if (ioctl(sgx_fd, SGXIOC_VERIFY_REPORT, &report) < 0) { + THROW_ERROR("failed to verify report"); + } + } + return 0; +} + +int test_sgx_ioctl_SGXIOC_IS_EDMM_SUPPORTED(void) { + return do_sgx_ioctl_test(do_SGXIOC_IS_EDMM_SUPPORTED); } int test_sgx_ioctl_SGXIOC_GET_EPID_GROUP_ID(void) { @@ -153,15 +203,25 @@ int test_sgx_ioctl_SGXIOC_GEN_QUOTE(void) { return do_sgx_ioctl_test(do_SGXIOC_GEN_QUOTE); } +int test_sgx_ioctl_SGXIOC_SELF_TARGET(void) { + return do_sgx_ioctl_test(do_SGXIOC_SELF_TARGET); +} + +int test_sgx_ioctl_SGXIOC_CREATE_AND_VERIFY_REPORT(void) { + return do_sgx_ioctl_test(do_SGXIOC_CREATE_AND_VERIFY_REPORT); +} + // ============================================================================ // Test suite // ============================================================================ static test_case_t test_cases[] = { TEST_CASE(test_tty_ioctl_TIOCGWINSZ), - TEST_CASE(test_sgx_ioctl_SGXIOC_IS_EDDM_SUPPORTED), + TEST_CASE(test_sgx_ioctl_SGXIOC_IS_EDMM_SUPPORTED), TEST_CASE(test_sgx_ioctl_SGXIOC_GET_EPID_GROUP_ID), - TEST_CASE(test_sgx_ioctl_SGXIOC_GEN_QUOTE) + TEST_CASE(test_sgx_ioctl_SGXIOC_GEN_QUOTE), + TEST_CASE(test_sgx_ioctl_SGXIOC_SELF_TARGET), + TEST_CASE(test_sgx_ioctl_SGXIOC_CREATE_AND_VERIFY_REPORT) }; int main() {