diff --git a/HACKING.md b/HACKING.md index da92dd4b..c938c044 100644 --- a/HACKING.md +++ b/HACKING.md @@ -23,12 +23,37 @@ so these references must be patched like this: sgx_tstd = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda" } ``` -However, also note that Cargo currently has this limitation: +### Cargo patch limitation workaround + +Ideally, we want to explicitly specify the tag or revision of the SGX-forked packages we use, +like this: + +```toml +serde = { git = "https://github.com/mesalock-linux/serde-sgx", tag = "sgx_1.1.3" } +``` + +However, this fails for packages that are also listed as dependencies of other SGX-forked packages +_without_ the explicit tag: Cargo will resolve these as different crates, which causes problems +(such as different crates referring to different versions of `serde`'s traits). + +We cannot use `[patch]` to override these dependencies to use the same specifiers, +because of this Cargo limitation: * [Cannot patch underspecified git dependency #7670](https://github.com/rust-lang/cargo/issues/7670) + * Comment: + +To work around this problem, our specifiers must exactly match the specifiers used by our dependencies' +dependency declarations. (That is, the `rev` / `tag` / `branch` values (or lack of them) must match.) + +Currently, at least these transitively-used dependencies must be specified exactly: -This prevents patching a repository reference to a different revision in the same repository, -which makes some SGX-patched packages (such as `serde-sgx` and `serde-json-sgx`) tricky to deal with. +```toml +once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx" } +serde = { git = "https://github.com/mesalock-linux/serde-sgx" } +serde-big-array = { git = "https://github.com/mesalock-linux/serde-big-array-sgx" } +serde_derive = { git = "https://github.com/mesalock-linux/serde-sgx" } +serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } +``` ## Aligned memory allocation for secret values diff --git a/codegen/auth_enclave/bindings.h b/codegen/auth_enclave/bindings.h index 949ef402..7b1b2bb4 100644 --- a/codegen/auth_enclave/bindings.h +++ b/codegen/auth_enclave/bindings.h @@ -18,6 +18,43 @@ #define SET_ACCESS_KEY_RESPONSE_SIZE 1 +typedef enum ExecTokenError { + EXEC_TOKEN_ERROR_GENERATE, + EXEC_TOKEN_ERROR_VALIDATION, + EXEC_TOKEN_ERROR_OUTPUT_BUFFER_SIZE, + EXEC_TOKEN_ERROR_CRYPTO, + EXEC_TOKEN_ERROR_IO, +} ExecTokenError; + +typedef uint8_t Nonce[24]; + +/** + * FFI safe result type that can be converted to and from a rust result. + */ +typedef enum EcallResult_Nonce__ExecTokenError_Tag { + ECALL_RESULT_NONCE_EXEC_TOKEN_ERROR_OK_NONCE_EXEC_TOKEN_ERROR, + ECALL_RESULT_NONCE_EXEC_TOKEN_ERROR_ERR_NONCE_EXEC_TOKEN_ERROR, +} EcallResult_Nonce__ExecTokenError_Tag; + +typedef struct EcallResult_Nonce__ExecTokenError { + EcallResult_Nonce__ExecTokenError_Tag tag; + union { + struct { + Nonce ok; + }; + struct { + enum ExecTokenError err; + }; + }; +} EcallResult_Nonce__ExecTokenError; + +typedef struct EcallResult_Nonce__ExecTokenError IssueTokenResult; + +typedef struct ExecReqMetadata { + uint8_t uploader_pub_key[32]; + Nonce nonce; +} ExecReqMetadata; + /** * FFI safe result type that can be converted to and from a rust result. */ diff --git a/codegen/auth_enclave/rtc_auth_t.c b/codegen/auth_enclave/rtc_auth_t.c index 81ff0a4b..fdab0226 100644 --- a/codegen/auth_enclave/rtc_auth_t.c +++ b/codegen/auth_enclave/rtc_auth_t.c @@ -34,6 +34,16 @@ typedef struct ms_enclave_create_report_t { sgx_report_t* ms_p_report; } ms_enclave_create_report_t; +typedef struct ms_issue_execution_token_t { + IssueTokenResult ms_retval; + const uint8_t* ms_payload_ptr; + size_t ms_payload_len; + const ExecReqMetadata* ms_metadata; + uint8_t* ms_out_token_ptr; + size_t ms_out_token_capacity; + size_t* ms_out_token_used; +} ms_issue_execution_token_t; + typedef struct ms_t_global_init_ecall_t { uint64_t ms_id; const uint8_t* ms_path; @@ -501,6 +511,69 @@ typedef struct ms_sgx_thread_set_multiple_untrusted_events_ocall_t { size_t ms_total; } ms_sgx_thread_set_multiple_untrusted_events_ocall_t; +typedef struct ms_u_sgxprotectedfs_exclusive_file_open_t { + void* ms_retval; + const char* ms_filename; + uint8_t ms_read_only; + int64_t* ms_file_size; + int32_t* ms_error_code; +} ms_u_sgxprotectedfs_exclusive_file_open_t; + +typedef struct ms_u_sgxprotectedfs_check_if_file_exists_t { + uint8_t ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_check_if_file_exists_t; + +typedef struct ms_u_sgxprotectedfs_fread_node_t { + int32_t ms_retval; + void* ms_f; + uint64_t ms_node_number; + uint8_t* ms_buffer; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_fread_node_t; + +typedef struct ms_u_sgxprotectedfs_fwrite_node_t { + int32_t ms_retval; + void* ms_f; + uint64_t ms_node_number; + uint8_t* ms_buffer; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_fwrite_node_t; + +typedef struct ms_u_sgxprotectedfs_fclose_t { + int32_t ms_retval; + void* ms_f; +} ms_u_sgxprotectedfs_fclose_t; + +typedef struct ms_u_sgxprotectedfs_fflush_t { + uint8_t ms_retval; + void* ms_f; +} ms_u_sgxprotectedfs_fflush_t; + +typedef struct ms_u_sgxprotectedfs_remove_t { + int32_t ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_remove_t; + +typedef struct ms_u_sgxprotectedfs_recovery_file_open_t { + void* ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_recovery_file_open_t; + +typedef struct ms_u_sgxprotectedfs_fwrite_recovery_node_t { + uint8_t ms_retval; + void* ms_f; + uint8_t* ms_data; + uint32_t ms_data_length; +} ms_u_sgxprotectedfs_fwrite_recovery_node_t; + +typedef struct ms_u_sgxprotectedfs_do_file_recovery_t { + int32_t ms_retval; + const char* ms_filename; + const char* ms_recovery_filename; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_do_file_recovery_t; + static sgx_status_t SGX_CDECL sgx_enclave_create_report(void* pms) { CHECK_REF_POINTER(pms, sizeof(ms_enclave_create_report_t)); @@ -580,6 +653,130 @@ static sgx_status_t SGX_CDECL sgx_enclave_create_report(void* pms) return status; } +static sgx_status_t SGX_CDECL sgx_issue_execution_token(void* pms) +{ + CHECK_REF_POINTER(pms, sizeof(ms_issue_execution_token_t)); + // + // fence after pointer checks + // + sgx_lfence(); + ms_issue_execution_token_t* ms = SGX_CAST(ms_issue_execution_token_t*, pms); + sgx_status_t status = SGX_SUCCESS; + const uint8_t* _tmp_payload_ptr = ms->ms_payload_ptr; + size_t _tmp_payload_len = ms->ms_payload_len; + size_t _len_payload_ptr = _tmp_payload_len * sizeof(uint8_t); + uint8_t* _in_payload_ptr = NULL; + const ExecReqMetadata* _tmp_metadata = ms->ms_metadata; + size_t _len_metadata = sizeof(ExecReqMetadata); + ExecReqMetadata* _in_metadata = NULL; + uint8_t* _tmp_out_token_ptr = ms->ms_out_token_ptr; + size_t _tmp_out_token_capacity = ms->ms_out_token_capacity; + size_t _len_out_token_ptr = _tmp_out_token_capacity * sizeof(uint8_t); + uint8_t* _in_out_token_ptr = NULL; + size_t* _tmp_out_token_used = ms->ms_out_token_used; + size_t _len_out_token_used = sizeof(size_t); + size_t* _in_out_token_used = NULL; + + if (sizeof(*_tmp_payload_ptr) != 0 && + (size_t)_tmp_payload_len > (SIZE_MAX / sizeof(*_tmp_payload_ptr))) { + return SGX_ERROR_INVALID_PARAMETER; + } + + if (sizeof(*_tmp_out_token_ptr) != 0 && + (size_t)_tmp_out_token_capacity > (SIZE_MAX / sizeof(*_tmp_out_token_ptr))) { + return SGX_ERROR_INVALID_PARAMETER; + } + + CHECK_UNIQUE_POINTER(_tmp_payload_ptr, _len_payload_ptr); + CHECK_UNIQUE_POINTER(_tmp_metadata, _len_metadata); + CHECK_UNIQUE_POINTER(_tmp_out_token_ptr, _len_out_token_ptr); + CHECK_UNIQUE_POINTER(_tmp_out_token_used, _len_out_token_used); + + // + // fence after pointer checks + // + sgx_lfence(); + + if (_tmp_payload_ptr != NULL && _len_payload_ptr != 0) { + if ( _len_payload_ptr % sizeof(*_tmp_payload_ptr) != 0) + { + status = SGX_ERROR_INVALID_PARAMETER; + goto err; + } + _in_payload_ptr = (uint8_t*)malloc(_len_payload_ptr); + if (_in_payload_ptr == NULL) { + status = SGX_ERROR_OUT_OF_MEMORY; + goto err; + } + + if (memcpy_s(_in_payload_ptr, _len_payload_ptr, _tmp_payload_ptr, _len_payload_ptr)) { + status = SGX_ERROR_UNEXPECTED; + goto err; + } + + } + if (_tmp_metadata != NULL && _len_metadata != 0) { + _in_metadata = (ExecReqMetadata*)malloc(_len_metadata); + if (_in_metadata == NULL) { + status = SGX_ERROR_OUT_OF_MEMORY; + goto err; + } + + if (memcpy_s(_in_metadata, _len_metadata, _tmp_metadata, _len_metadata)) { + status = SGX_ERROR_UNEXPECTED; + goto err; + } + + } + if (_tmp_out_token_ptr != NULL && _len_out_token_ptr != 0) { + if ( _len_out_token_ptr % sizeof(*_tmp_out_token_ptr) != 0) + { + status = SGX_ERROR_INVALID_PARAMETER; + goto err; + } + if ((_in_out_token_ptr = (uint8_t*)malloc(_len_out_token_ptr)) == NULL) { + status = SGX_ERROR_OUT_OF_MEMORY; + goto err; + } + + memset((void*)_in_out_token_ptr, 0, _len_out_token_ptr); + } + if (_tmp_out_token_used != NULL && _len_out_token_used != 0) { + if ( _len_out_token_used % sizeof(*_tmp_out_token_used) != 0) + { + status = SGX_ERROR_INVALID_PARAMETER; + goto err; + } + if ((_in_out_token_used = (size_t*)malloc(_len_out_token_used)) == NULL) { + status = SGX_ERROR_OUT_OF_MEMORY; + goto err; + } + + memset((void*)_in_out_token_used, 0, _len_out_token_used); + } + + ms->ms_retval = issue_execution_token((const uint8_t*)_in_payload_ptr, _tmp_payload_len, (const ExecReqMetadata*)_in_metadata, _in_out_token_ptr, _tmp_out_token_capacity, _in_out_token_used); + if (_in_out_token_ptr) { + if (memcpy_s(_tmp_out_token_ptr, _len_out_token_ptr, _in_out_token_ptr, _len_out_token_ptr)) { + status = SGX_ERROR_UNEXPECTED; + goto err; + } + } + if (_in_out_token_used) { + if (memcpy_s(_tmp_out_token_used, _len_out_token_used, _in_out_token_used, _len_out_token_used)) { + status = SGX_ERROR_UNEXPECTED; + goto err; + } + } + +err: + if (_in_payload_ptr) free(_in_payload_ptr); + if (_in_metadata) free(_in_metadata); + if (_in_out_token_ptr) free(_in_out_token_ptr); + if (_in_out_token_used) free(_in_out_token_used); + return status; +} + static sgx_status_t SGX_CDECL sgx_t_global_init_ecall(void* pms) { CHECK_REF_POINTER(pms, sizeof(ms_t_global_init_ecall_t)); @@ -714,11 +911,12 @@ static sgx_status_t SGX_CDECL sgx_end_session(void* pms) SGX_EXTERNC const struct { size_t nr_ecall; - struct {void* ecall_addr; uint8_t is_priv; uint8_t is_switchless;} ecall_table[6]; + struct {void* ecall_addr; uint8_t is_priv; uint8_t is_switchless;} ecall_table[7]; } g_ecall_table = { - 6, + 7, { {(void*)(uintptr_t)sgx_enclave_create_report, 0, 0}, + {(void*)(uintptr_t)sgx_issue_execution_token, 0, 0}, {(void*)(uintptr_t)sgx_t_global_init_ecall, 0, 0}, {(void*)(uintptr_t)sgx_t_global_exit_ecall, 0, 0}, {(void*)(uintptr_t)sgx_session_request, 0, 0}, @@ -729,73 +927,83 @@ SGX_EXTERNC const struct { SGX_EXTERNC const struct { size_t nr_ocall; - uint8_t entry_table[63][6]; + uint8_t entry_table[73][7]; } g_dyn_entry_table = { - 63, + 73, { - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, } }; @@ -4923,3 +5131,536 @@ sgx_status_t SGX_CDECL sgx_thread_set_multiple_untrusted_events_ocall(int* retva return status; } +sgx_status_t SGX_CDECL u_sgxprotectedfs_exclusive_file_open(void** retval, const char* filename, uint8_t read_only, int64_t* file_size, int32_t* error_code) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + size_t _len_file_size = sizeof(int64_t); + size_t _len_error_code = sizeof(int32_t); + + ms_u_sgxprotectedfs_exclusive_file_open_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_exclusive_file_open_t); + void *__tmp = NULL; + + void *__tmp_file_size = NULL; + void *__tmp_error_code = NULL; + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + CHECK_ENCLAVE_POINTER(file_size, _len_file_size); + CHECK_ENCLAVE_POINTER(error_code, _len_error_code); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (file_size != NULL) ? _len_file_size : 0)) + return SGX_ERROR_INVALID_PARAMETER; + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (error_code != NULL) ? _len_error_code : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_exclusive_file_open_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_exclusive_file_open_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_exclusive_file_open_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + ms->ms_read_only = read_only; + if (file_size != NULL) { + ms->ms_file_size = (int64_t*)__tmp; + __tmp_file_size = __tmp; + if (_len_file_size % sizeof(*file_size) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + memset(__tmp_file_size, 0, _len_file_size); + __tmp = (void *)((size_t)__tmp + _len_file_size); + ocalloc_size -= _len_file_size; + } else { + ms->ms_file_size = NULL; + } + + if (error_code != NULL) { + ms->ms_error_code = (int32_t*)__tmp; + __tmp_error_code = __tmp; + if (_len_error_code % sizeof(*error_code) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + memset(__tmp_error_code, 0, _len_error_code); + __tmp = (void *)((size_t)__tmp + _len_error_code); + ocalloc_size -= _len_error_code; + } else { + ms->ms_error_code = NULL; + } + + status = sgx_ocall(63, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + if (file_size) { + if (memcpy_s((void*)file_size, _len_file_size, __tmp_file_size, _len_file_size)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + } + if (error_code) { + if (memcpy_s((void*)error_code, _len_error_code, __tmp_error_code, _len_error_code)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + } + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_check_if_file_exists(uint8_t* retval, const char* filename) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + + ms_u_sgxprotectedfs_check_if_file_exists_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_check_if_file_exists_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_check_if_file_exists_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_check_if_file_exists_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_check_if_file_exists_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + status = sgx_ocall(64, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fread_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_buffer = node_size; + + ms_u_sgxprotectedfs_fread_node_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fread_node_t); + void *__tmp = NULL; + + void *__tmp_buffer = NULL; + + CHECK_ENCLAVE_POINTER(buffer, _len_buffer); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (buffer != NULL) ? _len_buffer : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fread_node_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fread_node_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fread_node_t); + + ms->ms_f = f; + ms->ms_node_number = node_number; + if (buffer != NULL) { + ms->ms_buffer = (uint8_t*)__tmp; + __tmp_buffer = __tmp; + if (_len_buffer % sizeof(*buffer) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + memset(__tmp_buffer, 0, _len_buffer); + __tmp = (void *)((size_t)__tmp + _len_buffer); + ocalloc_size -= _len_buffer; + } else { + ms->ms_buffer = NULL; + } + + ms->ms_node_size = node_size; + status = sgx_ocall(65, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + if (buffer) { + if (memcpy_s((void*)buffer, _len_buffer, __tmp_buffer, _len_buffer)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + } + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_buffer = node_size; + + ms_u_sgxprotectedfs_fwrite_node_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fwrite_node_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(buffer, _len_buffer); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (buffer != NULL) ? _len_buffer : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fwrite_node_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fwrite_node_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fwrite_node_t); + + ms->ms_f = f; + ms->ms_node_number = node_number; + if (buffer != NULL) { + ms->ms_buffer = (uint8_t*)__tmp; + if (_len_buffer % sizeof(*buffer) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, buffer, _len_buffer)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_buffer); + ocalloc_size -= _len_buffer; + } else { + ms->ms_buffer = NULL; + } + + ms->ms_node_size = node_size; + status = sgx_ocall(66, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fclose(int32_t* retval, void* f) +{ + sgx_status_t status = SGX_SUCCESS; + + ms_u_sgxprotectedfs_fclose_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fclose_t); + void *__tmp = NULL; + + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fclose_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fclose_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fclose_t); + + ms->ms_f = f; + status = sgx_ocall(67, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fflush(uint8_t* retval, void* f) +{ + sgx_status_t status = SGX_SUCCESS; + + ms_u_sgxprotectedfs_fflush_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fflush_t); + void *__tmp = NULL; + + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fflush_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fflush_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fflush_t); + + ms->ms_f = f; + status = sgx_ocall(68, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_remove(int32_t* retval, const char* filename) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + + ms_u_sgxprotectedfs_remove_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_remove_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_remove_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_remove_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_remove_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + status = sgx_ocall(69, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_recovery_file_open(void** retval, const char* filename) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + + ms_u_sgxprotectedfs_recovery_file_open_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_recovery_file_open_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_recovery_file_open_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_recovery_file_open_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_recovery_file_open_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + status = sgx_ocall(70, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_recovery_node(uint8_t* retval, void* f, uint8_t* data, uint32_t data_length) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_data = data_length * sizeof(uint8_t); + + ms_u_sgxprotectedfs_fwrite_recovery_node_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fwrite_recovery_node_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(data, _len_data); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (data != NULL) ? _len_data : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fwrite_recovery_node_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fwrite_recovery_node_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fwrite_recovery_node_t); + + ms->ms_f = f; + if (data != NULL) { + ms->ms_data = (uint8_t*)__tmp; + if (_len_data % sizeof(*data) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, data, _len_data)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_data); + ocalloc_size -= _len_data; + } else { + ms->ms_data = NULL; + } + + ms->ms_data_length = data_length; + status = sgx_ocall(71, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_do_file_recovery(int32_t* retval, const char* filename, const char* recovery_filename, uint32_t node_size) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + size_t _len_recovery_filename = recovery_filename ? strlen(recovery_filename) + 1 : 0; + + ms_u_sgxprotectedfs_do_file_recovery_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_do_file_recovery_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + CHECK_ENCLAVE_POINTER(recovery_filename, _len_recovery_filename); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (recovery_filename != NULL) ? _len_recovery_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_do_file_recovery_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_do_file_recovery_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_do_file_recovery_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + if (recovery_filename != NULL) { + ms->ms_recovery_filename = (const char*)__tmp; + if (_len_recovery_filename % sizeof(*recovery_filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, recovery_filename, _len_recovery_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_recovery_filename); + ocalloc_size -= _len_recovery_filename; + } else { + ms->ms_recovery_filename = NULL; + } + + ms->ms_node_size = node_size; + status = sgx_ocall(72, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + diff --git a/codegen/auth_enclave/rtc_auth_t.h b/codegen/auth_enclave/rtc_auth_t.h index d69a044b..73083339 100644 --- a/codegen/auth_enclave/rtc_auth_t.h +++ b/codegen/auth_enclave/rtc_auth_t.h @@ -26,6 +26,7 @@ extern "C" { #endif CreateReportResult enclave_create_report(const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report); +IssueTokenResult issue_execution_token(const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_capacity, size_t* out_token_used); void t_global_init_ecall(uint64_t id, const uint8_t* path, size_t len); void t_global_exit_ecall(void); SessionRequestResult session_request(sgx_enclave_id_t src_enclave_id); @@ -95,6 +96,16 @@ sgx_status_t SGX_CDECL sgx_thread_wait_untrusted_event_ocall(int* retval, const sgx_status_t SGX_CDECL sgx_thread_set_untrusted_event_ocall(int* retval, const void* waiter); sgx_status_t SGX_CDECL sgx_thread_setwait_untrusted_events_ocall(int* retval, const void* waiter, const void* self); sgx_status_t SGX_CDECL sgx_thread_set_multiple_untrusted_events_ocall(int* retval, const void** waiters, size_t total); +sgx_status_t SGX_CDECL u_sgxprotectedfs_exclusive_file_open(void** retval, const char* filename, uint8_t read_only, int64_t* file_size, int32_t* error_code); +sgx_status_t SGX_CDECL u_sgxprotectedfs_check_if_file_exists(uint8_t* retval, const char* filename); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fread_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fclose(int32_t* retval, void* f); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fflush(uint8_t* retval, void* f); +sgx_status_t SGX_CDECL u_sgxprotectedfs_remove(int32_t* retval, const char* filename); +sgx_status_t SGX_CDECL u_sgxprotectedfs_recovery_file_open(void** retval, const char* filename); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_recovery_node(uint8_t* retval, void* f, uint8_t* data, uint32_t data_length); +sgx_status_t SGX_CDECL u_sgxprotectedfs_do_file_recovery(int32_t* retval, const char* filename, const char* recovery_filename, uint32_t node_size); #ifdef __cplusplus } diff --git a/codegen/auth_enclave/rtc_auth_u.c b/codegen/auth_enclave/rtc_auth_u.c index 35caa9bf..8c77d079 100644 --- a/codegen/auth_enclave/rtc_auth_u.c +++ b/codegen/auth_enclave/rtc_auth_u.c @@ -8,6 +8,16 @@ typedef struct ms_enclave_create_report_t { sgx_report_t* ms_p_report; } ms_enclave_create_report_t; +typedef struct ms_issue_execution_token_t { + IssueTokenResult ms_retval; + const uint8_t* ms_payload_ptr; + size_t ms_payload_len; + const ExecReqMetadata* ms_metadata; + uint8_t* ms_out_token_ptr; + size_t ms_out_token_capacity; + size_t* ms_out_token_used; +} ms_issue_execution_token_t; + typedef struct ms_t_global_init_ecall_t { uint64_t ms_id; const uint8_t* ms_path; @@ -475,6 +485,69 @@ typedef struct ms_sgx_thread_set_multiple_untrusted_events_ocall_t { size_t ms_total; } ms_sgx_thread_set_multiple_untrusted_events_ocall_t; +typedef struct ms_u_sgxprotectedfs_exclusive_file_open_t { + void* ms_retval; + const char* ms_filename; + uint8_t ms_read_only; + int64_t* ms_file_size; + int32_t* ms_error_code; +} ms_u_sgxprotectedfs_exclusive_file_open_t; + +typedef struct ms_u_sgxprotectedfs_check_if_file_exists_t { + uint8_t ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_check_if_file_exists_t; + +typedef struct ms_u_sgxprotectedfs_fread_node_t { + int32_t ms_retval; + void* ms_f; + uint64_t ms_node_number; + uint8_t* ms_buffer; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_fread_node_t; + +typedef struct ms_u_sgxprotectedfs_fwrite_node_t { + int32_t ms_retval; + void* ms_f; + uint64_t ms_node_number; + uint8_t* ms_buffer; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_fwrite_node_t; + +typedef struct ms_u_sgxprotectedfs_fclose_t { + int32_t ms_retval; + void* ms_f; +} ms_u_sgxprotectedfs_fclose_t; + +typedef struct ms_u_sgxprotectedfs_fflush_t { + uint8_t ms_retval; + void* ms_f; +} ms_u_sgxprotectedfs_fflush_t; + +typedef struct ms_u_sgxprotectedfs_remove_t { + int32_t ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_remove_t; + +typedef struct ms_u_sgxprotectedfs_recovery_file_open_t { + void* ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_recovery_file_open_t; + +typedef struct ms_u_sgxprotectedfs_fwrite_recovery_node_t { + uint8_t ms_retval; + void* ms_f; + uint8_t* ms_data; + uint32_t ms_data_length; +} ms_u_sgxprotectedfs_fwrite_recovery_node_t; + +typedef struct ms_u_sgxprotectedfs_do_file_recovery_t { + int32_t ms_retval; + const char* ms_filename; + const char* ms_recovery_filename; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_do_file_recovery_t; + static sgx_status_t SGX_CDECL rtc_auth_u_thread_set_event_ocall(void* pms) { ms_u_thread_set_event_ocall_t* ms = SGX_CAST(ms_u_thread_set_event_ocall_t*, pms); @@ -979,11 +1052,91 @@ static sgx_status_t SGX_CDECL rtc_auth_sgx_thread_set_multiple_untrusted_events_ return SGX_SUCCESS; } +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_exclusive_file_open(void* pms) +{ + ms_u_sgxprotectedfs_exclusive_file_open_t* ms = SGX_CAST(ms_u_sgxprotectedfs_exclusive_file_open_t*, pms); + ms->ms_retval = u_sgxprotectedfs_exclusive_file_open(ms->ms_filename, ms->ms_read_only, ms->ms_file_size, ms->ms_error_code); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_check_if_file_exists(void* pms) +{ + ms_u_sgxprotectedfs_check_if_file_exists_t* ms = SGX_CAST(ms_u_sgxprotectedfs_check_if_file_exists_t*, pms); + ms->ms_retval = u_sgxprotectedfs_check_if_file_exists(ms->ms_filename); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fread_node(void* pms) +{ + ms_u_sgxprotectedfs_fread_node_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fread_node_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fread_node(ms->ms_f, ms->ms_node_number, ms->ms_buffer, ms->ms_node_size); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fwrite_node(void* pms) +{ + ms_u_sgxprotectedfs_fwrite_node_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fwrite_node_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fwrite_node(ms->ms_f, ms->ms_node_number, ms->ms_buffer, ms->ms_node_size); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fclose(void* pms) +{ + ms_u_sgxprotectedfs_fclose_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fclose_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fclose(ms->ms_f); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fflush(void* pms) +{ + ms_u_sgxprotectedfs_fflush_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fflush_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fflush(ms->ms_f); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_remove(void* pms) +{ + ms_u_sgxprotectedfs_remove_t* ms = SGX_CAST(ms_u_sgxprotectedfs_remove_t*, pms); + ms->ms_retval = u_sgxprotectedfs_remove(ms->ms_filename); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_recovery_file_open(void* pms) +{ + ms_u_sgxprotectedfs_recovery_file_open_t* ms = SGX_CAST(ms_u_sgxprotectedfs_recovery_file_open_t*, pms); + ms->ms_retval = u_sgxprotectedfs_recovery_file_open(ms->ms_filename); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fwrite_recovery_node(void* pms) +{ + ms_u_sgxprotectedfs_fwrite_recovery_node_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fwrite_recovery_node_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fwrite_recovery_node(ms->ms_f, ms->ms_data, ms->ms_data_length); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_do_file_recovery(void* pms) +{ + ms_u_sgxprotectedfs_do_file_recovery_t* ms = SGX_CAST(ms_u_sgxprotectedfs_do_file_recovery_t*, pms); + ms->ms_retval = u_sgxprotectedfs_do_file_recovery(ms->ms_filename, ms->ms_recovery_filename, ms->ms_node_size); + + return SGX_SUCCESS; +} + static const struct { size_t nr_ocall; - void * table[63]; + void * table[73]; } ocall_table_rtc_auth = { - 63, + 73, { (void*)rtc_auth_u_thread_set_event_ocall, (void*)rtc_auth_u_thread_wait_event_ocall, @@ -1048,6 +1201,16 @@ static const struct { (void*)rtc_auth_sgx_thread_set_untrusted_event_ocall, (void*)rtc_auth_sgx_thread_setwait_untrusted_events_ocall, (void*)rtc_auth_sgx_thread_set_multiple_untrusted_events_ocall, + (void*)rtc_auth_u_sgxprotectedfs_exclusive_file_open, + (void*)rtc_auth_u_sgxprotectedfs_check_if_file_exists, + (void*)rtc_auth_u_sgxprotectedfs_fread_node, + (void*)rtc_auth_u_sgxprotectedfs_fwrite_node, + (void*)rtc_auth_u_sgxprotectedfs_fclose, + (void*)rtc_auth_u_sgxprotectedfs_fflush, + (void*)rtc_auth_u_sgxprotectedfs_remove, + (void*)rtc_auth_u_sgxprotectedfs_recovery_file_open, + (void*)rtc_auth_u_sgxprotectedfs_fwrite_recovery_node, + (void*)rtc_auth_u_sgxprotectedfs_do_file_recovery, } }; sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportResult* retval, const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report) @@ -1062,6 +1225,21 @@ sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportRe return status; } +sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_capacity, size_t* out_token_used) +{ + sgx_status_t status; + ms_issue_execution_token_t ms; + ms.ms_payload_ptr = payload_ptr; + ms.ms_payload_len = payload_len; + ms.ms_metadata = metadata; + ms.ms_out_token_ptr = out_token_ptr; + ms.ms_out_token_capacity = out_token_capacity; + ms.ms_out_token_used = out_token_used; + status = sgx_ecall(eid, 1, &ocall_table_rtc_auth, &ms); + if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval; + return status; +} + sgx_status_t rtc_auth_t_global_init_ecall(sgx_enclave_id_t eid, uint64_t id, const uint8_t* path, size_t len) { sgx_status_t status; @@ -1069,14 +1247,14 @@ sgx_status_t rtc_auth_t_global_init_ecall(sgx_enclave_id_t eid, uint64_t id, con ms.ms_id = id; ms.ms_path = path; ms.ms_len = len; - status = sgx_ecall(eid, 1, &ocall_table_rtc_auth, &ms); + status = sgx_ecall(eid, 2, &ocall_table_rtc_auth, &ms); return status; } sgx_status_t rtc_auth_t_global_exit_ecall(sgx_enclave_id_t eid) { sgx_status_t status; - status = sgx_ecall(eid, 2, &ocall_table_rtc_auth, NULL); + status = sgx_ecall(eid, 3, &ocall_table_rtc_auth, NULL); return status; } @@ -1085,7 +1263,7 @@ sgx_status_t rtc_auth_session_request(sgx_enclave_id_t eid, SessionRequestResult sgx_status_t status; ms_session_request_t ms; ms.ms_src_enclave_id = src_enclave_id; - status = sgx_ecall(eid, 3, &ocall_table_rtc_auth, &ms); + status = sgx_ecall(eid, 4, &ocall_table_rtc_auth, &ms); if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval; return status; } @@ -1096,7 +1274,7 @@ sgx_status_t rtc_auth_exchange_report(sgx_enclave_id_t eid, ExchangeReportResult ms_exchange_report_t ms; ms.ms_src_enclave_id = src_enclave_id; ms.ms_dh_msg2 = dh_msg2; - status = sgx_ecall(eid, 4, &ocall_table_rtc_auth, &ms); + status = sgx_ecall(eid, 5, &ocall_table_rtc_auth, &ms); if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval; return status; } @@ -1106,7 +1284,7 @@ sgx_status_t rtc_auth_end_session(sgx_enclave_id_t eid, sgx_status_t* retval, sg sgx_status_t status; ms_end_session_t ms; ms.ms_src_enclave_id = src_enclave_id; - status = sgx_ecall(eid, 5, &ocall_table_rtc_auth, &ms); + status = sgx_ecall(eid, 6, &ocall_table_rtc_auth, &ms); if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval; return status; } diff --git a/codegen/auth_enclave/rtc_auth_u.h b/codegen/auth_enclave/rtc_auth_u.h index c3a5bcec..38074d3c 100644 --- a/codegen/auth_enclave/rtc_auth_u.h +++ b/codegen/auth_enclave/rtc_auth_u.h @@ -278,8 +278,49 @@ int SGX_UBRIDGE(SGX_CDECL, sgx_thread_setwait_untrusted_events_ocall, (const voi #define SGX_THREAD_SET_MULTIPLE_UNTRUSTED_EVENTS_OCALL_DEFINED__ int SGX_UBRIDGE(SGX_CDECL, sgx_thread_set_multiple_untrusted_events_ocall, (const void** waiters, size_t total)); #endif +#ifndef U_SGXPROTECTEDFS_EXCLUSIVE_FILE_OPEN_DEFINED__ +#define U_SGXPROTECTEDFS_EXCLUSIVE_FILE_OPEN_DEFINED__ +void* SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_exclusive_file_open, (const char* filename, uint8_t read_only, int64_t* file_size, int32_t* error_code)); +#endif +#ifndef U_SGXPROTECTEDFS_CHECK_IF_FILE_EXISTS_DEFINED__ +#define U_SGXPROTECTEDFS_CHECK_IF_FILE_EXISTS_DEFINED__ +uint8_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_check_if_file_exists, (const char* filename)); +#endif +#ifndef U_SGXPROTECTEDFS_FREAD_NODE_DEFINED__ +#define U_SGXPROTECTEDFS_FREAD_NODE_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fread_node, (void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size)); +#endif +#ifndef U_SGXPROTECTEDFS_FWRITE_NODE_DEFINED__ +#define U_SGXPROTECTEDFS_FWRITE_NODE_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fwrite_node, (void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size)); +#endif +#ifndef U_SGXPROTECTEDFS_FCLOSE_DEFINED__ +#define U_SGXPROTECTEDFS_FCLOSE_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fclose, (void* f)); +#endif +#ifndef U_SGXPROTECTEDFS_FFLUSH_DEFINED__ +#define U_SGXPROTECTEDFS_FFLUSH_DEFINED__ +uint8_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fflush, (void* f)); +#endif +#ifndef U_SGXPROTECTEDFS_REMOVE_DEFINED__ +#define U_SGXPROTECTEDFS_REMOVE_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_remove, (const char* filename)); +#endif +#ifndef U_SGXPROTECTEDFS_RECOVERY_FILE_OPEN_DEFINED__ +#define U_SGXPROTECTEDFS_RECOVERY_FILE_OPEN_DEFINED__ +void* SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_recovery_file_open, (const char* filename)); +#endif +#ifndef U_SGXPROTECTEDFS_FWRITE_RECOVERY_NODE_DEFINED__ +#define U_SGXPROTECTEDFS_FWRITE_RECOVERY_NODE_DEFINED__ +uint8_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fwrite_recovery_node, (void* f, uint8_t* data, uint32_t data_length)); +#endif +#ifndef U_SGXPROTECTEDFS_DO_FILE_RECOVERY_DEFINED__ +#define U_SGXPROTECTEDFS_DO_FILE_RECOVERY_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_do_file_recovery, (const char* filename, const char* recovery_filename, uint32_t node_size)); +#endif sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportResult* retval, const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report); +sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_capacity, size_t* out_token_used); sgx_status_t rtc_auth_t_global_init_ecall(sgx_enclave_id_t eid, uint64_t id, const uint8_t* path, size_t len); sgx_status_t rtc_auth_t_global_exit_ecall(sgx_enclave_id_t eid); sgx_status_t rtc_auth_session_request(sgx_enclave_id_t eid, SessionRequestResult* retval, sgx_enclave_id_t src_enclave_id); diff --git a/rtc_auth_enclave/Cargo.lock b/rtc_auth_enclave/Cargo.lock index 5dbfb236..4514a368 100644 --- a/rtc_auth_enclave/Cargo.lock +++ b/rtc_auth_enclave/Cargo.lock @@ -22,12 +22,26 @@ dependencies = [ "winapi", ] +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "base64" +version = "0.13.0" +source = "git+https://github.com/mesalock-linux/rust-base64-sgx#dc7389e10817b078f289386b3b6a852ab6c4c021" +dependencies = [ + "sgx_tstd", +] + [[package]] name = "bitflags" version = "1.2.1" @@ -77,6 +91,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.11" +source = "git+https://github.com/mesalock-linux/chrono-sgx#f964ae7f5f65bd2c9cd6f44a067e7980afc08ca0" +dependencies = [ + "num-integer", + "num-traits", + "sgx_tstd", +] + [[package]] name = "clap" version = "2.33.3" @@ -161,7 +185,7 @@ version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" dependencies = [ - "autocfg", + "autocfg 1.0.1", "hashbrown", ] @@ -188,6 +212,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonwebtoken" +version = "7.2.0" +source = "git+https://github.com/mesalock-linux/jsonwebtoken-sgx#a110ccf3a7ee5c1e9ca8ba776c2f37fc960a4b5f" +dependencies = [ + "base64", + "pem", + "ring 0.16.19", + "serde 1.0.118", + "serde_json 1.0.60", + "sgx_tstd", + "simple_asn1", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -215,13 +253,43 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ - "autocfg", + "autocfg 1.0.1", +] + +[[package]] +name = "num-bigint" +version = "0.2.5" +source = "git+https://github.com/mesalock-linux/num-bigint-sgx#76a5bed94dc31c32bd1670dbf72877abcf9bbc09" +dependencies = [ + "autocfg 1.0.1", + "num-integer", + "num-traits", + "sgx_tstd", +] + +[[package]] +name = "num-integer" +version = "0.1.41" +source = "git+https://github.com/mesalock-linux/num-integer-sgx#404c50e5378ca635261688b080dee328ff42b6bd" +dependencies = [ + "autocfg 0.1.7", + "num-traits", + "sgx_tstd", +] + +[[package]] +name = "num-traits" +version = "0.2.10" +source = "git+https://github.com/mesalock-linux/num-traits-sgx#af046e0b15c594c960007418097dd4ff37ec3f7a" +dependencies = [ + "autocfg 0.1.7", + "sgx_tstd", ] [[package]] name = "once_cell" version = "1.4.0" -source = "git+https://github.com/mesalock-linux/once_cell-sgx.git?tag=sgx_1.1.3#cefcaa03fed4d85276b3235d875f1b45d399cc3c" +source = "git+https://github.com/mesalock-linux/once_cell-sgx.git#cefcaa03fed4d85276b3235d875f1b45d399cc3c" dependencies = [ "sgx_tstd", ] @@ -232,6 +300,17 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +[[package]] +name = "pem" +version = "0.8.2" +source = "git+https://github.com/mesalock-linux/pem-rs-sgx#fdfef4f24a9fb3fa72e8a71bb28bd8ff15feff2f" +dependencies = [ + "base64", + "once_cell 1.4.0", + "regex", + "sgx_tstd", +] + [[package]] name = "ppv-lite86" version = "0.2.6" @@ -360,6 +439,23 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.3.1" +source = "git+https://github.com/mesalock-linux/regex-sgx#76aef86f9836532d17764523d0fa23bb7d2e31cf" +dependencies = [ + "regex-syntax", + "sgx_tstd", +] + +[[package]] +name = "regex-syntax" +version = "0.6.12" +source = "git+https://github.com/mesalock-linux/regex-sgx#76aef86f9836532d17764523d0fa23bb7d2e31cf" +dependencies = [ + "sgx_tstd", +] + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -369,6 +465,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "ring" +version = "0.16.19" +source = "git+https://github.com/mesalock-linux/ring-sgx?tag=v0.16.5#844efe271ed78a399d803b2579f5f2424d543c9f" +dependencies = [ + "cc", + "sgx_tstd", + "spin", + "untrusted", +] + [[package]] name = "ring" version = "0.17.0-alpha.10" @@ -410,12 +517,21 @@ dependencies = [ name = "rtc_auth_enclave" version = "0.1.0" dependencies = [ + "base64", "cbindgen", "cc", + "jsonwebtoken", + "once_cell 1.4.0", + "rand 0.7.3", "rtc_tenclave", "rtc_types", + "secrecy", + "serde 1.0.118", + "serde_json 1.0.60", + "sgx_tcrypto", "sgx_tstd", "sgx_types", + "uuid", ] [[package]] @@ -426,7 +542,7 @@ dependencies = [ "hex", "once_cell 1.4.0", "rand 0.7.3", - "ring", + "ring 0.17.0-alpha.10", "rkyv", "rtc_types", "secrecy", @@ -473,6 +589,7 @@ name = "serde" version = "1.0.118" source = "git+https://github.com/mesalock-linux/serde-sgx#db0226f1d5d70fca6b96af2c285851502204e21c" dependencies = [ + "serde_derive 1.0.118", "sgx_tstd", ] @@ -482,7 +599,17 @@ version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" dependencies = [ - "serde_derive", + "serde_derive 1.0.125", +] + +[[package]] +name = "serde_derive" +version = "1.0.118" +source = "git+https://github.com/mesalock-linux/serde-sgx#db0226f1d5d70fca6b96af2c285851502204e21c" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -499,7 +626,7 @@ dependencies = [ [[package]] name = "serde_json" version = "1.0.60" -source = "git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3#380893814ad2a057758d825bab798aa117f7362a" +source = "git+https://github.com/mesalock-linux/serde-json-sgx#380893814ad2a057758d825bab798aa117f7362a" dependencies = [ "itoa 0.4.5", "ryu", @@ -625,6 +752,17 @@ dependencies = [ "sgx_build_helper", ] +[[package]] +name = "simple_asn1" +version = "0.5.0" +source = "git+https://github.com/mesalock-linux/simple_asn1-sgx#ba48e2390f14094e5a210ab7dc0421a9a86725d0" +dependencies = [ + "chrono", + "num-bigint", + "num-traits", + "sgx_tstd", +] + [[package]] name = "sodalite" version = "0.4.0" @@ -752,6 +890,16 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "uuid" +version = "0.8.1" +source = "git+https://github.com/mesalock-linux/uuid-sgx#9b425a8f07d5bb6e50b9a24414d11a59ec86617a" +dependencies = [ + "rand 0.7.3", + "serde 1.0.118", + "sgx_tstd", +] + [[package]] name = "vec_map" version = "0.8.2" diff --git a/rtc_auth_enclave/Cargo.toml b/rtc_auth_enclave/Cargo.toml index 3e702170..6304c29b 100644 --- a/rtc_auth_enclave/Cargo.toml +++ b/rtc_auth_enclave/Cargo.toml @@ -15,8 +15,21 @@ cbindgen = "0.19.0" # See "Pinning SGX dependencies" in HACKING.md [target.'cfg(not(target_env = "sgx"))'.dependencies] +sgx_tcrypto = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda" } sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", features = ["extra_traits"] } sgx_tstd = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", features = ["backtrace"] } +rand = { git = "https://github.com/mesalock-linux/rand-sgx", tag = "v0.7.3_sgx1.1.3" } +jsonwebtoken = { git = "https://github.com/mesalock-linux/jsonwebtoken-sgx" } +# TODO: confirm that we have to use a forked crate here +uuid = { git = "https://github.com/mesalock-linux/uuid-sgx", features = ["v4", "serde"] } +base64 = { git = "https://github.com/mesalock-linux/rust-base64-sgx" } + +# See "Cargo patch limitation workaround" in HACKING.md: +once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx.git" } +serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = ["derive"] } +serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } + +secrecy = { version = "0.7.0", default-features = false } rtc_types = { path = "../rtc_types", features = ["teaclave_sgx"] } diff --git a/rtc_auth_enclave/rtc_auth.edl b/rtc_auth_enclave/rtc_auth.edl index 7a84afc0..f10f7c83 100644 --- a/rtc_auth_enclave/rtc_auth.edl +++ b/rtc_auth_enclave/rtc_auth.edl @@ -2,6 +2,7 @@ enclave { from "sgx_tstd.edl" import *; from "sgx_backtrace.edl" import *; from "rtc_tenclave.edl" import *; + from "sgx_tprotected_fs.edl" import *; include "sgx_report.h" include "sgx_dh.h" @@ -12,5 +13,11 @@ enclave { public CreateReportResult enclave_create_report([in]const sgx_target_info_t* p_qe3_target, [out, isary]EnclaveHeldData enclave_data, [out]sgx_report_t* p_report); + public IssueTokenResult issue_execution_token([in, count=payload_len]const uint8_t* payload_ptr, + size_t payload_len, + [in]const ExecReqMetadata* metadata, + [out, count=out_token_capacity]uint8_t* out_token_ptr, + size_t out_token_capacity, + [out] size_t* out_token_used); }; }; diff --git a/rtc_auth_enclave/src/jwt.rs b/rtc_auth_enclave/src/jwt.rs new file mode 100644 index 00000000..3ae3a246 --- /dev/null +++ b/rtc_auth_enclave/src/jwt.rs @@ -0,0 +1,96 @@ +use std::string::{String, ToString}; +use std::time::{SystemTime, UNIX_EPOCH}; + +use jsonwebtoken::{encode, EncodingKey, Header}; +use serde::{Deserialize, Serialize}; +use sgx_tstd::untrusted::time::SystemTimeEx; +use uuid::Uuid; + +use crate::uuid_to_string; + +/// Claims body of the JWT token +/// +/// Example output: +/// ``` +/// { +/// "iss": "registree_auth_enclave", +/// "nbf": 1623762799, +/// "iat": 1623762799, +/// "jti": "b300fe149d144e05aa9a9600816b42ca", +/// "exec_module_hash": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", +/// "dataset_uuid": "dd12012195c04ae8990ebd2512ae03ab" +/// } +/// ``` +#[derive(Debug, Serialize, Deserialize)] +struct Claims { + // Registered Claim Names: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 + // TODO: serialize to hex string? This can be mrenclave or mrsigner + iss: String, + nbf: u64, + iat: u64, + jti: String, + // TODO: Better names. use `x-ntls-mod-hash` etc? + exec_module_hash: String, + dataset_uuid: String, + dataset_size: u64, +} + +impl Claims { + fn new( + exec_module_hash: String, + dataset_uuid: String, + token_id: String, + dataset_size: u64, + ) -> Self { + // TODO: Look at the attack vectors opened up by using untrusted system time + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("System time before UNIX Epoch") + .as_secs(); + + Self { + iss: "registree_auth_enclave".to_string(), + nbf: now, + iat: now, + jti: token_id, + exec_module_hash, + dataset_uuid, + dataset_size, + } + } +} + +pub(crate) struct EncodedExecutionToken { + pub token: String, + pub token_id: Uuid, +} + +impl EncodedExecutionToken { + pub(crate) fn new(exec_module_hash: [u8; 32], dataset_uuid: Uuid, dataset_size: u64) -> Self { + let token_id = Uuid::new_v4(); + + let claims = Claims::new( + base64::encode(exec_module_hash), + uuid_to_string(dataset_uuid), + uuid_to_string(token_id), + dataset_size, + ); + + // TODO: Use a signing key that corresponds to the public key + // in the attestation enclave held data and move to crypto module in tenclave. + let encoding_key = EncodingKey::from_secret("secret".as_ref()); + // Header size 48 characters base64 + let header = Header { + // Explicit typing for the token type + // SEE: https://datatracker.ietf.org/doc/html/draft-ietf-secevent-token-02#section-2.2 + typ: Some("ntlexec+jwt".to_string()), + ..Header::default() + }; + + // Signature length: 44 + let token = encode(&header, &claims, &encoding_key) + .expect("encoding and signing execution token failed"); + + Self { token, token_id } + } +} diff --git a/rtc_auth_enclave/src/lib.rs b/rtc_auth_enclave/src/lib.rs index c1773a45..a036e0e2 100644 --- a/rtc_auth_enclave/src/lib.rs +++ b/rtc_auth_enclave/src/lib.rs @@ -3,9 +3,124 @@ #![deny(unsafe_op_in_unsafe_fn)] #![deny(clippy::mem_forget)] +mod jwt; +mod token_store; + #[cfg(not(target_env = "sgx"))] extern crate sgx_tstd as std; +use core::slice; +use std::ptr; +use std::string::{String, ToString}; + +use rtc_tenclave::crypto::{RtcCrypto, SodaBoxCrypto as Crypto}; pub use rtc_tenclave::dh::*; #[allow(unused_imports)] // for ECALL linking use rtc_tenclave::enclave::enclave_create_report; +use rtc_types::{EcallResult, EncryptedMessage, ExecReqMetadata, ExecTokenError, IssueTokenResult}; +use secrecy::{ExposeSecret, Secret}; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +/// Minimum size for the out_token parameter's buffer. +/// +/// From my testing, the total token size (including auth bytes) were never bigger than 500. +const MIN_OUT_TOKEN_LEN: usize = 500; + +/// Maximum size for the out_token parameter's buffer. +const MAX_OUT_TOKEN_LEN: usize = 1000; + +#[derive(Serialize, Deserialize)] +pub struct ExecReqData { + dataset_uuid: [u8; 16], + dataset_access_key: [u8; 24], + exec_module_hash: [u8; 32], + number_of_uses: u32, +} + +/// Issue an execution token using the parameters defined in the payload. +/// +/// # Safety +/// This function expects +/// 1. `payload_ptr` to be valid for a slice of len `payload_len` +/// 2. `metadata_ptr` should be a valid pointer. +/// 3. An allocated buffer of size `out_token_len` that starts at `out_token_ptr` +/// The edge code from sgx must uphold the above. +#[no_mangle] +pub unsafe extern "C" fn issue_execution_token( + payload_ptr: *const u8, + payload_len: usize, + metadata_ptr: *const ExecReqMetadata, + out_token_ptr: *mut u8, + out_token_capacity: usize, + out_token_used: *mut usize, +) -> IssueTokenResult { + // Ensure that the out token len is reasonable before proceeding + if out_token_capacity < MIN_OUT_TOKEN_LEN || out_token_capacity > MAX_OUT_TOKEN_LEN { + return EcallResult::Err(ExecTokenError::OutputBufferSize); + } + + let payload = unsafe { slice::from_raw_parts(payload_ptr, payload_len) }; + let metadata = unsafe { &*metadata_ptr }; + + match issue_execution_token_impl(payload, metadata) { + Ok(message) if message.ciphertext.len() <= out_token_capacity => { + let out_token_len = message.ciphertext.len(); + unsafe { + *out_token_used = out_token_len; + ptr::copy_nonoverlapping(message.ciphertext.as_ptr(), out_token_ptr, out_token_len); + } + EcallResult::Ok(message.nonce) + } + Ok(_) => EcallResult::Err(ExecTokenError::OutputBufferSize), + Err(err) => EcallResult::Err(err), + } +} + +fn issue_execution_token_impl( + payload: &[u8], + metadata: &ExecReqMetadata, +) -> Result { + let mut crypto = Crypto::new(); + let message_bytes = + crypto.decrypt_message(payload, &metadata.uploader_pub_key, &metadata.nonce)?; + + let message: ExecReqData = serde_json::from_slice(message_bytes.expose_secret()) + .map_err(|_| ExecTokenError::Validation)?; + + if let Some(dataset_size) = + validate_dataset_access_key(message.dataset_uuid, message.dataset_access_key) + { + let token = token_store::issue_token( + Uuid::from_bytes(message.dataset_uuid), + message.exec_module_hash, + message.number_of_uses, + dataset_size, + )?; + + let token_vec = token.into_bytes(); + + Ok(crypto.encrypt_message( + Secret::new(token_vec.into_boxed_slice()), + &metadata.uploader_pub_key, + )?) + } else { + Err(ExecTokenError::Validation) + } +} + +/// The size of the dataset in bytes +type DatasetSize = u64; + +// This is a placeholder and the signature might change when the dataset and access key store gets implemented. +fn validate_dataset_access_key( + _dataset_uuid: [u8; 16], + _access_key: [u8; 24], +) -> Option { + Some(20) +} + +pub(crate) fn uuid_to_string(uuid: Uuid) -> String { + let mut uuid_buf = Uuid::encode_buffer(); + uuid.to_simple().encode_lower(&mut uuid_buf).to_string() +} diff --git a/rtc_auth_enclave/src/token_store.rs b/rtc_auth_enclave/src/token_store.rs new file mode 100644 index 00000000..6c5e83ed --- /dev/null +++ b/rtc_auth_enclave/src/token_store.rs @@ -0,0 +1,82 @@ +use std::collections::HashMap; +use std::io; +use std::path::Path; +use std::string::String; + +use jwt::EncodedExecutionToken; +use once_cell::sync::OnceCell; +use rtc_tenclave::kv_store::fs::{FsStore, SgxFiler}; +use rtc_tenclave::kv_store::KvStore; +use serde::{Deserialize, Serialize}; +use sgx_tstd::sync::{SgxMutex as Mutex, SgxMutexGuard as MutexGuard}; +use sgx_tstd::untrusted::{fs as untrusted_fs, path as untrusted_path}; +use uuid::Uuid; + +use crate::{jwt, uuid_to_string}; + +#[derive(Serialize, Deserialize)] +struct ExecutionTokenRecord { + exec_module_hash: [u8; 32], + dataset_uuid: Uuid, + allowed_uses: u32, + current_uses: u32, +} + +fn kv_store<'a>( +) -> MutexGuard<'a, impl KvStore, Error = io::Error>> { + static TOKEN_FS_STORE: OnceCell>> = OnceCell::new(); + let store = TOKEN_FS_STORE.get_or_init(|| { + // TODO: Evaluate if this make sense, and what the possible attack vectors can be from relying on the + // untrusted fs and path functions. + let path = Path::new("./token_kv_store"); + if !untrusted_path::PathEx::exists(path) { + untrusted_fs::create_dir_all(path).expect("Failed to create token kv store directory"); + } + + Mutex::new(FsStore::new(path, SgxFiler)) + }); + store.lock().expect("FS store mutex poisoned") +} + +// Returns exec token hash +pub(crate) fn issue_token( + dataset_uuid: Uuid, + exec_module_hash: [u8; 32], + number_of_allowed_uses: u32, + dataset_size: u64, +) -> Result { + let EncodedExecutionToken { token, token_id } = + EncodedExecutionToken::new(exec_module_hash, dataset_uuid, dataset_size); + + save_token( + dataset_uuid, + token_id, + exec_module_hash, + number_of_allowed_uses, + )?; + + Ok(token) +} + +fn save_token( + dataset_uuid: Uuid, + token_uuid: Uuid, + exec_module_hash: [u8; 32], + number_of_allowed_uses: u32, +) -> Result<(), io::Error> { + let mut store = kv_store(); + let dataset_uuid_string = uuid_to_string(dataset_uuid); + let new_record = ExecutionTokenRecord { + dataset_uuid, + exec_module_hash, + allowed_uses: number_of_allowed_uses, + current_uses: 0u32, + }; + + store.alter(&dataset_uuid_string, |records| { + let mut records = records.unwrap_or_else(HashMap::new); + records.insert(token_uuid, new_record); + Some(records) + })?; + Ok(()) +} diff --git a/rtc_data_enclave/Cargo.lock b/rtc_data_enclave/Cargo.lock index 20e6e981..392ea11e 100644 --- a/rtc_data_enclave/Cargo.lock +++ b/rtc_data_enclave/Cargo.lock @@ -300,7 +300,7 @@ dependencies = [ [[package]] name = "once_cell" version = "1.4.0" -source = "git+https://github.com/mesalock-linux/once_cell-sgx.git?tag=sgx_1.1.3#cefcaa03fed4d85276b3235d875f1b45d399cc3c" +source = "git+https://github.com/mesalock-linux/once_cell-sgx.git#cefcaa03fed4d85276b3235d875f1b45d399cc3c" dependencies = [ "sgx_tstd", ] @@ -616,7 +616,7 @@ dependencies = [ [[package]] name = "serde_json" version = "1.0.60" -source = "git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3#380893814ad2a057758d825bab798aa117f7362a" +source = "git+https://github.com/mesalock-linux/serde-json-sgx#380893814ad2a057758d825bab798aa117f7362a" dependencies = [ "itoa 0.4.5", "ryu", diff --git a/rtc_data_enclave/Cargo.toml b/rtc_data_enclave/Cargo.toml index bea352c5..125aca25 100644 --- a/rtc_data_enclave/Cargo.toml +++ b/rtc_data_enclave/Cargo.toml @@ -31,11 +31,12 @@ rtc_types = { path = "../rtc_types", features = ["teaclave_sgx"] } rtc_tenclave = { path = "../rtc_tenclave" } [dependencies] -# XXX: See comment about serde-sgx dependency versioning in rtc_tenclave/Cargo.toml -serde_derive = { git = "https://github.com/mesalock-linux/serde-sgx" } +# See "Cargo patch limitation workaround" in HACKING.md: serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = ["derive"]} -bincode = { git = "https://github.com/mesalock-linux/bincode-sgx.git" } serde-big-array = { git = "https://github.com/mesalock-linux/serde-big-array-sgx" } +serde_derive = { git = "https://github.com/mesalock-linux/serde-sgx" } + +bincode = { git = "https://github.com/mesalock-linux/bincode-sgx.git" } simple_asn1 = { git = "https://github.com/mesalock-linux/simple_asn1-sgx.git" } thiserror = { git = "https://github.com/mesalock-linux/thiserror-sgx.git", tag = "sgx_1.1.3" } uuid = { git = "https://github.com/mesalock-linux/uuid-sgx", features = ["v4"] } diff --git a/rtc_data_service/tests/ecalls/issue_execution_token.rs b/rtc_data_service/tests/ecalls/issue_execution_token.rs new file mode 100644 index 00000000..4e015ec6 --- /dev/null +++ b/rtc_data_service/tests/ecalls/issue_execution_token.rs @@ -0,0 +1,91 @@ +use std::convert::TryInto; +use std::str::FromStr; + +use rtc_types::ExecReqMetadata; +use serde::{Deserialize, Serialize}; +use sgx_types::sgx_target_info_t; + +use crate::{helpers, CRYPTO_BOX_BOXZEROBYTES, CRYPTO_BOX_ZEROBYTES}; + +#[derive(Serialize, Deserialize)] +pub struct ExecReqData { + dataset_uuid: [u8; 16], + dataset_access_key: [u8; 24], + exec_module_hash: [u8; 32], + number_of_uses: u32, +} + +#[test] +fn test_issue_execution_token_success() { + let enclave = helpers::init_auth_enclave(); + + let enclave_pubkey = enclave + .create_report(&sgx_target_info_t::default()) + .unwrap() + .enclave_held_data; + + let mut pubkey = [0_u8; 32]; + let mut privkey = [0_u8; 32]; + + sodalite::box_keypair_seed(&mut pubkey, &mut privkey, &[2_u8; 32]); + + let uuid = uuid::Uuid::from_str("dd12012195c04ae8990ebd2512ae03ab").unwrap(); + let exec_module_hash: Vec = (0u8..32).collect(); + + let req_json = serde_json::to_vec(&ExecReqData { + dataset_uuid: *uuid.as_bytes(), + dataset_access_key: [1; 24], + exec_module_hash: exec_module_hash.try_into().unwrap(), + number_of_uses: 10, + }) + .unwrap(); + + let plaintext = [vec![0_u8; 32], req_json].concat(); + let mut ciphertext = vec![0_u8; plaintext.len()]; + let nonce = [8_u8; 24]; + + sodalite::box_( + &mut ciphertext, + &plaintext, + &nonce, + &enclave_pubkey, + &privkey, + ) + .unwrap(); + + let result = enclave + .issue_execution_token( + &ciphertext[CRYPTO_BOX_BOXZEROBYTES..], + ExecReqMetadata { + uploader_pub_key: pubkey, + nonce, + }, + ) + .unwrap(); + + let mut m = vec![0_u8; result.ciphertext.len() + CRYPTO_BOX_BOXZEROBYTES]; + + let padded_c = [ + vec![0u8; CRYPTO_BOX_BOXZEROBYTES], + result.ciphertext.to_vec(), + ] + .concat(); + + // TODO: Test bad privkey, nonce etc and ensure failure + + let open_result = + sodalite::box_open(&mut m, &padded_c, &result.nonce, &enclave_pubkey, &privkey); + + assert!(open_result.is_ok()); + + // Skip over the padding + let padding: &[u8; CRYPTO_BOX_ZEROBYTES] = + m[..CRYPTO_BOX_ZEROBYTES].try_into().expect("bad padding"); + + assert_eq!( + padding, &[0_u8; CRYPTO_BOX_ZEROBYTES], + "padding should be zero" + ); + + // TODO: Assert that decrypted value is a valid JWT +} diff --git a/rtc_data_service/tests/ecalls/mod.rs b/rtc_data_service/tests/ecalls/mod.rs index 422adaf7..4948a04c 100644 --- a/rtc_data_service/tests/ecalls/mod.rs +++ b/rtc_data_service/tests/ecalls/mod.rs @@ -1,3 +1,4 @@ //! ECALL tests +mod issue_execution_token; mod local_attestation; diff --git a/rtc_data_service/tests/main.rs b/rtc_data_service/tests/main.rs index 5b4f4d1b..6df53372 100644 --- a/rtc_data_service/tests/main.rs +++ b/rtc_data_service/tests/main.rs @@ -1,5 +1,9 @@ //! Top-level test module +// See rtc_tenclave/src/crypto.rs +pub const CRYPTO_BOX_ZEROBYTES: usize = 32; +pub const CRYPTO_BOX_BOXZEROBYTES: usize = 16; + mod helpers; mod ecalls; diff --git a/rtc_data_service/tests/web_api/data_upload.rs b/rtc_data_service/tests/web_api/data_upload.rs index f348b4b2..00cd8bef 100644 --- a/rtc_data_service/tests/web_api/data_upload.rs +++ b/rtc_data_service/tests/web_api/data_upload.rs @@ -13,8 +13,8 @@ use rtc_data_service::data_upload::models; use crate::helpers; // See rtc_tenclave/src/crypto.rs -const CRYPTO_BOX_ZEROBYTES: usize = 32; -const CRYPTO_BOX_BOXZEROBYTES: usize = 16; +use crate::CRYPTO_BOX_BOXZEROBYTES; +use crate::CRYPTO_BOX_ZEROBYTES; /// Upload some data, decrypt and check the result. #[actix_rt::test] diff --git a/rtc_exec_enclave/Cargo.lock b/rtc_exec_enclave/Cargo.lock index 934d8b41..8007a7b8 100644 --- a/rtc_exec_enclave/Cargo.lock +++ b/rtc_exec_enclave/Cargo.lock @@ -221,7 +221,7 @@ dependencies = [ [[package]] name = "once_cell" version = "1.4.0" -source = "git+https://github.com/mesalock-linux/once_cell-sgx.git?tag=sgx_1.1.3#cefcaa03fed4d85276b3235d875f1b45d399cc3c" +source = "git+https://github.com/mesalock-linux/once_cell-sgx.git#cefcaa03fed4d85276b3235d875f1b45d399cc3c" dependencies = [ "sgx_tstd", ] @@ -500,7 +500,7 @@ dependencies = [ [[package]] name = "serde_json" version = "1.0.60" -source = "git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3#380893814ad2a057758d825bab798aa117f7362a" +source = "git+https://github.com/mesalock-linux/serde-json-sgx#380893814ad2a057758d825bab798aa117f7362a" dependencies = [ "itoa 0.4.5", "ryu", diff --git a/rtc_tenclave/Cargo.lock b/rtc_tenclave/Cargo.lock index 2e467a1c..4153263a 100644 --- a/rtc_tenclave/Cargo.lock +++ b/rtc_tenclave/Cargo.lock @@ -255,7 +255,7 @@ dependencies = [ [[package]] name = "once_cell" version = "1.4.0" -source = "git+https://github.com/mesalock-linux/once_cell-sgx.git?tag=sgx_1.1.3#cefcaa03fed4d85276b3235d875f1b45d399cc3c" +source = "git+https://github.com/mesalock-linux/once_cell-sgx.git#cefcaa03fed4d85276b3235d875f1b45d399cc3c" dependencies = [ "sgx_tstd", ] @@ -710,7 +710,7 @@ checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" [[package]] name = "serde_json" version = "1.0.60" -source = "git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3#380893814ad2a057758d825bab798aa117f7362a" +source = "git+https://github.com/mesalock-linux/serde-json-sgx#380893814ad2a057758d825bab798aa117f7362a" dependencies = [ "itoa 0.4.5", "ryu", diff --git a/rtc_tenclave/Cargo.toml b/rtc_tenclave/Cargo.toml index faa2c0cb..e0914a69 100644 --- a/rtc_tenclave/Cargo.toml +++ b/rtc_tenclave/Cargo.toml @@ -24,34 +24,11 @@ rand = { git = "https://github.com/mesalock-linux/rand-sgx", tag = "v0.7.3_sgx1. thiserror = { git = "https://github.com/mesalock-linux/thiserror-sgx.git", tag = "sgx_1.1.3", optional = true } sgx_tcrypto = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", optional = true } sgx_tdh = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", features = ["use_lav2"], optional = true } -once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx.git", tag = "sgx_1.1.3", optional = true } -# XXX: Work around serde-json-sgx / Cargo version handling issue -# -# We want to specify tag = "sgx_1.1.3" for the serde dependency here, -# but this makes Cargo resolve the dependency to a different crate -# version identity than what serde-json-sgx's dependency resolves to, -# even though both "master" and "sgx_1.1.3" point to same git revision. -# -# This causes build failures due to serde_json referring to a different -# versions of the Serialize / Deserialize traits than this project's code. -# -# We cannot use [patch] to override serde-json-sgx's dependency to use -# the same tag for serde-sgx as here, because of this Cargo limitation: -# -# * "Cannot patch underspecified git dependency" -# https://github.com/rust-lang/cargo/issues/7670 -# -# Comment: https://github.com/rust-lang/cargo/issues/7670#issuecomment-841722488 -# -# To work around this problem, the git reference here must match -# the upstream dependency line exactly: -# -# * https://github.com/mesalock-linux/serde-json-sgx/blob/sgx_1.1.3/Cargo.toml#L17 -# +# See "Cargo patch limitation workaround" in HACKING.md: +once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx.git", optional = true } serde = { git = "https://github.com/mesalock-linux/serde-sgx", optional = true } - -serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx", tag = "sgx_1.1.3", optional = true } +serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx", optional = true } rtc_types = { path = "../rtc_types" } sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", features = ["extra_traits"] } diff --git a/rtc_tenclave/src/kv_store/fs/mod.rs b/rtc_tenclave/src/kv_store/fs/mod.rs index c199a6f6..18968e1f 100644 --- a/rtc_tenclave/src/kv_store/fs/mod.rs +++ b/rtc_tenclave/src/kv_store/fs/mod.rs @@ -5,6 +5,9 @@ pub mod std_filer; #[cfg(not(test))] pub mod sgx_filer; +#[cfg(not(test))] +pub use sgx_filer::SgxFiler; + // sgx_tstd (v1.1.3) does not support `fs::read_dir`, so limit the following to tests, for now. // // See: https://github.com/apache/incubator-teaclave-sgx-sdk/blob/v1.1.3/release_notes.md#partially-supported-modstraits-in-sgx_tstd diff --git a/rtc_tenclave/src/kv_store/mod.rs b/rtc_tenclave/src/kv_store/mod.rs index 6985944e..2edd5901 100644 --- a/rtc_tenclave/src/kv_store/mod.rs +++ b/rtc_tenclave/src/kv_store/mod.rs @@ -1,6 +1,6 @@ //! Simple key-value store abstraction -mod fs; +pub mod fs; mod in_memory; /// A key-value store. diff --git a/rtc_types/src/exec_token.rs b/rtc_types/src/exec_token.rs index 494f46b9..fb84c415 100644 --- a/rtc_types/src/exec_token.rs +++ b/rtc_types/src/exec_token.rs @@ -1,20 +1,26 @@ +use std::io; use std::vec::Vec; + use thiserror::Error; +use crate::{CryptoError, EcallResult, Nonce}; + #[repr(C)] #[derive(Debug)] pub struct ExecReqMetadata { pub uploader_pub_key: [u8; 32], - pub nonce: [u8; 24], + pub nonce: Nonce, } #[repr(C)] #[derive(Debug)] pub struct ExecTokenResponse { pub execution_token: Vec, - pub nonce: [u8; 24], + pub nonce: Nonce, } +pub type IssueTokenResult = EcallResult; + #[repr(C)] #[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Debug, Error)] pub enum ExecTokenError { @@ -22,4 +28,22 @@ pub enum ExecTokenError { Generate, #[error("Data validation failed")] Validation, + #[error("Output token buffer is either to small or too large")] + OutputBufferSize, + #[error("Encryption/Decryption failed")] + Crypto, + #[error("IO operation failed")] + IO, +} + +impl From for ExecTokenError { + fn from(_: CryptoError) -> Self { + ExecTokenError::Crypto + } +} + +impl From for ExecTokenError { + fn from(_: io::Error) -> Self { + ExecTokenError::IO + } } diff --git a/rtc_types/src/lib.rs b/rtc_types/src/lib.rs index 9af98c19..e3c46650 100644 --- a/rtc_types/src/lib.rs +++ b/rtc_types/src/lib.rs @@ -32,6 +32,8 @@ pub use ecall_result::*; pub mod byte_formats; pub mod enclave_messages; +pub type Nonce = [u8; 24]; + #[repr(C)] #[derive(Clone, Debug)] pub struct EncryptedMessage { diff --git a/rtc_uenclave/src/enclaves/rtc_auth.rs b/rtc_uenclave/src/enclaves/rtc_auth.rs index 8a65ee3d..579a706c 100644 --- a/rtc_uenclave/src/enclaves/rtc_auth.rs +++ b/rtc_uenclave/src/enclaves/rtc_auth.rs @@ -2,6 +2,7 @@ use std::borrow::Borrow; use crate::{AttestationError, EnclaveConfig, EnclaveReportResult, RtcEnclave}; use auth_sys::AuthSys; +use rtc_types::{EcallError, EncryptedMessage, ExecReqMetadata, ExecTokenError}; use sgx_types::*; /// Wraps all the functionality for interacting with the auth enclave @@ -47,4 +48,53 @@ where pub fn geteid(&self) -> sgx_enclave_id_t { self.0.geteid() } + + /// Issues an execution token using the provided payload + pub fn issue_execution_token( + &self, + payload: &[u8], + metadata: ExecReqMetadata, + ) -> Result> { + ecalls::issue_execution_token(self.geteid(), payload, metadata) + } +} + +pub mod ecalls { + use auth_sys::ffi; + use rtc_types::*; + use sgx_types::*; + + pub fn issue_execution_token( + eid: sgx_enclave_id_t, + payload: &[u8], + metadata: ExecReqMetadata, + ) -> Result> { + // See MAX / MIN_OUT_TOKEN_LEN in rtc_auth_enclave + let mut out_token_buffer = vec![0u8; 500]; + let mut out_token_used = 0; + let mut retval = IssueTokenResult::Ok([0u8; 24]); + + // Safety: Since the payload, and out buffer is allocated and valid this will be + // correctly handled by the SGX edge code + let res = unsafe { + ffi::rtc_auth_issue_execution_token( + eid, + &mut retval, + payload.as_ptr(), + payload.len(), + &metadata, + out_token_buffer.as_mut_ptr(), + out_token_buffer.len(), + &mut out_token_used, + ) + }; + + let x: Result> = retval.to_ecall_err(res).into(); + + x.map(|nonce| { + out_token_buffer.truncate(out_token_used); + let ciphertext = out_token_buffer.into_boxed_slice(); + EncryptedMessage { ciphertext, nonce } + }) + } }