Add ioctls for SGX local attestation
This commit is contained in:
		
							parent
							
								
									76b90efa8f
								
							
						
					
					
						commit
						a6e55881b9
					
				| @ -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 | LIBCOMPILER_RT_PATCH_A := $(BUILD_DIR)/lib/libcompiler-rt-patch.a | ||||||
| 
 | 
 | ||||||
| # All source code
 | # 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_TARGET_DIR := $(BUILD_DIR)/src/libos/cargo-target | ||||||
| RUST_OUT_DIR := $(BUILD_DIR)/lib | RUST_OUT_DIR := $(BUILD_DIR)/lib | ||||||
| EDL_C_SRCS := $(addprefix $(BUILD_DIR)/src/libos/,src/Enclave_t.c src/Enclave_t.h) | EDL_C_SRCS := $(addprefix $(BUILD_DIR)/src/libos/,src/Enclave_t.c src/Enclave_t.h) | ||||||
|  | |||||||
| @ -7,11 +7,13 @@ use sgx_types::*; | |||||||
| 
 | 
 | ||||||
| mod sgx_attestation_agent; | mod sgx_attestation_agent; | ||||||
| mod sgx_quote; | mod sgx_quote; | ||||||
|  | mod sgx_report; | ||||||
| 
 | 
 | ||||||
| pub use sgx_types::{ | 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_create_report, sgx_epid_group_id_t, sgx_quote_nonce_t, sgx_quote_sign_type_t, sgx_quote_t, | ||||||
|     sgx_spid_t, sgx_target_info_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_attestation_agent::SgxAttestationAgent; | ||||||
| pub use self::sgx_quote::SgxQuote; | pub use self::sgx_quote::SgxQuote; | ||||||
|  | pub use self::sgx_report::{create_report, get_self_target, verify_report}; | ||||||
|  | |||||||
							
								
								
									
										41
									
								
								src/libos/src/fs/dev_fs/dev_sgx/attestation/sgx_report.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										41
									
								
								src/libos/src/fs/dev_fs/dev_sgx/attestation/sgx_report.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | use super::*; | ||||||
|  | 
 | ||||||
|  | use std::ptr; | ||||||
|  | 
 | ||||||
|  | pub fn get_self_target() -> Result<sgx_target_info_t> { | ||||||
|  |     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<sgx_report_t> { | ||||||
|  |     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"), | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -17,6 +17,21 @@ pub const SGX_CMD_NUM_GEN_QUOTE: u32 = StructuredIoctlNum::new::<IoctlGenQuoteAr | |||||||
|     StructuredIoctlArgType::InputOutput, |     StructuredIoctlArgType::InputOutput, | ||||||
| ) | ) | ||||||
| .as_u32(); | .as_u32(); | ||||||
|  | /// Ioctl to get the target info of the current enclave
 | ||||||
|  | pub const SGX_CMD_NUM_SELF_TARGET: u32 = | ||||||
|  |     StructuredIoctlNum::new::<sgx_target_info_t>(3, SGX_MAGIC_CHAR, StructuredIoctlArgType::Output) | ||||||
|  |         .as_u32(); | ||||||
|  | /// Ioctl to create a report
 | ||||||
|  | pub const SGX_CMD_NUM_CREATE_REPORT: u32 = StructuredIoctlNum::new::<IoctlCreateReportArg>( | ||||||
|  |     4, | ||||||
|  |     SGX_MAGIC_CHAR, | ||||||
|  |     StructuredIoctlArgType::InputOutput, | ||||||
|  | ) | ||||||
|  | .as_u32(); | ||||||
|  | /// Ioctl to verify a report
 | ||||||
|  | pub const SGX_CMD_NUM_VERIFY_REPORT: u32 = | ||||||
|  |     StructuredIoctlNum::new::<sgx_report_t>(5, SGX_MAGIC_CHAR, StructuredIoctlArgType::Input) | ||||||
|  |         .as_u32(); | ||||||
| 
 | 
 | ||||||
| /// A magical number that distinguishes SGX ioctls for other ioctls
 | /// A magical number that distinguishes SGX ioctls for other ioctls
 | ||||||
| const SGX_MAGIC_CHAR: u8 = 's' as u8; | const SGX_MAGIC_CHAR: u8 = 's' as u8; | ||||||
|  | |||||||
| @ -60,8 +60,37 @@ impl File for DevSgx { | |||||||
|                 )?; |                 )?; | ||||||
|                 quote.dump_to_buf(quote_output_buf)?; |                 quote.dump_to_buf(quote_output_buf)?; | ||||||
|             } |             } | ||||||
|  |             SGX_CMD_NUM_SELF_TARGET => { | ||||||
|  |                 let arg = nonbuiltin_cmd.arg_mut::<sgx_target_info_t>()?; | ||||||
|  |                 *arg = get_self_target()?; | ||||||
|  |             } | ||||||
|  |             SGX_CMD_NUM_CREATE_REPORT => { | ||||||
|  |                 // Prepare the arguments
 | ||||||
|  |                 let arg = nonbuiltin_cmd.arg_mut::<IoctlCreateReportArg>()?; | ||||||
|  |                 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::<sgx_report_t>()?; | ||||||
|  |                 verify_report(arg)?; | ||||||
|  |             } | ||||||
|             _ => { |             _ => { | ||||||
|                 return_errno!(EINVAL, "unknown ioctl cmd for /dev/sgx"); |                 return_errno!(ENOSYS, "unknown ioctl cmd for /dev/sgx"); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         Ok(()) |         Ok(()) | ||||||
| @ -90,3 +119,10 @@ struct IoctlGenQuoteArg { | |||||||
|     quote_buf_len: u32,                // Input
 |     quote_buf_len: u32,                // Input
 | ||||||
|     quote_buf: *mut u8,                // Output
 |     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
 | ||||||
|  | } | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <termios.h> | #include <termios.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  | #include <sgx_report.h> | ||||||
| #include <sgx_quote.h> | #include <sgx_quote.h> | ||||||
| #include "test.h" | #include "test.h" | ||||||
| 
 | 
 | ||||||
| @ -40,18 +41,27 @@ typedef struct { | |||||||
|     } quote;                                        // output
 |     } quote;                                        // output
 | ||||||
| } sgxioc_gen_quote_arg_t; | } 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_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_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
 | // The max number of retries if ioctl returns EBUSY
 | ||||||
| #define IOCTL_MAX_RETRIES       20 | #define IOCTL_MAX_RETRIES       20 | ||||||
| 
 | 
 | ||||||
| typedef int(*sgx_ioctl_test_body_t)(int sgx_fd); | 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; |     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"); |         THROW_ERROR("failed to ioctl /dev/sgx"); | ||||||
|     } |     } | ||||||
|     if (is_edmm_supported != 0) { |     if (is_edmm_supported != 0) { | ||||||
| @ -60,7 +70,6 @@ static int do_SGXIOC_IS_EDDM_SUPPORTED(int sgx_fd) { | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| static int do_SGXIOC_GET_EPID_GROUP_ID(int sgx_fd) { | static int do_SGXIOC_GET_EPID_GROUP_ID(int sgx_fd) { | ||||||
|     int nretries = 0; |     int nretries = 0; | ||||||
|     while (nretries < IOCTL_MAX_RETRIES) { |     while (nretries < IOCTL_MAX_RETRIES) { | ||||||
| @ -141,8 +150,49 @@ static int do_sgx_ioctl_test(sgx_ioctl_test_body_t test_body) { | |||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int test_sgx_ioctl_SGXIOC_IS_EDDM_SUPPORTED(void) { | static int do_SGXIOC_SELF_TARGET(int sgx_fd) { | ||||||
|     return do_sgx_ioctl_test(do_SGXIOC_IS_EDDM_SUPPORTED); |     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) { | 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); |     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
 | // Test suite
 | ||||||
| // ============================================================================
 | // ============================================================================
 | ||||||
| 
 | 
 | ||||||
| static test_case_t test_cases[] = { | static test_case_t test_cases[] = { | ||||||
|     TEST_CASE(test_tty_ioctl_TIOCGWINSZ), |     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_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() { | int main() { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user