#include #include #include #include #include #include "enclave.h" #include "proxy.h" #include "util.h" sgx_enclave_id_t global_eid = 0; struct ProxyArgs { char* input_path; char* output_path; char* sealed_key_file_path; char* sgx_token_path; }; 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 }, }; /* Check error conditions for loading enclave */ static 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); } static int initialize_enclave(char* token_path) { FILE* sgx_token_file; sgx_launch_token_t token = {0}; sgx_status_t ret; int updated = 0; sgx_token_file = fopen(token_path, "r"); if(sgx_token_file == NULL){ perror("Error opening sgx token file"); exit(1); } size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), sgx_token_file); if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) { fprintf(stderr, "sgx token file is corrupted"); return (1); } ret = sgx_create_enclave("enclave.so", SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL); if (ret != SGX_SUCCESS) { print_error_message(ret); return (1); } if (updated) { sgx_token_file = freopen(token_path, "w", sgx_token_file); if(sgx_token_file == NULL){ perror("Error opening sgx token file"); return (1); } size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), sgx_token_file); if (write_num != sizeof(sgx_launch_token_t)){ fprintf(stderr,"Warning: Failed to save launch token to \"%s\".\n", token_path); return (1); } } return (0); } char* proxy_syntax(void) { return "proxy implementation of the enclave-powered SignatureProxy\n" " -i file path to the intermediary output(signature of firmware)\n" " -o output path of the signature\n" " -s file path of the sealed proxy key\n" " -t file path of the sgx token\n"; } int handle_proxy(int argc, char** argv) { struct ProxyArgs args = { NULL, NULL, NULL, NULL }; FILE* input_file; FILE* output_file; FILE* sealed_key_file; int i = 0; while(i < argc) { if(strcmp(argv[i], "-i")==0 && argc-i >=2){ args.input_path = argv[i+1]; i += 2; }else if(strcmp(argv[i], "-o")==0 && argc-i >=2){ args.output_path = argv[i+1]; i += 2; }else if(strcmp(argv[i], "-s")==0 && argc-i >=2){ args.sealed_key_file_path = argv[i+1]; i += 2; }else if(strcmp(argv[i], "-t")==0 && argc-i >=2){ args.sgx_token_path = argv[i+1]; i += 2; }else syntax_exit(); } if(args.input_path == NULL || args.output_path == NULL || args.sealed_key_file_path == NULL || args.sgx_token_path == NULL) syntax_exit(); input_file = fopen(args.input_path, "r"); if(input_file == NULL){ perror("Error opening input file"); exit(1); } output_file = fopen(args.output_path, "w"); if(output_file == NULL){ perror("Error opening output file"); exit(1); } //TODO read input -> calculate size of input (ECDSA of SHA3-256 of Firmware File, generated by intermediary) //TODO read sealed key -> calculate size or dynamic alloc sealed_key_file = fopen(args.sealed_key_file_path, "w"); if(sealed_key_file == NULL){ perror("Error opening sealed_key_file file"); exit(1); } if (initialize_enclave(args.sgx_token_path) != 0) exit(1); //TODO call enclave -> refactor interface to do verify and sign in one call to avoid trip through "untrusted" land. //TODO store sealed key if changed //TODO write output printf("proxy %s %s", args.input_path, args.output_path); exit(0); }