dcap_rs/types/
mod.rs

1use self::quotes::body::*;
2use crate::constants::{ENCLAVE_REPORT_LEN, SGX_TEE_TYPE, TD10_REPORT_LEN, TDX_TEE_TYPE};
3use alloy_sol_types::SolValue;
4use serde::{Deserialize, Serialize};
5
6pub mod cert;
7pub mod collaterals;
8pub mod enclave_identity;
9pub mod quotes;
10pub mod tcbinfo;
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub enum TcbStatus {
14    OK,
15    TcbSwHardeningNeeded,
16    TcbConfigurationAndSwHardeningNeeded,
17    TcbConfigurationNeeded,
18    TcbOutOfDate,
19    TcbOutOfDateConfigurationNeeded,
20    TcbRevoked,
21    TcbUnrecognized,
22}
23
24impl TcbStatus {
25    pub fn from_str(s: &str) -> Self {
26        return match s {
27            "UpToDate" => TcbStatus::OK,
28            "SWHardeningNeeded" => TcbStatus::TcbSwHardeningNeeded,
29            "ConfigurationAndSWHardeningNeeded" => TcbStatus::TcbConfigurationAndSwHardeningNeeded,
30            "ConfigurationNeeded" => TcbStatus::TcbConfigurationNeeded,
31            "OutOfDate" => TcbStatus::TcbOutOfDate,
32            "OutOfDateConfigurationNeeded" => TcbStatus::TcbOutOfDateConfigurationNeeded,
33            "Revoked" => TcbStatus::TcbRevoked,
34            _ => TcbStatus::TcbUnrecognized,
35        };
36    }
37}
38
39// serialization:
40// [quote_vesion][tee_type][tcb_status][fmspc][quote_body_raw_bytes]
41// 2 bytes + 4 bytes + 1 byte + 6 bytes + var (SGX_ENCLAVE_REPORT = 384; TD10_REPORT = 584)
42// total: 13 + var bytes
43#[derive(Debug)]
44pub struct VerifiedOutput {
45    pub quote_version: u16,
46    pub tee_type: u32,
47    pub tcb_status: TcbStatus,
48    pub fmspc: [u8; 6],
49    pub quote_body: QuoteBody,
50    pub advisory_ids: Option<Vec<String>>,
51}
52
53impl VerifiedOutput {
54    pub fn to_bytes(&self) -> Vec<u8> {
55        let mut output_vec = Vec::new();
56
57        output_vec.extend_from_slice(&self.quote_version.to_be_bytes());
58        output_vec.extend_from_slice(&self.tee_type.to_be_bytes());
59        output_vec.push(match self.tcb_status {
60            TcbStatus::OK => 0,
61            TcbStatus::TcbSwHardeningNeeded => 1,
62            TcbStatus::TcbConfigurationAndSwHardeningNeeded => 2,
63            TcbStatus::TcbConfigurationNeeded => 3,
64            TcbStatus::TcbOutOfDate => 4,
65            TcbStatus::TcbOutOfDateConfigurationNeeded => 5,
66            TcbStatus::TcbRevoked => 6,
67            TcbStatus::TcbUnrecognized => 7,
68        });
69        output_vec.extend_from_slice(&self.fmspc);
70
71        match self.quote_body {
72            QuoteBody::SGXQuoteBody(body) => {
73                output_vec.extend_from_slice(&body.to_bytes());
74            }
75            QuoteBody::TD10QuoteBody(body) => {
76                output_vec.extend_from_slice(&body.to_bytes());
77            }
78        }
79
80        if let Some(advisory_ids) = self.advisory_ids.as_ref() {
81            let encoded = advisory_ids.abi_encode();
82            output_vec.extend_from_slice(encoded.as_slice());
83        }
84
85        output_vec
86    }
87
88    pub fn from_bytes(slice: &[u8]) -> VerifiedOutput {
89        let mut quote_version = [0; 2];
90        quote_version.copy_from_slice(&slice[0..2]);
91        let mut tee_type = [0; 4];
92        tee_type.copy_from_slice(&slice[2..6]);
93        let tcb_status = match slice[6] {
94            0 => TcbStatus::OK,
95            1 => TcbStatus::TcbSwHardeningNeeded,
96            2 => TcbStatus::TcbConfigurationAndSwHardeningNeeded,
97            3 => TcbStatus::TcbConfigurationNeeded,
98            4 => TcbStatus::TcbOutOfDate,
99            5 => TcbStatus::TcbOutOfDateConfigurationNeeded,
100            6 => TcbStatus::TcbRevoked,
101            7 => TcbStatus::TcbUnrecognized,
102            _ => panic!("Invalid TCB Status"),
103        };
104        let mut fmspc = [0; 6];
105        fmspc.copy_from_slice(&slice[7..13]);
106
107        let mut offset = 13usize;
108        let quote_body = match u32::from_be_bytes(tee_type) {
109            SGX_TEE_TYPE => {
110                let raw_quote_body = &slice[offset..offset + ENCLAVE_REPORT_LEN];
111                offset += ENCLAVE_REPORT_LEN;
112                QuoteBody::SGXQuoteBody(EnclaveReport::from_bytes(raw_quote_body))
113            }
114            TDX_TEE_TYPE => {
115                let raw_quote_body = &slice[offset..offset + TD10_REPORT_LEN];
116                offset += TD10_REPORT_LEN;
117                QuoteBody::TD10QuoteBody(TD10ReportBody::from_bytes(raw_quote_body))
118            }
119            _ => panic!("unknown TEE type"),
120        };
121
122        let mut advisory_ids = None;
123        if offset < slice.len() {
124            let advisory_ids_slice = &slice[offset..];
125            advisory_ids = Some(<Vec<String>>::abi_decode(advisory_ids_slice, true).unwrap());
126        }
127
128        VerifiedOutput {
129            quote_version: u16::from_be_bytes(quote_version),
130            tee_type: u32::from_be_bytes(tee_type),
131            tcb_status,
132            fmspc,
133            quote_body,
134            advisory_ids,
135        }
136    }
137}