diff --git a/src/libos/src/config.rs b/src/libos/src/config.rs index cc45487e..6b766d6e 100644 --- a/src/libos/src/config.rs +++ b/src/libos/src/config.rs @@ -45,23 +45,15 @@ pub fn load_config(config_path: &str, expected_mac: &sgx_aes_gcm_128bit_tag_t) - } // This value will be modified during occlum build -#[no_mangle] +#[used] #[link_section = ".builtin_config"] -static OCCLUM_JSON_MAC: [i8; 48] = [0; 48]; +static OCCLUM_JSON_MAC: [u8; 47] = [0; 47]; fn conf_get_hardcoded_file_mac() -> sgx_aes_gcm_128bit_tag_t { - assert!( - *OCCLUM_JSON_MAC.last().unwrap() == 0, - "must be a null-terminated C string" - ); - - let mac_str = unsafe { - CStr::from_ptr(&OCCLUM_JSON_MAC as *const i8) - .to_str() - .expect("MAC contains non UTF-8 characters") - }; - - let mac = parse_mac(mac_str).expect("MAC string cannot be converted to numbers"); + // Use black_box to avoid the compiler's optimization for OCCLUM_JSON_MAC + let json_mac = std::hint::black_box(&OCCLUM_JSON_MAC); + let mac_str = String::from_utf8(json_mac.to_vec()).expect("MAC contains non UTF-8 characters"); + let mac = parse_mac(&mac_str).expect("MAC string cannot be converted to numbers"); mac } diff --git a/src/libos/src/lib.rs b/src/libos/src/lib.rs index f2589114..bc8531be 100644 --- a/src/libos/src/lib.rs +++ b/src/libos/src/lib.rs @@ -18,6 +18,8 @@ #![feature(slice_ptr_get)] #![feature(maybe_uninit_extra)] #![feature(get_mut_unchecked)] +// for std::hint::black_box +#![feature(test)] #[macro_use] extern crate alloc; diff --git a/tools/occlum_build.mk b/tools/occlum_build.mk index edd27165..94cace4a 100644 --- a/tools/occlum_build.mk +++ b/tools/occlum_build.mk @@ -8,6 +8,7 @@ INITFS := $(instance_dir)/initfs INITFS_IMAGE := $(instance_dir)/build/initfs/__ROOT/metadata INITFS_IMAGE_MAC := $(instance_dir)/build/initfs/.ROOT_MAC JSON_CONF := $(instance_dir)/Occlum.json +CONF_TMP_MAC := $(instance_dir)/build/tmp_mac LIBOS := $(instance_dir)/build/lib/$(libos_lib).$(occlum_version) SIGNED_ENCLAVE := $(instance_dir)/build/lib/libocclum-libos.signed.so @@ -33,14 +34,9 @@ endif SHELL:=/bin/bash -define get_occlum_sys_conf_file_mac +define get_occlum_file_mac LD_LIBRARY_PATH="$(SGX_SDK)/sdk_libs" \ - "$(occlum_dir)/build/bin/occlum-protect-integrity" show-mac "$(instance_dir)/build/.Occlum_sys.json.protected" -endef - -define get_occlum_user_conf_file_mac - LD_LIBRARY_PATH="$(SGX_SDK)/sdk_libs" \ - "$(occlum_dir)/build/bin/occlum-protect-integrity" show-mac "$(instance_dir)/build/Occlum.json.protected" + "$(occlum_dir)/build/bin/occlum-protect-integrity" show-mac $(1) $(2) endef .PHONY : all clean @@ -60,13 +56,13 @@ $(SIGNED_ENCLAVE): $(LIBOS) $(LIBOS): $(instance_dir)/build/.Occlum_sys.json.protected @echo "Building libOS..." - @export OCCLUM_BUILTIN_SYS_CONF_FILE_MAC=`$(get_occlum_sys_conf_file_mac)` ; \ - cd $(instance_dir)/build/lib && \ - cp "$(occlum_dir)/build/lib/$(libos_lib).$(occlum_version)" . && ln -sf "$(libos_lib).$(occlum_version)" "libocclum-libos.so.$(major_ver)" && \ + @cd $(instance_dir)/build/lib && \ + cp "$(occlum_dir)/build/lib/$(libos_lib).$(occlum_version)" . && \ + ln -sf "$(libos_lib).$(occlum_version)" "libocclum-libos.so.$(major_ver)" && \ ln -sf "libocclum-libos.so.$(major_ver)" libocclum-libos.so ; \ - echo -e "$$OCCLUM_BUILTIN_SYS_CONF_FILE_MAC\c" > temp_mac_file && \ - objcopy --update-section .builtin_config=temp_mac_file libocclum-libos.so && \ - rm temp_mac_file + $(call get_occlum_file_mac, "$(instance_dir)/build/.Occlum_sys.json.protected", "$(CONF_TMP_MAC)") && \ + objcopy --update-section .builtin_config="$(CONF_TMP_MAC)" libocclum-libos.so && \ + rm -f "$(CONF_TMP_MAC)" $(instance_dir)/build/.Occlum_sys.json.protected: $(instance_dir)/build/.Occlum_sys.json @cd "$(instance_dir)/build" ; \ @@ -108,13 +104,13 @@ $(INITFS_IMAGE): $(INITFS) $(INITFS_DIRS) $(INITFS_FILES) $(IMAGE_CONFIG_JSON) $ "$(INITFS_IMAGE_MAC)" $(IMAGE_CONFIG_JSON): $(instance_dir)/build/Occlum.json.protected - @export OCCLUM_CONF_FILE_MAC=`$(get_occlum_user_conf_file_mac)` ; \ - echo "EXPORT => OCCLUM_CONF_FILE_MAC = $$OCCLUM_CONF_FILE_MAC" ; \ + @$(call get_occlum_file_mac, "$(instance_dir)/build/Occlum.json.protected", "$(CONF_TMP_MAC)") && \ [ -n "$(SECURE_IMAGE_KEY)" ] && \ - jq -n --arg mac_val "$$OCCLUM_CONF_FILE_MAC" \ + jq -n --arg mac_val "`cat $(CONF_TMP_MAC)`" \ '{image_type: "encrypted", occlum_json_mac: $$mac_val}' > $(IMAGE_CONFIG_JSON) || \ - jq -n --arg mac_val "$$OCCLUM_CONF_FILE_MAC" \ + jq -n --arg mac_val "`cat $(CONF_TMP_MAC)`" \ '{image_type: "integrity-only", occlum_json_mac: $$mac_val}' > $(IMAGE_CONFIG_JSON) + @rm -f "$(CONF_TMP_MAC)" $(instance_dir)/build/Occlum.json.protected: $(instance_dir)/build/Occlum.json @cd "$(instance_dir)/build" ; \ diff --git a/tools/protect-integrity/App/App.cpp b/tools/protect-integrity/App/App.cpp index 206116a2..bbf31459 100644 --- a/tools/protect-integrity/App/App.cpp +++ b/tools/protect-integrity/App/App.cpp @@ -218,19 +218,31 @@ static int initialize_enclave(void) { return 0; } + +// File stream for output buffer +static FILE *fp_output = NULL; + // ========================================================================== // OCalls // ========================================================================== void ocall_print(const char *str) { - printf("%s", str); + if (fp_output) { + fprintf(fp_output, "%s", str); + } else { + fprintf(stdout, "%s", str); + } } void ocall_eprint(const char *str) { fprintf(stderr, "%s", str); } -int ocall_open(const char *path) { +int ocall_open_for_write(const char *path) { + return open(path, O_WRONLY | O_CREAT | O_TRUNC, 00644); +} + +int ocall_open_for_read(const char *path) { return open(path, O_RDONLY); } @@ -256,8 +268,8 @@ static void print_help(void) { "\n" "Usage:\n" "\tprotect-integrity protect \n" - "\tprotect-integrity show \n" - "\tprotect-integrity show-mac \n"); + "\tprotect-integrity show []\n" + "\tprotect-integrity show-mac []\n"); } #define CMD_ERROR (-1) @@ -271,15 +283,23 @@ static int parse_args( char *argv[], /* outputs */ int *arg_command, - char **arg_file_path) { - if (argc != 3) { return -1; } + char **arg_file_path, + char **arg_output_path) { + if (argc < 3 || argc > 4) { return -1; } if (strcmp(argv[1], "protect") == 0) { + if (argc != 3) { return -1; } *arg_command = CMD_PROTECT; } else if (strcmp(argv[1], "show") == 0) { *arg_command = CMD_SHOW; + if (argc == 4) { + *arg_output_path = argv[3]; + } } else if (strcmp(argv[1], "show-mac") == 0) { *arg_command = CMD_SHOW_MAC; + if (argc == 4) { + *arg_output_path = argv[3]; + } } else { return -1; } @@ -296,7 +316,8 @@ int SGX_CDECL main(int argc, char *argv[]) { /* Parse arguments */ int arg_command = CMD_ERROR; char *arg_file_path = NULL; - if (parse_args(argc, argv, &arg_command, &arg_file_path) < 0) { + char *arg_output_path = NULL; + if (parse_args(argc, argv, &arg_command, &arg_file_path, &arg_output_path) < 0) { print_help(); return -1; } @@ -328,7 +349,8 @@ int SGX_CDECL main(int argc, char *argv[]) { } case CMD_SHOW: { const char *input_path = arg_file_path; - if (ecall_show(global_eid, &ret, input_path)) { + const char *output_path = arg_output_path; + if (ecall_show(global_eid, &ret, input_path, output_path)) { fprintf(stderr, "Error: ecall failed\n"); ret = -1; } @@ -336,10 +358,22 @@ int SGX_CDECL main(int argc, char *argv[]) { } case CMD_SHOW_MAC: { const char *input_path = arg_file_path; + const char *output_path = arg_output_path; + if (output_path) { + fp_output = fopen(output_path, "w"); + if (!fp_output) { + fprintf(stderr, "Error: failed to open %s for output \n", output_path); + ret = -1; + break; + } + } if (ecall_show_mac(global_eid, &ret, input_path)) { fprintf(stderr, "Error: ecall failed\n"); ret = -1; } + if (fp_output) { + fclose(fp_output); + } break; } default: { diff --git a/tools/protect-integrity/Enclave.edl b/tools/protect-integrity/Enclave.edl index 03c1fc3c..3e5bac74 100644 --- a/tools/protect-integrity/Enclave.edl +++ b/tools/protect-integrity/Enclave.edl @@ -8,13 +8,15 @@ enclave { trusted { public int ecall_protect([in, string] const char* input_path, [in, string] const char* ouput_path); - public int ecall_show([in, string] const char* input_path); + public int ecall_show([in, string] const char* input_path, + [in, string] const char* output_path); public int ecall_show_mac([in, string] const char* input_path); }; untrusted { // File operations - int ocall_open([in, string] const char* path); + int ocall_open_for_write([in, string] const char* path); + int ocall_open_for_read([in, string] const char* path); ssize_t ocall_read(int fd, [out, size=size] void* buf, size_t size); ssize_t ocall_write(int fd, [in, size=size] const void* buf, size_t size); int ocall_close(int fd); diff --git a/tools/protect-integrity/Enclave/Enclave.cpp b/tools/protect-integrity/Enclave/Enclave.cpp index 6bd3e2c0..b13d8afc 100644 --- a/tools/protect-integrity/Enclave/Enclave.cpp +++ b/tools/protect-integrity/Enclave/Enclave.cpp @@ -39,10 +39,15 @@ static void print_mac(sgx_aes_gcm_128bit_tag_t *mac) { printf("\n"); } - -static int open(const char *path) { +static int open_for_write(const char *path) { int fd = 0; - ocall_open(&fd, path); + ocall_open_for_write(&fd, path); + return fd; +} + +static int open_for_read(const char *path) { + int fd = 0; + ocall_open_for_read(&fd, path); return fd; } @@ -74,7 +79,7 @@ int ecall_protect(const char *input_path, const char *output_path) { size_t len; char buf[4 * 1024]; - input_file = open(input_path); + input_file = open_for_read(input_path); if (input_file < 0) { eprintf("Error: cannot open the input file at %s\n", input_path); goto on_error; @@ -107,9 +112,10 @@ on_error: return -1; } -int ecall_show(const char *protected_file_path) { +int ecall_show(const char *protected_file_path, const char *show_path) { SGX_FILE *protected_file = NULL; ssize_t len; + int output_fd = 1; /* stdout */ char buf[4 * 1024]; protected_file = sgx_fopen_integrity_only(protected_file_path, "r"); @@ -117,9 +123,16 @@ int ecall_show(const char *protected_file_path) { eprintf("Error: failed to open the given protected file %s\n", protected_file_path); goto on_error; } + if (show_path) { + output_fd = open_for_write(show_path); + if (output_fd < 0) { + eprintf("Error: failed to open the given show_path %s\n", show_path); + goto on_error; + } + } while ((len = sgx_fread(buf, 1, sizeof(buf), protected_file)) > 0) { - write(1/* stdout */, buf, len); + write(output_fd, buf, len); } if (sgx_ferror(protected_file)) { @@ -128,11 +141,17 @@ int ecall_show(const char *protected_file_path) { } sgx_fclose(protected_file); + if (output_fd > 1) { + close(output_fd); + } return 0; on_error: if (protected_file != NULL) { sgx_fclose(protected_file); } + if (output_fd > 1) { + close(output_fd); + } return -1; }