blob: c81898faf59a3a3559175d975f59ea18b8335b6c [file] [log] [blame]
use std::{mem,fmt,u16};
use hex;
use itertools::Itertools;
const SGX_CPUSVN_SIZE: usize = 16;
const PSVN_SIZE: usize = 18; // sizeof(psvn_t)
const PSDA_SVN_SIZE: usize = 4;
const ISVSVN_SIZE: usize = 2;
const SGX_PLATFORM_INFO_SIZE:usize = 101;
const QE_EPID_GROUP_REVOKED : u8 = 0x01;
const PERF_REKEY_FOR_QE_EPID_GROUP_AVAILABLE : u8 = 0x02;
const QE_EPID_GROUP_OUT_OF_DATE : u8 = 0x04;
const QUOTE_CPUSVN_OUT_OF_DATE : u16 = 0x0001;
const QUOTE_ISVSVN_QE_OUT_OF_DATE : u16 = 0x0002;
const QUOTE_ISVSVN_PCE_OUT_OF_DATE : u16 = 0x0004;
const PSE_ISVSVN_OUT_OF_DATE : u16 = 0x0001;
const EPID_GROUP_ID_BY_PS_HW_GID_REVOKED : u16 = 0x0002;
const SVN_FROM_PS_HW_SEC_INFO_OUT_OF_DATE : u16 = 0x0004;
const SIGRL_VER_FROM_PS_HW_SIG_RLVER_OUT_OF_DATE :u16 = 0x0008;
const PRIVRL_VER_FROM_PS_HW_PRV_KEY_RLVER_OUT_OF_DATE:u16 = 0x0010;
#[allow(non_camel_case_types)]
type sgx_isv_svn_t = u16; // 2 bytes
#[allow(non_camel_case_types)]
type tcb_psvn_t = [u8;PSVN_SIZE];
#[allow(non_camel_case_types)]
type psda_svn_t = [u8;PSDA_SVN_SIZE];
#[allow(non_camel_case_types)]
type pse_isvsvn_t = [u8;ISVSVN_SIZE];
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(packed)]
struct sgx_cpu_svn_t { // 16 bytes
svn : [u8;SGX_CPUSVN_SIZE],
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(packed)]
struct psvn_t { // 16 + 2
cpu_svn : sgx_cpu_svn_t,
isv_svn : sgx_isv_svn_t,
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(packed)]
struct sgx_ec256_signature_t {
gx : [u8;32],
gy : [u8;32],
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(packed)]
pub struct platform_info_blob {
sgx_epid_group_flags : u8,
sgx_tcb_evaluation_flags : u16,
pse_evaluation_flags : u16,
latest_equivalent_tcb_psvn : tcb_psvn_t,
latest_pse_isvsvn : pse_isvsvn_t,
latest_psda_svn : psda_svn_t,
xeid : u32,
gid : u32,
signature : sgx_ec256_signature_t,
}
macro_rules! test_and_print {
($f:ident, $x:expr, $y:ident) => {
if $x & $y != 0 {
writeln!($f, "\t\t{}", stringify!($y))?;
}
}
}
impl fmt::Display for platform_info_blob {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "Platform info is:")?;
writeln!(f, "\tsgx_epid_group_fags = {:02X}", self.sgx_epid_group_flags)?;
test_and_print!(f, self.sgx_epid_group_flags, QE_EPID_GROUP_REVOKED);
test_and_print!(f, self.sgx_epid_group_flags, PERF_REKEY_FOR_QE_EPID_GROUP_AVAILABLE);
test_and_print!(f, self.sgx_epid_group_flags, QE_EPID_GROUP_OUT_OF_DATE);
let tcb_eflags = u16::from_be(self.sgx_tcb_evaluation_flags);
writeln!(f, "\n\tsgx_tcb_evaluation_flags = {:04X}", tcb_eflags)?;
test_and_print!(f, tcb_eflags, QUOTE_CPUSVN_OUT_OF_DATE);
test_and_print!(f, tcb_eflags, QUOTE_ISVSVN_QE_OUT_OF_DATE);
test_and_print!(f, tcb_eflags, QUOTE_ISVSVN_PCE_OUT_OF_DATE);
let pse_eflags = u16::from_be(self.pse_evaluation_flags);
writeln!(f, "\n\tpse_evaluation_flags = {:04X}", pse_eflags)?;
test_and_print!(f, pse_eflags, PSE_ISVSVN_OUT_OF_DATE);
test_and_print!(f, pse_eflags, EPID_GROUP_ID_BY_PS_HW_GID_REVOKED);
test_and_print!(f, pse_eflags, SVN_FROM_PS_HW_SEC_INFO_OUT_OF_DATE);
test_and_print!(f, pse_eflags, SIGRL_VER_FROM_PS_HW_SIG_RLVER_OUT_OF_DATE);
test_and_print!(f, pse_eflags, PRIVRL_VER_FROM_PS_HW_PRV_KEY_RLVER_OUT_OF_DATE);
writeln!(f,"\n\tlatest_equivalent_tcb_psvn: {:02X}", self.latest_equivalent_tcb_psvn.iter().format(""))?;
writeln!(f,"\n\tlatest_pse_isvsvn: {:02X}", self.latest_pse_isvsvn.iter().format(""))?;
writeln!(f,"\n\tlatest_psda_svn: {:02X}", self.latest_psda_svn.iter().format(""))?;
writeln!(f,"\n\txeid: {:08X}", u32::from_be(self.xeid))?;
writeln!(f,"\n\tgid: {:08X}", u32::from_be(self.gid))?;
writeln!(f,"\n\tsignature:")?;
writeln!(f,"\t\tgy: {:02X}", self.signature.gx.iter().format(""))?;
writeln!(f,"\t\tgy: {:02X}", self.signature.gy.iter().format(""))?;
writeln!(f)
}
}
#[allow(non_camel_case_types)]
#[repr(packed)]
pub struct platform_info {
#[allow(unused)]
platform_info: [u8;SGX_PLATFORM_INFO_SIZE],
}
impl platform_info {
pub fn from_str(pib_str : &str) -> platform_info_blob {
let z = hex::decode(pib_str).unwrap();
assert_eq!(z.len(), 105);
// Remove the TSV header (undocumented)
let pib_vec = z[4..].to_vec();
let mut pib_array : [u8;101] = [0;101];
pib_array.clone_from_slice(&pib_vec[..]);
let pib : platform_info_blob = unsafe { mem::transmute(pib_array)};
pib
}
}