/dev/sgx IOCTL codes

This commit is contained in:
Valentyn Faychuk 2024-10-19 04:17:33 +03:00
commit d8dc2d8756
5 changed files with 411 additions and 0 deletions

8
.gitignore vendored Normal file

@ -0,0 +1,8 @@
debug/
target/
Cargo.lock
**/*.rs.bk
# RustRover
.idea/

6
Cargo.toml Normal file

@ -0,0 +1,6 @@
[package]
name = "occlum-ioctl"
version = "0.1.0"
edition = "2021"
[dependencies]

2
README.md Normal file

@ -0,0 +1,2 @@
A simple app to display Occlum /dev/sgx IOCTL codes and needed types
Doesn't have any dependencies, run with `cargo run`

220
src/main.rs Normal file

@ -0,0 +1,220 @@
mod types;
use types::*;
fn main() {
println!("Occlum /dev/sgx IOCTL codes:");
println!("SGX_CMD_NUM_IS_EDMM_SUPPORTED {:x}", SGX_CMD_NUM_IS_EDMM_SUPPORTED);
println!("SGX_CMD_NUM_GET_EPID_GROUP_ID {:x}", SGX_CMD_NUM_GET_EPID_GROUP_ID);
println!("SGX_CMD_NUM_GEN_EPID_QUOTE {:x}", SGX_CMD_NUM_GEN_EPID_QUOTE);
println!("SGX_CMD_NUM_SELF_TARGET {:x}", SGX_CMD_NUM_SELF_TARGET);
println!("SGX_CMD_NUM_VERIFY_REPORT {:x}", SGX_CMD_NUM_VERIFY_REPORT);
println!("SGX_CMD_NUM_CREATE_REPORT {:x}", SGX_CMD_NUM_CREATE_REPORT);
println!("SGX_CMD_NUM_DETECT_DCAP_DRIVER {:x}", SGX_CMD_NUM_DETECT_DCAP_DRIVER);
println!("SGX_CMD_NUM_GET_DCAP_QUOTE_SIZE {:x}", SGX_CMD_NUM_GET_DCAP_QUOTE_SIZE);
println!("SGX_CMD_NUM_GEN_DCAP_QUOTE {:x}", SGX_CMD_NUM_GEN_DCAP_QUOTE);
println!("SGX_CMD_NUM_GET_DCAP_SUPPLEMENTAL_SIZE {:x}", SGX_CMD_NUM_GET_DCAP_SUPPLEMENTAL_SIZE);
println!("SGX_CMD_NUM_VER_DCAP_QUOTE {:x}", SGX_CMD_NUM_VER_DCAP_QUOTE);
println!("SGX_CMD_NUM_KEY {:x}", SGX_CMD_NUM_KEY);
//println!("{:x} SGX_CMD_NUM_IS_EDMM_SUPPORTED", SGX_CMD_NUM_IS_EDMM_SUPPORTED);
//println!("{:x} SGX_CMD_NUM_GET_EPID_GROUP_ID", SGX_CMD_NUM_GET_EPID_GROUP_ID);
//println!("{:x} SGX_CMD_NUM_GEN_EPID_QUOTE", SGX_CMD_NUM_GEN_EPID_QUOTE);
//println!("{:x} SGX_CMD_NUM_SELF_TARGET", SGX_CMD_NUM_SELF_TARGET);
//println!("{:x} SGX_CMD_NUM_VERIFY_REPORT", SGX_CMD_NUM_VERIFY_REPORT);
//println!("{:x} SGX_CMD_NUM_CREATE_REPORT", SGX_CMD_NUM_CREATE_REPORT);
//println!("{:x} SGX_CMD_NUM_DETECT_DCAP_DRIVER", SGX_CMD_NUM_DETECT_DCAP_DRIVER);
//println!("{:x} SGX_CMD_NUM_GET_DCAP_QUOTE_SIZE", SGX_CMD_NUM_GET_DCAP_QUOTE_SIZE);
//println!("{:x} SGX_CMD_NUM_GEN_DCAP_QUOTE", SGX_CMD_NUM_GEN_DCAP_QUOTE);
//println!("{:x} SGX_CMD_NUM_GET_DCAP_SUPPLEMENTAL_SIZE", SGX_CMD_NUM_GET_DCAP_SUPPLEMENTAL_SIZE);
//println!("{:x} SGX_CMD_NUM_VER_DCAP_QUOTE", SGX_CMD_NUM_VER_DCAP_QUOTE);
//println!("{:x} SGX_CMD_NUM_KEY", SGX_CMD_NUM_KEY);
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct StructuredIoctlNum {
cmd_id: u8,
magic_char: u8,
arg_size: u16,
arg_type: StructuredIoctlArgType,
}
impl StructuredIoctlNum {
pub const fn new<T>(
cmd_id: u8,
magic_char: u8,
arg_type: StructuredIoctlArgType,
) -> StructuredIoctlNum {
// TODO: make sure the size of T is not too big
// assert!(std::mem::size_of::<T>() <= (std::u16::MAX as usize));
let arg_size = std::mem::size_of::<T>() as u16;
StructuredIoctlNum {
cmd_id,
magic_char,
arg_size,
arg_type,
}
}
pub fn from_u32(raw_cmd_num: u32) -> StructuredIoctlNum {
// bits: [0, 8)
let cmd_id = (raw_cmd_num >> 0) as u8;
// bits: [8, 16)
let magic_char = (raw_cmd_num >> 8) as u8;
// bits: [16, 30)
let arg_size = ((raw_cmd_num >> 16) as u16) & 0x3FFF_u16;
// bits: [30, 32)
let arg_type = {
let type_bits = ((raw_cmd_num) >> 30) as u8;
StructuredIoctlArgType::from_u8(type_bits)
};
if arg_type == StructuredIoctlArgType::Void {
if arg_size != 0 {
panic!("invalid combination between type and size");
}
} else {
if arg_size == 0 {
panic!("invalid combination between type and size");
}
}
StructuredIoctlNum {
cmd_id,
magic_char,
arg_size,
arg_type,
}
}
pub const fn as_u32(&self) -> u32 {
(self.cmd_id as u32)
| (self.magic_char as u32) << 8
| (self.arg_size as u32) << 16
| (self.arg_type as u32) << 30
}
pub fn require_arg(&self) -> bool {
self.arg_type != StructuredIoctlArgType::Void
}
pub fn cmd_id(&self) -> u8 {
self.cmd_id
}
pub fn magic_char(&self) -> u8 {
self.magic_char
}
pub fn arg_size(&self) -> usize {
self.arg_size as usize
}
pub fn arg_type(&self) -> StructuredIoctlArgType {
self.arg_type
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(u8)]
pub enum StructuredIoctlArgType {
Void = 0,
Input = 1,
Output = 2,
InputOutput = 3,
}
impl StructuredIoctlArgType {
pub fn from_u8(type_bits: u8) -> StructuredIoctlArgType {
if type_bits > StructuredIoctlArgType::InputOutput as u8 {
panic!("invalid bits for StructuredIoctlArgType");
}
unsafe { core::mem::transmute(type_bits) }
}
pub fn can_be_input(&self) -> bool {
*self == StructuredIoctlArgType::Input || *self == StructuredIoctlArgType::InputOutput
}
pub fn can_be_output(&self) -> bool {
*self == StructuredIoctlArgType::Output || *self == StructuredIoctlArgType::InputOutput
}
}
/// Ioctl to check if EDMM (Enclave Dynamic Memory Management) is supported
pub const SGX_CMD_NUM_IS_EDMM_SUPPORTED: u32 =
StructuredIoctlNum::new::<i32>(0, SGX_MAGIC_CHAR, StructuredIoctlArgType::Output).as_u32();
/// Ioctl to get the EPID group ID
pub const SGX_CMD_NUM_GET_EPID_GROUP_ID: u32 = StructuredIoctlNum::new::<sgx_epid_group_id_t>(
1,
SGX_MAGIC_CHAR,
StructuredIoctlArgType::Output,
)
.as_u32();
/// Ioctl to get EPID quote
pub const SGX_CMD_NUM_GEN_EPID_QUOTE: u32 = StructuredIoctlNum::new::<IoctlGenEPIDQuoteArg>(
2,
SGX_MAGIC_CHAR,
StructuredIoctlArgType::InputOutput,
)
.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();
/// Ioctl to check if DCAP driver is installed on host
pub const SGX_CMD_NUM_DETECT_DCAP_DRIVER: u32 =
StructuredIoctlNum::new::<i32>(6, SGX_MAGIC_CHAR, StructuredIoctlArgType::Output).as_u32();
/// Ioctl to get DCAP quote size
pub const SGX_CMD_NUM_GET_DCAP_QUOTE_SIZE: u32 =
StructuredIoctlNum::new::<i32>(7, SGX_MAGIC_CHAR, StructuredIoctlArgType::Output).as_u32(); // 0x80047307
/// Ioctl to get DCAP quote
pub const SGX_CMD_NUM_GEN_DCAP_QUOTE: u32 = StructuredIoctlNum::new::<IoctlGenDCAPQuoteArg>(
8,
SGX_MAGIC_CHAR,
StructuredIoctlArgType::InputOutput,
)
.as_u32(); // 0xc0187308
/// Ioctl to get the verfication supplemental data size
pub const SGX_CMD_NUM_GET_DCAP_SUPPLEMENTAL_SIZE: u32 =
StructuredIoctlNum::new::<i32>(9, SGX_MAGIC_CHAR, StructuredIoctlArgType::Output).as_u32(); // 0x80047309
/// Ioctl to verify DCAP quote
pub const SGX_CMD_NUM_VER_DCAP_QUOTE: u32 = StructuredIoctlNum::new::<IoctlVerDCAPQuoteArg>(
10,
SGX_MAGIC_CHAR,
StructuredIoctlArgType::InputOutput,
)
.as_u32(); // 0xc030730a
/// Ioctl to get the key of the current enclave
pub const SGX_CMD_NUM_KEY: u32 = StructuredIoctlNum::new::<IoctlGetKeyArg>(
11,
SGX_MAGIC_CHAR,
StructuredIoctlArgType::InputOutput,
)
.as_u32();
/// A magical number that distinguishes SGX ioctls for other ioctls
const SGX_MAGIC_CHAR: u8 = 's' as u8;

175
src/types.rs Normal file

@ -0,0 +1,175 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(unused_attributes)]
#![allow(non_snake_case)]
#![allow(dead_code)]
pub type int8_t = i8;
pub type int16_t = i16;
pub type int32_t = i32;
pub type int64_t = i64;
pub type uint8_t = u8;
pub type uint16_t = u16;
pub type uint32_t = u32;
pub type uint64_t = u64;
pub type size_t = usize;
pub type sgx_epid_group_id_t = [uint8_t; 4];
pub const SGX_REPORT_DATA_SIZE: size_t = 64;
pub struct sgx_report_data_t {
pub d: [uint8_t; SGX_REPORT_DATA_SIZE],
}
pub struct sgx_spid_t {
pub id: [uint8_t; 16],
}
pub struct sgx_quote_nonce_t {
pub rand: [uint8_t; 16],
}
pub const SGX_HASH_SIZE: size_t = 32;
pub struct sgx_measurement_t {
pub m: [uint8_t; SGX_HASH_SIZE],
}
pub struct sgx_attributes_t {
pub flags: uint64_t,
pub xfrm: uint64_t,
}
pub type sgx_config_svn_t = uint16_t;
pub type sgx_misc_select_t = uint32_t;
pub const SGX_CONFIGID_SIZE: size_t = 64;
pub type sgx_config_id_t = [uint8_t; SGX_CONFIGID_SIZE];
pub const SGX_TARGET_INFO_RESERVED1_BYTES: size_t = 2;
pub const SGX_TARGET_INFO_RESERVED2_BYTES: size_t = 8;
pub const SGX_TARGET_INFO_RESERVED3_BYTES: size_t = 384;
pub struct sgx_target_info_t {
pub mr_enclave: sgx_measurement_t,
pub attributes: sgx_attributes_t,
pub reserved1: [uint8_t; SGX_TARGET_INFO_RESERVED1_BYTES],
pub config_svn: sgx_config_svn_t,
pub misc_select: sgx_misc_select_t,
pub reserved2: [uint8_t; SGX_TARGET_INFO_RESERVED2_BYTES],
pub config_id: sgx_config_id_t,
pub reserved3: [uint8_t; SGX_TARGET_INFO_RESERVED3_BYTES],
}
#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum sgx_quote_sign_type_t {
SGX_UNLINKABLE_SIGNATURE = 0,
SGX_LINKABLE_SIGNATURE = 1,
}
pub const SGX_KEYID_SIZE: size_t = 32;
pub const SGX_CPUSVN_SIZE: size_t = 16;
pub const SGX_KEY_REQUEST_RESERVED2_BYTES: size_t = 434;
pub const SGX_REPORT_BODY_RESERVED1_BYTES: size_t = 12;
pub const SGX_REPORT_BODY_RESERVED2_BYTES: size_t = 32;
pub const SGX_REPORT_BODY_RESERVED3_BYTES: size_t = 32;
pub const SGX_REPORT_BODY_RESERVED4_BYTES: size_t = 42;
pub struct sgx_cpu_svn_t {
pub svn: [uint8_t; SGX_CPUSVN_SIZE],
}
pub const SGX_ISVEXT_PROD_ID_SIZE: size_t = 16;
pub const SGX_ISV_FAMILY_ID_SIZE: size_t = 16;
pub type sgx_isvext_prod_id_t = [uint8_t; SGX_ISVEXT_PROD_ID_SIZE];
pub type sgx_isvfamily_id_t = [uint8_t; SGX_ISV_FAMILY_ID_SIZE];
pub type sgx_prod_id_t = uint16_t;
pub type sgx_isv_svn_t = uint16_t;
pub type sgx_key_128bit_t = [uint8_t; 16];
pub struct sgx_report_body_t {
pub cpu_svn: sgx_cpu_svn_t,
pub misc_select: sgx_misc_select_t,
pub reserved1: [uint8_t; SGX_REPORT_BODY_RESERVED1_BYTES],
pub isv_ext_prod_id: sgx_isvext_prod_id_t,
pub attributes: sgx_attributes_t,
pub mr_enclave: sgx_measurement_t,
pub reserved2: [uint8_t; SGX_REPORT_BODY_RESERVED2_BYTES],
pub mr_signer: sgx_measurement_t,
pub reserved3: [uint8_t; SGX_REPORT_BODY_RESERVED3_BYTES],
pub config_id: sgx_config_id_t,
pub isv_prod_id: sgx_prod_id_t,
pub isv_svn: sgx_isv_svn_t,
pub config_svn: sgx_config_svn_t,
pub reserved4: [uint8_t; SGX_REPORT_BODY_RESERVED4_BYTES],
pub isv_family_id: sgx_isvfamily_id_t,
pub report_data: sgx_report_data_t,
}
pub struct sgx_key_id_t {
pub id: [uint8_t; SGX_KEYID_SIZE],
}
pub const SGX_MAC_SIZE: size_t = 16;
pub type sgx_mac_t = [uint8_t; SGX_MAC_SIZE];
pub struct sgx_report_t {
pub body: sgx_report_body_t,
pub key_id: sgx_key_id_t,
pub mac: sgx_mac_t,
}
#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Debug)]
pub enum sgx_ql_qv_result_t {
SGX_QL_QV_RESULT_OK = 0x0000_0000,
// SGX_QL_QV_RESULT_MIN = 0x0000_A001,
SGX_QL_QV_RESULT_CONFIG_NEEDED = 0x0000_A001,
SGX_QL_QV_RESULT_OUT_OF_DATE = 0x0000_A002,
SGX_QL_QV_RESULT_OUT_OF_DATE_CONFIG_NEEDED = 0x0000_A003,
SGX_QL_QV_RESULT_INVALID_SIGNATURE = 0x0000_A004,
SGX_QL_QV_RESULT_REVOKED = 0x0000_A005,
SGX_QL_QV_RESULT_UNSPECIFIED = 0x0000_A006,
SGX_QL_QV_RESULT_SW_HARDENING_NEEDED = 0x0000_A007,
SGX_QL_QV_RESULT_CONFIG_AND_SW_HARDENING_NEEDED = 0x0000_A008,
SGX_QL_QV_RESULT_MAX = 0x0000_A0FF,
}
pub struct sgx_key_request_t {
pub key_name: uint16_t,
pub key_policy: uint16_t,
pub isv_svn: sgx_isv_svn_t,
pub reserved1: uint16_t,
pub cpu_svn: sgx_cpu_svn_t,
pub attribute_mask: sgx_attributes_t,
pub key_id: sgx_key_id_t,
pub misc_mask: sgx_misc_select_t,
pub config_svn: sgx_config_svn_t,
pub reserved2: [uint8_t; SGX_KEY_REQUEST_RESERVED2_BYTES],
}
#[repr(C)]
pub struct IoctlGenEPIDQuoteArg {
report_data: sgx_report_data_t, // Input
quote_type: sgx_quote_sign_type_t, // Input
spid: sgx_spid_t, // Input
nonce: sgx_quote_nonce_t, // Input
sigrl_ptr: *const u8, // Input (optional)
sigrl_len: u32, // Input (optional)
quote_buf_len: u32, // Input
quote_buf: *mut u8, // Output
}
#[repr(C)]
pub 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
}
#[repr(C)]
pub struct IoctlGenDCAPQuoteArg {
report_data: *const sgx_report_data_t, // Input
quote_size: *mut u32, // Input/output
quote_buf: *mut u8, // Output
}
#[repr(C)]
pub struct IoctlVerDCAPQuoteArg {
quote_buf: *const u8, // Input
quote_size: u32, // Input
collateral_expiration_status: *mut u32, // Output
quote_verification_result: *mut sgx_ql_qv_result_t, // Output
supplemental_data_size: u32, // Input (optional)
supplemental_data: *mut u8, // Output (optional)
}
#[repr(C)]
pub struct IoctlGetKeyArg {
key_request: *const sgx_key_request_t, // Input
key: *mut sgx_key_128bit_t, // Output
}