@@ -9,11 +9,49 @@ 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+ #[ cfg( feature = "tdx-module" ) ]
20+ use tdx_attest:: tdx_report_t;
21+
22+ #[ derive( Error , Debug , PartialEq , Eq ) ]
23+ pub enum TdxAttestError {
24+ /// Lower bound for error translations.
25+ #[ error( "Indicate min error to allow better translation, should be unexpected in production" ) ]
26+ Min ,
27+ #[ error( "The parameter is incorrect" ) ]
28+ InvalidParameter ,
29+ #[ error( "Not enough memory is available to complete this operation" ) ]
30+ OutOfMemory ,
31+ #[ error( "vsock related failure" ) ]
32+ VsockFailure ,
33+ #[ error( "Failed to get the TD Report" ) ]
34+ ReportFailure ,
35+ #[ error( "Failed to extend rtmr" ) ]
36+ ExtendFailure ,
37+ #[ error( "Request feature is not supported" ) ]
38+ NotSupported ,
39+ #[ error( "Failed to get the TD Quote" ) ]
40+ QuoteFailure ,
41+ #[ error( "The device driver return busy" ) ]
42+ Busy ,
43+ #[ error( "Failed to acess tdx attest device" ) ]
44+ DeviceFailure ,
45+ #[ error( "Only supported RTMR index is 2 and 3" ) ]
46+ InvalidRtmrIndex ,
47+ #[ error(
48+ "The platform Quoting infrastructure does not support any of the keys described in att_key_id_list"
49+ ) ]
50+ UnsupportedAttKeyId ,
51+ /// Upper bound for error translations.
52+ #[ error( "Indicate max error to allow better translation, should be unexpected in production" ) ]
53+ Max ,
54+ }
1755
1856/// SHA384
1957pub const TEE_HASH_384_SIZE : usize = 48 ;
@@ -34,8 +72,11 @@ pub const TEE_REPORT2_VERSION: usize = 0x0;
3472/// VERSION for Report Type2 which mr_servicetd is used
3573pub const TEE_REPORT2_VERSION_SERVICETD : usize = 0x1 ;
3674
37- // Ref: https://github.com/intel/confidential-computing.sgx/blob/main/common/inc/sgx_report2.h
3875struct_def ! {
76+ /// Rust definition of `REPORTTYPE` from `REPORTMACSTRUCT`.
77+ ///
78+ /// Ref: Intel TDX Module ABI Specification, section 4.7.4.
79+ /// Link to latest version (Sep 2025): https://cdrdv2.intel.com/v1/dl/getContent/733579
3980 #[ repr( C , align( 4 ) ) ]
4081 #[ derive( Clone , Debug , Default , Eq , PartialEq ) ]
4182 pub struct TeeReportType {
@@ -58,17 +99,19 @@ impl TeeReportType {
5899 pub const UNPADDED_SIZE : usize = 4 ;
59100}
60101
61-
62102pub const TDX_REPORT_MAC_STRUCT_SIZE : usize = 256 ;
63103pub const TDX_REPORT_MAC_STRUCT_RESERVED1_BYTES : usize = 12 ;
64104pub const TDX_REPORT_MAC_STRUCT_RESERVED2_BYTES : usize = 32 ;
65105
66- // Ref: https://github.com/intel/confidential-computing.sgx/blob/main/common/inc/sgx_report2.h
67106struct_def ! {
107+ /// Rust definition of `REPORTMACSTRUCT` from `TDREPORT_STRUCT`.
108+ ///
109+ /// Ref: Intel TDX Module ABI Specification, section 4.7.3.
110+ /// Link to latest version (Sep 2025): https://cdrdv2.intel.com/v1/dl/getContent/733579
68111 #[ repr( C , align( 256 ) ) ]
69112 #[ cfg_attr(
70113 feature = "large_array_derive" ,
71- derive( Clone , Debug , Default , Eq , PartialEq )
114+ derive( Clone , Debug , Eq , PartialEq )
72115 ) ]
73116 pub struct TdxReportMac {
74117 /// ( 0) TEE Report type
@@ -78,7 +121,7 @@ struct_def! {
78121 /// ( 16) Security Version of the CPU
79122 pub cpu_svn: [ u8 ; TEE_CPU_SVN_SIZE ] ,
80123 /// ( 32) SHA384 of TEE_TCB_INFO for TEEs
81- pub tee_tcb_info_hash: [ u8 ; TEE_HASH_384_SIZE ] ,
124+ pub tee_tcb_info_hash: [ u8 ; TEE_HASH_384_SIZE ] ,
82125 /// ( 80) SHA384 of TEE_INFO
83126 pub tee_info_hash: [ u8 ; TEE_HASH_384_SIZE ] ,
84127 /// (128) Data provided by the user
@@ -100,12 +143,16 @@ pub const TEE_TCB_INFO_SIZE: usize = 239;
100143pub const TDX_REPORT_RESERVED_SIZE : usize = 17 ;
101144pub const TEE_INFO_SIZE : usize = 512 ;
102145
103- // Ref: https://github.com/intel/confidential-computing.sgx/blob/main/common/inc/sgx_report2.h
104146struct_def ! {
147+ /// Rust definition of `TDREPORT_STRUCT` from the output of the `TDG.MR.REPORT` function.
148+ /// `TDG.MR.REPORT` is one variant of syscall `TDCALL`.
149+ ///
150+ /// Ref: Intel TDX Module ABI Specification, section 4.7.2.
151+ /// Link to latest version (Sep 2025): https://cdrdv2.intel.com/v1/dl/getContent/733579
105152 #[ repr( C , align( 1024 ) ) ]
106153 #[ cfg_attr(
107154 feature = "large_array_derive" ,
108- derive( Clone , Debug , Default , Eq , PartialEq )
155+ derive( Clone , Debug , Eq , PartialEq )
109156 ) ]
110157 pub struct TdxReport {
111158 /// ( 0) Report mac struct for SGX report type 2
@@ -119,12 +166,14 @@ struct_def! {
119166 }
120167}
121168
169+ #[ cfg( feature = "tdx-module" ) ]
122170impl From < tdx_report_t > for TdxReport {
123171 fn from ( report : tdx_report_t ) -> Self {
124172 Self :: try_copy_from ( & report. d ) . expect ( "validated size" )
125173 }
126174}
127175
176+ #[ cfg( feature = "tdx-module" ) ]
128177impl From < TdxReport > for tdx_report_t {
129178 fn from ( report : TdxReport ) -> Self {
130179 let mut d = [ 0u8 ; TDX_REPORT_SIZE ] ;
@@ -148,35 +197,28 @@ impl TdxReport {
148197 /// # Errors
149198 /// Propagates the underlying TDX attestation error code.
150199 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 ( ) )
200+ #[ cfg( feature = "ioctl" ) ]
201+ {
202+ return tdx_ioctl:: get_report ( report_data) ;
203+ }
204+ #[ cfg( all( not( feature = "ioctl" ) , feature = "tdx-module" ) ) ]
205+ {
206+ return tdx_attest:: get_report ( report_data) ;
207+ }
208+ #[ cfg( not( any( feature = "ioctl" , feature = "tdx-module" ) ) ) ]
209+ {
210+ Err ( TdxAttestError :: NotSupported )
211+ }
160212 }
161213}
162214
163215pub const TDX_RTMR_EVENT_HEADER_SIZE : usize = 68 ;
164216/// Size of the RTMR extend data field in bytes.
165217pub const TDX_RTMR_EXTEND_DATA_SIZE : usize = 48 ;
166218
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-
177219/// Extend one of the TDX runtime measurement registers (RTMRs).
178220///
179- /// RTMR[rtmr_index] = SHA384(RTMR[rtmr_index] || extend_data)
221+ /// ` RTMR[rtmr_index] = SHA384(RTMR[rtmr_index] || extend_data)`
180222/// - `rtmr_index`: only supported RTMR index is 2 and 3.
181223/// - `event_data`: field is currently expected to be empty by the platform
182224/// quoting infrastructure.
@@ -193,48 +235,66 @@ pub const REMR_EXTEND_DATA_SIZE: usize = 48;
193235/// not supported.
194236pub fn extend_rtmr (
195237 rtmr_index : u64 ,
196- extend_data : [ u8 ; REMR_EXTEND_DATA_SIZE ] ,
238+ extend_data : [ u8 ; TDX_RTMR_EXTEND_DATA_SIZE ] ,
197239) -> 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) )
240+ #[ cfg( feature = "ioctl" ) ]
241+ {
242+ return tdx_ioctl:: extend_rtmr ( rtmr_index, extend_data) ;
243+ }
244+ #[ cfg( all( not( feature = "ioctl" ) , feature = "tdx-module" ) ) ]
245+ {
246+ return tdx_attest:: extend_rtmr ( rtmr_index, extend_data) ;
247+ }
248+ #[ cfg( not( any( feature = "ioctl" , feature = "tdx-module" ) ) ) ]
249+ {
250+ Err ( TdxAttestError :: NotSupported )
251+ }
219252}
220253
221254#[ cfg( test) ]
222255mod tests {
223256 use super :: * ;
224257
225258 #[ test]
226- fn test_tdx_att_get_report ( ) {
259+ fn test_tdx_att_get_report_invalid_device ( ) {
260+ let expected_err = if cfg ! ( any( feature = "ioctl" , feature = "tdx-module" ) ) {
261+ TdxAttestError :: DeviceFailure
262+ } else {
263+ TdxAttestError :: NotSupported
264+ } ;
227265 let result = TdxReport :: get_report ( [ 0 ; TDX_REPORT_DATA_SIZE ] ) ;
228- assert ! ( matches!( result, Err ( TdxAttestError :: DeviceFailure ) ) ) ;
266+ match result {
267+ Ok ( _) => panic ! ( "expecting error" ) ,
268+ Err ( err) => assert_eq ! ( err, expected_err) ,
269+ }
270+ }
271+
272+ #[ test]
273+ fn test_tdx_att_extend_invalid_device ( ) {
274+ let expected_err = if cfg ! ( any( feature = "ioctl" , feature = "tdx-module" ) ) {
275+ TdxAttestError :: DeviceFailure
276+ } else {
277+ TdxAttestError :: NotSupported
278+ } ;
279+
280+ let mut extend_data = [ 0u8 ; TDX_RTMR_EXTEND_DATA_SIZE ] ;
281+ extend_data[ 0 ] = 123 ;
282+ let err = extend_rtmr ( 2 , extend_data) . expect_err ( "expecting err" ) ;
283+ assert_eq ! ( err, expected_err) ;
229284 }
230285
231286 #[ test]
232- fn test_tdx_att_extend ( ) {
287+ fn test_tdx_att_extend_invalid_index ( ) {
288+ let expected_err = if cfg ! ( any( feature = "ioctl" , feature = "tdx-module" ) ) {
289+ TdxAttestError :: InvalidRtmrIndex
290+ } else {
291+ TdxAttestError :: NotSupported
292+ } ;
293+
233294 let mut extend_data = [ 0u8 ; TDX_RTMR_EXTEND_DATA_SIZE ] ;
234295 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 ) ) ) ;
296+
297+ let err = extend_rtmr ( 77 , extend_data) . expect_err ( "expecting err" ) ;
298+ assert_eq ! ( err, expected_err) ;
239299 }
240300}
0 commit comments