using System; using System.Runtime.InteropServices; namespace Vanara.PInvoke { public static partial class Kernel32 { /// Enclave constant. public const int ENCLAVE_LONG_ID_LENGTH = 32; /// Enclave constant. public const int ENCLAVE_SHORT_ID_LENGTH = 16; /// Enclave constant. public const int IMAGE_ENCLAVE_LONG_ID_LENGTH = ENCLAVE_LONG_ID_LENGTH; /// Enclave constant. public const int IMAGE_ENCLAVE_SHORT_ID_LENGTH = ENCLAVE_SHORT_ID_LENGTH; /// Used by the function. /// The thread parameter. /// The return thread parameter. [PInvokeData("MinWinBase.h")] [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate IntPtr PENCLAVE_ROUTINE(IntPtr lpThreadParameter); /// /// Specifies how another enclave must be related to the enclave that calls EnclaveSealData for the enclave to unseal the data. /// [PInvokeData("ntenclv.h")] public enum ENCLAVE_SEALING_IDENTITY_POLICY { /// ENCLAVE_IDENTITY_POLICY_SEAL_INVALID = 0, /// ENCLAVE_IDENTITY_POLICY_SEAL_EXACT_CODE, /// ENCLAVE_IDENTITY_POLICY_SEAL_SAME_PRIMARY_CODE, /// ENCLAVE_IDENTITY_POLICY_SEAL_SAME_IMAGE, /// ENCLAVE_IDENTITY_POLICY_SEAL_SAME_FAMILY, /// ENCLAVE_IDENTITY_POLICY_SEAL_SAME_AUTHOR, } /// A flag that indicates whether the enclave permits debugging. public enum ENCLAVE_VBS_FLAG : uint { /// The enclave does not permit debugging. ENCLAVE_VBS_FLAG_NODEBUG = 0x00000000, /// The enclave permits debugging. ENCLAVE_VBS_FLAG_DEBUG = 0x00000001, } /// The architecture type of the enclave that you want to create. [Flags] public enum EnclaveType : uint { /// An enclave for the Intel Software Guard Extensions (SGX) architecture extension. ENCLAVE_TYPE_SGX = 0x00000001, /// A VBS enclave. ENCLAVE_TYPE_VBS = 0x00000010, } /// /// Calls a function within an enclave. CallEnclave can also be called within an enclave to call a function outside of the enclave. /// /// The address of the function that you want to call. /// The parameter than you want to pass to the function. /// /// /// TRUE if the call to the specified function should block execution until an idle enclave thread becomes available when no /// idle enclave thread is available. FALSE if the call to the specified function should fail when no idle enclave thread is available. /// /// This parameter is ignored when you use CallEnclave within an enclave to call a function that is not in any enclave. /// /// The return value of the function, if it is called successfully. /// /// TRUE if the specified function was called successfully; otherwise FALSE. To get extended error information, call GetLastError. /// // BOOL WINAPI CallEnclave( _In_ LPENCLAVE_ROUTINE lpRoutine, _In_ LPVOID lpParameter, _In_ BOOL fWaitForThread, _Out_ LPVOID // *lpReturnValue); https://msdn.microsoft.com/en-us/library/windows/desktop/mt844231(v=vs.85).aspx [DllImport(Lib.VertDll, SetLastError = true, ExactSpelling = true)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt844231")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CallEnclave(PENCLAVE_ROUTINE lpRoutine, IntPtr lpParameter, [MarshalAs(UnmanagedType.Bool)] bool fWaitForThread, out IntPtr lpReturnValue); /// /// Creates a new uninitialized enclave. An enclave is an isolated region of code and data within the address space for an /// application. Only code that runs within the enclave can access data within the same enclave. /// /// A handle to the process for which you want to create an enclave. /// /// The preferred base address of the enclave. Specify NULL to have the operating system assign the base address. /// /// /// The size of the enclave that you want to create, including the size of the code that you will load into the enclave, in bytes. /// /// /// The amount of memory to commit for the enclave, in bytes. /// /// If the amount of enclave memory available is not sufficient to commit this number of bytes, enclave creation fails. Any memory /// that remains unused when you initialize the enclave by calling InitializeEnclave is returned to the list of free pages. /// /// The value of the dwInitialCommittment parameter must not exceed the value of the dwSize parameter. /// This parameter is not used for virtualization-based security (VBS) enclaves. /// /// /// The architecture type of the enclave that you want to create. To verify that an enclave type is supported, call IsEnclaveTypeSupported. /// /// /// /// Value /// Meaning /// /// /// ENCLAVE_TYPE_SGX0x00000001 /// An enclave for the Intel Software Guard Extensions (SGX) architecture extension. /// /// /// ENCLAVE_TYPE_VBS0x00000010 /// A VBS enclave. /// /// /// /// /// /// A pointer to the architecture-specific information to use to create the enclave. /// For the ENCLAVE_TYPE_SGX enclave type, you must specify a pointer to an ENCLAVE_CREATE_INFO_SGX structure. /// For the ENCLAVE_TYPE_VBS enclave type, you must specify a pointer to an ENCLAVE_CREATE_INFO_VBS structure. /// /// /// The length of the structure that the lpEnclaveInformation parameter points to, in bytes. For the ENCLAVE_TYPE_SGX enclave /// type, this value must be 4096. For the ENCLAVE_TYPE_VBS enclave type, this value must be , which is 36 bytes. /// /// /// An optional pointer to a variable that receives an enclave error code that is architecture-specific. For the /// ENCLAVE_TYPE_SGX and ENCLAVE_TYPE_VBS enclave types, the lpEnclaveError parameter is not used. /// /// /// If the function succeeds, the return value is the base address of the created enclave. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// For a list of common error codes, see System Error Codes. The following error codes also apply for this function. /// /// /// /// Return code /// Description /// /// /// ERROR_NOT_SUPPORTED /// An unsupported enclave type was specified. /// /// /// ERROR_BAD_LENGTH /// /// The value of the dwInfoLength parameter did not match the value expected based on the value specified for the /// lpEnclaveInformation parameter. /// /// /// /// /// // PVOID WINAPI CreateEnclave( _In_ HANDLE hProcess, _In_opt_ LPVOID lpAddress, _In_ SIZE_T dwSize, _In_ SIZE_T dwInitialCommittment, // _In_ DWORD flEnclaveType, _In_ LPCVOID lpEnclaveInformation, _In_ DWORD dwInfoLength, _Out_opt_ LPDWORD lpEnclaveError); https://msdn.microsoft.com/en-us/library/windows/desktop/mt592866(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt592866")] public static extern SafeEnclaveHandle CreateEnclave(HPROCESS hProcess, IntPtr lpAddress, SizeT dwSize, SizeT dwInitialCommittment, EnclaveType flEnclaveType, in ENCLAVE_CREATE_INFO_SGX lpEnclaveInformation, uint dwInfoLength, out uint lpEnclaveError); /// /// Creates a new uninitialized enclave. An enclave is an isolated region of code and data within the address space for an /// application. Only code that runs within the enclave can access data within the same enclave. /// /// A handle to the process for which you want to create an enclave. /// /// The preferred base address of the enclave. Specify NULL to have the operating system assign the base address. /// /// /// The size of the enclave that you want to create, including the size of the code that you will load into the enclave, in bytes. /// /// /// The amount of memory to commit for the enclave, in bytes. /// /// If the amount of enclave memory available is not sufficient to commit this number of bytes, enclave creation fails. Any memory /// that remains unused when you initialize the enclave by calling InitializeEnclave is returned to the list of free pages. /// /// The value of the dwInitialCommittment parameter must not exceed the value of the dwSize parameter. /// This parameter is not used for virtualization-based security (VBS) enclaves. /// /// /// The architecture type of the enclave that you want to create. To verify that an enclave type is supported, call IsEnclaveTypeSupported. /// /// /// /// Value /// Meaning /// /// /// ENCLAVE_TYPE_SGX0x00000001 /// An enclave for the Intel Software Guard Extensions (SGX) architecture extension. /// /// /// ENCLAVE_TYPE_VBS0x00000010 /// A VBS enclave. /// /// /// /// /// /// A pointer to the architecture-specific information to use to create the enclave. /// For the ENCLAVE_TYPE_SGX enclave type, you must specify a pointer to an ENCLAVE_CREATE_INFO_SGX structure. /// For the ENCLAVE_TYPE_VBS enclave type, you must specify a pointer to an ENCLAVE_CREATE_INFO_VBS structure. /// /// /// The length of the structure that the lpEnclaveInformation parameter points to, in bytes. For the ENCLAVE_TYPE_SGX enclave /// type, this value must be 4096. For the ENCLAVE_TYPE_VBS enclave type, this value must be , which is 36 bytes. /// /// /// An optional pointer to a variable that receives an enclave error code that is architecture-specific. For the /// ENCLAVE_TYPE_SGX and ENCLAVE_TYPE_VBS enclave types, the lpEnclaveError parameter is not used. /// /// /// If the function succeeds, the return value is the base address of the created enclave. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// For a list of common error codes, see System Error Codes. The following error codes also apply for this function. /// /// /// /// Return code /// Description /// /// /// ERROR_NOT_SUPPORTED /// An unsupported enclave type was specified. /// /// /// ERROR_BAD_LENGTH /// /// The value of the dwInfoLength parameter did not match the value expected based on the value specified for the /// lpEnclaveInformation parameter. /// /// /// /// /// // PVOID WINAPI CreateEnclave( _In_ HANDLE hProcess, _In_opt_ LPVOID lpAddress, _In_ SIZE_T dwSize, _In_ SIZE_T dwInitialCommittment, // _In_ DWORD flEnclaveType, _In_ LPCVOID lpEnclaveInformation, _In_ DWORD dwInfoLength, _Out_opt_ LPDWORD lpEnclaveError); https://msdn.microsoft.com/en-us/library/windows/desktop/mt592866(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt592866")] public static extern SafeEnclaveHandle CreateEnclave(HPROCESS hProcess, IntPtr lpAddress, SizeT dwSize, SizeT dwInitialCommittment, EnclaveType flEnclaveType, in ENCLAVE_CREATE_INFO_VBS lpEnclaveInformation, uint dwInfoLength, out uint lpEnclaveError); /// Deletes the specified enclave. /// The base address of the enclave that you want to delete. /// /// TRUE if the enclave was deleted successfully; otherwise FALSE. To get extended error information, call GetLastError. /// For a list of common error codes, see System Error Codes. The following error codes also apply for this function. /// /// /// /// Return code /// Description /// /// /// ERROR_ENCLAVE_NOT_TERMINATED /// /// The execution of threads running with the enclave was not ended, because either TerminateEnclave was not called, or the execution /// of the threads has not yet ended in response to an earlier call to TerminateEnclave. /// /// /// /// /// // BOOL WINAPI DeleteEnclave( _In_ LPVOID lpAddress); https://msdn.microsoft.com/en-us/library/windows/desktop/mt844232(v=vs.85).aspx [DllImport(Lib.VertDll, SetLastError = true, ExactSpelling = true)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt844232")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DeleteEnclave(IntPtr lpAddress); /// /// Gets an enclave attestation report that describes the current enclave and is signed by the authority that is responsible for the /// type of the enclave. /// /// /// A pointer to a 64-byte buffer of data that the enclave wants to insert into its signed report. For example, this buffer could /// include a 256-bit nonce that the relying party supplied, followed by a SHA-256 hash of additional data that the enclave wants to /// convey, such as a public key that corresponds to a private key that the enclave owns. If this parameter is NULL, the /// corresponding field of the report is filled with zeroes. /// /// /// A pointer to a buffer where the report should be placed. This report may be stored either within the address range of the enclave /// or within the address space of the host process. Specify NULL to indicate that only the size of the buffer required for the /// output should be calculated, and not the report itself. /// /// /// The size of the buffer to which the Report parameter points. If Report is NULL, BufferSize must be zero. If Report is not NULL, /// and if the size of the report is larger than this value, an error is returned. /// /// A pointer to a variable that receives the size of the report. /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// EnclaveGetAttestationReport must be called from within an enclave. /// /// EnclaveGetAttestationReport is not currently supported for enclaves with a type of ENCLAVE_TYPE_SGX. For VBS /// enclaves, the report that EnclaveGetAttestationReport gets is signed by using a VBS-specific key. /// /// /// The enclave attestation report contains the identity of all code loaded into the enclave, as well as policies that control how /// the enclave is running, such as whether the enclave is running with debugger access active. The report also includes a small /// amount of information that the enclave generated to use in a key-exchange protocol. /// /// The report that EnclaveGetAttestationReport generates consists of the following items: /// /// /// A VBS_ENCLAVE_REPORT_PKG_HEADER structure /// /// /// A signed statement that consist of the following items: /// /// /// A signature /// /// /// /// The enclave attestation report provide proof that specific code is running with an enclave. If a validating entity also obtains /// proof that the host system is running with VBS turned on, that entity can use that proof in conjunction with the enclave /// attestation report to verify that a specific enclave, populated with specific code, has been loaded. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winenclaveapi/nf-winenclaveapi-enclavegetattestationreport HRESULT // EnclaveGetAttestationReport( const UINT8 [ENCLAVE_REPORT_DATA_LENGTH] EnclaveData, PVOID Report, UINT32 BufferSize, UINT32 // *OutputSize ); [DllImport(Lib.VertDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("winenclaveapi.h", MSDNShortId = "FEE8F05B-540F-4C10-A90C-55607A4E9293")] public static extern HRESULT EnclaveGetAttestationReport(byte[] EnclaveData, IntPtr Report, uint BufferSize, out uint OutputSize); /// Gets information about the currently executing enclave. /// /// The size of the ENCLAVE_INFORMATION structure that the EnclaveInformation parameter points to, in bytes. /// /// Information about the currently executing enclave. /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// EnclaveGetEnclaveInformation must be called from within an enclave, and is only supported within enclaves that have the /// ENCLAVE_TYPE_VBS enclave type. /// // https://docs.microsoft.com/en-us/windows/win32/api/winenclaveapi/nf-winenclaveapi-enclavegetenclaveinformation HRESULT // EnclaveGetEnclaveInformation( UINT32 InformationSize, ENCLAVE_INFORMATION *EnclaveInformation ); [DllImport(Lib.VertDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("winenclaveapi.h", MSDNShortId = "26349C3C-4B73-430C-B002-ED262DB0304F")] public static extern HRESULT EnclaveGetEnclaveInformation(uint InformationSize, ref ENCLAVE_INFORMATION EnclaveInformation); /// Generates an encrypted binary large object (blob) from unencypted data. /// /// A pointer to the data that you want to seal. This data can be stored either within the address range of the enclave or within the /// address range of the host process. /// /// The size of the data that you want to seal, in bytes. /// /// A value that specifies how another enclave must be related to the enclave that calls EnclaveSealData for the enclave to /// unseal the data. /// /// /// /// A value that indicates whether an enclave that runs with debugging turned on is permitted to unseal the data the this call to /// EnclaveSealData seals. /// /// /// /// Value /// Meaning /// /// /// ENCLAVE_RUNTIME_POLICY_ALLOW_FULL_DEBUG 1 /// /// If specified, indicates that an enclave that runs with debugging turned on is permitted to unseal the data. If not specified, /// indicates that an enclave that runs with debugging turned on is not permitted to unseal the data. This flag is automatically /// included if the calling enclave is running with debugging turned on. /// /// /// /// ENCLAVE_RUNTIME_POLICY_ALLOW_DYNAMIC_DEBUG 2 /// /// If specified, indicates that an enclave that runs with dynamic debugging turned on is permitted to unseal the data. If not /// specified, indicates that an enclave that runs with dynamic debugging turned on is not permitted to unseal the data. This flag is /// automatically included if the calling enclave is running with dynamic debugging turned on /// /// /// /// /// /// A pointer to a buffer where the sealed data should be placed. This data may be stored either within the address range of the /// enclave or within the address space of the host process. If this parameter is NULL, only the size of the protected blob is calculated. /// /// /// A pointer to a variable that holds the size of the buffer to which the ProtectedBlob parameter points. If ProtectedBlob is NULL, /// this value must be zero. If ProtectedBlob is not NULL, and if the size of the encrypted data is larger than this value, an error occurs. /// /// A pointer to a variable that receives the actual size of the encrypted blob. /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// EnclaveSealData must be called from within an enclave, and is only supported within enclaves that have the /// ENCLAVE_TYPE_VBS enclave type. /// // https://docs.microsoft.com/en-us/windows/win32/api/winenclaveapi/nf-winenclaveapi-enclavesealdata HRESULT EnclaveSealData( const // VOID *DataToEncrypt, UINT32 DataToEncryptSize, ENCLAVE_SEALING_IDENTITY_POLICY IdentityPolicy, UINT32 RuntimePolicy, PVOID // ProtectedBlob, UINT32 BufferSize, UINT32 *ProtectedBlobSize ); [DllImport(Lib.VertDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("winenclaveapi.h", MSDNShortId = "C5711D43-F0B4-43C6-B0DB-D65622851384")] public static extern HRESULT EnclaveSealData(IntPtr DataToEncrypt, uint DataToEncryptSize, ENCLAVE_SEALING_IDENTITY_POLICY IdentityPolicy, uint RuntimePolicy, IntPtr ProtectedBlob, uint BufferSize, out uint ProtectedBlobSize); /// Decrypts an encrypted binary large object (blob). /// /// A pointer to the sealed data to unseal. This data may be stored either within the address range of the enclave or within the /// address space of the host process /// /// The size of the sealed data to unseal, in bytes. /// /// A pointer to a buffer where the unencrypted data should be placed. This data may be stored either within the address range of the /// enclave or within the address space of the host process. If this parameter is NULL, only the size of the decrypted data is calculated. /// /// /// The size of the buffer to which the DecryptedData parameter points, in bytes. If DecryptedData is NULL, BufferSize must be zero. /// If DecryptedData is not NULL, and if the size of the decrypted data is larger than this value, an error is returned. /// /// A pointer to a variable that receives the actual size of the decrypted data, in bytes. /// /// An optional pointer to a buffer that should be filled with the identity of the enclave that sealed the data. If this pointer is /// NULL, the identity of the sealing enclave is not returned. /// /// /// /// An optional pointer to a variable that receives zero or more of the following flags that describe the encrypted binary large object. /// /// /// /// Value /// Meaning /// /// /// ENCLAVE_UNSEAL_FLAG_STALE_KEY 1 /// /// The data was encrypted with a stale key. Sealing keys are rotated when required for security, and the system can only maintain a /// fixed number of recently known keys. An enclave that determines that data was encrypted with a stale key should reencrypt the /// data with a current key to minimize the chances that the key used to encrypt the data is no longer maintained in the key list. /// /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// /// The enclave that calls EnclaveUnsealData must meet the criteria that correspond to the value of the /// ENCLAVE_SEALING_IDENTITY_POLICY that was specified by the enclave that sealed the data by calling EnclaveSealData. /// /// /// EnclaveUnsealData must be called from within an enclave, and is only supported within enclaves that have the /// ENCLAVE_TYPE_VBS enclave type. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winenclaveapi/nf-winenclaveapi-enclaveunsealdata HRESULT EnclaveUnsealData( // const VOID *ProtectedBlob, UINT32 ProtectedBlobSize, PVOID DecryptedData, UINT32 BufferSize, UINT32 *DecryptedDataSize, // ENCLAVE_IDENTITY *SealingIdentity, UINT32 *UnsealingFlags ); [DllImport(Lib.VertDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("winenclaveapi.h", MSDNShortId = "DDBDBEDE-E7EA-43B0-B2C7-B85D75EF3EB0")] public static extern HRESULT EnclaveUnsealData(IntPtr ProtectedBlob, uint ProtectedBlobSize, IntPtr DecryptedData, uint BufferSize, out uint DecryptedDataSize, out ENCLAVE_IDENTITY SealingIdentity, out uint UnsealingFlags); /// Verifies an attestation report that was generated on the current system. /// The type of the enclave for which the report was generated. Must be ENCLAVE_TYPE_VBS. /// /// A pointer to a buffer that stores the report. This report may be stored either within the address range of the enclave or within /// the address space of the host process. /// /// The size of the report, in bytes. /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// /// This function is used if two enclaves run on the same system and need to establish a secure channel between one another. When you /// call EnclaveVerifyAttestationReport from a virtualization-based security (VBS) enclave, you can only use /// EnclaveVerifyAttestationReport to validate an attestation report that another VBS enclave generated. /// /// /// EnclaveVerifyAttestationReport must be called from within an enclave, and is only supported within enclaves that have the /// ENCLAVE_TYPE_VBS enclave type. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winenclaveapi/nf-winenclaveapi-enclaveverifyattestationreport HRESULT // EnclaveVerifyAttestationReport( UINT32 EnclaveType, const VOID *Report, UINT32 ReportSize ); [DllImport(Lib.VertDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("winenclaveapi.h", MSDNShortId = "D74F89FB-9F06-4AA1-9E2E-C9265B3C5B44")] public static extern HRESULT EnclaveVerifyAttestationReport(uint EnclaveType, IntPtr Report, uint ReportSize); /// Initializes an enclave that you created and loaded with data. /// A handle to the process for which the enclave was created. /// Any address within the enclave. /// /// A pointer to architecture-specific information to use to initialize the enclave. /// For the ENCLAVE_TYPE_SGX enclave type, specify a pointer to an ENCLAVE_INIT_INFO_SGX structure. /// For the ENCLAVE_TYPE_VBS enclave type, specify a pointer to an ENCLAVE_INIT_INFO_VBS structure. /// /// /// The length of the structure that the lpEnclaveInformation parameter points to, in bytes. For the ENCLAVE_TYPE_SGX enclave /// type, this value must be 4096. For the ENCLAVE_TYPE_VBS enclave type, this value must be , which is 8 bytes. /// /// /// An optional pointer to a variable that receives an enclave error code that is architecture-specific. /// /// For the ENCLAVE_TYPE_SGX enclave type, the lpEnclaveError parameter contains the error that the EINIT instruction /// generated if the function fails and . GetLastError returns ERROR_ENCLAVE_FAILURE. /// /// For the ENCLAVE_TYPE_VBS enclave type, the lpEnclaveError parameter is not used. /// /// /// /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error /// information, call GetLastError. /// /// For a list of common error codes, see System Error Codes. The following error codes also apply for this function. /// /// /// /// Return code /// Description /// /// /// ERROR_ENCLAVE_FAILURE /// /// An failure specific to the underlying enclave architecture occurred. The value for the lpEnclaveError parameter contains the /// architecture-specific error. For the ENCLAVE_TYPE_SGX enclave type, the EINIT instruction that the ENCLAVE_INIT_INFO_SGX /// structure specified generated an error. The value of the lpEnclaveError parameter contains the error that the instruction generated. /// /// /// /// ERROR_BAD_LENGTH /// /// The value of the dwInfoLength parameter did not match the value expected based on the value specified for the /// lpEnclaveInformation parameter. /// /// /// /// ERROR_RETRY /// The processor was not able to initialize the enclave in a timely fashion. Try to initialize the enclave again. /// /// /// /// // BOOL WINAPI InitializeEnclave( _In_ HANDLE hProcess, _In_ LPVOID lpAddress, _In_ LPVOID lpEnclaveInformation, _In_ DWORD // dwInfoLength, _In_ LPDWORD lpEnclaveError); https://msdn.microsoft.com/en-us/library/windows/desktop/mt592869(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt592869")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitializeEnclave(HPROCESS hProcess, IntPtr lpAddress, in ENCLAVE_INIT_INFO_SGX lpEnclaveInformation, uint dwInfoLength, ref uint lpEnclaveError); /// Initializes an enclave that you created and loaded with data. /// A handle to the process for which the enclave was created. /// Any address within the enclave. /// /// A pointer to architecture-specific information to use to initialize the enclave. /// For the ENCLAVE_TYPE_SGX enclave type, specify a pointer to an ENCLAVE_INIT_INFO_SGX structure. /// For the ENCLAVE_TYPE_VBS enclave type, specify a pointer to an ENCLAVE_INIT_INFO_VBS structure. /// /// /// The length of the structure that the lpEnclaveInformation parameter points to, in bytes. For the ENCLAVE_TYPE_SGX enclave /// type, this value must be 4096. For the ENCLAVE_TYPE_VBS enclave type, this value must be , which is 8 bytes. /// /// /// An optional pointer to a variable that receives an enclave error code that is architecture-specific. /// /// For the ENCLAVE_TYPE_SGX enclave type, the lpEnclaveError parameter contains the error that the EINIT instruction /// generated if the function fails and . GetLastError returns ERROR_ENCLAVE_FAILURE. /// /// For the ENCLAVE_TYPE_VBS enclave type, the lpEnclaveError parameter is not used. /// /// /// /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error /// information, call GetLastError. /// /// For a list of common error codes, see System Error Codes. The following error codes also apply for this function. /// /// /// /// Return code /// Description /// /// /// ERROR_ENCLAVE_FAILURE /// /// An failure specific to the underlying enclave architecture occurred. The value for the lpEnclaveError parameter contains the /// architecture-specific error. For the ENCLAVE_TYPE_SGX enclave type, the EINIT instruction that the ENCLAVE_INIT_INFO_SGX /// structure specified generated an error. The value of the lpEnclaveError parameter contains the error that the instruction generated. /// /// /// /// ERROR_BAD_LENGTH /// /// The value of the dwInfoLength parameter did not match the value expected based on the value specified for the /// lpEnclaveInformation parameter. /// /// /// /// ERROR_RETRY /// The processor was not able to initialize the enclave in a timely fashion. Try to initialize the enclave again. /// /// /// /// // BOOL WINAPI InitializeEnclave( _In_ HANDLE hProcess, _In_ LPVOID lpAddress, _In_ LPVOID lpEnclaveInformation, _In_ DWORD // dwInfoLength, _In_ LPDWORD lpEnclaveError); https://msdn.microsoft.com/en-us/library/windows/desktop/mt592869(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt592869")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitializeEnclave(HPROCESS hProcess, IntPtr lpAddress, in ENCLAVE_INIT_INFO_VBS lpEnclaveInformation, uint dwInfoLength, ref uint lpEnclaveError); /// Retrieves whether the specified type of enclave is supported. /// /// The type of enclave to check. /// /// /// /// Value /// Meaning /// /// /// ENCLAVE_TYPE_SGX0x00000001 /// An enclave for the Intel Software Guard Extensions (SGX) architecture extension. /// /// /// ENCLAVE_TYPE_VBS0x00000010 /// A virtualization-based security (VBS) enclave. /// /// /// /// /// /// /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error /// information, call GetLastError. /// /// For a list of common error codes, see System Error Codes. The following error codes also apply for this function. /// /// /// /// Return code /// Description /// /// /// ERROR_NOT_SUPPORTED /// An unsupported enclave type was specified. /// /// /// /// // BOOL WINAPI IsEnclaveTypeSupported( _In_ DWORD flEnclaveType); https://msdn.microsoft.com/en-us/library/windows/desktop/mt592870(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt592870")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsEnclaveTypeSupported(EnclaveType flEnclaveType); /// Loads data into an uninitialized enclave that you created by calling CreateEnclave. /// A handle to the process for which the enclave was created. /// The address in the enclave where you want to load the data. /// A pointer to the data the you want to load into the enclave. /// /// The size of the data that you want to load into the enclave, in bytes. This value must be a whole-number multiple of the page size. /// /// /// /// The memory protection to use for the pages that you want to add to the enclave. For a list of memory protection values, see /// memory protection constants. This value must not include the following constants: /// /// This value can include the enclave specific constants that the following table describes. /// /// /// /// Constant /// Description /// /// /// PAGE_ENCLAVE_THREAD_CONTROL /// The page contains a thread control structure (TCS). /// /// /// PAGE_ENCLAVE_UNVALIDATED /// /// The page contents that you supply are excluded from measurement with the EEXTEND instruction of the Intel Software Guard /// Extensions programming model. /// /// /// /// /// /// /// A pointer to information that describes the pages that you want to add to the enclave. The lpPageInformation parameter is not used. /// /// /// The length of the structure that the lpPageInformation parameter points to, in bytes. This value must be 0. /// /// /// A pointer to a variable that receives the number of bytes that LoadEnclaveData copied into the enclave. /// /// /// An optional pointer to a variable that receives an enclave error code that is architecture-specific. The lpEnclaveError parameter /// is not used. /// /// /// /// If all of the data is loaded into the enclave successfully, the return value is nonzero. Otherwise, the return value is zero. To /// get extended error information, call GetLastError. /// /// For a list of common error codes, see System Error Codes. The following error codes also apply for this function. /// /// /// /// Return code /// Description /// /// /// ERROR_BAD_LENGTH /// /// The value of the dwInfoLength parameter did not match the value expected based on the value specified for the lpPageInformation parameter. /// /// /// /// /// // BOOL WINAPI LoadEnclaveData( _In_ HANDLE hProcess, _In_ LPVOID lpAddress, _In_ LPCVOID lpBuffer, _In_ SIZE_T nSize, _In_ DWORD // flProtect, _In_ LPCVOID lpPageInformation, _In_ DWORD dwInfoLength, _Out_ PSIZE_T lpNumberOfBytesWritten, _Out_opt_ LPDWORD // lpEnclaveError); https://msdn.microsoft.com/en-us/library/windows/desktop/mt592871(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt592871")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool LoadEnclaveData(HPROCESS hProcess, IntPtr lpAddress, IntPtr lpBuffer, SizeT nSize, MEM_PROTECTION flProtect, IntPtr lpPageInformation, uint dwInfoLength, out SizeT lpNumberOfBytesWritten, out uint lpEnclaveError); /// Loads an image and all of its imports into an enclave. /// The base address of the image into which to load the image. /// A NULL-terminated string that contains the name of the image to load. /// TRUE if the function succeeds; otherwise FALSE. To get extended error information, call GetLastError. // BOOL WINAPI LoadEnclaveImage( _In_ LPVOID lpEnclaveAddress, _In_ LPCSTR lpImageName); https://msdn.microsoft.com/en-us/library/windows/desktop/mt844248(v=vs.85).aspx [DllImport(Lib.VertDll, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt844248")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool LoadEnclaveImage(IntPtr lpEnclaveAddress, string lpImageName); /// Ends the execution of the threads that are running within an enclave. /// The base address of the enclave in which to end the execution of the threads. /// /// TRUE if TerminateEnclave should not return until all of the threads in the enclave end execution. FALSE if /// TerminateEnclave should return immediately. /// /// TRUE if the function succeeds; otherwise FALSE. To get extended error information, call GetLastError. // BOOL WINAPI TerminateEnclave( _In_ LPVOID lpAddress, _In_ BOOL fWait); https://msdn.microsoft.com/en-us/library/windows/desktop/mt844249(v=vs.85).aspx [DllImport(Lib.VertDll, SetLastError = true, ExactSpelling = true)] [PInvokeData("Enclaveapi.h", MSDNShortId = "mt844249")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool TerminateEnclave(IntPtr lpAddress, [MarshalAs(UnmanagedType.Bool)] bool fWait); /// /// Contains architecture-specific information to use to create an enclave when the enclave type is ENCLAVE_TYPE_SGX, which /// specifies an enclave for the Intel Software Guard Extensions (SGX) architecture extension. /// // typedef struct _ENCLAVE_CREATE_INFO_SGX { UCHAR Secs[4096];} ENCLAVE_CREATE_INFO_SGX, *PENCLAVE_CREATE_INFO_SGX; https://msdn.microsoft.com/en-us/library/windows/desktop/mt592867(v=vs.85).aspx [PInvokeData("Winnt.h", MSDNShortId = "mt592867")] [StructLayout(LayoutKind.Sequential)] public struct ENCLAVE_CREATE_INFO_SGX { /// The SGX enclave control structure ( SECS) to use to create the enclave. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)] public byte[] Secs; } /// /// Contains architecture-specific information to use to create an enclave when the enclave type is ENCLAVE_TYPE_VBS, which /// specifies a virtualization-based security (VBS) enclave. /// // typedef struct _ENCLAVE_CREATE_INFO_VBS { ULONG Flags; UCHAR OwnerID[32]; } ENCLAVE_CREATE_INFO_VBS, *PENCLAVE_CREATE_INFO_VBS; https://msdn.microsoft.com/en-us/library/windows/desktop/mt844238(v=vs.85).aspx [PInvokeData("Winnt.h", MSDNShortId = "mt844238")] [StructLayout(LayoutKind.Sequential)] public struct ENCLAVE_CREATE_INFO_VBS { /// /// A flag that indicates whether the enclave permits debugging. /// /// /// /// Value /// Meaning /// /// /// ENCLAVE_VBS_FLAG_DEBUG0x00000001 /// The enclave permits debugging. /// /// /// 0x00000000 /// The enclave does not permit debugging. /// /// /// /// public ENCLAVE_VBS_FLAG Flags; /// The identifier of the owner of the enclave. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] OwnerID; } /// Describes the identity of the primary module of an enclave. // https://docs.microsoft.com/en-us/windows/win32/api/ntenclv/ns-ntenclv-enclave_identity typedef struct ENCLAVE_IDENTITY { UINT8 // OwnerId[IMAGE_ENCLAVE_LONG_ID_LENGTH]; UINT8 UniqueId[IMAGE_ENCLAVE_LONG_ID_LENGTH]; UINT8 AuthorId[IMAGE_ENCLAVE_LONG_ID_LENGTH]; // UINT8 FamilyId[IMAGE_ENCLAVE_SHORT_ID_LENGTH]; UINT8 ImageId[IMAGE_ENCLAVE_SHORT_ID_LENGTH]; UINT32 EnclaveSvn; UINT32 // SecureKernelSvn; UINT32 PlatformSvn; UINT32 Flags; UINT32 SigningLevel; UINT32 EnclaveType; } ENCLAVE_IDENTITY; [PInvokeData("ntenclv.h", MSDNShortId = "D584D824-3C86-4BBB-9086-6DBE0290E0A4")] [StructLayout(LayoutKind.Sequential)] public struct ENCLAVE_IDENTITY { /// The identifier of the owner for the enclave. [MarshalAs(UnmanagedType.ByValArray, SizeConst = IMAGE_ENCLAVE_LONG_ID_LENGTH)] public byte[] OwnerId; /// The unique identifier of the primary module for the enclave. [MarshalAs(UnmanagedType.ByValArray, SizeConst = IMAGE_ENCLAVE_LONG_ID_LENGTH)] public byte[] UniqueId; /// The author identifier of the primary module for the enclave. [MarshalAs(UnmanagedType.ByValArray, SizeConst = IMAGE_ENCLAVE_LONG_ID_LENGTH)] public byte[] AuthorId; /// The family identifier of the primary module for the enclave. [MarshalAs(UnmanagedType.ByValArray, SizeConst = IMAGE_ENCLAVE_SHORT_ID_LENGTH)] public byte[] FamilyId; /// The image identifier of the primary module for the enclave. [MarshalAs(UnmanagedType.ByValArray, SizeConst = IMAGE_ENCLAVE_SHORT_ID_LENGTH)] public byte[] ImageId; /// The security version number of the primary module for the enclave. public uint EnclaveSvn; /// The security version number of the Virtual Secure Mode (VSM) kernel. public uint SecureKernelSvn; /// The security version number of the platform that hosts the enclave. public uint PlatformSvn; /// /// Flags that describe the runtime policy for the enclave. /// /// /// Value /// Meaning /// /// /// ENCLAVE_FLAG_FULL_DEBUG_ENABLED 0x00000001 /// The enclave supports debugging. /// /// /// ENCLAVE_FLAG_DYNAMIC_DEBUG_ENABLED 0x00000002 /// The enclave supports dynamic debugging. /// /// /// ENCLAVE_FLAG_DYNAMIC_DEBUG_ACTIVE 0x00000004 /// Dynamic debugging is turned on for the enclave. /// /// /// public uint Flags; /// The signing level of the primary module for the enclave. public uint SigningLevel; /// public uint EnclaveType; } /// Contains information about the currently executing enclave. // https://docs.microsoft.com/en-us/windows/win32/api/ntenclv/ns-ntenclv-enclave_information typedef struct ENCLAVE_INFORMATION { // ULONG EnclaveType; ULONG Reserved; PVOID BaseAddress; SIZE_T Size; ENCLAVE_IDENTITY Identity; } ENCLAVE_INFORMATION; [PInvokeData("ntenclv.h", MSDNShortId = "6720EDBE-6A0E-4192-A096-2ACA681E2AAF")] [StructLayout(LayoutKind.Sequential)] public struct ENCLAVE_INFORMATION { /// /// The architecture type of the enclave. /// /// /// Value /// Meaning /// /// /// ENCLAVE_TYPE_SGX 0x00000001 /// An enclave for the Intel Software Guard Extensions (SGX) architecture extension. /// /// /// ENCLAVE_TYPE_VBS 0x00000010 /// A VBS enclave. /// /// /// public uint EnclaveType; /// Reserved. public uint Reserved; /// A pointer to the base address of the enclave. public IntPtr BaseAddress; /// The size of the enclave, in bytes. public SizeT Size; /// The identity of the primary module of an enclave. public ENCLAVE_IDENTITY Identity; } /// /// Contains architecture-specific information to use to initialize an enclave when the enclave type is ENCLAVE_TYPE_SGX, /// which specifies an enclave for the Intel Software Guard Extensions (SGX) architecture extension. /// // typedef struct _ENCLAVE_INIT_INFO_SGX { UCHAR SigStruct[1808]; UCHAR Reserved1[240]; UCHAR EInitToken[304]; UCHAR Reserved2[744];} // ENCLAVE_INIT_INFO_SGX, *PENCLAVE_INIT_INFO_SGX; https://msdn.microsoft.com/en-us/library/windows/desktop/mt592868(v=vs.85).aspx [PInvokeData("Winnt.h", MSDNShortId = "mt592868")] [StructLayout(LayoutKind.Sequential)] public struct ENCLAVE_INIT_INFO_SGX { /// /// The enclave signature structure ( SIGSTRUCT) to use to initialize the enclave. This structure specifies information /// about the enclave from the enclave signer. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1808)] public byte[] SigStruct; /// Not used. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 240)] public byte[] Reserved1; /// /// The EINIT token structure ( EINITTOKEN) to use to initialize the enclave. The initialization operation uses this /// structure to verify that the enclave has permission to start. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 304)] public byte[] EInitToken; /// Not used. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1744)] public byte[] Reserved2; } /// /// Contains architecture-specific information to use to initialize an enclave when the enclave type is ENCLAVE_TYPE_VBS, /// which specifies a virtualization-based security (VBS) enclave. /// // typedef struct ENCLAVE_INIT_INFO_VBS { ULONG Length; ULONG ThreadCount; }; https://msdn.microsoft.com/en-us/library/windows/desktop/mt844241(v=vs.85).aspx [PInvokeData("Winnt.h", MSDNShortId = "mt844241")] [StructLayout(LayoutKind.Sequential)] public struct ENCLAVE_INIT_INFO_VBS { /// The total length of the ENCLAVE_INIT_INFO_VBS structure, in bytes. public uint Length; /// /// Upon entry to the InitializeEnclave function, specifies the number of threads to create in the enclave. Upon /// successful return from InitializeEnclave, contains the number of threads the function actually created. /// public uint ThreadCount; } /// Provides a for an enclave handle that is disposed using . public class SafeEnclaveHandle : SafeHANDLE { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeEnclaveHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeEnclaveHandle() : base() { } /// protected override bool InternalReleaseHandle() => DeleteEnclave(handle); } } }