diff --git a/rust/edlcodegen/Cargo.toml b/rust/edlcodegen/Cargo.toml index 3b89d9c7..36639f1a 100644 --- a/rust/edlcodegen/Cargo.toml +++ b/rust/edlcodegen/Cargo.toml @@ -20,6 +20,7 @@ edlcodegen-enclave = { version = "0.1.0", path = "crates/libs/edlcodegen-enclave edlcodegen-macros = { version = "0.1.0", path = "crates/libs/edlcodegen-macros" } edlcodegen-tools = { version = "0.1.0", path = "crates/libs/edlcodegen-tools" } spin = "0.10.0" +widestring = { version = "1.2.1", default-features = false, features = ["alloc"] } windows = "0.62.2" windows-link = "0.2.1" windows-result = {version = "0.4.1", default-features = false } diff --git a/rust/edlcodegen/crates/libs/edlcodegen-core/Cargo.toml b/rust/edlcodegen/crates/libs/edlcodegen-core/Cargo.toml index 5bd89342..609b4ed8 100644 --- a/rust/edlcodegen/crates/libs/edlcodegen-core/Cargo.toml +++ b/rust/edlcodegen/crates/libs/edlcodegen-core/Cargo.toml @@ -12,3 +12,4 @@ edlcodegen-tools = { workspace = true } [dependencies] edlcodegen-macros = { workspace = true } flatbuffers = { workspace = true } +widestring = { workspace = true } diff --git a/rust/edlcodegen/crates/libs/edlcodegen-core/src/helpers.rs b/rust/edlcodegen/crates/libs/edlcodegen-core/src/helpers.rs index 2dd551ca..81710ca4 100644 --- a/rust/edlcodegen/crates/libs/edlcodegen-core/src/helpers.rs +++ b/rust/edlcodegen/crates/libs/edlcodegen-core/src/helpers.rs @@ -82,3 +82,9 @@ macro_rules! return_hr_as_pvoid { return $crate::edl_core_types::S_OK as *mut core::ffi::c_void; }}; } + +pub fn assign_if_some(dst: Option<&mut T>, src: Option) { + if let (Some(dst_obj), Some(src_obj)) = (dst, src) { + *dst_obj = src_obj; + } +} diff --git a/rust/edlcodegen/crates/libs/edlcodegen-enclave/src/lib.rs b/rust/edlcodegen/crates/libs/edlcodegen-enclave/src/lib.rs index cd048d9e..2f0fb585 100644 --- a/rust/edlcodegen/crates/libs/edlcodegen-enclave/src/lib.rs +++ b/rust/edlcodegen/crates/libs/edlcodegen-enclave/src/lib.rs @@ -17,5 +17,6 @@ pub mod win_enclave_bindings; pub use edlcodegen_core::EdlDerive; pub use edlcodegen_core::edl_core_types::AbiError; pub use edlcodegen_core::flatbuffer_support::FlatbufferPack; +pub use edlcodegen_core::helpers::assign_if_some; pub use edlcodegen_core::impl_flatbuffer_pack; pub use edlcodegen_core::return_hr_as_pvoid; diff --git a/rust/edlcodegen/crates/libs/edlcodegen-host/src/lib.rs b/rust/edlcodegen/crates/libs/edlcodegen-host/src/lib.rs index 91d67e9e..d61f211c 100644 --- a/rust/edlcodegen/crates/libs/edlcodegen-host/src/lib.rs +++ b/rust/edlcodegen/crates/libs/edlcodegen-host/src/lib.rs @@ -12,7 +12,7 @@ pub use edlcodegen_core::edl_core_types::AbiError; pub use edlcodegen_core::edl_core_types::EnclaveHandle; pub use edlcodegen_core::flatbuffer_support::FlatbufferPack; pub use edlcodegen_core::helpers::{ - abi_func_to_address, allocate_memory_ffi, deallocate_memory_ffi, + abi_func_to_address, allocate_memory_ffi, assign_if_some, deallocate_memory_ffi, }; pub use edlcodegen_core::impl_flatbuffer_pack; pub use edlcodegen_core::return_hr_as_pvoid; diff --git a/rust/edlcodegen/crates/samples/helloworld/enclave/src/edl_impls.rs b/rust/edlcodegen/crates/samples/helloworld/enclave/src/edl_impls.rs index d22a0a6a..85ed6a91 100644 --- a/rust/edlcodegen/crates/samples/helloworld/enclave/src/edl_impls.rs +++ b/rust/edlcodegen/crates/samples/helloworld/enclave/src/edl_impls.rs @@ -5,7 +5,6 @@ use test_enclave_gen::implementation::trusted::Trusted; use test_enclave_gen::AbiError; use test_enclave_gen::stubs::untrusted::print; -use alloc::string::ToString; use tracelogging as tlg; use crate::{HELLO_WORLD_PROVIDER}; @@ -20,7 +19,7 @@ impl Trusted for EnclaveImpl { ); // Print message to console from within the enclave. - print(&"Performing secret math operation inside VTL1...".to_string())?; + print("Performing secret math operation inside VTL1...")?; Ok(val1 + val2) } } \ No newline at end of file diff --git a/rust/edlcodegen/crates/samples/helloworld/host/src/edl_impls.rs b/rust/edlcodegen/crates/samples/helloworld/host/src/edl_impls.rs index 18f09ba2..4f3fb080 100644 --- a/rust/edlcodegen/crates/samples/helloworld/host/src/edl_impls.rs +++ b/rust/edlcodegen/crates/samples/helloworld/host/src/edl_impls.rs @@ -8,7 +8,7 @@ use test_host_gen::AbiError; pub struct HostImpl{} impl Untrusted for HostImpl { - fn print(data: &String) -> Result<(), AbiError> { + fn print(data: &str) -> Result<(), AbiError> { println!("{}", data); Ok(()) } diff --git a/rust/sdk/crates/libs/sdk-enclave/src/common/sdk_impls.rs b/rust/sdk/crates/libs/sdk-enclave/src/common/sdk_impls.rs index 3abe0ef3..0e345885 100644 --- a/rust/sdk/crates/libs/sdk-enclave/src/common/sdk_impls.rs +++ b/rust/sdk/crates/libs/sdk-enclave/src/common/sdk_impls.rs @@ -10,7 +10,6 @@ use crate::etw; use crate::userboundkey; -use alloc::vec::Vec; use sdk_enclave_gen::AbiError; use sdk_enclave_gen::implementation::trusted::Trusted; use sdk_enclave_gen::implementation::types::attestationReportAndSessionInfo; @@ -25,7 +24,7 @@ pub struct EnclaveImpl; #[allow(non_snake_case)] impl Trusted for EnclaveImpl { fn userboundkey_get_attestation_report( - challenge: &Vec, + challenge: &[u8], ) -> Result { userboundkey::userboundkey_get_attestation_report(challenge) } diff --git a/rust/sdk/crates/libs/sdk-enclave/src/etw.rs b/rust/sdk/crates/libs/sdk-enclave/src/etw.rs index 0897f634..19e32719 100644 --- a/rust/sdk/crates/libs/sdk-enclave/src/etw.rs +++ b/rust/sdk/crates/libs/sdk-enclave/src/etw.rs @@ -215,8 +215,7 @@ unsafe extern "system" fn EtwSetInformation( let info_slice = unsafe { core::slice::from_raw_parts(information, information_length as usize) }; - let result = - untrusted::event_set_information(reg_handle, information_class, &info_slice.to_vec()); + let result = untrusted::event_set_information(reg_handle, information_class, info_slice); result_from_abi(result) } @@ -284,8 +283,8 @@ unsafe extern "system" fn EtwWriteTransfer( let result = untrusted::event_write_transfer( reg_handle, &abi_descriptor, - &activity_guid, - &related_guid, + activity_guid.as_ref(), + related_guid.as_ref(), &abi_data.to_vec(), ); diff --git a/rust/sdk/crates/libs/sdk-enclave/src/userboundkey/mod.rs b/rust/sdk/crates/libs/sdk-enclave/src/userboundkey/mod.rs index 7410d020..92862d83 100644 --- a/rust/sdk/crates/libs/sdk-enclave/src/userboundkey/mod.rs +++ b/rust/sdk/crates/libs/sdk-enclave/src/userboundkey/mod.rs @@ -277,32 +277,22 @@ pub fn create_user_bound_key_with_custom_key( custom_key_bytes: &[u8], ) -> Result, UserBoundKeyError> { // Format the key name (calls VTL0) - this is the FIRST VTL0 call - // Create WString from key_name slice - let key_name_wstring = sdk_enclave_gen::implementation::types::edl::WString { - wchars: key_name.as_slice().to_vec(), - }; - let formatted_key_name_wstring = untrusted::userboundkey_format_key_name(&key_name_wstring) - .map_err(UserBoundKeyError::AbiError)?; + let formatted_key_name_wstring = + untrusted::userboundkey_format_key_name(key_name).map_err(UserBoundKeyError::AbiError)?; // Security validation (wide string version) - let formatted_key_name_u16str = U16Str::from_slice(&formatted_key_name_wstring.wchars); - validate_formatted_key_name_wide(formatted_key_name_u16str, key_name)?; + validate_formatted_key_name_wide(&formatted_key_name_wstring, key_name)?; // Get enclave base address let enclave_ptr = get_enclave_base_address_u64()?; - // Create WString for message - let message_wstring = sdk_enclave_gen::implementation::types::edl::WString { - wchars: message.as_slice().to_vec(), - }; - // Establish session (calls VTL0 which triggers Windows Hello) // Requires at least 2 enclave threads - one for this call and one for the callback let credential_and_session = untrusted::userboundkey_establish_session_for_create( enclave_ptr, - &key_name_wstring, + key_name, BCRYPT_ECDH_P384_ALG_HANDLE_U64, - &message_wstring, + message, window_id, cache_config, key_credential_creation_option, @@ -320,13 +310,10 @@ pub fn create_user_bound_key_with_custom_key( let mut encrypted_request_size: u32 = 0; let mut local_nonce: u64 = 0; - // Create null-terminated wide string for Windows API - let formatted_key_name_with_null = U16String::from(formatted_key_name_u16str); - unsafe { let hr = CreateUserBoundKeyRequestForRetrieveAuthorizationContext( session_handle.get(), - formatted_key_name_with_null.as_ptr(), + formatted_key_name_wstring.as_ptr(), &mut local_nonce, &mut encrypted_request_ptr, &mut encrypted_request_size, @@ -350,7 +337,7 @@ pub fn create_user_bound_key_with_custom_key( let auth_context_blob = untrusted::userboundkey_get_authorization_context_from_credential( credential.get(), &encrypted_request, - &message_wstring, + message, window_id, ) .map_err(UserBoundKeyError::AbiError)?; @@ -378,7 +365,7 @@ pub fn create_user_bound_key_with_custom_key( unsafe { let hr = ValidateUserBoundKeyAuthContext( - formatted_key_name_with_null.as_ptr(), + formatted_key_name_wstring.as_ptr(), auth_context.get(), 1, &prop, @@ -451,29 +438,20 @@ pub fn load_user_bound_key( let ephemeral_public_key = get_ephemeral_public_key_bytes_from_bound_key(&bound_key_bytes)?; // Format the key name (calls VTL0) - let key_name_wstring = sdk_enclave_gen::implementation::types::edl::WString { - wchars: key_name.as_slice().to_vec(), - }; - let formatted_key_name_wstring = untrusted::userboundkey_format_key_name(&key_name_wstring) - .map_err(UserBoundKeyError::AbiError)?; + let formatted_key_name_wstring = + untrusted::userboundkey_format_key_name(key_name).map_err(UserBoundKeyError::AbiError)?; // Security validation (wide string version) - let formatted_key_name_u16str = U16Str::from_slice(&formatted_key_name_wstring.wchars); - validate_formatted_key_name_wide(formatted_key_name_u16str, key_name)?; + validate_formatted_key_name_wide(&formatted_key_name_wstring, key_name)?; // Get enclave base address let enclave_ptr = get_enclave_base_address_u64()?; - // Create WString for message - let message_wstring = sdk_enclave_gen::implementation::types::edl::WString { - wchars: message.as_slice().to_vec(), - }; - // Establish session for load (calls VTL0) let credential_and_session = untrusted::userboundkey_establish_session_for_load( enclave_ptr, - &key_name_wstring, - &message_wstring, + key_name, + message, window_id, ) .map_err(UserBoundKeyError::AbiError)?; @@ -489,13 +467,10 @@ pub fn load_user_bound_key( let mut encrypted_rac_size: u32 = 0; let mut local_nonce: u64 = 0; - // Create null-terminated wide string for Windows API - let formatted_key_name_with_null = U16String::from(formatted_key_name_u16str); - unsafe { let hr = CreateUserBoundKeyRequestForRetrieveAuthorizationContext( session_handle.get(), - formatted_key_name_with_null.as_ptr(), + formatted_key_name_wstring.as_ptr(), &mut local_nonce, &mut encrypted_rac_ptr, &mut encrypted_rac_size, @@ -518,7 +493,7 @@ pub fn load_user_bound_key( let auth_context_blob = untrusted::userboundkey_get_authorization_context_from_credential( credential.get(), &encrypted_rac_request, - &message_wstring, + message, window_id, ) .map_err(UserBoundKeyError::AbiError)?; @@ -546,7 +521,7 @@ pub fn load_user_bound_key( unsafe { let hr = ValidateUserBoundKeyAuthContext( - formatted_key_name_with_null.as_ptr(), + formatted_key_name_wstring.as_ptr(), auth_context.get(), 1, &prop, @@ -561,7 +536,7 @@ pub fn load_user_bound_key( unsafe { let hr = CreateUserBoundKeyRequestForDeriveSharedSecret( session_handle.get(), - formatted_key_name_with_null.as_ptr(), + formatted_key_name_wstring.as_ptr(), ephemeral_public_key.as_ptr() as *const core::ffi::c_void, ephemeral_public_key.len() as u32, &mut local_nonce, @@ -586,7 +561,7 @@ pub fn load_user_bound_key( let secret = untrusted::userboundkey_get_secret_from_credential( credential.get(), &encrypted_dss_request, - &message_wstring, + message, window_id, ) .map_err(UserBoundKeyError::AbiError)?; @@ -659,7 +634,7 @@ pub fn reseal_user_bound_key( #[allow(non_snake_case)] #[allow(clippy::ptr_arg)] // Signature must match EDL-generated trait pub fn userboundkey_get_attestation_report( - challenge: &Vec, + challenge: &[u8], ) -> Result { let mut report_ptr: *mut core::ffi::c_void = core::ptr::null_mut(); let mut report_size: u32 = 0; diff --git a/rust/sdk/crates/libs/sdk-host/src/common/mod.rs b/rust/sdk/crates/libs/sdk-host/src/common/mod.rs index f92e0ee4..b86a2b1e 100644 --- a/rust/sdk/crates/libs/sdk-host/src/common/mod.rs +++ b/rust/sdk/crates/libs/sdk-host/src/common/mod.rs @@ -8,6 +8,6 @@ pub mod sdk_impls; pub use sdk_impls::HostImpl; /// Print a message from the enclave to the host's standard output. -pub fn enclave_println(msg: &String) { +pub fn enclave_println(msg: &str) { println!("[Enclave] {}", msg); } diff --git a/rust/sdk/crates/libs/sdk-host/src/common/sdk_impls.rs b/rust/sdk/crates/libs/sdk-host/src/common/sdk_impls.rs index 355650fe..70595b12 100644 --- a/rust/sdk/crates/libs/sdk-host/src/common/sdk_impls.rs +++ b/rust/sdk/crates/libs/sdk-host/src/common/sdk_impls.rs @@ -8,15 +8,14 @@ //! This pattern allows feature implementations to live in their own modules //! while the trait impl acts as a thin wrapper. +use crate::etw; +use crate::userboundkey; use sdk_host_gen::AbiError; use sdk_host_gen::implementation::types::{ - EventDataDescriptor, EventDescriptor, Guid, credentialAndSessionInfo, edl::WString, - keyCredentialCacheConfig, + EventDataDescriptor, EventDescriptor, Guid, credentialAndSessionInfo, keyCredentialCacheConfig, }; use sdk_host_gen::implementation::untrusted::Untrusted; - -use crate::etw; -use crate::userboundkey; +use widestring::{U16Str, U16String}; /// SDK host implementation of the Untrusted trait. /// @@ -28,9 +27,9 @@ pub struct HostImpl; impl Untrusted for HostImpl { fn userboundkey_establish_session_for_create( enclave: u64, - keyName: &WString, + keyName: &U16Str, ecdhProtocol: u64, - message: &WString, + message: &U16Str, windowId: u64, cacheConfig: &keyCredentialCacheConfig, keyCredentialCreationOption: u32, @@ -48,8 +47,8 @@ impl Untrusted for HostImpl { fn userboundkey_establish_session_for_load( enclave: u64, - keyName: &WString, - message: &WString, + keyName: &U16Str, + message: &U16Str, windowId: u64, ) -> Result { userboundkey::userboundkey_establish_session_for_load(enclave, keyName, message, windowId) @@ -57,8 +56,8 @@ impl Untrusted for HostImpl { fn userboundkey_get_authorization_context_from_credential( credential: u64, - encryptedRequest: &Vec, - message: &WString, + encryptedRequest: &[u8], + message: &U16Str, windowId: u64, ) -> Result, AbiError> { userboundkey::userboundkey_get_authorization_context_from_credential( @@ -71,8 +70,8 @@ impl Untrusted for HostImpl { fn userboundkey_get_secret_from_credential( credential: u64, - encryptedRequest: &Vec, - message: &WString, + encryptedRequest: &[u8], + message: &U16Str, windowId: u64, ) -> Result, AbiError> { userboundkey::userboundkey_get_secret_from_credential( @@ -83,7 +82,7 @@ impl Untrusted for HostImpl { ) } - fn userboundkey_format_key_name(keyName: &WString) -> Result { + fn userboundkey_format_key_name(keyName: &U16Str) -> Result { userboundkey::userboundkey_format_key_name(keyName) } @@ -107,9 +106,9 @@ impl Untrusted for HostImpl { fn event_write_transfer( reg_handle: u64, descriptor: &EventDescriptor, - activity_id: &Option, - related_id: &Option, - user_data: &Vec, + activity_id: Option<&Guid>, + related_id: Option<&Guid>, + user_data: &[EventDataDescriptor], ) -> Result { etw::event_write_transfer(reg_handle, descriptor, activity_id, related_id, user_data) } @@ -117,7 +116,7 @@ impl Untrusted for HostImpl { fn event_set_information( reg_handle: u64, information_class: u32, - information: &Vec, + information: &[u8], ) -> Result { etw::event_set_information(reg_handle, information_class, information) } @@ -129,7 +128,7 @@ impl Untrusted for HostImpl { etw::event_activity_id_control(control_code, activity_id) } - fn println(msg: &String) -> Result<(), AbiError> { + fn println(msg: &str) -> Result<(), AbiError> { super::enclave_println(msg); Ok(()) } diff --git a/rust/sdk/crates/libs/sdk-host/src/etw.rs b/rust/sdk/crates/libs/sdk-host/src/etw.rs index 594cd9a9..4e21161d 100644 --- a/rust/sdk/crates/libs/sdk-host/src/etw.rs +++ b/rust/sdk/crates/libs/sdk-host/src/etw.rs @@ -40,9 +40,8 @@ fn abi_guid_to_winguid(guid: &codegen_types::Guid) -> windows::core::GUID { windows::core::GUID::from_values(guid.data1, guid.data2, guid.data3, guid.data4) } -fn opt_abi_guid_to_opt_winguid(guid: &Option) -> Option { - guid.as_ref() - .map(|g| windows::core::GUID::from_values(g.data1, g.data2, g.data3, g.data4)) +fn opt_abi_guid_to_opt_winguid(guid: Option<&codegen_types::Guid>) -> Option { + guid.map(|g| windows::core::GUID::from_values(g.data1, g.data2, g.data3, g.data4)) } // This is the callback function that will be called by the ETW framework when @@ -157,8 +156,8 @@ pub fn event_register( pub fn event_write_transfer( reg_handle: u64, descriptor: &codegen_types::EventDescriptor, - activity_id: &Option, - related_id: &Option, + activity_id: Option<&codegen_types::Guid>, + related_id: Option<&codegen_types::Guid>, user_data: &[codegen_types::EventDataDescriptor], ) -> Result { let etw_descriptor = Etw::EVENT_DESCRIPTOR { diff --git a/rust/sdk/crates/libs/sdk-host/src/userboundkey/mod.rs b/rust/sdk/crates/libs/sdk-host/src/userboundkey/mod.rs index a7a5d565..1d11ca81 100644 --- a/rust/sdk/crates/libs/sdk-host/src/userboundkey/mod.rs +++ b/rust/sdk/crates/libs/sdk-host/src/userboundkey/mod.rs @@ -9,8 +9,7 @@ use sdk_host_gen::AbiError; pub use sdk_host_gen::SdkHost; pub use sdk_host_gen::implementation::types::{ - attestationReportAndSessionInfo, credentialAndSessionInfo, edl::WString, - keyCredentialCacheConfig, + attestationReportAndSessionInfo, credentialAndSessionInfo, keyCredentialCacheConfig, }; use std::sync::{Arc, Mutex}; @@ -34,7 +33,7 @@ use userboundkey_kcm::{ KeyCredentialCacheOption, KeyCredentialCreationOption, KeyCredentialManager, KeyCredentialStatus, TimeSpan, WindowId, }; - +use widestring::{U16Str, U16String}; /// RAII wrapper for session handle that calls back to VTL1 on cleanup struct UniqueSessionHandle { handle: usize, @@ -219,8 +218,8 @@ fn sid_to_wide_string(sid: PSID) -> Result, AbiError> { } /// Helper to convert WString to HSTRING -fn wstring_to_hstring(ws: &WString) -> HSTRING { - HSTRING::from_wide(&ws.wchars) +fn wstring_to_hstring(ws: &U16Str) -> HSTRING { + HSTRING::from_wide(ws.as_slice()) } /// Establish a session for creating a new Windows Hello key. @@ -228,9 +227,9 @@ fn wstring_to_hstring(ws: &WString) -> HSTRING { #[allow(unused_variables)] pub fn userboundkey_establish_session_for_create( enclave: u64, - keyName: &WString, + keyName: &U16Str, ecdhProtocol: u64, - message: &WString, + message: &U16Str, windowId: u64, cacheConfig: &keyCredentialCacheConfig, keyCredentialCreationOption: u32, @@ -333,8 +332,8 @@ pub fn userboundkey_establish_session_for_create( #[allow(unused_variables)] pub fn userboundkey_establish_session_for_load( enclave: u64, - keyName: &WString, - message: &WString, + keyName: &U16Str, + message: &U16Str, windowId: u64, ) -> Result { let _ = (message, windowId); // Mark as intentionally unused @@ -394,8 +393,8 @@ pub fn userboundkey_establish_session_for_load( #[allow(clippy::ptr_arg)] // Signature must match EDL-generated trait pub fn userboundkey_get_authorization_context_from_credential( credential: u64, - encryptedRequest: &Vec, - message: &WString, + encryptedRequest: &[u8], + message: &U16Str, windowId: u64, ) -> Result, AbiError> { // Reconstruct KeyCredential from raw pointer @@ -431,8 +430,8 @@ pub fn userboundkey_get_authorization_context_from_credential( #[allow(clippy::ptr_arg)] // Signature must match EDL-generated trait pub fn userboundkey_get_secret_from_credential( credential: u64, - encryptedRequest: &Vec, - message: &WString, + encryptedRequest: &[u8], + message: &U16Str, windowId: u64, ) -> Result, AbiError> { // Reconstruct KeyCredential from raw pointer @@ -473,7 +472,7 @@ pub fn userboundkey_get_secret_from_credential( /// Format a key name with the current user's SID. #[allow(non_snake_case)] -pub fn userboundkey_format_key_name(keyName: &WString) -> Result { +pub fn userboundkey_format_key_name(keyName: &U16Str) -> Result { unsafe { let mut process_token = HANDLE::default(); OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut process_token) @@ -505,14 +504,14 @@ pub fn userboundkey_format_key_name(keyName: &WString) -> Result Result, AbiError> { @@ -158,9 +157,9 @@ impl Trusted for EnclaveImpl { // Create user-bound key with enclave sealing let sealed_key = create_user_bound_key( - U16Str::from_slice(&helloKeyName.wchars), + helloKeyName, &cache_config, - U16Str::from_slice(&pinMessage.wchars), + pinMessage, windowId, EnclaveSealingIdentityPolicy::EnclaveIdentity, RUNTIME_POLICY_NO_DEBUG, @@ -183,19 +182,19 @@ impl Trusted for EnclaveImpl { /// Load user-bound key and encrypt data. fn LoadUserBoundKeyAndEncryptData( - helloKeyName: &WString, - pinMessage: &WString, + helloKeyName: &U16Str, + pinMessage: &U16Str, windowId: u64, - securedEncryptionKeyBytes: &Vec, - inputData: &WString, + securedEncryptionKeyBytes: &[u8], + inputData: &U16Str, ) -> Result { let mut needs_reseal = false; let mut resealed_bytes = Vec::new(); // Ensure key is loaded (handles reseal if needed) ensure_user_bound_key_loaded( - U16Str::from_slice(&helloKeyName.wchars), - U16Str::from_slice(&pinMessage.wchars), + &helloKeyName, + &pinMessage, windowId, securedEncryptionKeyBytes, &mut needs_reseal, @@ -207,7 +206,7 @@ impl Trusted for EnclaveImpl { // Convert input to bytes (UTF-16 LE data) let input_bytes: Vec = inputData - .wchars + .as_slice() .iter() .flat_map(|c| c.to_le_bytes()) .collect(); @@ -233,11 +232,11 @@ impl Trusted for EnclaveImpl { /// Load user-bound key and decrypt data. fn LoadUserBoundKeyAndDecryptData( - helloKeyName: &WString, - pinMessage: &WString, + helloKeyName: &U16Str, + pinMessage: &U16Str, windowId: u64, - securedEncryptionKeyBytes: &Vec, - combinedInputData: &Vec, + securedEncryptionKeyBytes: &[u8], + combinedInputData: &[u8], ) -> Result { let mut needs_reseal = false; let mut resealed_bytes = Vec::new(); @@ -266,8 +265,8 @@ impl Trusted for EnclaveImpl { // Ensure key is loaded ensure_user_bound_key_loaded( - U16Str::from_slice(&helloKeyName.wchars), - U16Str::from_slice(&pinMessage.wchars), + &helloKeyName, + &pinMessage, windowId, securedEncryptionKeyBytes, &mut needs_reseal, @@ -294,11 +293,8 @@ impl Trusted for EnclaveImpl { .map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]])) .collect(); - // Create WString from UTF-16 data - let decrypted_string = WString { wchars: utf16 }; - Ok(DecryptResult { - decryptedData: decrypted_string, + decryptedData: U16String::from_vec(utf16), needsReseal: needs_reseal, resealedEncryptionKeyBytes: resealed_bytes, }) diff --git a/rust/sdk/crates/samples/userboundkey/host/src/edl_impls.rs b/rust/sdk/crates/samples/userboundkey/host/src/edl_impls.rs index 60f6630d..903cc5e1 100644 --- a/rust/sdk/crates/samples/userboundkey/host/src/edl_impls.rs +++ b/rust/sdk/crates/samples/userboundkey/host/src/edl_impls.rs @@ -11,7 +11,7 @@ pub struct UntrustedImpl; impl Untrusted for UntrustedImpl { /// Debug print function - prints to console from enclave - fn debug_print(message: &String) -> Result<(), AbiError> { + fn debug_print(message: &str) -> Result<(), AbiError> { println!("[Enclave] {}", message); Ok(()) } diff --git a/rust/sdk/crates/samples/userboundkey/host/src/main.rs b/rust/sdk/crates/samples/userboundkey/host/src/main.rs index 2e54e3bb..d1c4a99c 100644 --- a/rust/sdk/crates/samples/userboundkey/host/src/main.rs +++ b/rust/sdk/crates/samples/userboundkey/host/src/main.rs @@ -24,7 +24,7 @@ use windows::Win32::UI::WindowsAndMessaging::GetForegroundWindow; use windows::core::Interface; // Generated host stubs for enclave calls -use userboundkey_sample_host_gen::implementation::types::edl::WString; +use userboundkey_sample_host_gen::U16String; use userboundkey_sample_host_gen::stubs::trusted::UntrustedImpl; const KEY_NAME: &str = "MyEncryptionKey-001"; @@ -66,12 +66,6 @@ fn print_menu(is_key_loaded: bool) { io::stdout().flush().unwrap(); } -/// Create a WString from a Rust string (without null terminator - SDK adds it when needed) -fn to_wstring(s: &str) -> WString { - let wchars: Vec = s.encode_utf16().collect(); - WString { wchars } -} - /// Get secure ID from Windows Hello. /// /// Returns the secure ID buffer that identifies this Windows Hello user. @@ -196,8 +190,8 @@ fn main() -> Result<(), Box> { println!("Window ID: 0x{:X}", window_id); println!("Calling enclave... (Windows Hello prompt should appear)"); - let key_name = to_wstring(KEY_NAME); - let pin_message = to_wstring(PIN_MESSAGE); + let key_name = U16String::from_str(KEY_NAME); + let pin_message = U16String::from_str(PIN_MESSAGE); // KeyCredentialCreationOption::ReplaceExisting = 1 const REPLACE_EXISTING: u32 = 1; @@ -266,9 +260,9 @@ fn main() -> Result<(), Box> { continue; } - let key_name = to_wstring(KEY_NAME); - let pin_message = to_wstring(PIN_MESSAGE); - let input_data = to_wstring(text.trim()); + let key_name = U16String::from_str(KEY_NAME); + let pin_message = U16String::from_str(PIN_MESSAGE); + let input_data = U16String::from_str(text.trim()); match enclave.LoadUserBoundKeyAndEncryptData( &key_name, @@ -322,8 +316,8 @@ fn main() -> Result<(), Box> { } }; - let key_name = to_wstring(KEY_NAME); - let pin_message = to_wstring(PIN_MESSAGE); + let key_name = U16String::from_str(KEY_NAME); + let pin_message = U16String::from_str(PIN_MESSAGE); match enclave.LoadUserBoundKeyAndDecryptData( &key_name, @@ -343,13 +337,7 @@ fn main() -> Result<(), Box> { } // Convert WString to Rust String - let decrypted_text: String = result - .decryptedData - .wchars - .iter() - .take_while(|&&c| c != 0) - .map(|&c| char::from_u32(c as u32).unwrap_or('?')) - .collect(); + let decrypted_text = result.decryptedData.to_string_lossy(); println!("Decrypted data: {}", decrypted_text); } diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/Cargo.toml b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/Cargo.toml index b2b23503..fd474b09 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/Cargo.toml +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/Cargo.toml @@ -15,3 +15,4 @@ edlcodegen-tools = { git = "https://github.com/microsoft/VbsEnclaveTooling" } [dependencies] edlcodegen-enclave = { git = "https://github.com/microsoft/VbsEnclaveTooling" } flatbuffers = { version = "25.9.23", default-features = false } +widestring = { version = "1.2.1", default-features = false, features = ["alloc"] } diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/abi/abi_types.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/abi/abi_types.rs index c7340bcc..6534976a 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/abi/abi_types.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/abi/abi_types.rs @@ -11,6 +11,7 @@ use crate::implementation::types::*; use crate::abi::fb_support::fb_types::code_gen_test::flatbuffer_types; use crate::abi::fb_support::fb_types::edl::WStringT; use edlcodegen_enclave::EdlDerive; +use widestring::{U16String, U16Str}; #[repr(C)] @@ -29,7 +30,7 @@ pub struct FuncWithAllArgs_0_Args { pub m_arg6: Option, pub m_arg7: Vec, pub m_arg8: Vec, - pub m_arg9: [edl::WString;2], + pub m_arg9: [U16String;2], pub m__return_value_: i32, } @@ -49,7 +50,7 @@ pub struct FuncWithAllArgs_1_Args { pub m_arg6: Option, pub m_arg7: Vec, pub m_arg8: Vec, - pub m_arg9: [edl::WString;2], + pub m_arg9: [U16String;2], pub m__return_value_: i32, } @@ -62,12 +63,26 @@ pub struct AbiRegisterVtl0Callbacks_args pub m__return_value_: i32, } -pub mod edl { - use alloc::vec::Vec; - #[derive(Debug, Clone, PartialEq, Default, super::EdlDerive)] - #[target_struct(super::WStringT)] - pub struct WString { - pub wchars: Vec, +impl core::convert::From for WStringT { + fn from(src: U16String) -> Self { + Self { wchars: src.clone().into_vec() } } } +impl core::convert::From for U16String { + fn from(src: WStringT) -> Self { + U16String::from_vec(src.wchars) + } +} + +impl core::convert::From for Box { + fn from(src: U16String) -> Self { + Box::new(WStringT{ wchars: src.clone().into_vec() }) + } +} + +impl core::convert::From> for U16String { + fn from(src: Box) -> Self { + U16String::from_vec(src.wchars) + } +} diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/abi/definitions.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/abi/definitions.rs index b09844a4..16aef991 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/abi/definitions.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/abi/definitions.rs @@ -15,7 +15,7 @@ macro_rules! export_enclave_functions { use abi_types::FuncWithAllArgs_0_Args as AbiTypeT; use flatbuffer_types::FuncWithAllArgs_0_ArgsT as FlatBufferT; let abi_func = |abi_type: &mut AbiTypeT| -> Result<(), AbiError> { - abi_type.m__return_value_ = <$T>::FuncWithAllArgs(abi_type.m_arg1, &abi_type.m_arg2, &mut abi_type.m_arg3, &mut abi_type.m_arg4, &mut abi_type.m_arg5, &mut abi_type.m_arg6, &mut abi_type.m_arg7, &mut abi_type.m_arg8, &mut abi_type.m_arg9)?; + abi_type.m__return_value_ = <$T>::FuncWithAllArgs(abi_type.m_arg1, abi_type.m_arg2.as_ref(), abi_type.m_arg3.as_mut(), abi_type.m_arg4.as_mut(), &mut abi_type.m_arg5, abi_type.m_arg6.as_mut(), &mut abi_type.m_arg7, &mut abi_type.m_arg8, &mut abi_type.m_arg9)?; Ok(()) }; $crate::enable_enclave_restrict_containing_process_access_once(); diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/implementation/trusted.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/implementation/trusted.rs index 3e8ff676..aa89ee33 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/implementation/trusted.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/implementation/trusted.rs @@ -7,9 +7,10 @@ use alloc::string::String; use alloc::vec::Vec; use crate::implementation::types::*; +use widestring::{U16String, U16Str}; pub trait Trusted { - fn FuncWithAllArgs(arg1: bool, arg2: &Option, arg3: &mut Option, arg4: &mut Option, arg5: &mut TestStruct1, arg6: &mut Option, arg7: &mut Vec, arg8: &mut Vec, arg9: &mut [edl::WString;2]) -> Result; + fn FuncWithAllArgs(arg1 : bool, arg2 : Option<&u32>, arg3 : Option<&mut i32>, arg4 : Option<&mut u64>, arg5 : &mut TestStruct1, arg6 : Option<&mut TestStruct2>, arg7 : &mut Vec, arg8 : &mut Vec, arg9 : &mut [U16String;2]) -> Result; } diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/implementation/types.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/implementation/types.rs index cbd2af6a..4e79aed1 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/implementation/types.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/implementation/types.rs @@ -8,7 +8,7 @@ use alloc::string::String; use alloc::vec::Vec; use alloc::boxed::Box; use crate::abi::fb_support::fb_types::code_gen_test::flatbuffer_types; -pub use crate::abi::abi_types::edl; +use widestring::{U16String, U16Str}; use edlcodegen_enclave::EdlDerive; pub const VALUE1: usize = 1; diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/lib.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/lib.rs index 1dfcbb3f..76c086d0 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/lib.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/lib.rs @@ -7,7 +7,6 @@ extern crate alloc; pub mod abi; -pub use abi::abi_types::edl::WString; pub mod implementation; pub mod stubs; pub use edlcodegen_enclave::enclave_ffi::enable_enclave_restrict_containing_process_access_once; @@ -15,3 +14,5 @@ pub use edlcodegen_enclave::{AbiError, return_hr_as_pvoid}; pub use edlcodegen_enclave::enclave_helpers::{ call_vtl1_export_from_vtl1, register_vtl0_callouts }; +#[allow(unused_imports)] +pub use widestring::{U16String, U16Str}; diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/stubs/untrusted.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/stubs/untrusted.rs index 31dd021a..fbbdcb24 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/stubs/untrusted.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/Enclave/code_gen_test_gen/src/stubs/untrusted.rs @@ -8,27 +8,29 @@ use crate::abi::abi_types; use crate::abi::fb_support::fb_types::code_gen_test::flatbuffer_types; use crate::implementation::types::*; -use alloc::string::String; +use alloc::string::{String, ToString}; use alloc::vec::Vec; +use crate::alloc::borrow::ToOwned; use edlcodegen_enclave::enclave_helpers::call_vtl0_callback_from_vtl1; +use widestring::{U16String, U16Str}; -pub fn FuncWithAllArgs(arg1: bool, arg2: &Option, arg3: &mut Option, arg4: &mut Option, arg5: &mut TestStruct1, arg6: &mut Option, arg7: &mut Vec, arg8: &mut Vec, arg9: &mut [edl::WString;2]) -> Result +pub fn FuncWithAllArgs(arg1 : bool, arg2 : Option<&u32>, arg3 : Option<&mut i32>, arg4 : Option<&mut u64>, arg5 : &mut TestStruct1, arg6 : Option<&mut TestStruct2>, arg7 : &mut Vec, arg8 : &mut Vec, arg9 : &mut [U16String;2]) -> Result { use abi_types::FuncWithAllArgs_1_Args as AbiTypeT; use flatbuffer_types::FuncWithAllArgs_1_ArgsT as FlatBufferT; let mut abi_type : AbiTypeT = AbiTypeT::default(); abi_type.m_arg1 = arg1.clone(); - abi_type.m_arg2 = arg2.clone(); - abi_type.m_arg3 = arg3.clone(); + abi_type.m_arg2 = arg2.as_deref().copied(); + abi_type.m_arg3 = arg3.as_deref().copied(); abi_type.m_arg5 = arg5.clone(); - abi_type.m_arg7 = arg7.clone(); + abi_type.m_arg7 = arg7.to_owned(); let fb_native : FlatBufferT = abi_type.into(); let result = call_vtl0_callback_from_vtl1::(&fb_native, "FuncWithAllArgs_1_Generated_Stub")?; - *arg3 = result.m_arg3; - *arg4 = result.m_arg4; + edlcodegen_enclave::assign_if_some(arg3, result.m_arg3); + edlcodegen_enclave::assign_if_some(arg4, result.m_arg4); *arg5 = result.m_arg5; - *arg6 = result.m_arg6; + edlcodegen_enclave::assign_if_some(arg6, result.m_arg6); *arg7 = result.m_arg7; *arg8 = result.m_arg8; *arg9 = result.m_arg9; diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/Cargo.toml b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/Cargo.toml index 4f3e57f2..d9097577 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/Cargo.toml +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/Cargo.toml @@ -16,3 +16,4 @@ edlcodegen-tools = { git = "https://github.com/microsoft/VbsEnclaveTooling" } edlcodegen-host = { git = "https://github.com/microsoft/VbsEnclaveTooling" } windows-strings = "0.5" flatbuffers = { version = "25.9.23", default-features = false } +widestring = { version = "1.2.1", default-features = false, features = ["alloc"] } diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/abi/abi_types.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/abi/abi_types.rs index 67d6b995..667deee4 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/abi/abi_types.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/abi/abi_types.rs @@ -9,6 +9,7 @@ use crate::implementation::types::*; use crate::abi::fb_support::fb_types::code_gen_test::flatbuffer_types; use crate::abi::fb_support::fb_types::edl::WStringT; use edlcodegen_host::EdlDerive; +use widestring::{U16String, U16Str}; #[repr(C)] @@ -27,7 +28,7 @@ pub struct FuncWithAllArgs_0_Args { pub m_arg6: Option, pub m_arg7: Vec, pub m_arg8: Vec, - pub m_arg9: [edl::WString;2], + pub m_arg9: [U16String;2], pub m__return_value_: i32, } @@ -47,7 +48,7 @@ pub struct FuncWithAllArgs_1_Args { pub m_arg6: Option, pub m_arg7: Vec, pub m_arg8: Vec, - pub m_arg9: [edl::WString;2], + pub m_arg9: [U16String;2], pub m__return_value_: i32, } @@ -60,12 +61,26 @@ pub struct AbiRegisterVtl0Callbacks_args pub m__return_value_: i32, } -pub mod edl { - - #[derive(Debug, Clone, PartialEq, Default, super::EdlDerive)] - #[target_struct(super::WStringT)] - pub struct WString { - pub wchars: Vec, +impl core::convert::From for WStringT { + fn from(src: U16String) -> Self { + Self { wchars: src.clone().into_vec() } } } +impl core::convert::From for U16String { + fn from(src: WStringT) -> Self { + U16String::from_vec(src.wchars) + } +} + +impl core::convert::From for Box { + fn from(src: U16String) -> Self { + Box::new(WStringT{ wchars: src.clone().into_vec() }) + } +} + +impl core::convert::From> for U16String { + fn from(src: Box) -> Self { + U16String::from_vec(src.wchars) + } +} diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/abi/definitions.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/abi/definitions.rs index a64ae6d2..5ffa509a 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/abi/definitions.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/abi/definitions.rs @@ -11,7 +11,7 @@ macro_rules! define_trait_callback_functions { use $crate::abi::abi_types::FuncWithAllArgs_1_Args as AbiTypeT; use $crate::abi::fb_support::fb_types::code_gen_test::flatbuffer_types::FuncWithAllArgs_1_ArgsT as FlatBufferT; let abi_func = |abi_type: &mut AbiTypeT| -> Result<(), AbiError> { - abi_type.m__return_value_ = Self::FuncWithAllArgs(abi_type.m_arg1, &abi_type.m_arg2, &mut abi_type.m_arg3, &mut abi_type.m_arg4, &mut abi_type.m_arg5, &mut abi_type.m_arg6, &mut abi_type.m_arg7, &mut abi_type.m_arg8, &mut abi_type.m_arg9)?; + abi_type.m__return_value_ = Self::FuncWithAllArgs(abi_type.m_arg1, abi_type.m_arg2.as_ref(), abi_type.m_arg3.as_mut(), abi_type.m_arg4.as_mut(), &mut abi_type.m_arg5, abi_type.m_arg6.as_mut(), &mut abi_type.m_arg7, &mut abi_type.m_arg8, &mut abi_type.m_arg9)?; Ok(()) }; return_hr_as_pvoid!(call_vtl0_callback_from_vtl0::<_, AbiTypeT, FlatBufferT>(abi_func, fn_context)) diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/implementation/types.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/implementation/types.rs index 4f1f3b91..e4c84280 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/implementation/types.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/implementation/types.rs @@ -6,7 +6,7 @@ #![allow(non_snake_case)] use crate::abi::fb_support::fb_types::code_gen_test::flatbuffer_types; -pub use crate::abi::abi_types::edl; +use widestring::{U16String, U16Str}; use edlcodegen_host::EdlDerive; pub const VALUE1: usize = 1; diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/implementation/untrusted.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/implementation/untrusted.rs index e1c298fb..6ec8eb4f 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/implementation/untrusted.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/implementation/untrusted.rs @@ -5,9 +5,10 @@ #![allow(non_snake_case)] use crate::implementation::types::*; +use widestring::{U16String, U16Str}; pub trait Untrusted { - fn FuncWithAllArgs(arg1: bool, arg2: &Option, arg3: &mut Option, arg4: &mut Option, arg5: &mut TestStruct1, arg6: &mut Option, arg7: &mut Vec, arg8: &mut Vec, arg9: &mut [edl::WString;2]) -> Result; + fn FuncWithAllArgs(arg1 : bool, arg2 : Option<&u32>, arg3 : Option<&mut i32>, arg4 : Option<&mut u64>, arg5 : &mut TestStruct1, arg6 : Option<&mut TestStruct2>, arg7 : &mut Vec, arg8 : &mut Vec, arg9 : &mut [U16String;2]) -> Result; crate::define_trait_callback_functions!(); } diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/lib.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/lib.rs index 1d339377..25871ec1 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/lib.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/lib.rs @@ -3,9 +3,10 @@ #![allow(clippy::all)] pub mod abi; -pub use abi::abi_types::edl::WString; pub mod implementation; pub mod stubs; pub use stubs::trusted::CodeGenTestClass; pub use edlcodegen_host::{AbiError, abi_func_to_address, return_hr_as_pvoid}; pub use edlcodegen_host::host_helpers::call_vtl0_callback_from_vtl0; +#[allow(unused_imports)] +pub use widestring::{U16String, U16Str}; diff --git a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/stubs/trusted.rs b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/stubs/trusted.rs index 63f05f56..bdda5ef6 100644 --- a/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/stubs/trusted.rs +++ b/src/ToolingSharedLibrary/CurrentCodeGenerationState/Rust/HostApp/code_gen_test_gen/src/stubs/trusted.rs @@ -10,8 +10,10 @@ use crate::abi::fb_support::fb_types::code_gen_test::flatbuffer_types; use crate::implementation::types::*; use crate::implementation::untrusted::Untrusted; use edlcodegen_host::host_helpers::call_vtl1_export_from_vtl0; + use edlcodegen_host::EnclaveHandle; use windows_strings::s; +use widestring::{U16String, U16Str}; pub struct CodeGenTestClass { enclave_handle: EnclaveHandle, @@ -22,23 +24,23 @@ impl CodeGenTestClass { Self { enclave_handle : EnclaveHandle(enclave_ptr) } } - pub fn FuncWithAllArgs(&self, arg1: bool, arg2: &Option, arg3: &mut Option, arg4: &mut Option, arg5: &mut TestStruct1, arg6: &mut Option, arg7: &mut Vec, arg8: &mut Vec, arg9: &mut [edl::WString;2]) -> Result + pub fn FuncWithAllArgs(&self, arg1 : bool, arg2 : Option<&u32>, arg3 : Option<&mut i32>, arg4 : Option<&mut u64>, arg5 : &mut TestStruct1, arg6 : Option<&mut TestStruct2>, arg7 : &mut Vec, arg8 : &mut Vec, arg9 : &mut [U16String;2]) -> Result { use abi_types::FuncWithAllArgs_0_Args as AbiTypeT; use flatbuffer_types::FuncWithAllArgs_0_ArgsT as FlatBufferT; let mut abi_type : AbiTypeT = AbiTypeT::default(); abi_type.m_arg1 = arg1.clone(); - abi_type.m_arg2 = arg2.clone(); - abi_type.m_arg3 = arg3.clone(); + abi_type.m_arg2 = arg2.as_deref().copied(); + abi_type.m_arg3 = arg3.as_deref().copied(); abi_type.m_arg5 = arg5.clone(); - abi_type.m_arg7 = arg7.clone(); + abi_type.m_arg7 = arg7.to_owned(); let fb_native : FlatBufferT = abi_type.into(); let result = call_vtl1_export_from_vtl0::(&fb_native, self.enclave_handle.0, s!("FuncWithAllArgs_0_Generated_Stub"))?; - *arg3 = result.m_arg3; - *arg4 = result.m_arg4; + edlcodegen_host::assign_if_some(arg3, result.m_arg3); + edlcodegen_host::assign_if_some(arg4, result.m_arg4); *arg5 = result.m_arg5; - *arg6 = result.m_arg6; + edlcodegen_host::assign_if_some(arg6, result.m_arg6); *arg7 = result.m_arg7; *arg8 = result.m_arg8; *arg9 = result.m_arg9; diff --git a/src/ToolingSharedLibrary/Includes/CodeGeneration/Rust/CodeGenerationHelpers.h b/src/ToolingSharedLibrary/Includes/CodeGeneration/Rust/CodeGenerationHelpers.h index 6be51a9f..81ba4b9c 100644 --- a/src/ToolingSharedLibrary/Includes/CodeGeneration/Rust/CodeGenerationHelpers.h +++ b/src/ToolingSharedLibrary/Includes/CodeGeneration/Rust/CodeGenerationHelpers.h @@ -15,7 +15,10 @@ namespace CodeGeneration::Rust { using namespace CodeGeneration::Common; - inline std::string EdlTypeToRustType(const EdlTypeInfo& info) + inline bool IsStructOrWStringType(const Declaration& declaration); + inline std::string GetParameterSyntax(const Declaration& declaration); + + inline std::string EdlTypeToRustType(const EdlTypeInfo& info, bool is_string_slice = false) { switch (info.m_type_kind) { @@ -38,9 +41,9 @@ namespace CodeGeneration::Rust case EdlTypeKind::UIntPtr: return "u64"; case EdlTypeKind::String: - return "String"; + return (is_string_slice) ? "str" : "String"; case EdlTypeKind::WString: - return "edl::WString"; + return (is_string_slice) ? "U16Str" : "U16String"; default: return info.m_name; } @@ -58,31 +61,67 @@ namespace CodeGeneration::Rust return result; } - inline std::string AddVectorEncapulation(const Declaration& vector_declaration) + inline std::string GetBasicRustTypeInfo(const Declaration& declaration) { - auto inner_type = vector_declaration.m_edl_type_info.inner_type; - auto inner_type_name = EdlTypeToRustType(*inner_type); - return std::format("Vec<{}>", inner_type_name); + if (declaration.IsEdlType(EdlTypeKind::Optional)) + { + return std::format("Option<{}>", EdlTypeToRustType(*declaration.m_edl_type_info.inner_type)); + } + else if (declaration.IsEdlType(EdlTypeKind::Vector)) + { + return std::format("Vec<{}>", EdlTypeToRustType(*declaration.m_edl_type_info.inner_type)); + } + else if (declaration.IsEdlType(EdlTypeKind::Void)) + { + return "()"; + } + else if (!declaration.m_array_dimensions.empty()) + { + auto arr_size = declaration.m_array_dimensions.front(); + auto type_name = EdlTypeToRustType(declaration.m_edl_type_info); + return std::format(c_array_initializer, type_name, TransformCaseToUpper(arr_size)); + } + + return EdlTypeToRustType(declaration.m_edl_type_info); } - inline std::string AddOptionalEncapulation(const Declaration& optional_declaration) + inline std::string GetInnerTypeAndParameterSyntax( + const Declaration& declaration, + bool should_use_string_slice, + std::string& out_inner_type_name) { - auto inner_type = optional_declaration.m_edl_type_info.inner_type; - auto inner_type_name = EdlTypeToRustType(*inner_type); - - return std::format("Option<{}>", inner_type_name); + auto inner_type = declaration.m_edl_type_info.inner_type; + out_inner_type_name = EdlTypeToRustType(*inner_type, should_use_string_slice); + return GetParameterSyntax(declaration); } - - inline std::string GetFullDeclarationType(const Declaration& declaration) + inline std::string AddVectorEncapulation(const Declaration& vector_declaration) { - EdlTypeKind type_kind = declaration.m_edl_type_info.m_type_kind; - std::string type_name = EdlTypeToRustType(declaration.m_edl_type_info); + std::string inner_type_name; + auto param_syntax = GetInnerTypeAndParameterSyntax(vector_declaration, false, inner_type_name); - if (type_kind == EdlTypeKind::Void) + if (vector_declaration.IsInParameterOnly()) { - return "()"; + // For in parameters, we use a slice. + return std::format("{} : {}[{}]", vector_declaration.m_name, param_syntax, inner_type_name); } + return std::format("{} : {}Vec<{}>", vector_declaration.m_name, param_syntax, inner_type_name); + } + + inline std::string AddOptionalEncapulation(const Declaration& optional_declaration) + { + std::string inner_type_name; + auto param_syntax = GetInnerTypeAndParameterSyntax( + optional_declaration, + optional_declaration.IsInParameterOnly(), + inner_type_name); + + // For in parameters that are optional, we use Option or Option<&T>/Option<&mut T> if a borrow is needed. + return std::format("{} : Option<{}{}>", optional_declaration.m_name, param_syntax, inner_type_name); + } + + inline std::string GetParameterForFunction(const Declaration& declaration) + { if (declaration.IsEdlType(EdlTypeKind::Optional)) { return AddOptionalEncapulation(declaration); @@ -90,16 +129,21 @@ namespace CodeGeneration::Rust if (declaration.IsEdlType(EdlTypeKind::Vector)) { - type_name = AddVectorEncapulation(declaration); + return AddVectorEncapulation(declaration); } + auto param_syntax = GetParameterSyntax(declaration); + if (!declaration.m_array_dimensions.empty()) { auto arr_size = declaration.m_array_dimensions.front(); + std::string type_name = EdlTypeToRustType(declaration.m_edl_type_info, false); type_name = std::format(c_array_initializer, type_name, TransformCaseToUpper(arr_size)); + return std::format("{} : {}{}", declaration.m_name, param_syntax, type_name); } - return type_name; + std::string type_name = EdlTypeToRustType(declaration.m_edl_type_info, declaration.IsInParameterOnly()); + return std::format("{} : {}{}", declaration.m_name, param_syntax, type_name); } inline std::string GetParameterSyntax(const Declaration& declaration) @@ -120,14 +164,6 @@ namespace CodeGeneration::Rust return "&"; } - inline std::string GetParameterForFunction(const Declaration& declaration) - { - std::string full_type = GetFullDeclarationType(declaration); - std::string param_declarator = GetParameterSyntax(declaration); - - return std::format("{}: {}{}", declaration.m_name, param_declarator, full_type); - } - inline std::string GetEnumValueExpression(const EnumType& enum_value) { if (enum_value.m_value) @@ -177,33 +213,147 @@ namespace CodeGeneration::Rust uint32_t indentation, const std::vector& parameters) { - std::ostringstream abi_struct_fill_statments {}; + std::ostringstream abi_struct_fill_statements {}; auto tabs = GenerateTabs(indentation); for (auto& param : parameters) { - if (param.IsInParameter()) + // Out-only parameters are written back separately. + if (param.IsOutParameterOnly()) { - abi_struct_fill_statments << std::format( + continue; + } + + // Arrays are cloned verbatim. + if (!param.m_array_dimensions.empty()) + { + abi_struct_fill_statements << std::format( "{}abi_type.m_{} = {}.clone();\n", tabs, param.m_name, param.m_name); + + continue; } + + // Vectors require ownership transfer. + if (param.IsEdlType(EdlTypeKind::Vector)) + { + abi_struct_fill_statements << std::format( + "{}abi_type.m_{} = {}.to_owned();\n", + tabs, + param.m_name, + param.m_name); + + continue; + } + + // Strings require explicit allocation. + if (param.IsEdlType(EdlTypeKind::String) || + param.IsEdlType(EdlTypeKind::WString)) + { + auto func = param.IsEdlType(EdlTypeKind::String) + ? ".to_string()" + : ".to_ustring()"; + + abi_struct_fill_statements << std::format( + "{}abi_type.m_{} = {}{};\n", + tabs, + param.m_name, + param.m_name, + func); + + continue; + } + + // Optional requires cloning or copying the inner value. + if (param.IsEdlType(EdlTypeKind::Optional)) + { + if (param.IsInnerEdlType(EdlTypeKind::String) || + param.IsInnerEdlType(EdlTypeKind::WString)) + { + const char* func = param.IsInnerEdlType(EdlTypeKind::String) + ? "map(String::from)" + : "map(widestring::U16String::from)"; + + abi_struct_fill_statements << std::format( + "{}abi_type.m_{} = {}.{};\n", + tabs, + param.m_name, + param.m_name, + func); + } + else + { + auto inner = param.m_edl_type_info.inner_type; + bool is_primitive = c_edlTypes_primitive_set.contains(inner->m_type_kind); + + abi_struct_fill_statements << std::format( + "{}abi_type.m_{} = {}.as_deref().{}();\n", + tabs, + param.m_name, + param.m_name, + is_primitive ? "copied" : "cloned"); + } + + continue; + } + + // Fallback: clone everything else. + abi_struct_fill_statements << std::format( + "{}abi_type.m_{} = {}.clone();\n", + tabs, + param.m_name, + param.m_name); } - return abi_struct_fill_statments.str(); + return abi_struct_fill_statements.str(); } inline std::string GetMoveFromAbiStructToParamStatements( uint32_t indentation, + std::string_view parent_crate, const std::vector& parameters) { std::ostringstream param_update_statements {}; auto tabs = GenerateTabs(indentation); for (auto& param : parameters) { - if (param.IsInOutOrOutParameter()) + if (param.IsInParameterOnly()) + { + continue; + } + + bool is_array = !param.m_array_dimensions.empty(); + + // For struct and wstring out-parameters, the ABI uses Option because + // FlatBuffers represents non-required table fields that way. Even though the .edl + // signature declares an out parameter of type T, we must unwrap the + // Option here to satisfy the ABI contract. This value is expected to + // always be present; encountering None indicates a bug in the flatbuffer to ABI type + // layer. + if (!is_array && param.IsOutParameterOnly() && IsStructOrWStringType(param)) + { + param_update_statements << std::format( + "{}*{} = result.m_{}.expect(\"Unexpected empty Option: m_{}\");\n", + tabs, + param.m_name, + param.m_name, + param.m_name); + } + // For optional out and inout parameters, we need to use the assign_if_some helper + // to only update the parameter if the ABI provided a value. + else if (param.IsInOutOrOutParameter() && param.IsEdlType(EdlTypeKind::Optional)) + { + param_update_statements << std::format( + "{}{}::assign_if_some({}, result.m_{});\n", + tabs, + parent_crate, + param.m_name, + param.m_name); + } + else { + // Fallback: direct move assignment. param_update_statements << std::format("{}*{} = result.m_{};\n", tabs, param.m_name, param.m_name); } } @@ -225,7 +375,47 @@ namespace CodeGeneration::Rust for (auto i = 0U; i < function.m_parameters.size(); i++) { Declaration param = function.m_parameters[i]; - abi_struct_fields << std::format("{}abi_type.m_{}", GetParameterSyntax(param), param.m_name); + + bool is_array = !param.m_array_dimensions.empty(); + + // Out-only struct / wstring params are Option in the ABI; unwrap to get &mut T. + // None here indicates an ABI-layer bug. + if (!is_array && param.IsOutParameterOnly() && IsStructOrWStringType(param)) + { + abi_struct_fields << std::format( + "abi_type.m_{}.as_mut().expect(\"Unexpected empty Option: m_{}\")", + param.m_name, + param.m_name); + } + // Optional: project to the appropriate borrowed form based on direction and inner type. + else if (param.IsEdlType(EdlTypeKind::Optional)) + { + std::string func {}; + + if (param.IsInnerEdlType(EdlTypeKind::String) || + param.IsInnerEdlType(EdlTypeKind::WString)) + { + // in parameter of optional string/wstring are mapped as Option<&str> / Option<&U16Str> + // and out/inout as Option<&mut String> / Option<&mut U16String> + func = param.IsInParameterOnly() ? "as_deref()" : "as_mut()"; + } + else + { + // in parameter of other optional types are mapped as Option<&T> and out/inout as Option<&mut T> + func = param.IsInParameterOnly() ? "as_ref()" : "as_mut()"; + } + + abi_struct_fields << std::format( + "abi_type.m_{}.{}", + param.m_name, + func); + } + // All other parameters are passed through directly with appropriate borrowing. + else + { + abi_struct_fields << std::format("{}abi_type.m_{}", GetParameterSyntax(param), param.m_name); + } + if (i < function.m_parameters.size() - 1) { abi_struct_fields << ", "; diff --git a/src/ToolingSharedLibrary/Includes/CodeGeneration/Rust/Constants.h b/src/ToolingSharedLibrary/Includes/CodeGeneration/Rust/Constants.h index 1108190f..4172a2ba 100644 --- a/src/ToolingSharedLibrary/Includes/CodeGeneration/Rust/Constants.h +++ b/src/ToolingSharedLibrary/Includes/CodeGeneration/Rust/Constants.h @@ -39,6 +39,7 @@ edlcodegen-tools = {{ git = "https://github.com/microsoft/VbsEnclaveTooling" }} [dependencies] {} flatbuffers = {{ version = "25.9.23", default-features = false }} +widestring = {{ version = "1.2.1", default-features = false, features = ["alloc"] }} )"; inline constexpr std::string_view c_build_rs_file_content = @@ -93,7 +94,7 @@ R"({} #![allow(non_snake_case)] {} use crate::abi::fb_support::fb_types::{}::flatbuffer_types; -pub use crate::abi::abi_types::edl; +use widestring::{{U16String, U16Str}}; use {}::EdlDerive; {} )"; @@ -108,6 +109,7 @@ use crate::implementation::types::*; use crate::abi::fb_support::fb_types::{}::flatbuffer_types; use crate::abi::fb_support::fb_types::edl::WStringT; use {}::EdlDerive; +use widestring::{{U16String, U16Str}}; {} #[derive(Debug, Clone, PartialEq, Default, EdlDerive)] @@ -119,15 +121,29 @@ pub struct AbiRegisterVtl0Callbacks_args pub m__return_value_: i32, }} -pub mod edl {{ - {} - #[derive(Debug, Clone, PartialEq, Default, super::EdlDerive)] - #[target_struct(super::WStringT)] - pub struct WString {{ - pub wchars: Vec, +impl core::convert::From for WStringT {{ + fn from(src: U16String) -> Self {{ + Self {{ wchars: src.clone().into_vec() }} }} }} +impl core::convert::From for U16String {{ + fn from(src: WStringT) -> Self {{ + U16String::from_vec(src.wchars) + }} +}} + +impl core::convert::From for Box {{ + fn from(src: U16String) -> Self {{ + Box::new(WStringT{{ wchars: src.clone().into_vec() }}) + }} +}} + +impl core::convert::From> for U16String {{ + fn from(src: Box) -> Self {{ + U16String::from_vec(src.wchars) + }} +}} )"; inline constexpr std::string_view c_flatbuffers_module_name = "fb_support.rs"; @@ -201,7 +217,6 @@ R"({} extern crate alloc; pub mod abi; -pub use abi::abi_types::edl::WString; pub mod implementation; pub mod stubs; pub use edlcodegen_enclave::enclave_ffi::enable_enclave_restrict_containing_process_access_once; @@ -209,18 +224,21 @@ pub use edlcodegen_enclave::{{AbiError, return_hr_as_pvoid}}; pub use edlcodegen_enclave::enclave_helpers::{{ call_vtl1_export_from_vtl1, register_vtl0_callouts }}; +#[allow(unused_imports)] +pub use widestring::{{U16String, U16Str}}; )"; inline constexpr std::string_view c_host_lib_rs = R"({} #![allow(clippy::all)] pub mod abi; -pub use abi::abi_types::edl::WString; pub mod implementation; pub mod stubs; pub use stubs::trusted::{}; pub use edlcodegen_host::{{AbiError, abi_func_to_address, return_hr_as_pvoid}}; pub use edlcodegen_host::host_helpers::call_vtl0_callback_from_vtl0; +#[allow(unused_imports)] +pub use widestring::{{U16String, U16Str}}; )"; inline constexpr std::string_view c_trait_function = @@ -234,6 +252,7 @@ R"({} use alloc::string::String; use alloc::vec::Vec; use crate::implementation::types::*; +use widestring::{{U16String, U16Str}}; pub trait Trusted {{ @@ -247,6 +266,7 @@ R"({} #![allow(non_snake_case)] use crate::implementation::types::*; +use widestring::{{U16String, U16Str}}; pub trait Untrusted {{ {} @@ -263,9 +283,11 @@ R"({} use crate::abi::abi_types; use crate::abi::fb_support::fb_types::{}::flatbuffer_types; use crate::implementation::types::*; -use alloc::string::String; +use alloc::string::{{String, ToString}}; use alloc::vec::Vec; +use crate::alloc::borrow::ToOwned; use edlcodegen_enclave::enclave_helpers::call_vtl0_callback_from_vtl1; +use widestring::{{U16String, U16Str}}; {} )"; @@ -294,8 +316,10 @@ use crate::abi::fb_support::fb_types::{}::flatbuffer_types; use crate::implementation::types::*; use crate::implementation::untrusted::Untrusted; use edlcodegen_host::host_helpers::call_vtl1_export_from_vtl0; + use edlcodegen_host::EnclaveHandle; use windows_strings::s; +use widestring::{{U16String, U16Str}}; pub struct {} {{ enclave_handle: EnclaveHandle, diff --git a/src/ToolingSharedLibrary/ToolingExecutable/CodeGeneration/Flatbuffers/BuilderHelpers.cpp b/src/ToolingSharedLibrary/ToolingExecutable/CodeGeneration/Flatbuffers/BuilderHelpers.cpp index 3c145f9e..b054d6ca 100644 --- a/src/ToolingSharedLibrary/ToolingExecutable/CodeGeneration/Flatbuffers/BuilderHelpers.cpp +++ b/src/ToolingSharedLibrary/ToolingExecutable/CodeGeneration/Flatbuffers/BuilderHelpers.cpp @@ -199,6 +199,7 @@ namespace CodeGeneration::Flatbuffers auto& inner_type = declaration.m_edl_type_info.inner_type; bool is_inner_struct_or_string = inner_type->m_type_kind == EdlTypeKind::Struct || + inner_type->m_type_kind == EdlTypeKind::WString || inner_type->m_type_kind == EdlTypeKind::String; // In the flatbuffer schema, structs & strings are optional by default without the "= null" expression. diff --git a/src/ToolingSharedLibrary/ToolingExecutable/CodeGeneration/Rust/RustCodeBuilder.cpp b/src/ToolingSharedLibrary/ToolingExecutable/CodeGeneration/Rust/RustCodeBuilder.cpp index b8dabf84..7eaa4fa5 100644 --- a/src/ToolingSharedLibrary/ToolingExecutable/CodeGeneration/Rust/RustCodeBuilder.cpp +++ b/src/ToolingSharedLibrary/ToolingExecutable/CodeGeneration/Rust/RustCodeBuilder.cpp @@ -77,8 +77,7 @@ namespace CodeGeneration::Rust crate_info.m_alloc_imports, developer_namespace_name, crate_info.m_crate_name, - types_module.str(), - crate_info.m_vec_import); + types_module.str()); } Definition CodeBuilder::BuildStartOfDefinition( @@ -145,7 +144,7 @@ namespace CodeGeneration::Rust { bool is_array = !field.m_array_dimensions.empty(); - std::string field_type = GetFullDeclarationType(field); + std::string field_type = GetBasicRustTypeInfo(field); if (!is_array && !field.IsOutParameterOnly() && IsStructOrWStringType(field)) { @@ -208,7 +207,7 @@ namespace CodeGeneration::Rust for (auto& func : functions.values()) { auto returned_result = std::format("Result<{}, edlcodegen_{}::AbiError>", - GetFullDeclarationType(func.m_return_info), + GetBasicRustTypeInfo(func.m_return_info), vtl_kind == VirtualTrustLayerKind::HostApp ? "host" : "enclave"); trait_functions << std::format( @@ -260,19 +259,24 @@ namespace CodeGeneration::Rust else if (!func_returns_void && is_return_struct_or_wstring) { return_statement_value = std::format( - "result.m_{}.expect(\"abi layer returned unexpected empty Option\")", + "result.m_{}.expect(\"Unexpected empty Option ({})\")", + func.m_return_info.m_name, func.m_return_info.m_name); } std::string to_flatbuffer_statements = GetCloneToAbiStructStatements(indentation, func.m_parameters); + auto parent_crate = vtl_kind == VirtualTrustLayerKind::HostApp + ? "edlcodegen_host" + : "edlcodegen_enclave"; + std::string to_inout_param_statements = - GetMoveFromAbiStructToParamStatements(indentation, func.m_parameters); + GetMoveFromAbiStructToParamStatements(indentation, parent_crate, func.m_parameters); auto abi_func_struct_name = std::format(c_function_args_struct, func.abi_m_name); auto param_list = GenerateFunctionParametersList(func.m_parameters); - auto return_type = GetFullDeclarationType(func.m_return_info); + auto return_type = GetBasicRustTypeInfo(func.m_return_info); auto abi_stub_func_name = std::format(c_generated_stub_name_no_quotes, func.abi_m_name); mod_content << FormatString(