1use crate::{
7 certs::{csv::Certificate, Usage, Verifiable},
8 crypto::{sig::ecdsa, PublicKey, Signature},
9 util::*,
10};
11
12use hex::encode;
13use log::*;
14use serde::{Deserialize, Serialize};
15use std::ffi::c_void;
16use std::io::Write;
17
18#[repr(C)]
21#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
22pub struct Body {
23 pub version: u32,
25 pub chip_id: [u8; 16],
27 #[serde(with = "serde_bytes")]
29 pub user_data: [u8; 64],
30 pub measure: [u8; 32],
32 #[serde(with = "serde_bytes")]
34 pub reserved: [u8; 128],
35 pub sig_usage: u32,
37 pub sig_algo: u32,
39}
40
41impl Default for Body {
42 fn default() -> Self {
44 Self {
45 version: Default::default(),
46 chip_id: Default::default(),
47 user_data: [0u8; 64],
48 measure: Default::default(),
49 reserved: [0u8; 128],
50 sig_usage: Default::default(),
51 sig_algo: Default::default(),
52 }
53 }
54}
55
56impl Body {
57 pub fn print_fields(&self) {
59 trace!("Version: {}", self.version);
60 trace!("Chip ID: {}", String::from_utf8_lossy(&self.chip_id));
61 trace!("User data: {}", encode(self.user_data));
62 trace!("Measure: {:?}", self.measure);
63 trace!("Signature Usage: {}", self.sig_usage);
64 trace!("Signature Algorithm: {}", self.sig_algo);
65 }
66}
67
68#[repr(C)]
70#[derive(Debug, Serialize, Deserialize, Clone)]
71pub struct AttestationReport {
72 pub body: Body,
74 pub sig: ecdsa::Signature,
76}
77
78impl AttestationReport {
79 pub fn print_report(&self) {
81 self.body.print_fields();
82 self.sig.print_fields();
83 }
84}
85
86impl Default for AttestationReport {
87 fn default() -> Self {
89 Self {
90 body: Default::default(),
91 sig: Default::default(),
92 }
93 }
94}
95
96#[repr(C)]
98#[derive(Debug, serde::Deserialize)]
99pub struct AttestationResponse {
100 pub report_size: u32,
102 pub reserved: [u8; 28],
104 pub report: AttestationReport,
106}
107
108impl Default for AttestationResponse {
109 fn default() -> Self {
111 Self {
112 report_size: 0,
113 reserved: [0u8; 28],
114 report: AttestationReport::default(),
115 }
116 }
117}
118
119impl AttestationResponse {
120 pub unsafe fn from_raw<'a>(ptr: *mut c_void) -> Option<&'a mut Self> {
124 if ptr.is_null() {
125 None
126 } else {
127 Some(&mut *(ptr as *mut Self))
128 }
129 }
130}
131
132impl codicon::Encoder<crate::Body> for AttestationReport {
134 type Error = std::io::Error;
135
136 fn encode(&self, mut writer: impl Write, _: crate::Body) -> Result<(), std::io::Error> {
138 writer.save(&self.body)
139 }
140}
141
142impl TryFrom<&AttestationReport> for Signature {
143 type Error = std::io::Error;
144
145 #[inline]
147 fn try_from(value: &AttestationReport) -> Result<Self, std::io::Error> {
148 let sig = Vec::try_from(&value.sig)?;
149 Ok(Self {
150 sig,
151 id: None,
152 usage: Usage::CEK,
153 algo: None,
154 })
155 }
156}
157
158impl Verifiable for (&Certificate, &AttestationReport) {
160 type Output = ();
161
162 fn verify(self) -> Result<(), std::io::Error> {
164 let key: PublicKey = self.0.try_into()?;
165 let sig: Signature = self.1.try_into()?;
166 key.verify(
167 self.1,
168 &self.0.body.data.user_id[..self.0.body.data.uid_size as usize],
169 &sig,
170 )
171 }
172}