将可变大小缓冲区从 SGX 飞地传递到外部

Pass variable-size buffer from SGX enclave to outside

我正在尝试使用以下原型做一个函数:

void pass_buffer(void** buffer_out, size_t* buffer_out_len, const void* buffer_in, size_t buffer_in_len);

所以想法是将一个缓冲区传递到飞地中,然后 return 另一个缓冲区中的响应,其大小可以不同,该大小存储在 buffer_out_len.

我在定义 EDL 函数时遇到问题。所以我的想法是做类似的事情:

public void pass_buffer([out]void** buffer_out, [out]size_t* buffer_out_len, [in, size = buffer_in_len]const void* buffer_in, size_t buffer_in_len);

现在,只有 return 一个缓冲区充满了一个。我知道我应该使用 size 参数传递缓冲区的长度,但不允许在 size 中使用指针:

public void pass_buffer([out, size = *buffer_out_len]void** buffer_out, [out]size_t* buffer_out_len, [in, size = buffer_in_len]const void* buffer_in, size_t buffer_in_len);

我的最后一个解决方案是否可以使用另一种语法?或者也许通过使 return 值成为 size_t buffer_out_len?如果是这样,我如何从 [out] 中的 size 参数引用它?

或者也许有另一种方法可以实现这种行为?初始化一个可变大小的缓冲区并将其传递给外部?非常感谢。

据我所知,您无法按照您的意愿去做。调用函数时,ecall 函数似乎需要知道带有 [out] 属性的缓冲区的大小。这也是为什么您的最后一个解决方案不起作用的原因,大小函数或变量是在函数调用时计算的。

我看到有两种方法可以解决您的问题,要么使用预先确定的足够大小的缓冲区,要么声明一个具有可变大小参数的 ocall 函数,然后从您的 ecall 函数的代码中调用它 "set" 您的return 值。这是第二种解决方案的(未经测试的)示例:

在您的 .edl 文件中:

untrusted {
  public void get_buffer([in, size = buffer_in_len] void* buffer_in, size_t buffer_in_len);
};

trusted {
  void set_buffer([in, size = buffer_len] void* buffer, size_t buffer_len);
};

在你的飞地中:

void get_buffer(void* buffer_in, size_t buffer_in_len){
  [...]
  set_buffer(my_buffer, my_buffer_len);
}

我不确定这是最优的,但这是我最终使用的解决方案。