From fd16c3378c910d6d5a3d038f9be0047ac2fc1722 Mon Sep 17 00:00:00 2001 From: Petr Evstifeev Date: Mon, 4 Apr 2022 13:21:46 +0300 Subject: [PATCH] check the hash of a pf if the file is in both lists (pf and tf) --- Pal/src/host/Linux-SGX/db_files.c | 16 ++++++++ Pal/src/host/Linux-SGX/enclave_pf.c | 63 +++++++++++++++++++++++++++++ Pal/src/host/Linux-SGX/enclave_pf.h | 3 ++ 3 files changed, 82 insertions(+) diff --git a/Pal/src/host/Linux-SGX/db_files.c b/Pal/src/host/Linux-SGX/db_files.c index 6fdf33224b..c0774facc0 100644 --- a/Pal/src/host/Linux-SGX/db_files.c +++ b/Pal/src/host/Linux-SGX/db_files.c @@ -156,6 +156,22 @@ static int file_open(PAL_HANDLE* handle, const char* type, const char* uri, goto fail_pf_unlock; } + if (tf && !tf->allowed) { + if (do_create || (pal_access == PAL_ACCESS_RDWR) || (pal_access == PAL_ACCESS_WRONLY)) { + log_error("Disallowing create/write/append to a protected file '%s' with fixed hash", + hdl->file.realpath); + ret = -PAL_ERROR_DENIED; + goto fail_pf_unlock; + } + + if (!protected_file_check_hash(pf->context, &tf->file_hash)) { + log_error("Hash of trusted/protected file '%s' does not match with the reference hash in manifest", + pf->path); + ret = -PAL_ERROR_DENIED; + goto fail_pf_unlock; + } + } + if (pf_mode & PF_FILE_MODE_WRITE) { pf->writable_fd = fd; } diff --git a/Pal/src/host/Linux-SGX/enclave_pf.c b/Pal/src/host/Linux-SGX/enclave_pf.c index f71037ca15..4ac808ed0d 100644 --- a/Pal/src/host/Linux-SGX/enclave_pf.c +++ b/Pal/src/host/Linux-SGX/enclave_pf.c @@ -809,3 +809,66 @@ int set_protected_files_key(const char* pf_key_hex) { return 0; } + +bool protected_file_check_hash(pf_context_t* pf, const sgx_file_hash_t *file_hash) +{ + if (!pf) { + log_warning("protected_file_check_hash: PF not initialized"); + return false; + } + + if (!file_hash) { + log_warning("protected_file_check_hash: file_hash must be initialized"); + return false; + } + + uint64_t file_size = 0u; + pf_get_size(pf, &file_size); + + LIB_SHA256_CONTEXT file_sha; + int ret = lib_SHA256Init(&file_sha); + if (ret < 0) { + log_error("Error during hash initialization"); + return false; + } + + uint64_t offset = 0; + size_t bytes_read = 0; + pf_status_t pfs = PF_STATUS_SUCCESS; + uint8_t buffer[PF_NODE_SIZE]; + + while (true) { + uint64_t chunk_size = MIN(file_size - offset, PF_NODE_SIZE); + if (chunk_size == 0) { + break; + } + + pfs = pf_read(pf, offset, chunk_size, buffer, &bytes_read); + if (bytes_read != chunk_size) { + pfs = PF_STATUS_CORRUPTED; + } + + if (PF_FAILURE(pfs)) { + log_error("Read from protected file failed (offset %lu, size %lu): %s\n", + offset, chunk_size, pf_strerror(pfs)); + return false; + } + + ret = lib_SHA256Update(&file_sha, buffer, chunk_size); + if (ret < 0) { + log_error("Error during hash update"); + return false; + } + + offset += bytes_read; + } + + sgx_file_hash_t pf_file_hash; + ret = lib_SHA256Final(&file_sha, pf_file_hash.bytes); + + if (memcmp(&pf_file_hash, file_hash, sizeof(pf_file_hash))) { + return false; + } + + return true; +} diff --git a/Pal/src/host/Linux-SGX/enclave_pf.h b/Pal/src/host/Linux-SGX/enclave_pf.h index b5549bca59..a628905477 100644 --- a/Pal/src/host/Linux-SGX/enclave_pf.h +++ b/Pal/src/host/Linux-SGX/enclave_pf.h @@ -105,4 +105,7 @@ struct protected_file* find_protected_file_handle(PAL_HANDLE handle); /* Initialize the PF library, register PFs from the manifest */ int init_protected_files(void); +/* Сalculates the hash and compares with the given one */ +bool protected_file_check_hash(pf_context_t* pf, const sgx_file_hash_t *file_hash); + #endif /* ENCLAVE_PF_H_ */