将 Public 密钥 Mod 从英特尔 SGX 飞地复制到不受信任的区域

Copying a Public key Mod from an Intel SGX Enclave to Untrusted area

我正在开发一个 C 伪API,其中 Java 代码通过 JNI 调用 C 代码,在 JNI 中它连接到 Intel SGX Enclave。我有一个函数,我可以在其中创建一个 RSA 密钥对以供进一步使用。

创建 RSA 对:

sgx_status_t create_rsa_pair(){
unsigned char p_n[RSA_MOD_SIZE];
unsigned char p_d[RSA_MOD_SIZE];
unsigned char p_p[RSA_MOD_SIZE];
unsigned char p_q[RSA_MOD_SIZE];
unsigned char p_dmp1[RSA_MOD_SIZE];
unsigned char p_dmq1[RSA_MOD_SIZE];
unsigned char p_iqmp[RSA_MOD_SIZE];

int n_byte_size = RSA_MOD_SIZE;
long e = 65537;


sgx_status_t ret_create_key_params = sgx_create_rsa_key_pair(n_byte_size, sizeof(e), p_n, p_d, (unsigned char*)&e, p_p, p_q, p_dmp1, p_dmq1, p_iqmp);

if (ret_create_key_params != SGX_SUCCESS) {
    ocall_print("Key param generation failed");
}

//void *private_key = NULL;

sgx_status_t ret_create_private_key = sgx_create_rsa_priv2_key(n_byte_size, sizeof(e), (unsigned char*)&e, p_p, p_q, p_dmp1, p_dmq1, p_iqmp, &private_rsa);

if(ret_create_private_key != SGX_SUCCESS) {
    ocall_print("Private key generation failed");
}

void *public_key = NULL;

sgx_status_t ret_create_public_key = sgx_create_rsa_pub1_key(n_byte_size, sizeof(e), p_n, (unsigned char*)&e, &public_key);

if(ret_create_public_key != SGX_SUCCESS) {
    ocall_print("Public key generation failed");
}

//Copy the result and send it in an ocall.
uint8_t* ocall_mod = (uint8_t*)malloc(RSA_MOD_SIZE);
uint8_t* ocall_exp = (uint8_t*)malloc(sizeof(long));
memcpy(ocall_mod,p_n,RSA_MOD_SIZE);
memcpy(ocall_exp,&e,sizeof(long));
printf("pre/ocall_mod::");
for(int i = 0; i < RSA_MOD_SIZE;i++){
    printf("%"PRIu8",",ocall_mod[i]);
}
printf("\n");
ocall_return_pubkey(ocall_mod,ocall_exp);
return SGX_SUCCESS;
}

电话号码:

void ocall_return_pubkey(uint8_t* key_mod,long *key_exp){
  printf("Post/Ocall key-mod:: ");
  for(int i = 0; i < RSA_PUBLIC_SIZE;i++)
    printf("%"PRIu8",",key_mod[i]);
   printf("\n");

现在,如果我编译它并检查终端结果:

pre/ocall_mod::199,100,141,174,148,185,21,88,102,216,116,190,170,232,156,196,107,78,228,1,5,38,92,154,20,11,234,149,74,19,254,237,240,223,145,92,188,248,25

Post/Ocall key-mod:: 199,0,0,0,0,0,0,0,0,0,57,44,0,127,0,0,0,83,144,167,247,127,0,0,9,107,99,240,0,0,0,0,172,141,193,3,0,0,0,0,68,83,144,167,247

为简洁起见,我只发布了 mod 的一部分,但信息似乎确实已损坏或删除,尤其是考虑到大量 0。

我已经尝试通过 Ecall 传递一个指针作为参数,以便通过它接收我的结果,但是(至少在这种情况下),由于此副本从受信任到不受信任,飞地阻止了程序执行内存,这意味着通过 ocall 从 enclave 发送指针似乎是唯一的选择。对此有任何帮助或提示吗? 提前致谢。

编辑:单独说明一下,如果所有代码都用于单个函数(加密、解密 + 创建 AES 密钥),我编写的所有代码都有效,但如果它被分成多个函数,它就会失败,出于某种原因。

使用 ocalls 获取 return 信息不是解决此问题的方法。

虽然我之前的这个想法失败了,但方法是将指针及其大小添加到函数参数以复制结果。

所以 飞地 EDL

public sgx_status_t whatever([out,size=output_size]uint8_t* output,size_t output_size)

现在,请记住 output_size 不是写入的字节数。通过在使用 Ecall 之前设置 output_size = 0,enclave 内的相应缓冲区将为 NULL,return 在使用时引发段错误。 如果在任何时候你需要写入的字节数,即加密,你应该使用以下内容:

sgx_status_t encrypt([out,size=output_size]uint8_t *output, size_t output_size, [out,size=num_size]size_t* bytes_written,size_t num_size);

其中num_size应该等于sizeof(size_t).

我解决了这个问题,希望对大家有帮助。