/* * Copyright (C) 2011-2017 Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.challa * */ #define SGX_DH_MAC_SIZE 16 #define SGX_TARGET_INFO_RESERVED1_BYTES 4 #define SGX_TARGET_INFO_RESERVED2_BYTES 456 #define SGX_ECP256_KEY_SIZE 32 #define SGX_CPUSVN_SIZE 16 #define SGX_REPORT_DATA_SIZE 64 #define SGX_MAC_SIZE 16 /* Message Authentication Code - 16 bytes */ #define SGX_KEYID_SIZE 32 #define SGX_HASH_SIZE 32 /* SHA256 */ #define SGX_REPORT_BODY_RESERVED1 28 #define SGX_REPORT_BODY_RESERVED2 32 #define SGX_REPORT_BODY_RESERVED3 96 #define SGX_REPORT_BODY_RESERVED4 60 // App.cpp : Defines the entry point for the console application. #include #include #include "../Decryptor/Decryptor_u.h" #include "sgx_eid.h" #include "sgx_urts.h" #define __STDC_FORMAT_MACROS #include #include // for sealing - sgx_calc_sealed_data_size #include "sgx_tseal.h" // For socket programming #include #include #include #include #include #include // For reading from/writing to file -sealing. #include #include #include // For google proto buffers #include "dhmsgs.pb.h" #include #include #include #include "SgxProtobufLATransforms_initiator.h" using namespace google::protobuf::io; //#define UNUSED(val) (void)(val) #define TCHAR char #define _TCHAR char #define _T(str) str #define scanf_s scanf // Not sure if I need this later - as such, I (decryptor app) will only ever need to talk to 1 enclave at a time - verifier enclave first and then the apache enclave. //extern std::mapg_enclave_id_map; sgx_enclave_id_t e2_enclave_id = 0; #define Decryptor_PATH "libDecryptor.so" ////////////////////////////////////////////////// // For google proto buffers #include "dhmsgs.pb.h" #include #include #include using namespace google::protobuf::io; #include //#include "sgx_eid.h" //#include "sgx_urts.h" int fit_32_into_uint8_t(google::protobuf::uint32 temp32, uint8_t* temp8) { if(temp32 > UINT8_MAX) return -1; else { // *temp8 = *(uint8_t*)&temp32; // Probably works irrespective of endianness but not sure. *temp8 = (uint8_t)temp32; return 0; } } int fit_32_into_uint16_t(google::protobuf::uint32 temp32, uint16_t* temp16) { if(temp32 > UINT16_MAX) return -1; else { // *temp8 = *(uint8_t*)&temp32; // Probably works irrespective of endianness but not sure. *temp16 = (uint16_t)temp32; return 0; } } void encode_ec256_public_key_to_protobuf(protobuf_sgx_ec256_public_t* protobuf_g_a , sgx_ec256_public_t* g_a) { int counter; google::protobuf::uint32 temp32; for(counter=0;countergx[counter]; protobuf_g_a->add_gx(temp32); temp32 = g_a->gy[counter]; protobuf_g_a->add_gy(temp32); } } int decode_ec256_public_key_from_protobuf(protobuf_sgx_ec256_public_t* protobuf_g_a , sgx_ec256_public_t* g_a) { printf("\n ec256 pub key\n"); int counter; google::protobuf::uint32 temp32; for(counter=0;countergx(counter); if(fit_32_into_uint8_t(temp32, &(g_a->gx[counter]))!=0) return -1; printf("%d ",g_a->gx[counter]); temp32 = protobuf_g_a->gy(counter); if(fit_32_into_uint8_t(temp32, &(g_a->gy[counter]))!=0) return -1; printf("%d ",g_a->gy[counter]); } return 0; } void encode_attributes_to_protobuf(protobuf_sgx_attributes_t* protobuf_attributes, sgx_attributes_t* attributes) { protobuf_attributes->set_flags(attributes->flags); // 64 bit protobuf_attributes->set_xfrm(attributes->xfrm); // 64 bit } int decode_attributes_from_protobuf(protobuf_sgx_attributes_t* protobuf_attributes, sgx_attributes_t* attributes) { attributes->flags = protobuf_attributes->flags(); printf("\n flags %" PRIu64 " \n", attributes->flags); attributes->xfrm = protobuf_attributes->xfrm(); printf("\n xfrm %" PRIu64 " \n", attributes->xfrm); return 0; } void encode_report_to_protobuf(protobuf_sgx_report_t* protobuf_report, sgx_report_t* report) { int counter; google::protobuf::uint32 temp32; for(counter=0;counterkey_id.id[counter]; protobuf_report->add_key_id(temp32); } for(counter=0;countermac[counter]; protobuf_report->add_mac(temp32); } protobuf_report->mutable_body()->set_misc_select(report->body.misc_select); // 32 bit protobuf_report->mutable_body()->set_isv_svn(report->body.isv_svn); // 16 bit protobuf_report->mutable_body()->set_isv_prod_id(report->body.isv_prod_id); // 16 bit encode_attributes_to_protobuf(protobuf_report->mutable_body()->mutable_attributes(), &(report->body.attributes)); for(counter=0;counterbody.cpu_svn.svn[counter]; protobuf_report->mutable_body()->add_cpu_svn(temp32); } for(counter=0;counterbody.reserved1[counter]; // TODO: Could be optimized out - if these are determined to be 0s. protobuf_report->mutable_body()->add_reserved1(temp32); } for(counter=0;counterbody.reserved2[counter]; // TODO: Could be optimized out - if these are determined to be 0s. protobuf_report->mutable_body()->add_reserved2(temp32); } for(counter=0;counterbody.reserved3[counter]; // TODO: Could be optimized out - if these are determined to be 0s. protobuf_report->mutable_body()->add_reserved3(temp32); } for(counter=0;counterbody.reserved4[counter]; // TODO: Could be optimized out - if these are determined to be 0s. protobuf_report->mutable_body()->add_reserved4(temp32); } for(counter=0;counterbody.mr_enclave.m[counter]; protobuf_report->mutable_body()->add_mr_enclave(temp32); } for(counter=0;counterbody.mr_signer.m[counter]; protobuf_report->mutable_body()->add_mr_signer(temp32); } for(counter=0;counterbody.report_data.d[counter]; protobuf_report->mutable_body()->add_report_data(temp32); } } int decode_report_from_protobuf(protobuf_sgx_report_t* protobuf_report, sgx_report_t* report) { int counter; google::protobuf::uint32 temp32; printf("\nreport body keyid\n"); for(counter=0;counterkey_id(counter); if(fit_32_into_uint8_t(temp32, &(report->key_id.id[counter]))!=0) return -1; printf("%d ", report->key_id.id[counter]); } printf("\nreport mac\n"); for(counter=0;countermac(counter); if(fit_32_into_uint8_t(temp32, &(report->mac[counter]))!=0) return -1; printf("%d ", report->mac[counter]); } report->body.misc_select=protobuf_report->mutable_body()->misc_select(); // 32 bit temp32=protobuf_report->mutable_body()->isv_svn(); if(fit_32_into_uint16_t(temp32, &(report->body.isv_svn))!=0) return -1; printf("\nmisc select %d \n", report->body.misc_select); temp32=protobuf_report->mutable_body()->isv_prod_id(); if(fit_32_into_uint16_t(temp32, &(report->body.isv_prod_id))!=0) return -1; printf("\nprod id %d \n", report->body.isv_prod_id); decode_attributes_from_protobuf(protobuf_report->mutable_body()->mutable_attributes(), &(report->body.attributes)); printf("\n cpu svn\n"); for(counter=0;countermutable_body()->cpu_svn(counter); if(fit_32_into_uint8_t(temp32, &(report->body.cpu_svn.svn[counter]))!=0) return -1; printf("%d ", report->body.cpu_svn.svn[counter]); } printf("\n reserved1 \n"); for(counter=0;countermutable_body()->reserved1(counter); if(fit_32_into_uint8_t(temp32, &(report->body.reserved1[counter]))!=0) return -1; printf("%d ", report->body.reserved1[counter]); } printf("\n reserved2 \n"); for(counter=0;countermutable_body()->reserved2(counter); if(fit_32_into_uint8_t(temp32, &(report->body.reserved2[counter]))!=0) return -1; printf("%d ", report->body.reserved2[counter]); } printf("\n reserved3 \n"); for(counter=0;countermutable_body()->reserved3(counter); if(fit_32_into_uint8_t(temp32, &(report->body.reserved3[counter]))!=0) return -1; printf("%d ", report->body.reserved3[counter]); } printf("\n reserved4 \n"); for(counter=0;countermutable_body()->reserved4(counter); if(fit_32_into_uint8_t(temp32, &(report->body.reserved4[counter]))!=0) return -1; printf("%d ", report->body.reserved4[counter]); } printf("\n mrenclave \n"); for(counter=0;countermutable_body()->mr_enclave(counter); if(fit_32_into_uint8_t(temp32, &(report->body.mr_enclave.m[counter]))!=0) return -1; printf("%x ", report->body.mr_enclave.m[counter]); } printf("\n mrsigner \n"); for(counter=0;countermutable_body()->mr_signer(counter); if(fit_32_into_uint8_t(temp32, &(report->body.mr_signer.m[counter]))!=0) return -1; printf("%x ", report->body.mr_signer.m[counter]); } printf("\n report data\n"); for(counter=0;countermutable_body()->report_data(counter); if(fit_32_into_uint8_t(temp32, &(report->body.report_data.d[counter]))!=0) return -1; printf("%d ", report->body.report_data.d[counter]); } return 0; } void encode_msg1_to_protobuf( protobuf_sgx_dh_msg1_t& protobuf_dhmsg1, sgx_dh_msg1_t* native_dhmsg1) { int counter; google::protobuf::uint32 temp32; // google::protobuf::uint64 temp64; encode_ec256_public_key_to_protobuf(protobuf_dhmsg1.mutable_g_a(), &(native_dhmsg1->g_a)); for(counter=0;countertarget.mr_enclave.m[counter]; protobuf_dhmsg1.mutable_target()->add_mr_enclave(temp32); } for(counter=0;countertarget.reserved1[counter]; protobuf_dhmsg1.mutable_target()->add_reserved1(temp32); } for(counter=0;countertarget.reserved2[counter]; protobuf_dhmsg1.mutable_target()->add_reserved2(temp32); } encode_attributes_to_protobuf(protobuf_dhmsg1.mutable_target()->mutable_attributes(), &(native_dhmsg1->target.attributes)); temp32=native_dhmsg1->target.misc_select ; protobuf_dhmsg1.mutable_target()->set_misc_select(temp32); } void encode_msg3_to_protobuf(protobuf_sgx_dh_msg3_t& protobuf_dhmsg3, sgx_dh_msg3_t* native_dhmsg3) { int counter; google::protobuf::uint32 temp32; for(counter=0;countercmac[counter]; protobuf_dhmsg3.add_cmac(temp32); } encode_report_to_protobuf(protobuf_dhmsg3.mutable_msg3_body()->mutable_report(), &(native_dhmsg3->msg3_body.report)); int max_counter=native_dhmsg3->msg3_body.additional_prop_length; unsigned char*temp; for(counter=0,temp=native_dhmsg3->msg3_body.additional_prop;counteradd_additional_prop(*temp); } } int decode_msg2_from_protobuf(protobuf_sgx_dh_msg2_t& protobuf_dhmsg2, sgx_dh_msg2_t* native_dhmsg2) { int counter; google::protobuf::uint32 temp32; //google::protobuf::uint64 temp64; printf("\ncmac\n"); for(counter=0;countercmac[counter]))!=0) return -1; printf("%d ",native_dhmsg2->cmac[counter]); } if(decode_ec256_public_key_from_protobuf(protobuf_dhmsg2.mutable_g_b(), &(native_dhmsg2->g_b)) !=0) return -1; if(decode_report_from_protobuf(protobuf_dhmsg2.mutable_report(), &(native_dhmsg2->report)) !=0) return -1; return 0; } int print_initialized_msg1( protobuf_sgx_dh_msg1_t& protobuf_dhmsg1, sgx_dh_msg1_t* native_dhmsg1) { int counter; printf("gx\n"); for(counter=0;counterg_a.gx[counter]); } printf("\ngy\n"); for(counter=0;counterg_a.gy[counter]); } printf("\nmrenclave in target\n"); for(counter=0;countertarget.mr_enclave.m[counter]); } printf("\nreserved1 in target\n"); for(counter=0;countertarget.reserved1[counter]); } printf("\nreserved2 in target\n"); for(counter=0;countertarget.reserved2[counter]); } printf("\n %" PRIu64 "\n", native_dhmsg1->target.attributes.flags); printf("\n %" PRIu64 "\n", protobuf_dhmsg1.target().attributes().flags()); printf("\n %" PRIu64 "\n", native_dhmsg1->target.attributes.xfrm); printf("\n %" PRIu64 "\n", protobuf_dhmsg1.target().attributes().xfrm()); printf("\n %" PRIu32 "\n", native_dhmsg1->target.misc_select); printf("\n %" PRIu32 "\n", protobuf_dhmsg1.target().misc_select()); return 0; } int read_protobuf_msg_from_fd(int accept_fd, google::protobuf::MessageLite& message) { ZeroCopyInputStream* raw_input; CodedInputStream* coded_input; uint32_t size; CodedInputStream::Limit limit; raw_input = new FileInputStream(accept_fd); coded_input = new CodedInputStream(raw_input); if(!coded_input->ReadVarint32(&size)) { printf("Error in reading size of msg"); fflush(stdout); return -1; } //printf("size of msg was read to be %" PRIu32 " \n", size); fflush(stdout); limit = coded_input->PushLimit(size); if(!message.ParseFromCodedStream(coded_input)) { printf("Error in parsing msg"); fflush(stdout); return -1; } coded_input->PopLimit(limit); return 0; } int write_protobuf_msg_to_fd(int accept_fd, google::protobuf::MessageLite& message) { ZeroCopyOutputStream* raw_output = new FileOutputStream(accept_fd); CodedOutputStream* coded_output = new CodedOutputStream(raw_output); coded_output->WriteVarint32(message.ByteSize()); if(!message.SerializeToCodedStream(coded_output)) { printf("SerializeToCodedStream failed"); fflush(stdout); return -1; } // As per this - https://stackoverflow.com/questions/22881876/protocol-buffers-how-to-serialize-and-deserialize-multiple-messages-into-a-file?noredirect=1&lq=1 // TODO: There may be a better way to do this - 1) this happens with every accept now and 2) make it happen on the stack vs heap - destructor will be called on return from this function (main) and the items will then be written out. (We probably don't want that, actually) delete coded_output; delete raw_output; fflush(stdout); return 0; } ///////////// TRY TO INCLUDE RIGHT SGX HEADERS IN SGX_PROTOBUF CPP uint32_t write_to_fd(int fd, uint8_t* msg, uint32_t* expected_msg_length) { ssize_t bytes_written; bytes_written = write(fd, msg, *expected_msg_length); if(bytes_written <= 0) return 0xFFFFFFFF; fsync(fd); *expected_msg_length = bytes_written; return 0; } uint32_t read_from_fd(int fd, uint8_t* msg, uint32_t* expected_msg_length) { ssize_t bytes_read; lseek(fd, 0, SEEK_SET); bytes_read = read(fd, msg, *expected_msg_length); if(bytes_read <= 0) return 0xFFFFFFFF; return 0; } // Sets up a socket to bind and listen to the given port. Returns FD of the socket on success, -1 on failure (and prints a msg to stdout with the errno) int set_up_socket(int port, sockaddr_in* address) { int server_fd = 0; // Creating socket file descriptor for listening for attestation requests. server_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); if (server_fd == -1) { printf("Error in creating a socket - %d", errno); return -1; } // Preparing the address struct for binding address->sin_family = AF_INET; address->sin_addr.s_addr = INADDR_ANY; // Todo: should this be localhost? address->sin_port = htons(port); // memset(address->sin_zero,0,sizeof(address->sin_zero)); socklen_t addrlen = sizeof(*address); // Binding if (bind(server_fd, (sockaddr*)address, addrlen)<0) { printf("Error in binding %d - port was %d - ", errno, port); return -1; } // Listening if (listen(server_fd, 128) < 0) { printf("Error in listening %d", errno); return -1; } return server_fd; } int local_attestation_initiator(__attribute__((unused)) uint8_t* expected_mr_signer) { // declare msg1, msg2, msg3 protobuf objects and native SGX structs protobuf_sgx_dh_msg1_t protobuf_msg1; protobuf_sgx_dh_msg2_t protobuf_msg2; protobuf_sgx_dh_msg3_t protobuf_msg3; // For sgx - ecalls and storing msgs rcvd from pipes for processing. uint32_t session_id; sgx_dh_msg1_t dh_msg1; //Diffie-Hellman Message 1 sgx_dh_msg2_t dh_msg2; //Diffie-Hellman Message 2 sgx_dh_msg3_t dh_msg3; //Diffie-Hellman Message 3 sgx_key_128bit_t dh_aek; // Session Key // initializing native sgx structs memset(&dh_aek,0, sizeof(sgx_key_128bit_t)); memset(&dh_msg1, 0, sizeof(sgx_dh_msg1_t)); memset(&dh_msg2, 0, sizeof(sgx_dh_msg2_t)); memset(&dh_msg3, 0, sizeof(sgx_dh_msg3_t)); // For socket to listen to the Apache enclave. int apache_port = 3825; int server_fd=0; int accept_fd = 0; struct sockaddr_in own_addr; struct sockaddr_storage apache_addr; socklen_t apache_addr_size = sizeof(apache_addr); // int counter; server_fd=set_up_socket(apache_port, &own_addr); if(server_fd==-1) return -1; printf("Successfully set up a socket to communicate with the Apache enclave."); fflush(stdout); uint32_t ret_status; Decryptor_session_request(e2_enclave_id, &ret_status, &dh_msg1, &session_id); // TODO: Check Return status if(ret_status != SGX_SUCCESS) { printf("session request returned failure\n"); fflush(stdout); return 0xffffffff; } encode_msg1_to_protobuf(protobuf_msg1, &dh_msg1); print_initialized_msg1(protobuf_msg1, &dh_msg1); printf("Done initialization"); fflush(stdout); int no_of_msgs_xchanged=0; accept_fd = accept(server_fd, (struct sockaddr *)&apache_addr,&apache_addr_size); if (accept_fd <0) { printf("Error in accepting %d", errno); return -1; } do { if(no_of_msgs_xchanged==0){ if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg1)!=0) return -1; } else { printf("about to read msg2\n"); fflush(stdout); // read msg2 - if(read_protobuf_msg_from_fd(accept_fd, protobuf_msg2)!=0) return -1; if(decode_msg2_from_protobuf(protobuf_msg2, &dh_msg2)!=0) return -1; printf("Done reading and decoding msg2\n"); // process msg2 and generate msg3 Decryptor_exchange_report(e2_enclave_id, &ret_status, &dh_msg2, &dh_msg3, &session_id); if(ret_status!=SGX_SUCCESS) { fflush(stdout); printf("exchange report failed:%x\n", ret_status); fflush(stdout); return -1; } printf("return status %d", ret_status); fflush(stdout); // convert msg3 sgx_dh_msg3_t object to a protobuf msg3 object. encode_msg3_to_protobuf(protobuf_msg3, &dh_msg3); printf("about to write msg3\n"); fflush(stdout); // write msg3 - if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg3)!=0) return -1; no_of_msgs_xchanged+=1; } no_of_msgs_xchanged++; } while(no_of_msgs_xchanged!=3); printf("Out of while loop\n"); fflush(stdout); return 0; } /* uint32_t unseal_signing_key_pair_from_disk(int fd, __attribute__((unused)) sgx_ec256_public_t* pub_key, uint32_t* actual_sealed_msg_length) { uint32_t ret_status; uint8_t* sgx_sealed_msg; sgx_sealed_msg = (uint8_t*) malloc(*actual_sealed_msg_length); ret_status = read_from_fd(fd, sgx_sealed_msg, actual_sealed_msg_length); if(ret_status != 0) { free(sgx_sealed_msg); return 0xFFFFFFFF; } Decryptor_unseal_and_restore_sealed_signing_key_pair(e2_enclave_id, &ret_status, pub_key, sgx_sealed_msg, actual_sealed_msg_length); free(sgx_sealed_msg); return ret_status; } uint32_t create_and_seal_signing_key_pair_to_disk(int fd, sgx_ec256_public_t* pub_key, uint32_t* actual_sealed_msg_length) { uint32_t ret_status; // Generating a signing ECDSA key to sign the encryption key. Decryptor_calculate_sealed_data_size(e2_enclave_id, 3*SGX_ECP256_KEY_SIZE, actual_sealed_msg_length); // sgx_calc_sealed_data_size(0,3*SGX_ECP256_KEY_SIZE); if(*actual_sealed_msg_length == 0xFFFFFFFF) return 0xFFFFFFFF; printf("%x bytes for sealed msg\n", *actual_sealed_msg_length); fflush(stdout); uint8_t* sealed_data=(uint8_t*) malloc(*actual_sealed_msg_length); printf("Made call to sgx_calc_sealed_data_size\n"); fflush(stdout); Decryptor_create_and_seal_ecdsa_signing_key_pair(e2_enclave_id, &ret_status, (sgx_ec256_public_t*)pub_key, actual_sealed_msg_length, sealed_data); if(ret_status != SGX_SUCCESS) { printf("create_and_seal called returned an error: %x", ret_status); free(sealed_data); return 0xFFFFFFFF; } printf("It returned sgx_success\n"); fflush(stdout); ret_status = write_to_fd(fd, sealed_data, actual_sealed_msg_length); free(sealed_data); return ret_status; } */ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) { uint32_t ret_status; sgx_status_t status; // For sgx setup int launch_token_updated; sgx_launch_token_t launch_token; // uint8_t* pub_key = (uint8_t*) malloc(2*SGX_ECP256_KEY_SIZE); // sgx_ec256_public_t pub_key; // uint32_t actual_sealed_msg_length; status = sgx_create_enclave(Decryptor_PATH, SGX_DEBUG_FLAG, &launch_token, &launch_token_updated, &e2_enclave_id, NULL); if(status != SGX_SUCCESS) { printf("\nLoad Enclave Failure"); return -1; } printf("\nDecryptor - EnclaveID %" PRIx64, e2_enclave_id); fflush(stdout); ret_status=local_attestation_initiator(NULL); if(ret_status!=0) { printf("local attestation did not successfully return: %x\n", ret_status); fflush(stdout); return 0xFFFFFFFF; } /* int sealed_signing_key_fd = open("sealed_signing_key.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if(sealed_signing_key_fd == -1) { perror("\nError in opening the file sealed_signing_key.txt - "); fflush(stderr); return 0xFFFFFFFF; } printf("\nSuccessfully opened a file to seal the signing key pair for the client.\n"); fflush(stdout); int start = lseek(sealed_signing_key_fd, 0, SEEK_CUR); int end = lseek(sealed_signing_key_fd, 0, SEEK_END); if(start == end && start != -1) { // TODO: file is empty. create signing key pair. start = lseek(sealed_signing_key_fd, 0, SEEK_CUR); ret_status = create_and_seal_signing_key_pair_to_disk(sealed_signing_key_fd, &pub_key, &actual_sealed_msg_length); if(ret_status != 0) { printf("\n error in generating the ecdsa signing key pair \n"); fflush(stdout); return 0xFFFFFFFF; } fflush(stdout); printf("\n Generated the ecdsa key pair successfully - gx, gy\n"); fflush(stdout); } else { start = lseek(sealed_signing_key_fd, 0, SEEK_CUR); if(actual_sealed_msg_length == 0) actual_sealed_msg_length = end - start; ret_status = unseal_signing_key_pair_from_disk(sealed_signing_key_fd, &pub_key, &actual_sealed_msg_length); if(ret_status != SGX_SUCCESS) { printf("\n error in unsealing the ecdsa signing key pair:%d \n", ret_status); fflush(stdout); return 0xFFFFFFFF; } printf("\n Recovered the ecdsa key pair successfully - gx, gy\n"); fflush(stdout); } */ // TODO: Continue with other msgs - send sign(enc | verifier mr_enclave) sgx_destroy_enclave(e2_enclave_id); return 0; }