将公钥 Mod 从 Intel SGX Enclave 复制到不受信任的区域
我正在开发一个 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;
}
Ocall 代码:
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 传递一个指针作为参数,以便通过它接收我的结果,但是(至少在这种情况下),由于此副本从可信内存到不可信内存,飞地会阻止程序执行,这意味着发送从 enclave 通过 ocall 的指针似乎是唯一的选择。对此有什么帮助或提示吗? 提前致谢。
编辑:在一个单独的说明中,如果我编写的所有代码全部用于单个函数(加密、解密+创建 AES 密钥),那么我编写的所有代码都可以工作,但是如果它被分成多个函数,那么由于某种原因,它会失败。
I am developing a C pseudo-API in which Java code calls C code through the JNI, in which it connects to an Intel SGX Enclave. I have a function in which I create an RSA-Key pair to be used further on.
Create RSA Pair:
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;
}
Ocall code:
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");
Now, If I compile this and check terminal results:
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
I've posted only a portion of the mod for brevity's sake, but the information does seem to be corrupted or deleted, especially considering the large number of 0's.
I've tried passing a pointer throught the Ecall as an argument in order to receive my result through it, but (at least in this scenario), the enclave blocks the program execution due to this copy from trusted to untrusted memory, meaning that sending a pointer from the enclave through an ocall seems like the only option. Any help or tips for this?
Thanks in advance.
Edit: On a separate note, All the code I've written works if all used in a single function (Encryption, Decryption + Creation of an AES key), but if it is separated into multiple functions, it fails, for some reason.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用 ocalls 返回信息并不是解决此问题的方法。
虽然我之前的想法失败了,但解决方法是向函数参数添加一个指针及其大小,以便复制结果。
所以
Enclave EDL
现在,请记住,output_size 不是写入的字节数。通过在使用 Ecall 之前设置 output_size = 0,enclave 内的相应缓冲区将为 NULL,在使用时返回段错误。
如果在任何时候您需要写入的字节数,即加密,您应该使用以下内容:
其中 num_size 应等于 sizeof(size_t)。
我能够解决这个问题,希望对你们有帮助。
Using ocalls to return information is not the way to go for this.
While I had failed previously with this Idea, the way to go is by adding a pointer and its size to a functions arguments in order to copy the results.
so
Enclave EDL
Now, bear in mind that output_size is not the number of bytes written. By setting output_size = 0 before using the Ecall, the corresponding buffer inside the enclave will be NULL, returning a segfault upon usage.
if at any point you require the number of bytes written, i.e encryption, you should use the following:
In which num_size should be equal to sizeof(size_t).
I was able to solve this problem, Hope it helps you guys.