SGX Enclave向外部传递可变大小缓冲区的EDL函数定义问题
Got it, let's break down how to properly define your pass_buffer function in SGX EDL—handling dynamic output buffers can be tricky at first, but I’ve worked through this exact scenario before.
Step 1: Correct EDL Function Definition
Here’s the precise EDL syntax you need, with explanations for each parameter attribute:
enclave { public { void pass_buffer( [out, alloc, size=buffer_out_len] void** buffer_out, [out] size_t* buffer_out_len, [in, size=buffer_in_len] const void* buffer_in, [in] size_t buffer_in_len ); }; };
Let’s unpack the attributes to understand why they matter:
[out, alloc, size=buffer_out_len] void** buffer_out:outmarks this as an output parameter that the Enclave will populate.alloctells SGX the Enclave will allocate memory for this buffer (using SGX’s specializedsgx_ocallocinstead of standardmalloc).size=buffer_out_lenlinks the buffer’s size to the output length parameter, so SGX knows exactly how much data to copy from the Enclave to the untrusted side.
[out] size_t* buffer_out_len: This stores the length of the returned buffer—we set this value before allocating the output buffer in the Enclave.[in, size=buffer_in_len] const void* buffer_in:inflags it as input, andsize=buffer_in_lenspecifies the input buffer’s length so SGX can safely copy it into the Enclave.[in] size_t buffer_in_len: The explicit length of the input buffer, paired with the previous parameter’ssizeattribute to validate the input.
Step 2: Enclave-Side Implementation
When writing the Enclave function, use SGX’s dedicated allocation function to ensure the buffer can be safely passed back to the untrusted side:
#include "sgx_trts.h" // For sgx_ocalloc #include <string.h> // For memcpy/memset void pass_buffer(void** buffer_out, size_t* buffer_out_len, const void* buffer_in, size_t buffer_in_len) { // First: Calculate your required output buffer size (replace this with your actual logic) // Example: Return a buffer twice the input size, with original data + zero padding *buffer_out_len = buffer_in_len * 2; // Allocate the output buffer with sgx_ocalloc (critical for cross-enclave memory safety) *buffer_out = sgx_ocalloc(*buffer_out_len); if (*buffer_out == NULL) { // Handle allocation failure: reset length to 0 to signal error to the untrusted side *buffer_out_len = 0; return; } // Process the input data (replace this with your Enclave-specific logic) memcpy(*buffer_out, buffer_in, buffer_in_len); memset((uint8_t*)*buffer_out + buffer_in_len, 0, buffer_in_len); }
Key rule: Never use standard malloc/free for buffers passed to the untrusted side—sgx_ocalloc allocates memory in the untrusted heap, which the untrusted code can safely free later.
Step 3: Untrusted Side Call
When calling the function from the untrusted application, initialize the buffer pointer to NULL and remember to free it with sgx_free after use:
#include "sgx_urts.h" // For sgx_enclave_id_t, sgx_status_t, sgx_free #include <stdio.h> void example_enclave_call(sgx_enclave_id_t enclave_id) { const uint8_t input_data[] = "Hello SGX!"; size_t input_len = sizeof(input_data); void* output_buffer = NULL; size_t output_len = 0; // Call the Enclave function sgx_status_t ret = sgx_pass_buffer(enclave_id, &output_buffer, &output_len, input_data, input_len); if (ret != SGX_SUCCESS || output_buffer == NULL || output_len == 0) { printf("Error calling pass_buffer!\n"); return; } // Use the output buffer here (e.g., print or process data) printf("Output buffer length: %zu\n", output_len); printf("Output data: %s\n", (char*)output_buffer); // Free the allocated buffer (must use sgx_free, not standard free()) sgx_free(output_buffer); }
Critical Reminders
- Always initialize
buffer_outtoNULLbefore calling the function—SGX will overwrite it with the allocated pointer. - Set
buffer_out_lenbefore allocating the output buffer in the Enclave, so thesizeattribute in EDL has a valid value to reference. - Always check for allocation failures in the Enclave and handle them gracefully (resetting
buffer_out_lento 0 is a clear way to signal an error to the untrusted side).
内容的提问来源于stack exchange,提问作者Guilherme Borges

