dcap_rs/types/quotes/
mod.rs

1use super::cert::Certificates;
2
3pub mod version_3;
4pub mod version_4;
5pub mod body;
6
7use body::EnclaveReport;
8
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct QuoteHeader {
11    pub version: u16,                   // [2 bytes]
12                                        // Version of the quote data structure - 4, 5
13    pub att_key_type: u16,              // [2 bytes]
14                                        // Type of the Attestation Key used by the Quoting Enclave -
15                                        // 2 (ECDSA-256-with-P-256 curve) 
16                                        // 3 (ECDSA-384-with-P-384 curve)
17    pub tee_type: u32,                  // [4 bytes]
18                                        // TEE for this Attestation
19                                        // 0x00000000: SGX
20                                        // 0x00000081: TDX
21    pub qe_svn: [u8; 2],                // [2 bytes]
22                                        // Security Version of the Quoting Enclave - 1 (only applicable for SGX Quotes)
23    pub pce_svn: [u8; 2],               // [2 bytes]
24                                        // Security Version of the PCE - 0 (only applicable for SGX Quotes)
25    pub qe_vendor_id: [u8; 16],         // [16 bytes]
26                                        // Unique identifier of the QE Vendor. 
27                                        // Value: 939A7233F79C4CA9940A0DB3957F0607 (IntelĀ® SGX QE Vendor)
28                                        // Note: Each vendor that decides to provide a customized Quote data structure should have
29                                        // unique ID.
30    pub user_data: [u8; 20],            // [20 bytes]
31                                        // Custom user-defined data. For the IntelĀ® SGX and TDX DCAP Quote Generation Libraries, 
32                                        // the first 16 bytes contain a Platform Identifier that is used to link a PCK Certificate to an Enc(PPID).
33}
34
35impl QuoteHeader {
36    pub fn from_bytes(raw_bytes: &[u8]) -> Self {
37        let version = u16::from_le_bytes([raw_bytes[0], raw_bytes[1]]);
38        let att_key_type = u16::from_le_bytes([raw_bytes[2], raw_bytes[3]]);
39        let tee_type = u32::from_le_bytes([raw_bytes[4], raw_bytes[5], raw_bytes[6], raw_bytes[7]]);
40        let mut qe_svn = [0; 2];
41        qe_svn.copy_from_slice(&raw_bytes[8..10]);
42        let mut pce_svn = [0; 2];
43        pce_svn.copy_from_slice(&raw_bytes[10..12]);
44        let mut qe_vendor_id = [0; 16];
45        qe_vendor_id.copy_from_slice(&raw_bytes[12..28]);
46        let mut user_data = [0; 20];
47        user_data.copy_from_slice(&raw_bytes[28..48]);
48
49        QuoteHeader {
50            version,
51            att_key_type,
52            tee_type,
53            qe_svn,
54            pce_svn,
55            qe_vendor_id,
56            user_data,
57        }
58    }
59
60    pub fn to_bytes(&self) -> [u8; 48] {
61        let mut raw_bytes = [0; 48];
62        raw_bytes[0..2].copy_from_slice(&self.version.to_le_bytes());
63        raw_bytes[2..4].copy_from_slice(&self.att_key_type.to_le_bytes());
64        raw_bytes[4..8].copy_from_slice(&self.tee_type.to_le_bytes());
65        raw_bytes[8..10].copy_from_slice(&self.qe_svn);
66        raw_bytes[10..12].copy_from_slice(&self.pce_svn);
67        raw_bytes[12..28].copy_from_slice(&self.qe_vendor_id);
68        raw_bytes[28..48].copy_from_slice(&self.user_data);
69
70        raw_bytes
71    }
72}
73
74#[derive(Clone, Debug, PartialEq, Eq)]
75pub struct QeAuthData {
76    pub size: u16,
77    pub data: Vec<u8>,
78}
79
80impl QeAuthData {
81    pub fn from_bytes(raw_bytes: &[u8]) -> QeAuthData {
82        let size = u16::from_le_bytes([raw_bytes[0], raw_bytes[1]]);
83        let data = raw_bytes[2..2+size as usize].to_vec();
84        QeAuthData {
85            size,
86            data,
87        }
88    }
89}
90
91#[derive(Clone, Debug, PartialEq, Eq)]
92pub struct CertData {
93    pub cert_data_type: u16,            // [2 bytes]
94                                        // Determines type of data required to verify the QE Report Signature in the Quote Signature Data structure. 
95                                        // 1 - (PCK identifier: PPID in plain text, CPUSVN, and PCESVN)
96                                        // 2 - (PCK identifier: PPID encrypted using RSA-2048-OAEP, CPUSVN, and PCESVN)
97                                        // 3 - (PCK identifier: PPID encrypted using RSA-2048-OAEP, CPUSVN, PCESVN, and QEID)
98                                        // 4 - (PCK Leaf Certificate in plain text; currently not supported)
99                                        // 5 - (Concatenated PCK Cert Chain)
100                                        // 6 - (QE Report Certification Data)
101                                        // 7 - (PLATFORM_MANIFEST; currently not supported)
102    pub cert_data_size: u32,            // [4 bytes]
103                                        // Size of Certification Data field.
104    pub cert_data: Vec<u8>,             // [variable bytes]
105                                        // Data required to verify the QE Report Signature depending on the value of the Certification Data Type:
106                                        // 1: Byte array that contains concatenation of PPID, CPUSVN, PCESVN (LE), PCEID (LE).
107                                        // 2: Byte array that contains concatenation of PPID encrypted using RSA-2048-OAEP, CPUSVN, PCESVN (LE), PCEID (LE).
108                                        // 3: Byte array that contains concatenation of PPID encrypted using RSA-3072-OAEP, CPUSVN, PCESVN (LE), PCEID (LE).
109                                        // 4: PCK Leaf Certificate
110                                        // 5: Concatenated PCK Cert Chain (PEM formatted). PCK Leaf Cert || Intermediate CA Cert || Root CA Cert 
111                                        // 6: QE Report Certification Data
112                                        // 7: PLATFORM_MANIFEST
113}
114
115impl CertData {
116    pub fn from_bytes(raw_bytes: &[u8]) -> Self {
117        let cert_data_type = u16::from_le_bytes([raw_bytes[0], raw_bytes[1]]);
118        let cert_data_size = u32::from_le_bytes([raw_bytes[2], raw_bytes[3], raw_bytes[4], raw_bytes[5]]);
119        let cert_data = raw_bytes[6..6+cert_data_size as usize].to_vec();
120
121        CertData {
122            cert_data_type,
123            cert_data_size,
124            cert_data,
125        }
126    }
127
128    pub fn get_cert_data(&self) -> CertDataType {
129        match self.cert_data_type {
130            1 => CertDataType::Type1(self.cert_data.clone()),
131            2 => CertDataType::Type2(self.cert_data.clone()),
132            3 => CertDataType::Type3(self.cert_data.clone()),
133            4 => CertDataType::Type4(self.cert_data.clone()),
134            5 => CertDataType::CertChain(Certificates::from_pem(&self.cert_data)),
135            6 => CertDataType::QeReportCertData(QeReportCertData::from_bytes(&self.cert_data)),
136            7 => CertDataType::Type7(self.cert_data.clone()),
137            _ => CertDataType::Unused,
138        }
139    }
140}
141
142pub enum CertDataType {
143    Unused,
144    Type1(Vec<u8>),
145    Type2(Vec<u8>),
146    Type3(Vec<u8>),
147    Type4(Vec<u8>),
148    CertChain(Certificates),
149    QeReportCertData(QeReportCertData),
150    Type7(Vec<u8>),
151}
152
153#[derive(Clone, Debug)]
154pub struct QeReportCertData {
155    pub qe_report: EnclaveReport,
156    pub qe_report_signature: [u8; 64],
157    pub qe_auth_data: QeAuthData,
158    pub qe_cert_data: CertData,
159}
160
161impl QeReportCertData {
162    pub fn from_bytes(raw_bytes: &[u8]) -> Self {
163        // 384 bytes for qe_report
164        let qe_report = EnclaveReport::from_bytes(&raw_bytes[0..384]);
165        // 64 bytes for qe_report_signature
166        let mut qe_report_signature = [0; 64];
167        qe_report_signature.copy_from_slice(&raw_bytes[384..448]);
168        // qe auth data is variable length, we'll pass remaining bytes to the from_bytes method
169        let qe_auth_data = QeAuthData::from_bytes(&raw_bytes[448..]);
170        // get the length of qe_auth_data
171        let qe_auth_data_size = 2 + qe_auth_data.size as usize;
172        // finish off with the parsing of qe_cert_data
173        let qe_cert_data_start = 448 + qe_auth_data_size;
174        let qe_cert_data = CertData::from_bytes(&raw_bytes[qe_cert_data_start..]);
175
176        QeReportCertData {
177            qe_report,
178            qe_report_signature,
179            qe_auth_data,
180            qe_cert_data,
181        }
182    }
183}