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#[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}