1#![no_std]
14#![doc(
15 html_logo_url = "https://edp.fortanix.com/img/docs/edp-logo.svg",
16 html_favicon_url = "https://edp.fortanix.com/favicon.ico",
17 html_root_url = "https://edp.fortanix.com/docs/api/"
18)]
19#![cfg_attr(all(feature = "sgxstd", target_env = "sgx"), feature(sgx_platform))]
20
21#[cfg(all(feature = "sgxstd", target_env = "sgx"))]
22extern crate std;
23
24#[macro_use]
25extern crate bitflags;
26
27#[cfg(feature = "serde")]
28extern crate serde;
29
30#[cfg(feature = "serde")]
31use serde::{Deserialize, Serialize};
32
33#[cfg(target_env = "sgx")]
34mod arch;
35
36use core::slice;
37
38#[cfg(target_env = "sgx")]
39use core::convert::TryFrom;
40
41#[cfg(feature = "serde")]
42mod array_64 {
43 use core::fmt;
44 use serde::{
45 de::{Deserializer, Error, SeqAccess, Visitor},
46 ser::{SerializeTuple, Serializer},
47 };
48
49 const LEN: usize = 64;
50
51 pub fn serialize<S: Serializer>(array: &[u8; LEN], serializer: S) -> Result<S::Ok, S::Error> {
52 let mut seq = serializer.serialize_tuple(LEN)?;
53 for elem in &array[..] {
54 seq.serialize_element(elem)?;
55 }
56 seq.end()
57 }
58
59 pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<[u8; LEN], D::Error> {
60 struct ArrayVisitor;
61 impl<'de> Visitor<'de> for ArrayVisitor {
62 type Value = [u8; LEN];
63 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
64 write!(formatter, "an array of length 64")
65 }
66 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<[u8; LEN], A::Error> {
67 let mut arr = [0; LEN];
68 for i in 0..LEN {
69 arr[i] = seq
70 .next_element()?
71 .ok_or_else(|| A::Error::invalid_length(i, &self))?;
72 }
73 Ok(arr)
74 }
75 }
76 deserializer.deserialize_tuple(64, ArrayVisitor)
77 }
78}
79
80#[cfg(feature = "serde")]
83fn report_reserved4() -> [u8; 42] {
84 [0u8; 42]
85}
86
87#[cfg(feature = "serde")]
88fn ti_reserved1() -> [u8; 4] {
89 [0u8; 4]
90}
91
92#[cfg(feature = "serde")]
93fn ti_reserved2() -> [u8; 456] {
94 [0u8; 456]
95}
96
97#[cfg(not(feature = "large_array_derive"))]
98#[macro_use]
99mod large_array_impl;
100#[cfg(feature = "large_array_derive")]
101macro_rules! impl_default_clone_eq {
102 ($n:ident) => {};
103}
104
105pub mod tdx;
106
107#[macro_export]
108macro_rules! enum_def {
109 (
110 #[derive($($derive:meta),*)]
111 #[repr($repr:ident)]
112 pub enum $name:ident {
113 $($key:ident = $val:expr,)*
114 }
115 ) => (
116 #[derive($($derive),*)]
117 #[repr($repr)]
118 pub enum $name {
119 $($key = $val,)*
120 }
121
122 impl core::convert::TryFrom<$repr> for $name {
123 type Error = core::num::TryFromIntError;
124 fn try_from(v: $repr) -> Result<Self, Self::Error> {
125 match v {
126 $($val => Ok($name::$key),)*
127 _ => Err(u8::try_from(256u16).unwrap_err()),
128 }
129 }
130 }
131 )
132}
133
134#[macro_export]
135macro_rules! struct_def {
136 (
137 $(#[doc = $doc:expr])*
138 #[repr(C $(, align($align:tt))*)]
139 $(#[cfg_attr(feature = "large_array_derive", derive($($cfgderive:meta),*))])*
140 $(#[cfg_attr(feature = "serde", derive($($serdederive:meta),*))])*
141 $(#[derive($($derive:meta),*)])*
142 pub struct $name:ident $impl:tt
143 ) => {
144 $(
145 impl_default_clone_eq!($name);
146 #[cfg_attr(feature = "large_array_derive", derive($($cfgderive),*))]
147 )*
148 #[repr(C $(, align($align))*)]
149 $(#[cfg_attr(feature = "serde", derive($($serdederive),*))])*
150 $(#[derive($($derive),*)])*
151 $(#[doc = $doc])*
152 pub struct $name $impl
153
154 impl $name {
155 pub fn try_copy_from(src: &[u8]) -> Option<Self> {
158 if src.len() == Self::UNPADDED_SIZE {
159 unsafe {
160 let mut ret : Self = ::core::mem::zeroed();
161 ::core::ptr::copy_nonoverlapping(src.as_ptr(),
162 &mut ret as *mut _ as *mut _,
163 Self::UNPADDED_SIZE);
164 Some(ret)
165 }
166 } else {
167 None
168 }
169 }
170
171 fn _type_tests() {
174 #[repr(C)]
175 $(#[cfg_attr(feature = "serde", derive($($serdederive),*))])*
176 struct _Unaligned $impl
177
178 impl _Unaligned {
179 unsafe fn _check_size(self) -> [u8; $name::UNPADDED_SIZE] {
180 ::core::mem::transmute(self)
181 }
182 }
183
184 }
188 }
189
190 $(
191 #[test]
193 #[allow(non_snake_case)]
194 fn $name() {
195 assert_eq!($align, ::core::mem::align_of::<$name>());
196 }
197 )*
198
199 impl AsRef<[u8]> for $name {
200 fn as_ref(&self) -> &[u8] {
201 unsafe {
202 slice::from_raw_parts(self as *const $name as *const u8, Self::UNPADDED_SIZE)
203 }
204 }
205 }
206
207 struct_def!(@align bytes $($align)* name $name);
208 };
209 (@align bytes 16 name $name:ident) => {
210 struct_def!(@align type Align16 name $name);
211 };
212 (@align bytes 128 name $name:ident) => {
213 struct_def!(@align type Align128 name $name);
214 };
215 (@align bytes 256 name $name:ident) => {
216 struct_def!(@align type Align256 name $name);
217 };
218 (@align bytes 512 name $name:ident) => {
219 struct_def!(@align type Align512 name $name);
220 };
221 (@align bytes $($other:tt)*) => {};
222 (@align type $ty:ident name $name:ident) => {
223 #[cfg(target_env = "sgx")]
224 impl AsRef<arch::$ty<[u8; $name::UNPADDED_SIZE]>> for $name {
225 fn as_ref(&self) -> &arch::$ty<[u8; $name::UNPADDED_SIZE]> {
226 unsafe {
227 &*(self as *const _ as *const _)
228 }
229 }
230 }
231 };
232}
233
234enum_def! {
235#[derive(Clone,Copy,Debug,PartialEq,Eq)]
236#[repr(u32)]
237pub enum Encls {
238 ECreate = 0,
239 EAdd = 1,
240 EInit = 2,
241 ERemove = 3,
242 EDbgrd = 4,
243 EDbgwr = 5,
244 EExtend = 6,
245 ELdb = 7,
246 ELdu = 8,
247 EBlock = 9,
248 EPa = 10,
249 EWb = 11,
250 ETrack = 12,
251 EAug = 13,
252 EModpr = 14,
253 EModt = 15,
254}
255}
256
257enum_def! {
258#[derive(Clone,Copy,Debug,PartialEq,Eq)]
259#[repr(u32)]
260pub enum Enclu {
261 EReport = 0,
262 EGetkey = 1,
263 EEnter = 2,
264 EResume = 3,
265 EExit = 4,
266 EAccept = 5,
267 EModpe = 6,
268 EAcceptcopy = 7,
269 EVerifyReport2 = 8,
270}
271}
272
273enum_def! {
274#[derive(Clone,Copy,Debug,PartialEq,Eq)]
275#[repr(u32)]
276pub enum ErrorCode {
277 Success = 0,
278 InvalidSigStruct = 1,
279 InvalidAttribute = 2,
280 Blkstate = 3, InvalidMeasurement = 4,
282 Notblockable = 5,
283 PgInvld = 6,
284 Lockfail = 7,
285 InvalidSignature = 8,
286 MacCompareFail = 9,
287 PageNotBlocked = 10,
288 NotTracked = 11,
289 VaSlotOccupied = 12,
290 ChildPresent = 13,
291 EnclaveAct = 14,
292 EntryepochLocked = 15,
293 InvalidEinitToken = 16,
294 PrevTrkIncmpl = 17,
295 PgIsSecs = 18,
296 PageAttributesMismatch = 19,
297 PageNotModifiable = 20,
298 PageNotDebuggable = 21,
299 InvalidReportMacStruct = 28,
300 InvalidCpusvn = 32,
301 InvalidIsvsvn = 64,
302 UnmaskedEvent = 128,
303 InvalidKeyname = 256,
304}
305}
306
307pub const MEAS_ECREATE: u64 = 0x0045544145524345;
308pub const MEAS_EADD: u64 = 0x0000000044444145;
309pub const MEAS_EEXTEND: u64 = 0x00444E4554584545;
310
311pub const SIGSTRUCT_HEADER1: [u8; 16] = [
312 0x06, 0x00, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
313];
314pub const SIGSTRUCT_HEADER2: [u8; 16] = [
315 0x01, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
316];
317
318enum_def! {
319#[derive(Clone,Copy,Debug,PartialEq,Eq)]
320#[repr(u8)]
321pub enum PageType {
322 Secs = 0,
323 Tcs = 1,
324 Reg = 2,
325 Va = 3,
326 Trim = 4,
327}
328}
329
330enum_def! {
331#[derive(Clone,Copy,Debug,PartialEq,Eq)]
332#[repr(u16)]
333pub enum Keyname {
334 Einittoken = 0,
335 Provision = 1,
336 ProvisionSeal = 2,
337 Report = 3,
338 Seal = 4,
339}
340}
341
342struct_def! {
343#[repr(C, align(4096))]
344#[cfg_attr(
345 feature = "large_array_derive",
346 derive(Clone, Debug, Default, Eq, PartialEq)
347)]
348pub struct Secs {
349 pub size: u64,
350 pub baseaddr: u64,
351 pub ssaframesize: u32,
352 pub miscselect: Miscselect,
353 pub _reserved1: [u8; 24],
354 pub attributes: Attributes,
355 pub mrenclave: [u8; 32],
356 pub _reserved2: [u8; 32],
357 pub mrsigner: [u8; 32],
358 pub _reserved3: [u8; 96],
359 pub isvprodid: u16,
360 pub isvsvn: u16,
361 pub padding: [u8; 3836],
362}
363}
364
365impl Secs {
366 pub const UNPADDED_SIZE: usize = 4096;
367}
368
369struct_def! {
370#[repr(C)]
371#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
372#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
373pub struct Attributes {
374 pub flags: AttributesFlags,
375 pub xfrm: u64,
376}
377}
378
379impl Attributes {
380 pub const UNPADDED_SIZE: usize = 16;
381}
382
383bitflags! {
384 #[repr(C)]
385 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
386 pub struct AttributesFlags: u64 {
387 const INIT = 0b0000_0001;
388 const DEBUG = 0b0000_0010;
389 const MODE64BIT = 0b0000_0100;
390 const PROVISIONKEY = 0b0001_0000;
391 const EINITTOKENKEY = 0b0010_0000;
392 const CET = 0b0100_0000;
393 const KSS = 0b1000_0000;
394 }
395}
396
397impl Default for AttributesFlags {
398 fn default() -> Self {
399 Self::empty()
400 }
401}
402
403bitflags! {
404 #[repr(C)]
405 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
406 pub struct Miscselect: u32 {
407 const EXINFO = 0b0000_0001;
408 }
409}
410
411impl Default for Miscselect {
412 fn default() -> Self {
413 Self::empty()
414 }
415}
416
417struct_def! {
418#[repr(C, align(4096))]
419#[cfg_attr(
420 feature = "large_array_derive",
421 derive(Clone, Debug, Default, Eq, PartialEq)
422)]
423pub struct Tcs {
424 pub _reserved1: u64,
425 pub flags: TcsFlags,
426 pub ossa: u64,
427 pub cssa: u32,
428 pub nssa: u32,
429 pub oentry: u64,
430 pub _reserved2: u64,
431 pub ofsbasgx: u64,
432 pub ogsbasgx: u64,
433 pub fslimit: u32,
434 pub gslimit: u32,
435 pub _reserved3: [u8; 4024],
436}
437}
438
439impl Tcs {
440 pub const UNPADDED_SIZE: usize = 4096;
441}
442
443bitflags! {
444 #[repr(C)]
445 pub struct TcsFlags: u64 {
446 const DBGOPTIN = 0b0000_0001;
447 }
448}
449
450impl Default for TcsFlags {
451 fn default() -> Self {
452 Self::empty()
453 }
454}
455
456struct_def! {
457#[repr(C, align(32))]
458#[derive(Clone, Debug, Default, Eq, PartialEq)]
459pub struct Pageinfo {
460 pub linaddr: u64,
461 pub srcpge: u64,
462 pub secinfo: u64,
463 pub secs: u64,
464}
465}
466
467impl Pageinfo {
468 pub const UNPADDED_SIZE: usize = 32;
469}
470
471struct_def! {
472#[repr(C, align(64))]
473#[cfg_attr(
474 feature = "large_array_derive",
475 derive(Clone, Debug, Default, Eq, PartialEq)
476)]
477pub struct Secinfo {
478 pub flags: SecinfoFlags,
479 pub _reserved1: [u8; 56],
480}
481}
482
483impl Secinfo {
484 pub const UNPADDED_SIZE: usize = 64;
485}
486
487bitflags! {
488 #[repr(C)]
489 pub struct SecinfoFlags: u64 {
490 const R = 0b0000_0000_0000_0001;
491 const W = 0b0000_0000_0000_0010;
492 const X = 0b0000_0000_0000_0100;
493 const PENDING = 0b0000_0000_0000_1000;
494 const MODIFIED = 0b0000_0000_0001_0000;
495 const PR = 0b0000_0000_0010_0000;
496 const PT_MASK = 0b1111_1111_0000_0000;
497 const PT_B0 = 0b0000_0001_0000_0000; const PT_B1 = 0b0000_0010_0000_0000; const PT_B2 = 0b0000_0100_0000_0000; const PT_B3 = 0b0000_1000_0000_0000; const PT_B4 = 0b0001_0000_0000_0000; const PT_B5 = 0b0010_0000_0000_0000; const PT_B6 = 0b0100_0000_0000_0000; const PT_B7 = 0b1000_0000_0000_0000; }
506}
507
508impl Default for SecinfoFlags {
509 fn default() -> Self {
510 Self::empty()
511 }
512}
513
514impl SecinfoFlags {
515 pub fn page_type(&self) -> u8 {
516 (((*self & SecinfoFlags::PT_MASK).bits) >> 8) as u8
517 }
518
519 pub fn page_type_mut(&mut self) -> &mut u8 {
520 use core::mem::transmute;
521 unsafe {
522 let page_type: &mut [u8; 8] = transmute(&mut self.bits);
523 transmute(&mut page_type[1])
524 }
525 }
526}
527
528impl From<PageType> for SecinfoFlags {
529 fn from(data: PageType) -> SecinfoFlags {
530 SecinfoFlags::from_bits_truncate((data as u64) << 8)
531 }
532}
533
534struct_def! {
535#[repr(C, align(128))]
536#[cfg_attr(
537 feature = "large_array_derive",
538 derive(Clone, Debug, Default, Eq, PartialEq)
539)]
540pub struct Pcmd {
541 pub secinfo: Secinfo,
542 pub enclaveid: u64,
543 pub _reserved1: [u8; 40],
544 pub mac: [u8; 16],
545}
546}
547
548impl Pcmd {
549 pub const UNPADDED_SIZE: usize = 128;
550}
551
552struct_def! {
553#[repr(C, align(4096))]
554#[cfg_attr(
555 feature = "large_array_derive",
556 derive(Clone, Debug, Default, Eq, PartialEq)
557)]
558pub struct Sigstruct {
559 pub header: [u8; 16],
560 pub vendor: u32,
561 pub date: u32,
562 pub header2: [u8; 16],
563 pub swdefined: u32,
564 pub _reserved1: [u8; 84],
565 pub modulus: [u8; 384],
566 pub exponent: u32,
567 pub signature: [u8; 384],
568 pub miscselect: Miscselect,
569 pub miscmask: u32,
570 pub cet_attributes: u8,
571 pub cet_attributes_mask: u8,
572 pub _reserved2: u16,
573 pub isvfamilyid: [u8; 16],
574 pub attributes: Attributes,
575 pub attributemask: [u64; 2],
576 pub enclavehash: [u8; 32],
577 pub _reserved3: [u8; 16],
578 pub isvextprodid: [u8; 16],
579 pub isvprodid: u16,
580 pub isvsvn: u16,
581 pub _reserved4: [u8; 12],
582 pub q1: [u8; 384],
583 pub q2: [u8; 384],
584}
585}
586
587impl Sigstruct {
588 pub const UNPADDED_SIZE: usize = 1808;
589
590 pub fn signature_data(&self) -> (&[u8], &[u8]) {
593 unsafe {
594 let part1_start = &(self.header) as *const _ as *const u8;
595 let part1_end = &(self.modulus) as *const _ as *const u8 as usize;
596 let part2_start = &(self.miscselect) as *const _ as *const u8;
597 let part2_end = &(self._reserved4) as *const _ as *const u8 as usize;
598
599 (
600 slice::from_raw_parts(part1_start, part1_end - (part1_start as usize)),
601 slice::from_raw_parts(part2_start, part2_end - (part2_start as usize)),
602 )
603 }
604 }
605}
606
607struct_def! {
608#[repr(C, align(512))]
609#[cfg_attr(
610 feature = "large_array_derive",
611 derive(Clone, Debug, Default, Eq, PartialEq)
612)]
613pub struct Einittoken {
614 pub valid: u32,
615 pub _reserved1: [u8; 44],
616 pub attributes: Attributes,
617 pub mrenclave: [u8; 32],
618 pub _reserved2: [u8; 32],
619 pub mrsigner: [u8; 32],
620 pub _reserved3: [u8; 32],
621 pub cpusvnle: [u8; 16],
622 pub isvprodidle: u16,
623 pub isvsvnle: u16,
624 pub _reserved4: [u8; 24],
625 pub maskedmiscselectle: Miscselect,
626 pub maskedattributesle: Attributes,
627 pub keyid: [u8; 32],
628 pub mac: [u8; 16],
629}
630}
631
632impl Einittoken {
633 pub const UNPADDED_SIZE: usize = 304;
634}
635
636struct_def! {
637#[repr(C, align(512))]
638#[cfg_attr(
639 feature = "large_array_derive",
640 derive(Clone, Debug, Default, Eq, PartialEq)
641)]
642#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
643pub struct Report {
644 pub cpusvn: [u8; 16],
645 pub miscselect: Miscselect,
646 pub cet_attributes: u8,
647 #[cfg_attr(feature = "serde", serde(skip))]
648 pub _reserved1: [u8; 11],
649 pub isvextnprodid: [u8; 16],
650 pub attributes: Attributes,
651 pub mrenclave: [u8; 32],
652 #[cfg_attr(feature = "serde", serde(skip))]
653 pub _reserved2: [u8; 32],
654 pub mrsigner: [u8; 32],
655 #[cfg_attr(feature = "serde", serde(skip))]
656 pub _reserved3: [u8; 32],
657 #[cfg_attr(feature = "serde", serde(with = "array_64"))]
658 pub configid: [u8; 64],
659 pub isvprodid: u16,
660 pub isvsvn: u16,
661 pub configsvn: u16,
662 #[cfg_attr(feature = "serde", serde(default = "report_reserved4"), serde(skip))]
663 pub _reserved4: [u8; 42],
664 pub isvfamilyid: [u8; 16],
665 #[cfg_attr(feature = "serde", serde(with = "array_64"))]
666 pub reportdata: [u8; 64],
667 pub keyid: [u8; 32],
668 pub mac: [u8; 16],
669}
670}
671
672impl Report {
673 pub const UNPADDED_SIZE: usize = 432;
674 pub const TRUNCATED_SIZE: usize = 384;
676
677 #[cfg(target_env = "sgx")]
687 pub fn for_self() -> Self {
688 let reportdata = arch::Align128([0; 64]);
689 let targetinfo = arch::Align512([0; 512]);
690 let out = arch::ereport(&targetinfo, &reportdata);
691 Report::try_copy_from(&out.0).unwrap()
693 }
694
695 #[cfg(target_env = "sgx")]
696 pub fn for_target(targetinfo: &Targetinfo, reportdata: &[u8; 64]) -> Report {
697 let reportdata = arch::Align128(*reportdata);
698 let out = arch::ereport(targetinfo.as_ref(), &reportdata);
699 Report::try_copy_from(&out.0).unwrap()
701 }
702
703 #[cfg(target_env = "sgx")]
709 pub fn verify<F, R>(&self, check_mac: F) -> R
710 where
711 F: FnOnce(&[u8; 16], &[u8; Report::TRUNCATED_SIZE], &[u8; 16]) -> R,
712 {
713 let req = Keyrequest {
714 keyname: Keyname::Report as u16,
715 keyid: self.keyid,
716 ..Default::default()
717 };
718 let key = req.egetkey().expect("Couldn't get report key");
719 check_mac(&key, self.mac_data(), &self.mac)
720 }
721
722 pub fn mac_data(&self) -> &[u8; Report::TRUNCATED_SIZE] {
724 unsafe { &*(self as *const Self as *const [u8; Report::TRUNCATED_SIZE]) }
725 }
726}
727
728struct_def! {
729#[repr(C, align(512))]
730#[cfg_attr(
731 feature = "large_array_derive",
732 derive(Clone, Debug, Default, Eq, PartialEq)
733)]
734#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
735pub struct Targetinfo {
736 pub measurement: [u8; 32],
737 pub attributes: Attributes,
738 #[cfg_attr(feature = "serde", serde(default = "ti_reserved1"), serde(skip))]
739 pub _reserved1: [u8; 4],
740 pub miscselect: Miscselect,
741 #[cfg_attr(feature = "serde", serde(default = "ti_reserved2"), serde(skip))]
742 pub _reserved2: [u8; 456],
743}
744}
745
746impl Targetinfo {
747 pub const UNPADDED_SIZE: usize = 512;
748}
749
750impl From<Report> for Targetinfo {
751 fn from(r: Report) -> Targetinfo {
752 Targetinfo {
753 measurement: r.mrenclave,
754 attributes: r.attributes,
755 miscselect: r.miscselect,
756 ..Targetinfo::default()
757 }
758 }
759}
760
761struct_def! {
762#[repr(C, align(512))]
763#[cfg_attr(
764 feature = "large_array_derive",
765 derive(Clone, Debug, Default, Eq, PartialEq)
766)]
767pub struct Keyrequest {
768 pub keyname: u16,
769 pub keypolicy: Keypolicy,
770 pub isvsvn: u16,
771 pub _reserved1: u16,
772 pub cpusvn: [u8; 16],
773 pub attributemask: [u64; 2],
774 pub keyid: [u8; 32],
775 pub miscmask: u32,
776 pub _reserved2: [u8; 436],
777}
778}
779
780impl Keyrequest {
781 pub const UNPADDED_SIZE: usize = 512;
782
783 #[cfg(target_env = "sgx")]
784 pub fn egetkey(&self) -> Result<[u8; 16], ErrorCode> {
785 match arch::egetkey(self.as_ref()) {
786 Ok(k) => Ok(k.0),
787 Err(e) => Err(ErrorCode::try_from(e).unwrap()),
789 }
790 }
791}
792
793bitflags! {
794 #[repr(C)]
795 pub struct Keypolicy: u16 {
796 const MRENCLAVE = 0b0000_0001;
797 const MRSIGNER = 0b0000_0010;
798 }
799}
800
801impl Default for Keypolicy {
802 fn default() -> Self {
803 Self::empty()
804 }
805}
806
807struct_def! {
808 #[repr(C, align(4))]
814 #[derive(Clone, Debug, Default, Eq, PartialEq)]
815 pub struct ReportType {
816 pub report_type: u8,
823 pub subtype: u8,
825 pub version: u8,
827 pub reserved: u8,
828 }
829}
830
831impl ReportType {
832 pub const UNPADDED_SIZE: usize = 4;
833}
834
835enum_def! {
837#[derive(Clone,Copy,Debug,PartialEq,Eq)]
838#[repr(u8)]
839pub enum ReportTypeType {
840 Sgx = 0x00,
841 Tdx = 0x81,
844 }
846}
847
848pub const HASH_384_SIZE: usize = 48;
850pub type Sha384Hash = [u8; HASH_384_SIZE];
852
853pub const CPU_SVN_SIZE: usize = 16;
854pub const REPORT_MAC_STRUCT_SIZE: usize = 256;
855pub const REPORT_MAC_STRUCT_RESERVED1_BYTES: usize = 12;
856pub const REPORT_MAC_STRUCT_RESERVED2_BYTES: usize = 32;
857pub const REPORT_DATA_SIZE: usize = 64;
858
859pub const TEE_MAC_SIZE: usize = 32;
861
862struct_def! {
863#[repr(C, align(256))]
871#[cfg_attr(
872 feature = "large_array_derive",
873 derive(Clone, Debug, Default, Eq, PartialEq)
874)]
875pub struct ReportMacStruct {
876 pub report_type: ReportType,
878 pub _reserved1: [u8; REPORT_MAC_STRUCT_RESERVED1_BYTES],
880 pub cpusvn: [u8; CPU_SVN_SIZE],
882 pub tee_tcb_info_hash: Sha384Hash,
884 pub tee_info_hash: Sha384Hash,
886 pub report_data: [u8; REPORT_DATA_SIZE],
888 pub _reserved2: [u8; REPORT_MAC_STRUCT_RESERVED2_BYTES],
890 pub mac: [u8; TEE_MAC_SIZE],
892}
893}
894
895impl ReportMacStruct {
896 pub const UNPADDED_SIZE: usize = 256;
897
898 #[cfg(target_env = "sgx")]
899 pub fn verify(&self) -> Result<(), ErrorCode> {
900 arch::everifyreport2(self.as_ref())
901 .map_err(|e| ErrorCode::try_from(e).unwrap())
903 }
904}
905
906#[test]
907fn test_eq() {
908 let mut a = Keyrequest::default();
909 let mut b = Keyrequest::default();
910 assert!(a == b);
911
912 a.keyname = 22;
913 assert!(a != b);
914
915 b.keyname = 22;
916 assert!(a == b);
917
918 a.miscmask = 0xdeadbeef;
919 assert!(a != b);
920
921 b.miscmask = 0xdeadbeef;
922 assert!(a == b);
923}