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