From 66e62650267e04b7fbd97f26ce056b93af51c6d4 Mon Sep 17 00:00:00 2001 From: Paul Zinselmeyer Date: Thu, 4 Jul 2024 21:05:55 +0200 Subject: [PATCH] [Assignment-7] App Intermediary and Proxy - Intermediary is fully functional - Proxy is ready until invocation of enclave --- 7-SGX_Hands-on/src/Makefile | 45 ++--- 7-SGX_Hands-on/src/app/intermediary.c | 202 ++++++++++---------- 7-SGX_Hands-on/src/app/intermediary_key.pem | 5 + 7-SGX_Hands-on/src/app/main.c | 2 +- 7-SGX_Hands-on/src/app/proxy.c | 74 ++++--- 7-SGX_Hands-on/src/app/util.c | 6 +- 7-SGX_Hands-on/src/app/util.h | 3 +- 7 files changed, 182 insertions(+), 155 deletions(-) create mode 100644 7-SGX_Hands-on/src/app/intermediary_key.pem diff --git a/7-SGX_Hands-on/src/Makefile b/7-SGX_Hands-on/src/Makefile index 756187f..7aea36b 100644 --- a/7-SGX_Hands-on/src/Makefile +++ b/7-SGX_Hands-on/src/Makefile @@ -74,8 +74,8 @@ else Urts_Library_Name := sgx_urts endif -App_C_Files := App/App.c -App_Include_Paths := -IInclude -IApp -I$(SGX_SDK)/include +App_C_Files := app/main.c app/proxy.c app/intermediary.c app/util.c +App_Include_Paths := -IInclude -Iapp -I$(SGX_SDK)/include App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) @@ -91,7 +91,8 @@ else App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG endif -App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread +Openssl_Link_Flags = `pkg-config --libs openssl` +App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread $(Openssl_Link_Flags) ifneq ($(SGX_MODE), HW) App_Link_Flags += -lsgx_uae_service_sim @@ -101,7 +102,7 @@ endif App_C_Objects := $(App_C_Files:.c=.o) -App_Name := app +App_Name := signatureproxy ######## Enclave Settings ######## @@ -115,8 +116,8 @@ else endif Crypto_Library_Name := sgx_tcrypto -Enclave_C_Files := Enclave/Enclave.c -Enclave_Include_Paths := -IInclude -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx +Enclave_C_Files := enclave/enclave.c +Enclave_Include_Paths := -IInclude -Ienclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx CC_BELOW_4_9 := $(shell expr "`$(CC) -dumpversion`" \< "4.9") ifeq ($(CC_BELOW_4_9), 1) @@ -141,13 +142,13 @@ Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefau -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ -Wl,-pie,-eenclave_entry -Wl,--export-dynamic \ -Wl,--defsym,__ImageBase=0 -Wl,--gc-sections \ - -Wl,--version-script=Enclave/Enclave.lds \ + -Wl,--version-script=enclave/enclave.lds \ Enclave_C_Objects := $(Enclave_C_Files:.c=.o) Enclave_Name := enclave.so Signed_Enclave_Name := enclave.signed.so -Enclave_Config_File := Enclave/Enclave.config.xml +Enclave_Config_File := enclave/enclave.config.xml ifeq ($(SGX_MODE), HW) ifeq ($(SGX_DEBUG), 1) @@ -200,49 +201,49 @@ endif ######## App Objects ######## -App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl - @cd App && $(SGX_EDGER8R) --untrusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include +app/enclave_u.c: $(SGX_EDGER8R) enclave/enclave.edl + @cd app && $(SGX_EDGER8R) --untrusted ../enclave/enclave.edl --search-path ../enclave --search-path $(SGX_SDK)/include @echo "GEN => $@" -App/Enclave_u.o: App/Enclave_u.c +app/enclave_u.o: app/enclave_u.c @$(CC) $(App_C_Flags) -c $< -o $@ @echo "CC <= $<" -App/%.o: App/%.c - @$(CC) $(App_C_Flags) -c $< -o $@ +app/%.o: app/%.c + @$(CC) $(app_C_Flags) -c $< -o $@ @echo "CC <= $<" -$(App_Name): App/Enclave_u.o $(App_C_Objects) +$(App_Name): app/enclave_u.o $(App_C_Objects) @$(CC) $^ -o $@ $(App_Link_Flags) @echo "LINK => $@" .config_$(Build_Mode)_$(SGX_ARCH): - @rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_C_Objects) App/Enclave_u.* $(Enclave_C_Objects) Enclave/Enclave_t.* + @rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_C_Objects) app/enclave_u.* $(Enclave_C_Objects) enclave/enclave_t.* @touch .config_$(Build_Mode)_$(SGX_ARCH) ######## Enclave Objects ######## -Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl - @cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include +enclave/enclave_t.c: $(SGX_EDGER8R) enclave/enclave.edl + @cd enclave && $(SGX_EDGER8R) --trusted ../enclave/enclave.edl --search-path ../enclave --search-path $(SGX_SDK)/include @echo "GEN => $@" -Enclave/Enclave_t.o: Enclave/Enclave_t.c +enclave/enclave_t.o: enclave/enclave_t.c @$(CC) $(Enclave_C_Flags) -c $< -o $@ @echo "CC <= $<" -Enclave/%.o: Enclave/%.c +enclave/%.o: enclave/%.c @$(CC) $(Enclave_C_Flags) -c $< -o $@ @echo "CC <= $<" -$(Enclave_Name): Enclave/Enclave_t.o $(Enclave_C_Objects) +$(Enclave_Name): enclave/enclave_t.o $(Enclave_C_Objects) @$(CC) $^ -o $@ $(Enclave_Link_Flags) @echo "LINK => $@" $(Signed_Enclave_Name): $(Enclave_Name) - @$(SGX_ENCLAVE_SIGNER) sign -key Enclave/Enclave_private.pem -enclave $(Enclave_Name) -out $@ -config $(Enclave_Config_File) + @$(SGX_ENCLAVE_SIGNER) sign -key enclave/enclave_private.pem -enclave $(Enclave_Name) -out $@ -config $(Enclave_Config_File) @echo "SIGN => $@" .PHONY: clean clean: - @rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_C_Objects) App/Enclave_u.* $(Enclave_C_Objects) Enclave/Enclave_t.* \ No newline at end of file + @rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_C_Objects) app/enclave_u.* $(Enclave_C_Objects) enclave/enclave_t.* diff --git a/7-SGX_Hands-on/src/app/intermediary.c b/7-SGX_Hands-on/src/app/intermediary.c index 01387ac..e299c40 100644 --- a/7-SGX_Hands-on/src/app/intermediary.c +++ b/7-SGX_Hands-on/src/app/intermediary.c @@ -5,149 +5,155 @@ #include #include -#include "enclave.h" #include "intermediary.h" #include "util.h" +#include +#include +#include +#include + #define HASH_BYTES 32 #define HASH_CHUNK_BYTES 32 #define KEY_BYTES 32 struct IntermediaryArgs { - char* firmware_path; char* key_path; - char* output_path; }; + +static int generate_key(EVP_PKEY** key) { + OSSL_PARAM key_params[2]; + EVP_PKEY_CTX* gctx; + + gctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + if (gctx == NULL) + return (1); + + if (EVP_PKEY_keygen_init(gctx) != 1) + return (2); + + key_params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, "prime256v1", 0); + key_params[1] = OSSL_PARAM_construct_end(); + + if (EVP_PKEY_CTX_set_params(gctx, key_params) != 1) + return (3); + + if(EVP_PKEY_generate(gctx, key) != 1) + return (4); + + EVP_PKEY_CTX_free(gctx); + return (0); +} + + char* intermediary_syntax(void) { - return + return "intermediary mock up implementation of the employee binary\n" - " -f file path to Firmware file\n" - " -k key file path\n" - " -o output file path\n"; + " expects firmware on stdin\n" + " outputs signature on stdout\n" + " -k key file path\n"; } int handle_intermediary(int argc, char** argv) { struct IntermediaryArgs args = { - NULL, - NULL, NULL }; - FILE* firmware_file; FILE* key_file; - FILE* output_file; - //uint8_t firmware_hash[HASH_BYTES]; uint8_t firmware_chunk[HASH_CHUNK_BYTES]; - uint8_t key[KEY_BYTES]; - //EVP_MD_CTX *mdctx; - //const EVP_MD *md; - //unsigned char md_value[EVP_MAX_MD_SIZE]; - //unsigned int md_len; + EVP_PKEY* key; + OSSL_PARAM key_params[2]; + EVP_PKEY_CTX* gctx; + EVP_MD_CTX *mdctx; + size_t sig_len; + unsigned char* sig; + + /* + * Parse Input + */ int i = 0; while(i < argc) { - if(strcmp(argv[i], "-f")==0 && argc-i >=2){ - args.firmware_path = argv[i+1]; - i += 2; - }else if(strcmp(argv[i], "-k")==0 && argc-i >=2){ + if(strcmp(argv[i], "-k")==0 && argc-i >=2){ args.key_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 syntax_exit(); } - if(args.firmware_path == NULL || args.key_path == NULL || args.output_path == NULL) + if(args.key_path == NULL) syntax_exit(); - firmware_file = fopen(args.firmware_path, "r"); - if(firmware_file == NULL){ - perror("Error opening firmware file"); - exit(1); - } - /* - md = EVP_sha3_256(); - mdctx = EVP_MD_CTX_new(); - if (!EVP_DigestSignInit(mdctx, NULL, md, NULL, key)) { - fprintf(stderr, "Message digest initialization failed.\n"); - EVP_MD_CTX_free(mdctx); - exit(1); - } - */ + * Load Signing Key + */ - size_t chunk_len = HASH_CHUNK_BYTES; - while(chunk_len==HASH_CHUNK_BYTES) { - chunk_len = fread(&firmware_chunk, HASH_CHUNK_BYTES, 1, firmware_file); - if(chunk_len!=HASH_CHUNK_BYTES&&ferror(firmware_file)!=0){ - perror("Failed to read firmware file"); - exit(1); - } - - /* - if (!EVP_DigestSignUpdate(mdctx, firmware_chunk, chunk_len)) { - printf("Message digest update failed.\n"); - EVP_MD_CTX_free(mdctx); - exit(1); - } - */ - } - - /* - if (!EVP_DigestSignFinal_ex(mdctx, md_value, &md_len)) { - printf("Message digest finalization failed.\n"); - EVP_MD_CTX_free(mdctx); - exit(1); - } - EVP_MD_CTX_free(mdctx); - - printf("Digest is: "); - for (i = 0; i < md_len; i++) - printf("%02x", md_value[i]); - printf("\n"); - */ - - key_file = fopen(args.key_path, "r"); + key_file = fopen(args.key_path, "rb"); if(key_file == NULL){ perror("Error opening key file"); exit(1); } - - size_t key_len = fread(&key, 1, KEY_BYTES, key_file); - if(ferror(key_file)!=0){ - perror("Failed to read key"); - exit(1); - } - if(key_len != KEY_BYTES){ - fprintf(stderr, "invalid key length\n"); + key = PEM_read_PrivateKey(key_file, &key, NULL, NULL); + if(key == NULL) { + fprintf(stderr, "failed to read key"); exit(1); } - //eckey = EC_KEY_new_by_curve_name(NID_secp256r1); - //if(eckey == NULL) { - // fprintf(stderr, "failed to initialize SECP256R1 key\n"); - // exit(1); - //} + /* + * Sign Firmware + */ - //if (!EC_KEY_generate_key(eckey)) { - // fprintf(stderr, "failed to generate key\n"); - // exit(1); - //} - //sig = ECDSA_do_sign(md_value, md_len, eckey); - //if (sig == NULL){ - // fprintf(stderr, "failed to sign firmware hash\n"); - // exit(1); - //} - - output_file = fopen(args.output_path, "w"); - if(output_file == NULL){ - perror("Error opening output file"); + mdctx = EVP_MD_CTX_new(); + if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, key) != 1) { + fprintf(stderr, "Message digest initialization failed.\n"); + EVP_MD_CTX_free(mdctx); exit(1); } - printf("intermediary %s %s %s", args.firmware_path, args.key_path, args.output_path); + size_t chunk_len = HASH_CHUNK_BYTES; + while(chunk_len==HASH_CHUNK_BYTES) { + chunk_len = fread(&firmware_chunk, HASH_CHUNK_BYTES, 1, stdin); + if(chunk_len!=HASH_CHUNK_BYTES&&ferror(stdin)!=0){ + perror("Failed to read firmware file"); + exit(1); + } + + if (EVP_DigestSignUpdate(mdctx, firmware_chunk, chunk_len) != 1) { + printf("Message digest update failed.\n"); + EVP_MD_CTX_free(mdctx); + exit(1); + } + } + + // call with empty sig to get length + if (EVP_DigestSignFinal(mdctx, NULL, &sig_len) != 1) { + printf("Message digest finalization failed.\n"); + EVP_MD_CTX_free(mdctx); + exit(1); + } + + // allocate signature buffer + sig = malloc(sizeof(unsigned char) * sig_len); + if(sig == NULL){ + perror("could not initialize digest buffer"); + exit(1); + } + + // load signature into buffer + if (EVP_DigestSignFinal(mdctx, sig, &sig_len) != 1) { + printf("Message digest finalization failed.\n"); + EVP_MD_CTX_free(mdctx); + exit(1); + } + + EVP_MD_CTX_free(mdctx); + + for (unsigned int i = 0; i < sig_len; i++) + printf("%02x", sig[i]); + printf("\n"); + + + EVP_PKEY_free(key); exit(0); } diff --git a/7-SGX_Hands-on/src/app/intermediary_key.pem b/7-SGX_Hands-on/src/app/intermediary_key.pem new file mode 100644 index 0000000..a46bfb6 --- /dev/null +++ b/7-SGX_Hands-on/src/app/intermediary_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIH0KXxaw/nRzJU5evlEJQrciYUtfJ16PILWtlA5KKh/koAoGCCqGSM49 +AwEHoUQDQgAEduVQXmH1K+ocSSnv0l9PKdC2+xxPQrVyABAYGk+jlo2hugpH8aWk +nfR9cTTOLy6T7ASx3a22S6DftcTz+aZYsg== +-----END EC PRIVATE KEY----- diff --git a/7-SGX_Hands-on/src/app/main.c b/7-SGX_Hands-on/src/app/main.c index 3daa211..abeb52d 100644 --- a/7-SGX_Hands-on/src/app/main.c +++ b/7-SGX_Hands-on/src/app/main.c @@ -9,7 +9,7 @@ int main(int argc, char** argv) { if(argc < 1) syntax_exit(); - BIN_NAME = argv[0]; + set_bin_name(argv[0]); if(argc < 2) syntax_exit(); diff --git a/7-SGX_Hands-on/src/app/proxy.c b/7-SGX_Hands-on/src/app/proxy.c index 7a529b2..4c12e37 100644 --- a/7-SGX_Hands-on/src/app/proxy.c +++ b/7-SGX_Hands-on/src/app/proxy.c @@ -4,15 +4,13 @@ #include #include -#include "enclave.h" +#include "../enclave/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; }; @@ -127,26 +125,28 @@ static int initialize_enclave(char* token_path) { sgx_status_t ret; int updated = 0; - sgx_token_file = fopen(token_path, "r"); + sgx_token_file = fopen(token_path, "rb"); if(sgx_token_file == NULL){ perror("Error opening sgx token file"); exit(1); } + //TODO create new on error / ignore missing token file + 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); + ret = sgx_create_enclave("enclave.signed.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); + sgx_token_file = freopen(token_path, "wb", sgx_token_file); if(sgx_token_file == NULL){ perror("Error opening sgx token file"); return (1); @@ -163,32 +163,32 @@ static int initialize_enclave(char* token_path) { 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" + " expects intermediary signature on stdin\n" + " outputs proxied signature on stdout\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* input_file = stdin; + FILE* output_file = stdout; FILE* sealed_key_file; + uint8_t *sealed; + uint32_t sealed_size; + char line[141]; + uint8_t signature[70]; + + /* + * Parse Input + */ 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){ + 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){ @@ -198,25 +198,28 @@ int handle_proxy(int argc, char** argv) { syntax_exit(); } - if(args.input_path == NULL || args.output_path == NULL || args.sealed_key_file_path == NULL || args.sgx_token_path == NULL) + if(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"); + if(fgets(line, 141, stdin) == NULL) { + fprintf(stderr, "failed to read signature from stdin"); exit(1); } - output_file = fopen(args.output_path, "w"); - if(output_file == NULL){ - perror("Error opening output file"); + if(line[140] != '\0') { + fprintf(stderr, "invalid input"); 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 + for (i = 0; i < 70; i++) { + sscanf(line+2*i, "%02x", &signature[i]); + } - sealed_key_file = fopen(args.sealed_key_file_path, "w"); + /* + * Initialize SGX Enclave + */ + + sealed_key_file = fopen(args.sealed_key_file_path, "rb"); if(sealed_key_file == NULL){ perror("Error opening sealed_key_file file"); exit(1); @@ -225,11 +228,20 @@ int handle_proxy(int argc, char** argv) { 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. + sealed_size = get_sealed_size(); + sealed = malloc(sizeof(uint8_t)*sealed_size); + if (sealed == NULL) { + fprintf(stderr, "failed to allocate for sealed key"); + exit(1); + } + + //TODO load sealed (what to do when missing?) + + //TODO call enclave //TODO store sealed key if changed //TODO write output + //TODO enclave teardown - printf("proxy %s %s", args.input_path, args.output_path); exit(0); } diff --git a/7-SGX_Hands-on/src/app/util.c b/7-SGX_Hands-on/src/app/util.c index 8d483a0..f5b5791 100644 --- a/7-SGX_Hands-on/src/app/util.c +++ b/7-SGX_Hands-on/src/app/util.c @@ -6,7 +6,7 @@ #include "intermediary.h" -char* BIN_NAME = "SignatureProxy"; +static char* BIN_NAME = "SignatureProxy"; void syntax_exit(void) { char* syntax = @@ -21,3 +21,7 @@ void syntax_exit(void) { printf(syntax, BIN_NAME, intermediary_syntax(), proxy_syntax()); exit(1); } + +void set_bin_name(char* bin_name) { + BIN_NAME = bin_name; +} diff --git a/7-SGX_Hands-on/src/app/util.h b/7-SGX_Hands-on/src/app/util.h index c447800..f1aa72e 100644 --- a/7-SGX_Hands-on/src/app/util.h +++ b/7-SGX_Hands-on/src/app/util.h @@ -2,12 +2,11 @@ #define _APP_UTIL_H_ -char* BIN_NAME; - /* * @brief prints the command syntax and exits with EXIT_FAILURE */ void syntax_exit(void); +void set_bin_name(char* bin_name); #endif