/* Adapted from sample code SampleEnclave/App/App.cpp in the SGX SDK: */ /* * Copyright (C) 2011-2021 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. * */ #include #include #include #include # include # include # define MAX_PATH FILENAME_MAX #define ENCLAVE_FILENAME "enclave.signed.so" #include "sgx_error.h" #include "sgx_urts.h" #include "sgx_tcrypto.h" #include "sgx_tseal.h" #include "Untrusted.hpp" #include "Enclave_u.h" /* Global EID shared by multiple threads */ sgx_enclave_id_t global_eid = 0; typedef struct _sgx_errlist_t { sgx_status_t err; const char *msg; const char *sug; /* Suggestion */ } sgx_errlist_t; /* Error code returned by sgx_create_enclave */ static sgx_errlist_t sgx_errlist[] = { { SGX_ERROR_UNEXPECTED, "Unexpected error occurred.", NULL }, { SGX_ERROR_INVALID_PARAMETER, "Invalid parameter.", NULL }, { SGX_ERROR_OUT_OF_MEMORY, "Out of memory.", NULL }, { SGX_ERROR_ENCLAVE_LOST, "Power transition occurred.", "Please refer to the sample \"PowerTransition\" for details." }, { SGX_ERROR_INVALID_ENCLAVE, "Invalid enclave image.", NULL }, { SGX_ERROR_INVALID_ENCLAVE_ID, "Invalid enclave identification.", NULL }, { SGX_ERROR_INVALID_SIGNATURE, "Invalid enclave signature.", NULL }, { SGX_ERROR_OUT_OF_EPC, "Out of EPC memory.", NULL }, { SGX_ERROR_NO_DEVICE, "Invalid SGX device.", "Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards." }, { SGX_ERROR_MEMORY_MAP_CONFLICT, "Memory map conflicted.", NULL }, { SGX_ERROR_INVALID_METADATA, "Invalid enclave metadata.", NULL }, { SGX_ERROR_DEVICE_BUSY, "SGX device was busy.", NULL }, { SGX_ERROR_INVALID_VERSION, "Enclave version was invalid.", NULL }, { SGX_ERROR_INVALID_ATTRIBUTE, "Enclave was not authorized.", NULL }, { SGX_ERROR_ENCLAVE_FILE_ACCESS, "Can't open enclave file.", NULL }, { SGX_ERROR_MEMORY_MAP_FAILURE, "Failed to reserve memory for the enclave.", NULL }, }; /* Check error conditions for loading enclave */ void print_error_message(sgx_status_t ret) { size_t idx = 0; size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0]; for (idx = 0; idx < ttl; idx++) { if(ret == sgx_errlist[idx].err) { if(NULL != sgx_errlist[idx].sug) printf("Info: %s\n", sgx_errlist[idx].sug); printf("Error: %s\n", sgx_errlist[idx].msg); break; } } if (idx == ttl) printf("Error code is 0x%X. Please refer to the \"Intel SGX SDK Developer Reference\" for more details.\n", ret); } /* Initialize the enclave: * Call sgx_create_enclave to initialize an enclave instance */ int initialize_enclave(void) { sgx_status_t ret = SGX_ERROR_UNEXPECTED; /* Call sgx_create_enclave to initialize an enclave instance */ /* Debug Support: set 2nd parameter to 1 */ ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, NULL, NULL, &global_eid, NULL); if (ret != SGX_SUCCESS) { print_error_message(ret); return -1; } return 0; } void ocall_print_string(const char *str) { printf("%s", str); } /* Print the given string, prefixed with the current time, and return the * current time. */ unsigned long ocall_print_string_with_rtclock(const char *str) { struct timespec tp; clock_gettime(CLOCK_REALTIME_COARSE, &tp); unsigned long now = tp.tv_sec * 1000000 + tp.tv_nsec/1000; printf("%lu.%06lu: %s", tp.tv_sec, tp.tv_nsec/1000, str); return now; } /* Print the given string, prefixed with the current time, and return the * current time. Also print the time difference to the provided time. */ unsigned long ocall_print_string_with_rtclock_diff(const char *str, unsigned long before) { struct timespec tp; clock_gettime(CLOCK_REALTIME_COARSE, &tp); unsigned long now = tp.tv_sec * 1000000 + tp.tv_nsec/1000; unsigned long diff = now - before; printf("%lu.%06lu: (%lu.%06lu) %s", tp.tv_sec, tp.tv_nsec/1000, diff/1000000, diff%1000000, str); return now; } void ecall_identity_key_new(sgx_ec256_public_t* outpub, sgx_sealed_data_t* outsealedpriv) { ecall_identity_key_new(global_eid, outpub, outsealedpriv); } bool ecall_identity_key_load(sgx_ec256_public_t* outpub, const sgx_sealed_data_t* insealedpriv) { bool ret; ecall_identity_key_load(global_eid, &ret, outpub, insealedpriv); return ret; } bool ecall_config_load(threadid_t nthreads, struct EnclaveAPIParams *apiparams, struct EnclaveAPINodeConfig *apinodeconfigs, nodenum_t num_nodes, nodenum_t my_node_num) { bool ret; ecall_config_load(global_eid, &ret, nthreads, apiparams, apinodeconfigs, num_nodes, my_node_num); return ret; } void ecall_close() { ecall_close(global_eid); } bool ecall_comms_start(std::function cb) { std::function *p = new std::function; *p = cb; bool ret; ecall_comms_start(global_eid, &ret, p); return ret; } bool ecall_message(nodenum_t node_num, uint32_t message_len) { bool ret; ecall_message(global_eid, &ret, node_num, message_len); return ret; } bool ecall_chunk(nodenum_t node_num, const uint8_t *chunkdata, uint32_t chunklen) { bool ret; ecall_chunk(global_eid, &ret, node_num, chunkdata, chunklen); return ret; } size_t ecall_precompute_sort(int sizeidx) { size_t ret; ecall_precompute_sort(global_eid, &ret, sizeidx); return ret; } bool ecall_ingest_raw(uint8_t *msgs, uint32_t num_msgs) { bool ret; ecall_ingest_raw(global_eid, &ret, msgs, num_msgs); return ret; } void ecall_routing_proceed(std::function cb) { std::function *p = new std::function; *p = cb; ecall_routing_proceed(global_eid, p); } void ocall_comms_ready(void *cbpointer) { std::function *p = (std::function *)cbpointer; std::function f = *p; delete p; f(); } void ocall_routing_round_complete(void *cbpointer, uint32_t round_num) { std::function *p = (std::function *)cbpointer; std::function f = *p; delete p; f(round_num); } bool ecall_ingest_msgbundle(clientid_t cid, unsigned char *msgbundle, uint32_t num_msgs) { bool ret; ecall_ingest_msgbundle(global_eid, &ret, cid, msgbundle, num_msgs); return ret; } bool ecall_ingestion_authenticate(clientid_t cid, unsigned char *auth_string) { bool ret; ecall_ingestion_authenticate(global_eid, &ret, cid, auth_string); return ret; } bool ecall_storage_authenticate(clientid_t cid, unsigned char *auth_string) { bool ret; ecall_storage_authenticate(global_eid, &ret, cid, auth_string); return ret; } void ecall_supply_storage_buffers(unsigned char *mailboxes, uint32_t mailboxes_size, unsigned char *tokens, uint32_t tokens_size) { ecall_supply_storage_buffers(global_eid, mailboxes, mailboxes_size, tokens, tokens_size); }