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