@@ -9,11 +9,46 @@ extern crate memory_layout;
99
1010use memory_layout:: impl_default_clone_eq;
1111use std:: slice;
12- use tdx_module :: tdx_rtmr_event_t ;
12+ use thiserror :: Error ;
1313
14+ #[ cfg( feature = "tdx-module" ) ]
1415pub mod tdx_attest;
16+ #[ cfg( feature = "ioctl" ) ]
17+ pub mod tdx_ioctl;
1518
16- use tdx_attest:: { TdxAttestError , tdx_report_data_t, tdx_report_t} ;
19+ #[ derive( Error , Debug , PartialEq , Eq ) ]
20+ pub enum TdxAttestError {
21+ /// Lower bound for error translations.
22+ #[ error( "Indicate min error to allow better translation, should be unexpected in production" ) ]
23+ Min ,
24+ #[ error( "The parameter is incorrect" ) ]
25+ InvalidParameter ,
26+ #[ error( "Not enough memory is available to complete this operation" ) ]
27+ OutOfMemory ,
28+ #[ error( "vsock related failure" ) ]
29+ VsockFailure ,
30+ #[ error( "Failed to get the TD Report" ) ]
31+ ReportFailure ,
32+ #[ error( "Failed to extend rtmr" ) ]
33+ ExtendFailure ,
34+ #[ error( "Request feature is not supported" ) ]
35+ NotSupported ,
36+ #[ error( "Failed to get the TD Quote" ) ]
37+ QuoteFailure ,
38+ #[ error( "The device driver return busy" ) ]
39+ Busy ,
40+ #[ error( "Failed to acess tdx attest device" ) ]
41+ DeviceFailure ,
42+ #[ error( "Only supported RTMR index is 2 and 3" ) ]
43+ InvalidRtmrIndex ,
44+ #[ error(
45+ "The platform Quoting infrastructure does not support any of the keys described in att_key_id_list"
46+ ) ]
47+ UnsupportedAttKeyId ,
48+ /// Upper bound for error translations.
49+ #[ error( "Indicate max error to allow better translation, should be unexpected in production" ) ]
50+ Max ,
51+ }
1752
1853/// SHA384
1954pub const TEE_HASH_384_SIZE : usize = 48 ;
@@ -34,8 +69,11 @@ pub const TEE_REPORT2_VERSION: usize = 0x0;
3469/// VERSION for Report Type2 which mr_servicetd is used
3570pub const TEE_REPORT2_VERSION_SERVICETD : usize = 0x1 ;
3671
37- // Ref: https://github.com/intel/confidential-computing.sgx/blob/main/common/inc/sgx_report2.h
3872struct_def ! {
73+ /// Rust definition of `REPORTTYPE` from `REPORTMACSTRUCT`.
74+ ///
75+ /// Ref: Intel TDX Module ABI Specification, section 4.7.4.
76+ /// Link to latest version (Sep 2025): https://cdrdv2.intel.com/v1/dl/getContent/733579
3977 #[ repr( C , align( 4 ) ) ]
4078 #[ derive( Clone , Debug , Default , Eq , PartialEq ) ]
4179 pub struct TeeReportType {
@@ -58,17 +96,19 @@ impl TeeReportType {
5896 pub const UNPADDED_SIZE : usize = 4 ;
5997}
6098
61-
6299pub const TDX_REPORT_MAC_STRUCT_SIZE : usize = 256 ;
63100pub const TDX_REPORT_MAC_STRUCT_RESERVED1_BYTES : usize = 12 ;
64101pub const TDX_REPORT_MAC_STRUCT_RESERVED2_BYTES : usize = 32 ;
65102
66- // Ref: https://github.com/intel/confidential-computing.sgx/blob/main/common/inc/sgx_report2.h
67103struct_def ! {
104+ /// Rust definition of `REPORTMACSTRUCT` from `TDREPORT_STRUCT`.
105+ ///
106+ /// Ref: Intel TDX Module ABI Specification, section 4.7.3.
107+ /// Link to latest version (Sep 2025): https://cdrdv2.intel.com/v1/dl/getContent/733579
68108 #[ repr( C , align( 256 ) ) ]
69109 #[ cfg_attr(
70110 feature = "large_array_derive" ,
71- derive( Clone , Debug , Default , Eq , PartialEq )
111+ derive( Clone , Debug , Eq , PartialEq )
72112 ) ]
73113 pub struct TdxReportMac {
74114 /// ( 0) TEE Report type
@@ -78,7 +118,7 @@ struct_def! {
78118 /// ( 16) Security Version of the CPU
79119 pub cpu_svn: [ u8 ; TEE_CPU_SVN_SIZE ] ,
80120 /// ( 32) SHA384 of TEE_TCB_INFO for TEEs
81- pub tee_tcb_info_hash: [ u8 ; TEE_HASH_384_SIZE ] ,
121+ pub tee_tcb_info_hash: [ u8 ; TEE_HASH_384_SIZE ] ,
82122 /// ( 80) SHA384 of TEE_INFO
83123 pub tee_info_hash: [ u8 ; TEE_HASH_384_SIZE ] ,
84124 /// (128) Data provided by the user
@@ -100,12 +140,16 @@ pub const TEE_TCB_INFO_SIZE: usize = 239;
100140pub const TDX_REPORT_RESERVED_SIZE : usize = 17 ;
101141pub const TEE_INFO_SIZE : usize = 512 ;
102142
103- // Ref: https://github.com/intel/confidential-computing.sgx/blob/main/common/inc/sgx_report2.h
104143struct_def ! {
144+ /// Rust definition of `TDREPORT_STRUCT` from the output of the `TDG.MR.REPORT` function.
145+ /// `TDG.MR.REPORT` is one variant of syscall `TDCALL`.
146+ ///
147+ /// Ref: Intel TDX Module ABI Specification, section 4.7.2.
148+ /// Link to latest version (Sep 2025): https://cdrdv2.intel.com/v1/dl/getContent/733579
105149 #[ repr( C , align( 1024 ) ) ]
106150 #[ cfg_attr(
107151 feature = "large_array_derive" ,
108- derive( Clone , Debug , Default , Eq , PartialEq )
152+ derive( Clone , Debug , Eq , PartialEq )
109153 ) ]
110154 pub struct TdxReport {
111155 /// ( 0) Report mac struct for SGX report type 2
@@ -119,19 +163,6 @@ struct_def! {
119163 }
120164}
121165
122- impl From < tdx_report_t > for TdxReport {
123- fn from ( report : tdx_report_t ) -> Self {
124- Self :: try_copy_from ( & report. d ) . expect ( "validated size" )
125- }
126- }
127-
128- impl From < TdxReport > for tdx_report_t {
129- fn from ( report : TdxReport ) -> Self {
130- let mut d = [ 0u8 ; TDX_REPORT_SIZE ] ;
131- d. copy_from_slice ( report. as_ref ( ) ) ;
132- tdx_report_t { d }
133- }
134- }
135166
136167impl TdxReport {
137168 pub const UNPADDED_SIZE : usize = 1024 ;
@@ -148,35 +179,28 @@ impl TdxReport {
148179 /// # Errors
149180 /// Propagates the underlying TDX attestation error code.
150181 pub fn get_report ( report_data : [ u8 ; TDX_REPORT_DATA_SIZE ] ) -> Result < Self , TdxAttestError > {
151- let mut tdx_report = tdx_report_t {
152- d : [ 0 ; TDX_REPORT_SIZE ] ,
153- } ;
154- let report_data = tdx_report_data_t { d : report_data } ;
155- tdx_attest:: parse_tdx_attest_error ( tdx_attest:: tdx_att_get_report (
156- Some ( & report_data) ,
157- & mut tdx_report,
158- ) ) ?;
159- Ok ( tdx_report. into ( ) )
182+ #[ cfg( feature = "ioctl" ) ]
183+ {
184+ return tdx_ioctl:: get_report ( report_data) ;
185+ }
186+ #[ cfg( all( not( feature = "ioctl" ) , feature = "tdx-module" ) ) ]
187+ {
188+ return tdx_attest:: get_report ( report_data) ;
189+ }
190+ #[ cfg( not( any( feature = "ioctl" , feature = "tdx-module" ) ) ) ]
191+ {
192+ Err ( TdxAttestError :: NotSupported )
193+ }
160194 }
161195}
162196
163197pub const TDX_RTMR_EVENT_HEADER_SIZE : usize = 68 ;
164198/// Size of the RTMR extend data field in bytes.
165199pub const TDX_RTMR_EXTEND_DATA_SIZE : usize = 48 ;
166200
167- #[ repr( u8 ) ]
168- pub enum TdxStatus {
169- Success = 0 ,
170- InvalidParameter = 1 ,
171- AccessDenied = 2 ,
172- InternalError = 255 ,
173- }
174-
175- pub const REMR_EXTEND_DATA_SIZE : usize = 48 ;
176-
177201/// Extend one of the TDX runtime measurement registers (RTMRs).
178202///
179- /// RTMR[rtmr_index] = SHA384(RTMR[rtmr_index] || extend_data)
203+ /// ` RTMR[rtmr_index] = SHA384(RTMR[rtmr_index] || extend_data)`
180204/// - `rtmr_index`: only supported RTMR index is 2 and 3.
181205/// - `event_data`: field is currently expected to be empty by the platform
182206/// quoting infrastructure.
@@ -193,48 +217,66 @@ pub const REMR_EXTEND_DATA_SIZE: usize = 48;
193217/// not supported.
194218pub fn extend_rtmr (
195219 rtmr_index : u64 ,
196- extend_data : [ u8 ; REMR_EXTEND_DATA_SIZE ] ,
220+ extend_data : [ u8 ; TDX_RTMR_EXTEND_DATA_SIZE ] ,
197221) -> Result < ( ) , TdxAttestError > {
198- match rtmr_index {
199- 2 ..=3 => ( ) ,
200- _ => return Err ( TdxAttestError :: InvalidRtmrIndex ) ,
201- } ;
202- // From: `tdx_attest_sys` crate generated binding code
203- // ```C
204- // typedef struct _tdx_rtmr_event_t {
205- // uint32_t version;
206- // uint64_t rtmr_index;
207- // uint8_t extend_data[48];
208- // uint32_t event_type;
209- // uint32_t event_data_size;
210- // uint8_t event_data[];
211- // } tdx_rtmr_event_t;
212- // ```
213- let mut rtmr_event = [ 0u8 ; std:: mem:: size_of :: < tdx_rtmr_event_t > ( ) ] ;
214- rtmr_event[ 0 ..0 + 4 ] . copy_from_slice ( & 1u32 . to_ne_bytes ( ) ) ;
215- rtmr_event[ 4 ..4 + 8 ] . copy_from_slice ( & rtmr_index. to_ne_bytes ( ) ) ;
216- rtmr_event[ 12 ..12 + REMR_EXTEND_DATA_SIZE ] . copy_from_slice ( & extend_data) ;
217-
218- tdx_attest:: parse_tdx_attest_error ( tdx_attest:: tdx_att_extend ( & rtmr_event) )
222+ #[ cfg( feature = "ioctl" ) ]
223+ {
224+ return tdx_ioctl:: extend_rtmr ( rtmr_index, extend_data) ;
225+ }
226+ #[ cfg( all( not( feature = "ioctl" ) , feature = "tdx-module" ) ) ]
227+ {
228+ return tdx_attest:: extend_rtmr ( rtmr_index, extend_data) ;
229+ }
230+ #[ cfg( not( any( feature = "ioctl" , feature = "tdx-module" ) ) ) ]
231+ {
232+ Err ( TdxAttestError :: NotSupported )
233+ }
219234}
220235
221236#[ cfg( test) ]
222237mod tests {
223238 use super :: * ;
224239
225240 #[ test]
226- fn test_tdx_att_get_report ( ) {
241+ fn test_tdx_att_get_report_invalid_device ( ) {
242+ let expected_err = if cfg ! ( any( feature = "ioctl" , feature = "tdx-module" ) ) {
243+ TdxAttestError :: DeviceFailure
244+ } else {
245+ TdxAttestError :: NotSupported
246+ } ;
227247 let result = TdxReport :: get_report ( [ 0 ; TDX_REPORT_DATA_SIZE ] ) ;
228- assert ! ( matches!( result, Err ( TdxAttestError :: DeviceFailure ) ) ) ;
248+ match result {
249+ Ok ( _) => panic ! ( "expecting error" ) ,
250+ Err ( err) => assert_eq ! ( err, expected_err) ,
251+ }
252+ }
253+
254+ #[ test]
255+ fn test_tdx_att_extend_invalid_device ( ) {
256+ let expected_err = if cfg ! ( any( feature = "ioctl" , feature = "tdx-module" ) ) {
257+ TdxAttestError :: DeviceFailure
258+ } else {
259+ TdxAttestError :: NotSupported
260+ } ;
261+
262+ let mut extend_data = [ 0u8 ; TDX_RTMR_EXTEND_DATA_SIZE ] ;
263+ extend_data[ 0 ] = 123 ;
264+ let err = extend_rtmr ( 2 , extend_data) . expect_err ( "expecting err" ) ;
265+ assert_eq ! ( err, expected_err) ;
229266 }
230267
231268 #[ test]
232- fn test_tdx_att_extend ( ) {
269+ fn test_tdx_att_extend_invalid_index ( ) {
270+ let expected_err = if cfg ! ( any( feature = "ioctl" , feature = "tdx-module" ) ) {
271+ TdxAttestError :: InvalidRtmrIndex
272+ } else {
273+ TdxAttestError :: NotSupported
274+ } ;
275+
233276 let mut extend_data = [ 0u8 ; TDX_RTMR_EXTEND_DATA_SIZE ] ;
234277 extend_data[ 0 ] = 123 ;
235- let result = extend_rtmr ( 2 , extend_data) ;
236- assert ! ( matches!( result, Err ( TdxAttestError :: DeviceFailure ) ) ) ;
237- let result = extend_rtmr ( 77 , extend_data) ;
238- assert ! ( matches!( result, Err ( TdxAttestError :: InvalidRtmrIndex ) ) ) ;
278+
279+ let err = extend_rtmr ( 77 , extend_data) . expect_err ( "expecting err" ) ;
280+ assert_eq ! ( err, expected_err) ;
239281 }
240282}
0 commit comments