sgx_cpu/
lib.rs

1use console::{Emoji, Style};
2use raw_cpuid::{CpuId, SgxSectionInfo};
3use std::fmt;
4
5pub struct SgxCpuInfo(CpuId);
6
7impl SgxCpuInfo {
8    pub fn new() -> Self {
9        Self { 0: CpuId::new() }
10    }
11}
12
13impl Default for SgxCpuInfo {
14    fn default() -> Self {
15        SgxCpuInfo::new()
16    }
17}
18
19impl From<SgxCpuInfo> for CpuId {
20    fn from(sgx_cpu_info: SgxCpuInfo) -> CpuId {
21        sgx_cpu_info.0
22    }
23}
24
25impl fmt::Display for SgxCpuInfo {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        writeln!(f, "# CPU features")?;
28        let feature_info = self
29            .0
30            .get_feature_info()
31            .expect("Cannot get feature information");
32        writeln!(f, "stepping {}", feature_info.stepping_id())?;
33        writeln!(
34            f,
35            "model {} (extended {})",
36            feature_info.model_id(),
37            feature_info.extended_model_id()
38        )?;
39        writeln!(
40            f,
41            "family {} (extended {})",
42            feature_info.family_id(),
43            feature_info.extended_family_id()
44        )?;
45        writeln!(
46            f,
47            "{}  SMX support",
48            Emoji(&emoji(feature_info.has_smx()), "")
49        )?;
50
51        writeln!(f, "\n# Intel SGX capabilities")?;
52        let extended_features = self
53            .0
54            .get_extended_feature_info()
55            .expect("Cannot get extended features information");
56        writeln!(
57            f,
58            "{}  SGX availability",
59            Emoji(&emoji(extended_features.has_sgx()), "")
60        )?;
61        writeln!(
62            f,
63            "{}  SGX FLC (Flexible Launch Control)",
64            Emoji(&emoji(extended_features.has_sgx_lc()), "")
65        )?;
66        let sgx_info = self.0.get_sgx_info().expect("Cannot get SGX information");
67        writeln!(
68            f,
69            "{}  SGX 1 support",
70            Emoji(&emoji(sgx_info.has_sgx1()), "")
71        )?;
72        write!(
73            f,
74            "{}  SGX 2 support",
75            Emoji(&emoji(sgx_info.has_sgx2()), "")
76        )?;
77
78        // FLC disclaimer
79        if !extended_features.has_sgx_lc() {
80            let yellow = Style::new().yellow();
81            writeln!(
82                f,
83                "\n\n{}   {}",
84                Emoji("⚠️", ""),
85                yellow.apply_to("Warning !")
86            )?;
87            writeln!(
88                f,
89                "This CPU does not have FLC feature, so it does not support DCAP."
90            )?;
91            writeln!(
92                f,
93                "This CPU will not be able to run SGX using in-kernel SGX driver from Linux (starting from kernel 5.11)."
94            )?;
95            write!(f, "You must use the regular SGX driver")?;
96        }
97        Ok(())
98    }
99}
100
101fn emoji(b: bool) -> String {
102    if b {
103        "✅".to_owned()
104    } else {
105        "❌".to_owned()
106    }
107}
108
109impl fmt::Debug for SgxCpuInfo {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        writeln!(f, "# CPU features")?;
112        let feature_info = self
113            .0
114            .get_feature_info()
115            .expect("Cannot get feature information");
116        writeln!(f, "{:#02x?}", feature_info)?;
117        writeln!(f, "stepping {}", feature_info.stepping_id())?;
118        writeln!(f, "model {}", feature_info.model_id())?;
119        writeln!(f, "extended model {}", feature_info.extended_model_id())?;
120        writeln!(f, "family {}", feature_info.family_id())?;
121        writeln!(f, "extended family {}", feature_info.extended_family_id())?;
122        // TODO add support for processor type in `raw_cpuid` crate
123        // writeln!(f, "processor type {}", feature_info.processor_id());
124        writeln!(f, "SMX support {}", feature_info.has_smx())?;
125
126        writeln!(f, "\n# Extended feature bits")?;
127        let extended_features = self
128            .0
129            .get_extended_feature_info()
130            .expect("Cannot get extended features information");
131        writeln!(f, "{:#02x?}", extended_features)?;
132        writeln!(f, "SGX available: {}", extended_features.has_sgx())?;
133        writeln!(
134            f,
135            "SGX FLC (Flexible Launch Control): {}",
136            extended_features.has_sgx_lc()
137        )?;
138
139        writeln!(f, "\n# Intel SGX capabilities")?;
140        writeln!(f, "\n## Sub-leaf 0 (ECX=0)")?;
141        let sgx_info = self.0.get_sgx_info().expect("Cannot get SGX information");
142        writeln!(f, "{:#02x?}", sgx_info)?;
143        writeln!(f, "SGX 1 supported: {}", sgx_info.has_sgx1())?;
144        writeln!(f, "SGX 2 supported: {}", sgx_info.has_sgx2())?;
145        writeln!(
146            f,
147            "MaxEnclaveSize_Not64: {:#02x}",
148            sgx_info.max_enclave_size_non_64bit()
149        )?;
150        writeln!(
151            f,
152            "MaxEnclaveSize_64: {:#02x}",
153            sgx_info.max_enclave_size_64bit()
154        )?;
155
156        writeln!(f, "\n## Sub-leaf 1 (ECX=1)")?;
157        let (eax, ecx) = sgx_info.secs_attributes();
158        write!(f, "eax: {:#02x?}, ebx: 0, ecx: {:#02x?}, edx: 0", eax, ecx)?;
159
160        for (idx, SgxSectionInfo::Epc(epc_section)) in sgx_info.iter().enumerate() {
161            writeln!(f, "\nSub-leaf {} (ECX={})", idx + 2, idx + 2)?;
162            writeln!(
163                f,
164                "EPC (Enclave Page Cache) section:\n{:#02x?}",
165                epc_section
166            )?;
167            writeln!(
168                f,
169                "physical base address: {:#02x?}",
170                epc_section.physical_base()
171            )?;
172            write!(
173                f,
174                "size of EPC section in Processor Reserved Memory: {} MB",
175                epc_section.size() / 1_048_576
176            )?;
177        }
178        Ok(())
179    }
180}