Skip to content

Conversation

kennykerr
Copy link
Collaborator

@kennykerr kennykerr commented Oct 6, 2025

The Win32 metadata includes some support for Windows virtualization-based security enclaves but these APIs are a little tricky because you need to import the APIs from a different system library depending on whether you are inside or outside of the enclave. This update thus does the following:

  • Remaps the general-purpose enclave APIs so that they are imported by default from kernel32.dll for crates like windows and windows-sys.
  • Adds a dedicated windows-enclaves crate that provides dedicated bindings for use within an enclave where all of the functions provided by this crate are specifically imported from vertdll.dll.

I'm opening this PR for testing and validation as I am not too familiar with enclaves. Hopefully this will help make using enclaves easier from Rust.

.to_lowercase();

// Workaround for https://github.com/microsoft/windows-rs/pull/3788
if result == "vertdll.dll" {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to completely remove anything that uses winenclaveapi.h too? The APIs in that header file are only present in vertdll.dll but this change will attempt to link them to kernel32.dll; I don't know how much of an issue this would be since a normal process can't call the APIs, but I want to make sure there's no confusion. I'll comment on the APIs in their mod.rs as well

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's why I am inclined to remove them from the windows and windows-sys crates entirely as they can accidentally get linked even if you don't call them directly if you happen to enable the feature that allows those bindings to compile.

windows_link::link!("vertdll.dll" "system" fn EnclaveSealData(datatoencrypt : *const core::ffi::c_void, datatoencryptsize : u32, identitypolicy : ENCLAVE_SEALING_IDENTITY_POLICY, runtimepolicy : u32, protectedblob : *mut core::ffi::c_void, buffersize : u32, protectedblobsize : *mut u32) -> windows_sys::core::HRESULT);
windows_link::link!("vertdll.dll" "system" fn EnclaveUnsealData(protectedblob : *const core::ffi::c_void, protectedblobsize : u32, decrypteddata : *mut core::ffi::c_void, buffersize : u32, decrypteddatasize : *mut u32, sealingidentity : *mut ENCLAVE_IDENTITY, unsealingflags : *mut u32) -> windows_sys::core::HRESULT);
windows_link::link!("vertdll.dll" "system" fn EnclaveVerifyAttestationReport(enclavetype : u32, report : *const core::ffi::c_void, reportsize : u32) -> windows_sys::core::HRESULT);
windows_link::link!("kernel32.dll" "system" fn EnclaveGetAttestationReport(enclavedata : *const u8, report : *mut core::ffi::c_void, buffersize : u32, outputsize : *mut u32) -> windows_sys::core::HRESULT);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These five APIs (EnclaveGetAttestationReport, EnclaveGetEnclaveInformation, EnclaveSealData, EnclaveUnsealData, EnclaveVerifyAttestationReport) are only present in vertdll, they're not in kernel32. Since they can't be called outside of an enclave, it's actually okay to remove these completely from windows-sys and only put them in windows-enclaves

In general, I think anything that starts with "Enclave" is going to be an Enclave-specific API that does not need to be in windows-sys, only in windows-enclaves

windows_link::link!("kernel32.dll" "system" fn SetEnvironmentVariableA(lpname : windows_sys::core::PCSTR, lpvalue : windows_sys::core::PCSTR) -> windows_sys::core::BOOL);
windows_link::link!("kernel32.dll" "system" fn SetEnvironmentVariableW(lpname : windows_sys::core::PCWSTR, lpvalue : windows_sys::core::PCWSTR) -> windows_sys::core::BOOL);
windows_link::link!("vertdll.dll" "system" fn TerminateEnclave(lpaddress : *const core::ffi::c_void, fwait : windows_sys::core::BOOL) -> windows_sys::core::BOOL);
windows_link::link!("kernel32.dll" "system" fn TerminateEnclave(lpaddress : *const core::ffi::c_void, fwait : windows_sys::core::BOOL) -> windows_sys::core::BOOL);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just leaving a comment here that this one is correct, it does live in kernel32 (and isn't something an enclave can call)

#[inline]
pub unsafe fn EnclaveGetAttestationReport(enclavedata: Option<&[u8; 64]>, report: Option<*mut core::ffi::c_void>, buffersize: u32, outputsize: *mut u32) -> windows_core::Result<()> {
windows_core::link!("vertdll.dll" "system" fn EnclaveGetAttestationReport(enclavedata : *const u8, report : *mut core::ffi::c_void, buffersize : u32, outputsize : *mut u32) -> windows_core::HRESULT);
windows_core::link!("kernel32.dll" "system" fn EnclaveGetAttestationReport(enclavedata : *const u8, report : *mut core::ffi::c_void, buffersize : u32, outputsize : *mut u32) -> windows_core::HRESULT);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, all of these "Enclave*" APIs are not present in kernel32, so they can just be removed entirely and only present in windows-enclaves if possible. Otherwise, they should be vertdll

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants