From c17f4ceb94e22cfcb3050eb6fa43dd17ef3010a0 Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Thu, 11 Apr 2024 05:56:43 -0700 Subject: [PATCH 1/4] [common] Refactor Protected Files slightly This commit refactors PF code without changing functionality: - Many renames of data structs, variable names, func names - More readable comments (and fixing incorrect comments) - Removed unused `pf_get_handle()` - Removed unused `g_pf_mrenclave_key`, `g_pf_wrap_key`, etc. - Removed all mentions of `list`/`LIST` operations (were unused) This commit contains changes (renames) in `pf_tamper.c`, but this file and corresponding tool are not tested and most probably broken. We did the changes purely to survive compilation. Signed-off-by: Dmitrii Kuvaiskii --- common/src/protected_files/protected_files.c | 738 ++++++++---------- common/src/protected_files/protected_files.h | 34 +- .../protected_files/protected_files_format.h | 128 ++- .../protected_files_internal.h | 27 +- tools/sgx/pf_tamper/pf_tamper.c | 192 ++--- 5 files changed, 527 insertions(+), 592 deletions(-) diff --git a/common/src/protected_files/protected_files.c b/common/src/protected_files/protected_files.c index 40ad501c75..a7f887d19e 100644 --- a/common/src/protected_files/protected_files.c +++ b/common/src/protected_files/protected_files.c @@ -64,12 +64,11 @@ static const char* g_pf_error_list[] = { }; /* ipf prefix means "Intel protected files", these are functions from the SGX SDK implementation */ -static file_node_t* ipf_append_mht_node(pf_context_t* pf, uint64_t mht_node_number); +static file_node_t* ipf_append_mht_node(pf_context_t* pf, uint64_t logical_mht_node_number); static file_node_t* ipf_append_data_node(pf_context_t* pf, uint64_t offset); -static file_node_t* ipf_read_mht_node(pf_context_t* pf, uint64_t mht_node_number); +static file_node_t* ipf_read_mht_node(pf_context_t* pf, uint64_t logical_mht_node_number); static file_node_t* ipf_read_data_node(pf_context_t* pf, uint64_t offset); -// memcpy src->dest if src is not NULL, zero dest otherwise static void memcpy_or_zero_initialize(void* dest, const void* src, size_t size) { if (src) memcpy(dest, src, size); @@ -99,9 +98,9 @@ static size_t partition(file_node_t** data, size_t low, size_t high) { size_t j = high; while (true) { - while (data[i]->node_number < pivot->node_number) + while (data[i]->logical_node_number < pivot->logical_node_number) i++; - while (data[j]->node_number > pivot->node_number) + while (data[j]->logical_node_number > pivot->logical_node_number) j--; if (i >= j) return j; @@ -113,7 +112,7 @@ static size_t partition(file_node_t** data, size_t low, size_t high) { static void sort_nodes(file_node_t** data, size_t low, size_t high) { if (high - low == 1) { - if (data[low]->node_number > data[high]->node_number) + if (data[low]->logical_node_number > data[high]->logical_node_number) swap_nodes(data, low, high); return; } @@ -140,14 +139,14 @@ static bool ipf_generate_random_key(pf_context_t* pf, pf_key_t* output) { // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-108.pdf // // This function derives a metadata key in two modes: -// - restore == false: derives a per-file random key from user_kdk_key using a random nonce, to -// encrypt the metadata block of the protected file; the nonce is stored in -// plaintext part of the metadata block so that the file can be loaded later -// and decrypted using the same key -// - restore == true: derives a key from user_kdk_key + nonce stored in plaintext part of the -// metadata block, to decrypt the encrypted part of the metadata block (and -// thus "restore" access to the whole protected file) -static bool ipf_import_metadata_key(pf_context_t* pf, bool restore, pf_key_t* output) { +// - salt_from_pf == false: derives a per-file random key from kdk using a random salt, to +// encrypt the metadata node of the protected file; the salt is stored in +// plaintext header of the metadata node so that the file can be loaded +// later and decrypted using the same key +// - salt_from_pf == true: derives a key from kdk + salt stored in plaintext header of the +// metadata node, to decrypt the encrypted part of the metadata node (and +// thus gain access to the whole protected file) +static bool ipf_generate_metadata_key(pf_context_t* pf, bool salt_from_pf, pf_key_t* output) { kdf_input_t buf = {0}; pf_status_t status; @@ -155,160 +154,148 @@ static bool ipf_import_metadata_key(pf_context_t* pf, bool restore, pf_key_t* ou if (!strcpy_static(buf.label, METADATA_KEY_NAME, MAX_LABEL_SIZE)) return false; - if (!restore) { - status = g_cb_random((uint8_t*)&buf.nonce, sizeof(buf.nonce)); + if (!salt_from_pf) { + status = g_cb_random((uint8_t*)&buf.key_salt, sizeof(buf.key_salt)); if (PF_FAILURE(status)) { pf->last_error = status; return false; } } else { - COPY_ARRAY(buf.nonce, pf->file_metadata.plain_part.metadata_key_id); + COPY_ARRAY(buf.key_salt, pf->metadata_node.plaintext_header.metadata_key_salt); } - // length of output (128 bits) buf.output_len = 0x80; - status = g_cb_aes_cmac(&pf->user_kdk_key, &buf, sizeof(buf), output); + status = g_cb_aes_cmac(&pf->kdk, &buf, sizeof(buf), output); if (PF_FAILURE(status)) { pf->last_error = status; return false; } - if (!restore) { - COPY_ARRAY(pf->file_metadata.plain_part.metadata_key_id, buf.nonce); + if (!salt_from_pf) { + COPY_ARRAY(pf->metadata_node.plaintext_header.metadata_key_salt, buf.key_salt); } erase_memory(&buf, sizeof(buf)); - return true; } static bool ipf_generate_random_metadata_key(pf_context_t* pf, pf_key_t* output) { - return ipf_import_metadata_key(pf, /*restore=*/false, output); + return ipf_generate_metadata_key(pf, /*salt_from_pf=*/false, output); } -static bool ipf_restore_current_metadata_key(pf_context_t* pf, pf_key_t* output) { - return ipf_import_metadata_key(pf, /*restore=*/true, output); +static bool ipf_generate_salted_metadata_key(pf_context_t* pf, pf_key_t* output) { + return ipf_generate_metadata_key(pf, /*salt_from_pf=*/true, output); } -static void ipf_init_root_mht(file_node_t* mht) { - memset(mht, 0, sizeof(*mht)); +static void ipf_init_root_mht_node(file_node_t* mht_node) { + memset(mht_node, 0, sizeof(*mht_node)); - mht->type = FILE_MHT_NODE_TYPE; - mht->physical_node_number = 1; - mht->node_number = 0; - mht->need_writing = false; + mht_node->type = FILE_MHT_NODE_TYPE; + mht_node->physical_node_number = 1; + mht_node->logical_node_number = 0; + mht_node->need_writing = false; } static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { bool ret = false; - file_node_t** mht_array = NULL; + file_node_t** mht_nodes_array = NULL; pf_status_t status; - void* data = lruc_get_first(pf->cache); - - // 1. encrypt the changed data - // 2. set the IV+GMAC in the parent MHT - // [3. set the need_writing flag for all the parents] - while (data != NULL) { - if (((file_node_t*)data)->type == FILE_DATA_NODE_TYPE) { - file_node_t* data_node = (file_node_t*)data; - - if (data_node->need_writing) { - gcm_crypto_data_t* gcm_crypto_data = - &data_node->parent->decrypted.mht - .data_nodes_crypto[data_node->node_number % ATTACHED_DATA_NODES_COUNT]; - - if (!ipf_generate_random_key(pf, &gcm_crypto_data->key)) - goto out; - - // encrypt the data, this also saves the gmac of the operation in the mht crypto - // node - status = g_cb_aes_gcm_encrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, // aad - data_node->decrypted.data.data, PF_NODE_SIZE, - data_node->encrypted.cipher, &gcm_crypto_data->gmac); - if (PF_FAILURE(status)) { - pf->last_error = status; - goto out; - } + void* node; + + // 1. encrypt the changed data nodes + // 2. set the key + GMAC in the parent MHT nodes + // 3. set the need_writing flag for all parent MHT nodes + for (node = lruc_get_first(pf->cache); node != NULL; node = lruc_get_next(pf->cache)) { + if (((file_node_t*)node)->type != FILE_DATA_NODE_TYPE) + continue; + + file_node_t* data_node = (file_node_t*)node; + if (!data_node->need_writing) + continue; + + gcm_crypto_data_t* gcm_crypto_data = + &data_node->parent->decrypted.mht + .data_nodes_crypto[data_node->logical_node_number % ATTACHED_DATA_NODES_COUNT]; + + if (!ipf_generate_random_key(pf, &gcm_crypto_data->key)) + goto out; + + // encrypt data node, this also saves GMAC in the corresponding crypto slot of MHT node + status = g_cb_aes_gcm_encrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, // aad + &data_node->decrypted.data.bytes, PF_NODE_SIZE, + &data_node->encrypted.bytes, &gcm_crypto_data->gmac); + if (PF_FAILURE(status)) { + pf->last_error = status; + goto out; + } #ifdef DEBUG - file_node_t* file_mht_node = data_node->parent; - // this loop should do nothing, add it here just to be safe - while (file_mht_node->node_number != 0) { - assert(file_mht_node->need_writing == true); - file_mht_node = file_mht_node->parent; - } -#endif - } + file_node_t* mht_node = data_node->parent; + while (mht_node->logical_node_number != 0) { + assert(mht_node->need_writing == true); + mht_node = mht_node->parent; } - data = lruc_get_next(pf->cache); +#endif } + // count dirty MHT nodes size_t dirty_count = 0; - - // count dirty mht nodes - data = lruc_get_first(pf->cache); - while (data != NULL) { - if (((file_node_t*)data)->type == FILE_MHT_NODE_TYPE) { - if (((file_node_t*)data)->need_writing) + for (node = lruc_get_first(pf->cache); node != NULL; node = lruc_get_next(pf->cache)) { + if (((file_node_t*)node)->type == FILE_MHT_NODE_TYPE) { + if (((file_node_t*)node)->need_writing) dirty_count++; } - data = lruc_get_next(pf->cache); } - // add all the mht nodes that needs writing to a list - mht_array = malloc(dirty_count * sizeof(*mht_array)); - if (!mht_array) { + // add all the MHT nodes that need writing to a list + mht_nodes_array = malloc(dirty_count * sizeof(*mht_nodes_array)); + if (!mht_nodes_array) { pf->last_error = PF_STATUS_NO_MEMORY; goto out; } - data = lruc_get_first(pf->cache); uint64_t dirty_idx = 0; - while (data != NULL) { - if (((file_node_t*)data)->type == FILE_MHT_NODE_TYPE) { - file_node_t* file_mht_node = (file_node_t*)data; - - if (file_mht_node->need_writing) - mht_array[dirty_idx++] = file_mht_node; + for (node = lruc_get_first(pf->cache); node != NULL; node = lruc_get_next(pf->cache)) { + if (((file_node_t*)node)->type == FILE_MHT_NODE_TYPE) { + file_node_t* mht_node = (file_node_t*)node; + if (mht_node->need_writing) + mht_nodes_array[dirty_idx++] = mht_node; } - - data = lruc_get_next(pf->cache); } if (dirty_count > 0) - sort_nodes(mht_array, 0, dirty_count - 1); + sort_nodes(mht_nodes_array, 0, dirty_count - 1); - // update the gmacs in the parents from last node to first (bottom layers first) + // update the keys and GMACs in the parents from last node to first (bottom layers first) for (dirty_idx = dirty_count; dirty_idx > 0; dirty_idx--) { - file_node_t* file_mht_node = mht_array[dirty_idx - 1]; + file_node_t* mht_node = mht_nodes_array[dirty_idx - 1]; gcm_crypto_data_t* gcm_crypto_data = - &file_mht_node->parent->decrypted.mht - .mht_nodes_crypto[(file_mht_node->node_number - 1) % CHILD_MHT_NODES_COUNT]; + &mht_node->parent->decrypted.mht + .mht_nodes_crypto[(mht_node->logical_node_number - 1) % CHILD_MHT_NODES_COUNT]; - if (!ipf_generate_random_key(pf, &gcm_crypto_data->key)) { + if (!ipf_generate_random_key(pf, &gcm_crypto_data->key)) goto out; - } status = g_cb_aes_gcm_encrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, - &file_mht_node->decrypted.mht, PF_NODE_SIZE, - &file_mht_node->encrypted.cipher, &gcm_crypto_data->gmac); + &mht_node->decrypted.mht, PF_NODE_SIZE, + &mht_node->encrypted.bytes, &gcm_crypto_data->gmac); if (PF_FAILURE(status)) { pf->last_error = status; goto out; } } - // update mht root gmac in the meta data node - if (!ipf_generate_random_key(pf, &pf->encrypted_part_plain.mht_key)) + // update root MHT node's key and GMAC in the metadata node's headers + if (!ipf_generate_random_key(pf, &pf->metadata_decrypted_header.root_mht_node_key)) goto out; - status = g_cb_aes_gcm_encrypt(&pf->encrypted_part_plain.mht_key, &g_empty_iv, + status = g_cb_aes_gcm_encrypt(&pf->metadata_decrypted_header.root_mht_node_key, &g_empty_iv, NULL, 0, - &pf->root_mht.decrypted.mht, PF_NODE_SIZE, - &pf->root_mht.encrypted.cipher, - &pf->encrypted_part_plain.mht_gmac); + &pf->root_mht_node.decrypted.mht, PF_NODE_SIZE, + &pf->root_mht_node.encrypted.bytes, + &pf->metadata_decrypted_header.root_mht_node_gmac); if (PF_FAILURE(status)) { pf->last_error = status; goto out; @@ -317,15 +304,14 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { ret = true; out: - free(mht_array); + free(mht_nodes_array); return ret; } -static bool ipf_read_node(pf_context_t* pf, pf_handle_t handle, uint64_t node_number, void* buffer, - uint32_t node_size) { - uint64_t offset = node_number * node_size; +static bool ipf_read_node(pf_context_t* pf, uint64_t logical_node_number, void* buffer) { + uint64_t offset = logical_node_number * PF_NODE_SIZE; - pf_status_t status = g_cb_read(handle, buffer, offset, node_size); + pf_status_t status = g_cb_read(pf->host_file_handle, buffer, offset, PF_NODE_SIZE); if (PF_FAILURE(status)) { pf->last_error = status; return false; @@ -334,9 +320,10 @@ static bool ipf_read_node(pf_context_t* pf, pf_handle_t handle, uint64_t node_nu return true; } -static bool ipf_write_file(pf_context_t* pf, pf_handle_t handle, uint64_t offset, void* buffer, - uint32_t size) { - pf_status_t status = g_cb_write(handle, buffer, offset, size); +static bool ipf_write_node(pf_context_t* pf, uint64_t logical_node_number, void* buffer) { + uint64_t offset = logical_node_number * PF_NODE_SIZE; + + pf_status_t status = g_cb_write(pf->host_file_handle, buffer, offset, PF_NODE_SIZE); if (PF_FAILURE(status)) { pf->last_error = status; return false; @@ -345,48 +332,44 @@ static bool ipf_write_file(pf_context_t* pf, pf_handle_t handle, uint64_t offset return true; } -static bool ipf_write_node(pf_context_t* pf, pf_handle_t handle, uint64_t node_number, void* buffer, - uint32_t node_size) { - return ipf_write_file(pf, handle, node_number * node_size, buffer, node_size); -} - // this is a very 'specific' function, tied to the architecture of the file layout, // returning the node numbers according to the data offset in the file -static void get_node_numbers(uint64_t offset, uint64_t* mht_node_number, uint64_t* data_node_number, +static void get_node_numbers(uint64_t offset, uint64_t* logical_mht_node_number, + uint64_t* logical_data_node_number, uint64_t* physical_mht_node_number, uint64_t* physical_data_node_number) { // physical nodes (file layout): - // node 0 - meta data node - // node 1 - mht - // nodes 2-97 - data (ATTACHED_DATA_NODES_COUNT == 96) - // node 98 - mht - // node 99-195 - data + // node 0 - metadata node + // node 1 - root MHT node + // nodes 2-97 - data node (ATTACHED_DATA_NODES_COUNT == 96) + // node 98 - MHT node + // node 99-195 - data node // etc. uint64_t _physical_mht_node_number; uint64_t _physical_data_node_number; - // "logical" nodes: sequential index of the corresponding mht/data node in all mht/data nodes - uint64_t _mht_node_number; - uint64_t _data_node_number; + // "logical" nodes: sequential index of the corresponding MHT/data node in all MHT/data nodes + uint64_t _logical_mht_node_number; + uint64_t _logical_data_node_number; assert(offset >= MD_USER_DATA_SIZE); - _data_node_number = (offset - MD_USER_DATA_SIZE) / PF_NODE_SIZE; - _mht_node_number = _data_node_number / ATTACHED_DATA_NODES_COUNT; - _physical_data_node_number = _data_node_number - + 1 // meta data node - + 1 // mht root - + _mht_node_number; // number of mht nodes in the middle - // (the root mht mht_node_number is 0) + _logical_data_node_number = (offset - MD_USER_DATA_SIZE) / PF_NODE_SIZE; + _logical_mht_node_number = _logical_data_node_number / ATTACHED_DATA_NODES_COUNT; + _physical_data_node_number = _logical_data_node_number + + 1 // metadata node + + 1 // MHT root node + + _logical_mht_node_number; // number of MHT nodes in the middle + // (the logical_mht_node_number of root MHT node is 0) _physical_mht_node_number = _physical_data_node_number - - _data_node_number % ATTACHED_DATA_NODES_COUNT // now we are at - // the first data node attached to this mht node - - 1; // and now at the mht node itself! - - if (mht_node_number != NULL) - *mht_node_number = _mht_node_number; - if (data_node_number != NULL) - *data_node_number = _data_node_number; + - _logical_data_node_number % ATTACHED_DATA_NODES_COUNT + // now we are at the first data node attached to this MHT node + - 1; // and now at the MHT node itself + + if (logical_mht_node_number != NULL) + *logical_mht_node_number = _logical_mht_node_number; + if (logical_data_node_number != NULL) + *logical_data_node_number = _logical_data_node_number; if (physical_mht_node_number != NULL) *physical_mht_node_number = _physical_mht_node_number; if (physical_data_node_number != NULL) @@ -394,38 +377,34 @@ static void get_node_numbers(uint64_t offset, uint64_t* mht_node_number, uint64_ } static bool ipf_write_all_changes_to_disk(pf_context_t* pf) { - if (pf->encrypted_part_plain.size > MD_USER_DATA_SIZE && pf->root_mht.need_writing) { - void* data = NULL; + if (pf->metadata_decrypted_header.file_size > MD_USER_DATA_SIZE + && pf->root_mht_node.need_writing) { uint8_t* data_to_write; - uint64_t node_number; - file_node_t* file_node; + uint64_t logical_node_number; - for (data = lruc_get_first(pf->cache); data != NULL; data = lruc_get_next(pf->cache)) { - file_node = (file_node_t*)data; + void* node = NULL; + for (node = lruc_get_first(pf->cache); node != NULL; node = lruc_get_next(pf->cache)) { + file_node_t* file_node = (file_node_t*)node; if (!file_node->need_writing) continue; data_to_write = (uint8_t*)&file_node->encrypted; - node_number = file_node->physical_node_number; + logical_node_number = file_node->physical_node_number; - if (!ipf_write_node(pf, pf->file, node_number, data_to_write, PF_NODE_SIZE)) { + if (!ipf_write_node(pf, logical_node_number, data_to_write)) return false; - } file_node->need_writing = false; } - if (!ipf_write_node(pf, pf->file, /*node_number=*/1, &pf->root_mht.encrypted, - PF_NODE_SIZE)) { + if (!ipf_write_node(pf, /*logical_node_number=*/1, &pf->root_mht_node.encrypted)) return false; - } - pf->root_mht.need_writing = false; + pf->root_mht_node.need_writing = false; } - if (!ipf_write_node(pf, pf->file, /*node_number=*/0, &pf->file_metadata, PF_NODE_SIZE)) { + if (!ipf_write_node(pf, /*logical_node_number=*/0, &pf->metadata_node)) return false; - } return true; } @@ -434,16 +413,17 @@ static bool ipf_update_metadata_node(pf_context_t* pf) { pf_status_t status; pf_key_t key; - // randomize a new key, saves the key _id_ in the meta data plain part + // new key for metadata node encryption, saves the key salt in metadata plaintext header if (!ipf_generate_random_metadata_key(pf, &key)) { // last error already set return false; } - // encrypt meta data encrypted part, also updates the gmac in the meta data plain part - status = g_cb_aes_gcm_encrypt(&key, &g_empty_iv, NULL, 0, &pf->encrypted_part_plain, - sizeof(metadata_encrypted_t), &pf->file_metadata.encrypted_part, - &pf->file_metadata.plain_part.metadata_gmac); + // encrypt metadata part-to-be-encrypted, also updates the GMAC in metadata plaintext header + status = g_cb_aes_gcm_encrypt(&key, &g_empty_iv, NULL, 0, &pf->metadata_decrypted_header, + sizeof(metadata_decrypted_header_t), + &pf->metadata_node.encrypted_blob, + &pf->metadata_node.plaintext_header.metadata_gmac); if (PF_FAILURE(status)) { pf->last_error = status; return false; @@ -454,17 +434,16 @@ static bool ipf_update_metadata_node(pf_context_t* pf) { static bool ipf_internal_flush(pf_context_t* pf) { if (!pf->need_writing) { - // no changes at all DEBUG_PF("no need to write"); return true; } - if (pf->encrypted_part_plain.size > MD_USER_DATA_SIZE && pf->root_mht.need_writing) { - // otherwise it's just one write - the meta-data node + if (pf->metadata_decrypted_header.file_size > MD_USER_DATA_SIZE && + pf->root_mht_node.need_writing) { if (!ipf_update_all_data_and_mht_nodes(pf)) { // this is something that shouldn't happen, can't fix this... pf->file_status = PF_STATUS_CRYPTO_ERROR; - DEBUG_PF("failed to update data nodes"); + DEBUG_PF("failed to update data and MHT nodes"); return false; } } @@ -472,25 +451,23 @@ static bool ipf_internal_flush(pf_context_t* pf) { if (!ipf_update_metadata_node(pf)) { // this is something that shouldn't happen, can't fix this... pf->file_status = PF_STATUS_CRYPTO_ERROR; - DEBUG_PF("failed to update metadata nodes"); + DEBUG_PF("failed to update metadata node"); return false; } if (!ipf_write_all_changes_to_disk(pf)) { pf->file_status = PF_STATUS_WRITE_TO_DISK_FAILED; - DEBUG_PF("failed to write changes to disk"); return false; } pf->need_writing = false; - return true; } static file_node_t* ipf_get_mht_node(pf_context_t* pf, uint64_t offset) { - file_node_t* file_mht_node; - uint64_t mht_node_number; + file_node_t* mht_node; + uint64_t logical_mht_node_number; uint64_t physical_mht_node_number; if (offset < MD_USER_DATA_SIZE) { @@ -498,99 +475,91 @@ static file_node_t* ipf_get_mht_node(pf_context_t* pf, uint64_t offset) { return NULL; } - get_node_numbers(offset, &mht_node_number, NULL, &physical_mht_node_number, NULL); + get_node_numbers(offset, &logical_mht_node_number, NULL, &physical_mht_node_number, NULL); - if (mht_node_number == 0) - return &pf->root_mht; + if (logical_mht_node_number == 0) + return &pf->root_mht_node; - // file is constructed from (ATTACHED_DATA_NODES_COUNT + CHILD_MHT_NODES_COUNT) * PF_NODE_SIZE - // bytes per MHT node if ((offset - MD_USER_DATA_SIZE) % (ATTACHED_DATA_NODES_COUNT * PF_NODE_SIZE) == 0 && - offset == pf->encrypted_part_plain.size) { - file_mht_node = ipf_append_mht_node(pf, mht_node_number); + offset == pf->metadata_decrypted_header.file_size) { + mht_node = ipf_append_mht_node(pf, logical_mht_node_number); } else { - file_mht_node = ipf_read_mht_node(pf, mht_node_number); + mht_node = ipf_read_mht_node(pf, logical_mht_node_number); } - return file_mht_node; + return mht_node; } -static file_node_t* ipf_append_mht_node(pf_context_t* pf, uint64_t mht_node_number) { - assert(mht_node_number > 0); - file_node_t* parent_file_mht_node = - ipf_read_mht_node(pf, (mht_node_number - 1) / CHILD_MHT_NODES_COUNT); +static file_node_t* ipf_append_mht_node(pf_context_t* pf, uint64_t logical_mht_node_number) { + assert(logical_mht_node_number > 0); + file_node_t* parent_mht_node = + ipf_read_mht_node(pf, (logical_mht_node_number - 1) / CHILD_MHT_NODES_COUNT); - if (parent_file_mht_node == NULL) // some error happened + if (parent_mht_node == NULL) return NULL; - uint64_t physical_node_number = 1 + // meta data node - // the '1' is for the mht node preceding every 96 data nodes - mht_node_number * (1 + ATTACHED_DATA_NODES_COUNT); + uint64_t physical_node_number = 1 + // metadata node + // the '1' is for the MHT node preceding every 96 data nodes + logical_mht_node_number * (1 + ATTACHED_DATA_NODES_COUNT); - file_node_t* new_file_mht_node = NULL; - new_file_mht_node = calloc(1, sizeof(*new_file_mht_node)); - if (!new_file_mht_node) { + file_node_t* new_mht_node = calloc(1, sizeof(*new_mht_node)); + if (!new_mht_node) { pf->last_error = PF_STATUS_NO_MEMORY; return NULL; } - new_file_mht_node->type = FILE_MHT_NODE_TYPE; - new_file_mht_node->parent = parent_file_mht_node; - new_file_mht_node->node_number = mht_node_number; - new_file_mht_node->physical_node_number = physical_node_number; + new_mht_node->type = FILE_MHT_NODE_TYPE; + new_mht_node->parent = parent_mht_node; + new_mht_node->logical_node_number = logical_mht_node_number; + new_mht_node->physical_node_number = physical_node_number; - if (!lruc_add(pf->cache, new_file_mht_node->physical_node_number, new_file_mht_node)) { - free(new_file_mht_node); + if (!lruc_add(pf->cache, new_mht_node->physical_node_number, new_mht_node)) { + free(new_mht_node); pf->last_error = PF_STATUS_NO_MEMORY; return NULL; } - return new_file_mht_node; + return new_mht_node; } - static file_node_t* ipf_get_data_node(pf_context_t* pf, uint64_t offset) { - file_node_t* file_data_node = NULL; + file_node_t* data_node = NULL; if (offset < MD_USER_DATA_SIZE) { pf->last_error = PF_STATUS_UNKNOWN_ERROR; return NULL; } - if ((offset - MD_USER_DATA_SIZE) % PF_NODE_SIZE == 0 - && offset == pf->encrypted_part_plain.size) { - // new node - file_data_node = ipf_append_data_node(pf, offset); + if ((offset - MD_USER_DATA_SIZE) % PF_NODE_SIZE == 0 && + offset == pf->metadata_decrypted_header.file_size) { + data_node = ipf_append_data_node(pf, offset); } else { - // existing node - file_data_node = ipf_read_data_node(pf, offset); + data_node = ipf_read_data_node(pf, offset); } - // bump all the parents mht to reside before the data node in the cache - if (file_data_node != NULL) { - file_node_t* file_mht_node = file_data_node->parent; - while (file_mht_node->node_number != 0) { - // bump the mht node to the head of the lru - lruc_get(pf->cache, file_mht_node->physical_node_number); - file_mht_node = file_mht_node->parent; + // bump all the parent MHT nodes to reside before the data node in the cache + if (data_node != NULL) { + file_node_t* mht_node = data_node->parent; + while (mht_node->logical_node_number != 0) { + // bump the MHT node to the head of the LRU + lruc_get(pf->cache, mht_node->physical_node_number); + mht_node = mht_node->parent; } } // even if we didn't get the required data_node, we might have read other nodes in the process while (lruc_size(pf->cache) > MAX_PAGES_IN_CACHE) { - void* data = lruc_get_last(pf->cache); - assert(data != NULL); - // for production - - if (data == NULL) { + void* node = lruc_get_last(pf->cache); + if (node == NULL) { pf->last_error = PF_STATUS_UNKNOWN_ERROR; return NULL; } - if (!((file_node_t*)data)->need_writing) { + if (!((file_node_t*)node)->need_writing) { lruc_remove_last(pf->cache); // before deleting the memory, need to scrub the plain secrets - file_node_t* file_node = (file_node_t*)data; + file_node_t* file_node = (file_node_t*)node; erase_memory(&file_node->decrypted, sizeof(file_node->decrypted)); free(file_node); } else { @@ -604,172 +573,167 @@ static file_node_t* ipf_get_data_node(pf_context_t* pf, uint64_t offset) { } } - return file_data_node; + return data_node; } static file_node_t* ipf_append_data_node(pf_context_t* pf, uint64_t offset) { - file_node_t* file_mht_node = ipf_get_mht_node(pf, offset); - if (file_mht_node == NULL) // some error happened + file_node_t* mht_node = ipf_get_mht_node(pf, offset); + if (mht_node == NULL) return NULL; - file_node_t* new_file_data_node = NULL; - - new_file_data_node = calloc(1, sizeof(*new_file_data_node)); - if (!new_file_data_node) { + file_node_t* new_data_node = calloc(1, sizeof(*new_data_node)); + if (!new_data_node) { pf->last_error = PF_STATUS_NO_MEMORY; return NULL; } - uint64_t node_number, physical_node_number; - get_node_numbers(offset, NULL, &node_number, NULL, &physical_node_number); + uint64_t logical_node_number; + uint64_t physical_node_number; + get_node_numbers(offset, NULL, &logical_node_number, NULL, &physical_node_number); - new_file_data_node->type = FILE_DATA_NODE_TYPE; - new_file_data_node->parent = file_mht_node; - new_file_data_node->node_number = node_number; - new_file_data_node->physical_node_number = physical_node_number; + new_data_node->type = FILE_DATA_NODE_TYPE; + new_data_node->parent = mht_node; + new_data_node->logical_node_number = logical_node_number; + new_data_node->physical_node_number = physical_node_number; - if (!lruc_add(pf->cache, new_file_data_node->physical_node_number, new_file_data_node)) { - free(new_file_data_node); + if (!lruc_add(pf->cache, new_data_node->physical_node_number, new_data_node)) { + free(new_data_node); pf->last_error = PF_STATUS_NO_MEMORY; return NULL; } - return new_file_data_node; + return new_data_node; } static file_node_t* ipf_read_data_node(pf_context_t* pf, uint64_t offset) { - uint64_t data_node_number; - uint64_t physical_node_number; - file_node_t* file_mht_node; + file_node_t* mht_node; pf_status_t status; - get_node_numbers(offset, NULL, &data_node_number, NULL, &physical_node_number); + uint64_t logical_data_node_number; + uint64_t physical_node_number; + get_node_numbers(offset, NULL, &logical_data_node_number, NULL, &physical_node_number); - file_node_t* file_data_node = (file_node_t*)lruc_get(pf->cache, physical_node_number); - if (file_data_node != NULL) - return file_data_node; + file_node_t* data_node = (file_node_t*)lruc_get(pf->cache, physical_node_number); + if (data_node != NULL) + return data_node; // need to read the data node from the disk - - file_mht_node = ipf_get_mht_node(pf, offset); - if (file_mht_node == NULL) // some error happened + mht_node = ipf_get_mht_node(pf, offset); + if (mht_node == NULL) return NULL; - file_data_node = calloc(1, sizeof(*file_data_node)); - if (!file_data_node) { + data_node = calloc(1, sizeof(*data_node)); + if (!data_node) { pf->last_error = PF_STATUS_NO_MEMORY; return NULL; } - file_data_node->type = FILE_DATA_NODE_TYPE; - file_data_node->node_number = data_node_number; - file_data_node->physical_node_number = physical_node_number; - file_data_node->parent = file_mht_node; + data_node->type = FILE_DATA_NODE_TYPE; + data_node->parent = mht_node; + data_node->logical_node_number = logical_data_node_number; + data_node->physical_node_number = physical_node_number; - if (!ipf_read_node(pf, pf->file, file_data_node->physical_node_number, - file_data_node->encrypted.cipher, PF_NODE_SIZE)) { - free(file_data_node); + if (!ipf_read_node(pf, data_node->physical_node_number, data_node->encrypted.bytes)) { + free(data_node); return NULL; } gcm_crypto_data_t* gcm_crypto_data = - &file_data_node->parent->decrypted.mht - .data_nodes_crypto[file_data_node->node_number % ATTACHED_DATA_NODES_COUNT]; + &data_node->parent->decrypted.mht + .data_nodes_crypto[data_node->logical_node_number % ATTACHED_DATA_NODES_COUNT]; - // this function decrypt the data _and_ checks the integrity of the data against the gmac + // decrypt data and check integrity against the GMAC in corresponding slot in MHT node status = g_cb_aes_gcm_decrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, - file_data_node->encrypted.cipher, PF_NODE_SIZE, - file_data_node->decrypted.data.data, &gcm_crypto_data->gmac); + &data_node->encrypted.bytes, PF_NODE_SIZE, + &data_node->decrypted.data.bytes, &gcm_crypto_data->gmac); if (PF_FAILURE(status)) { - free(file_data_node); + free(data_node); pf->last_error = status; if (status == PF_STATUS_MAC_MISMATCH) pf->file_status = PF_STATUS_CORRUPTED; return NULL; } - if (!lruc_add(pf->cache, file_data_node->physical_node_number, file_data_node)) { - // scrub the plaintext data - erase_memory(&file_data_node->decrypted, sizeof(file_data_node->decrypted)); - free(file_data_node); + if (!lruc_add(pf->cache, data_node->physical_node_number, data_node)) { + erase_memory(&data_node->decrypted, sizeof(data_node->decrypted)); + free(data_node); pf->last_error = PF_STATUS_NO_MEMORY; return NULL; } - return file_data_node; + return data_node; } -static file_node_t* ipf_read_mht_node(pf_context_t* pf, uint64_t mht_node_number) { +static file_node_t* ipf_read_mht_node(pf_context_t* pf, uint64_t logical_mht_node_number) { pf_status_t status; - if (mht_node_number == 0) - return &pf->root_mht; + if (logical_mht_node_number == 0) + return &pf->root_mht_node; - uint64_t physical_node_number = 1 + // meta data node - // the '1' is for the mht node preceding every 96 data nodes - mht_node_number * (1 + ATTACHED_DATA_NODES_COUNT); + uint64_t physical_node_number = 1 + // metadata node + // the '1' is for the MHT node preceding every 96 data nodes + logical_mht_node_number * (1 + ATTACHED_DATA_NODES_COUNT); - file_node_t* file_mht_node = (file_node_t*)lruc_find(pf->cache, physical_node_number); - if (file_mht_node != NULL) - return file_mht_node; + file_node_t* mht_node = (file_node_t*)lruc_find(pf->cache, physical_node_number); + if (mht_node != NULL) + return mht_node; - file_node_t* parent_file_mht_node = - ipf_read_mht_node(pf, (mht_node_number - 1) / CHILD_MHT_NODES_COUNT); + file_node_t* parent_mht_node = + ipf_read_mht_node(pf, (logical_mht_node_number - 1) / CHILD_MHT_NODES_COUNT); - if (parent_file_mht_node == NULL) // some error happened + if (parent_mht_node == NULL) return NULL; - file_mht_node = calloc(1, sizeof(*file_mht_node)); - if (!file_mht_node) { + mht_node = calloc(1, sizeof(*mht_node)); + if (!mht_node) { pf->last_error = PF_STATUS_NO_MEMORY; return NULL; } - file_mht_node->type = FILE_MHT_NODE_TYPE; - file_mht_node->node_number = mht_node_number; - file_mht_node->physical_node_number = physical_node_number; - file_mht_node->parent = parent_file_mht_node; + mht_node->type = FILE_MHT_NODE_TYPE; + mht_node->parent = parent_mht_node; + mht_node->logical_node_number = logical_mht_node_number; + mht_node->physical_node_number = physical_node_number; - if (!ipf_read_node(pf, pf->file, file_mht_node->physical_node_number, - file_mht_node->encrypted.cipher, PF_NODE_SIZE)) { - free(file_mht_node); + if (!ipf_read_node(pf, mht_node->physical_node_number, mht_node->encrypted.bytes)) { + free(mht_node); return NULL; } gcm_crypto_data_t* gcm_crypto_data = - &file_mht_node->parent->decrypted.mht - .mht_nodes_crypto[(file_mht_node->node_number - 1) % CHILD_MHT_NODES_COUNT]; + &mht_node->parent->decrypted.mht + .mht_nodes_crypto[(mht_node->logical_node_number - 1) % CHILD_MHT_NODES_COUNT]; - // this function decrypt the data _and_ checks the integrity of the data against the gmac + // decrypt data and check integrity against the GMAC in corresponding slot in parent MHT node status = g_cb_aes_gcm_decrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, - file_mht_node->encrypted.cipher, PF_NODE_SIZE, - &file_mht_node->decrypted.mht, &gcm_crypto_data->gmac); + &mht_node->encrypted.bytes, PF_NODE_SIZE, + &mht_node->decrypted.mht, &gcm_crypto_data->gmac); if (PF_FAILURE(status)) { - free(file_mht_node); + free(mht_node); pf->last_error = status; if (status == PF_STATUS_MAC_MISMATCH) pf->file_status = PF_STATUS_CORRUPTED; return NULL; } - if (!lruc_add(pf->cache, file_mht_node->physical_node_number, file_mht_node)) { - erase_memory(&file_mht_node->decrypted, sizeof(file_mht_node->decrypted)); - free(file_mht_node); + if (!lruc_add(pf->cache, mht_node->physical_node_number, mht_node)) { + erase_memory(&mht_node->decrypted, sizeof(mht_node->decrypted)); + free(mht_node); pf->last_error = PF_STATUS_NO_MEMORY; return NULL; } - return file_mht_node; + return mht_node; } static bool ipf_init_new_file(pf_context_t* pf, const char* path) { - pf->file_metadata.plain_part.file_id = PF_FILE_ID; - pf->file_metadata.plain_part.major_version = PF_MAJOR_VERSION; - pf->file_metadata.plain_part.minor_version = PF_MINOR_VERSION; + pf->metadata_node.plaintext_header.file_id = PF_FILE_ID; + pf->metadata_node.plaintext_header.major_version = PF_MAJOR_VERSION; + pf->metadata_node.plaintext_header.minor_version = PF_MINOR_VERSION; // path length is checked in ipf_open() - memcpy(pf->encrypted_part_plain.path, path, strlen(path) + 1); + memcpy(pf->metadata_decrypted_header.file_path, path, strlen(path) + 1); pf->need_writing = true; if (!ipf_internal_flush(pf)) @@ -786,16 +750,16 @@ static bool ipf_init_fields(pf_context_t* pf) { return false; } #endif - memset(&pf->file_metadata, 0, sizeof(pf->file_metadata)); - memset(&pf->encrypted_part_plain, 0, sizeof(pf->encrypted_part_plain)); + memset(&pf->metadata_node, 0, sizeof(pf->metadata_node)); + memset(&pf->metadata_decrypted_header, 0, sizeof(pf->metadata_decrypted_header)); memset(&g_empty_iv, 0, sizeof(g_empty_iv)); - ipf_init_root_mht(&pf->root_mht); + ipf_init_root_mht_node(&pf->root_mht_node); - pf->file = NULL; - pf->need_writing = false; - pf->file_status = PF_STATUS_UNINITIALIZED; - pf->last_error = PF_STATUS_SUCCESS; + pf->host_file_handle = NULL; + pf->need_writing = false; + pf->file_status = PF_STATUS_UNINITIALIZED; + pf->last_error = PF_STATUS_SUCCESS; pf->cache = lruc_create(); return true; @@ -804,62 +768,60 @@ static bool ipf_init_fields(pf_context_t* pf) { static bool ipf_init_existing_file(pf_context_t* pf, const char* path) { pf_status_t status; - // read meta-data node - if (!ipf_read_node(pf, pf->file, /*node_number=*/0, (uint8_t*)&pf->file_metadata, - PF_NODE_SIZE)) { + // read metadata node + if (!ipf_read_node(pf, /*logical_node_number=*/0, (uint8_t*)&pf->metadata_node)) { return false; } - if (pf->file_metadata.plain_part.file_id != PF_FILE_ID) { + if (pf->metadata_node.plaintext_header.file_id != PF_FILE_ID) { // such a file exists, but it is not a protected file pf->last_error = PF_STATUS_INVALID_HEADER; return false; } - if (pf->file_metadata.plain_part.major_version != PF_MAJOR_VERSION) { + if (pf->metadata_node.plaintext_header.major_version != PF_MAJOR_VERSION) { pf->last_error = PF_STATUS_INVALID_VERSION; return false; } pf_key_t key; - if (!ipf_restore_current_metadata_key(pf, &key)) + if (!ipf_generate_salted_metadata_key(pf, &key)) return false; - // decrypt the encrypted part of the meta-data + // decrypt the encrypted part of the metadata node status = g_cb_aes_gcm_decrypt(&key, &g_empty_iv, NULL, 0, - &pf->file_metadata.encrypted_part, - sizeof(pf->file_metadata.encrypted_part), - &pf->encrypted_part_plain, - &pf->file_metadata.plain_part.metadata_gmac); + &pf->metadata_node.encrypted_blob, + sizeof(pf->metadata_node.encrypted_blob), + &pf->metadata_decrypted_header, + &pf->metadata_node.plaintext_header.metadata_gmac); if (PF_FAILURE(status)) { pf->last_error = status; DEBUG_PF("failed to decrypt metadata: %d", status); return false; } - DEBUG_PF("data size %lu", pf->encrypted_part_plain.size); + DEBUG_PF("data size %lu", pf->metadata_decrypted_header.file_size); if (path) { - size_t path_len = strlen(pf->encrypted_part_plain.path); + size_t path_len = strlen(pf->metadata_decrypted_header.file_path); if (path_len != strlen(path) - || memcmp(path, pf->encrypted_part_plain.path, path_len) != 0) { + || memcmp(path, pf->metadata_decrypted_header.file_path, path_len) != 0) { pf->last_error = PF_STATUS_INVALID_PATH; return false; } } - if (pf->encrypted_part_plain.size > MD_USER_DATA_SIZE) { - // read the root node of the mht - if (!ipf_read_node(pf, pf->file, /*node_number=*/1, &pf->root_mht.encrypted.cipher, - PF_NODE_SIZE)) + if (pf->metadata_decrypted_header.file_size > MD_USER_DATA_SIZE) { + // read the root MHT node + if (!ipf_read_node(pf, /*logical_node_number=*/1, &pf->root_mht_node.encrypted.bytes)) return false; - // this also verifies the root mht gmac against the gmac in the meta-data encrypted part - status = g_cb_aes_gcm_decrypt(&pf->encrypted_part_plain.mht_key, &g_empty_iv, + // also verifies root MHT node's GMAC against the GMAC in metadata node's decrypted header + status = g_cb_aes_gcm_decrypt(&pf->metadata_decrypted_header.root_mht_node_key, &g_empty_iv, NULL, 0, // aad - &pf->root_mht.encrypted.cipher, PF_NODE_SIZE, - &pf->root_mht.decrypted.mht, - &pf->encrypted_part_plain.mht_gmac); + &pf->root_mht_node.encrypted.bytes, PF_NODE_SIZE, + &pf->root_mht_node.decrypted.mht, + &pf->metadata_decrypted_header.root_mht_node_gmac); if (PF_FAILURE(status)) { pf->last_error = status; return false; @@ -869,7 +831,6 @@ static bool ipf_init_existing_file(pf_context_t* pf, const char* path) { return true; } - static void ipf_try_clear_error(pf_context_t* pf) { if (pf->file_status == PF_STATUS_UNINITIALIZED || pf->file_status == PF_STATUS_CRYPTO_ERROR || @@ -896,7 +857,6 @@ static void ipf_try_clear_error(pf_context_t* pf) { } } - static pf_context_t* ipf_open(const char* path, pf_file_mode_t mode, bool create, pf_handle_t file, uint64_t real_size, const pf_key_t* kdk_key, pf_status_t* status) { *status = PF_STATUS_NO_MEMORY; @@ -922,13 +882,7 @@ static pf_context_t* ipf_open(const char* path, pf_file_mode_t mode, bool create goto out; } - // for new file, this value will later be saved in the meta data plain part (init_new_file) - // for existing file, we will later compare this value with the value from the file - // (init_existing_file) - COPY_ARRAY(pf->user_kdk_key, *kdk_key); - - // omeg: we require a canonical full path to file, so no stripping path to filename only - // omeg: Intel's implementation opens the file, we get the fd and size from the Gramine handler + COPY_ARRAY(pf->kdk, *kdk_key); if (!file) { DEBUG_PF("invalid handle"); @@ -941,22 +895,20 @@ static pf_context_t* ipf_open(const char* path, pf_file_mode_t mode, bool create goto out; } - pf->file = file; + pf->host_file_handle = file; pf->mode = mode; if (!create) { - // existing file if (!ipf_init_existing_file(pf, path)) goto out; } else { - // new file if (!ipf_init_new_file(pf, path)) goto out; } pf->last_error = pf->file_status = PF_STATUS_SUCCESS; - DEBUG_PF("OK (data size %lu)", pf->encrypted_part_plain.size); + DEBUG_PF("OK (data size %lu)", pf->metadata_decrypted_header.file_size); out: if (pf) @@ -987,46 +939,44 @@ static bool ipf_check_writable(pf_context_t* pf) { return true; } -// write zeros if `ptr` is NULL +// writes zeros if `ptr` is NULL static size_t ipf_write(pf_context_t* pf, const void* ptr, uint64_t offset, size_t size) { if (size == 0) { pf->last_error = PF_STATUS_INVALID_PARAMETER; return 0; } - size_t data_left_to_write = size; - if (!ipf_check_writable(pf)) { return 0; } + size_t data_left_to_write = size; const unsigned char* data_to_write = (const unsigned char*)ptr; - // the first block of user data is written in the meta-data encrypted part + // the first 3KB of user data is written in the metadata node's encrypted part if (offset < MD_USER_DATA_SIZE) { - // offset is smaller than MD_USER_DATA_SIZE size_t empty_place_left_in_md = MD_USER_DATA_SIZE - (size_t)offset; size_t size_to_write = MIN(data_left_to_write, empty_place_left_in_md); - memcpy_or_zero_initialize(&pf->encrypted_part_plain.data[offset], data_to_write, + memcpy_or_zero_initialize(&pf->metadata_decrypted_header.file_data[offset], data_to_write, size_to_write); offset += size_to_write; if (data_to_write) data_to_write += size_to_write; data_left_to_write -= size_to_write; - if (offset > pf->encrypted_part_plain.size) - pf->encrypted_part_plain.size = offset; // file grew, update the new file size + if (offset > pf->metadata_decrypted_header.file_size) + pf->metadata_decrypted_header.file_size = offset; // file grew, update new file size pf->need_writing = true; } while (data_left_to_write > 0) { - file_node_t* file_data_node = NULL; + file_node_t* data_node = NULL; // return the data node of the current offset, will read it from disk or create new one - // if needed (and also the mht node if needed) - file_data_node = ipf_get_data_node(pf, offset); - if (file_data_node == NULL) { + // if needed (and also the MHT node(s) if needed) + data_node = ipf_get_data_node(pf, offset); + if (data_node == NULL) { DEBUG_PF("failed to get data node"); break; } @@ -1035,26 +985,26 @@ static size_t ipf_write(pf_context_t* pf, const void* ptr, uint64_t offset, size size_t empty_place_left_in_node = PF_NODE_SIZE - offset_in_node; size_t size_to_write = MIN(data_left_to_write, empty_place_left_in_node); - memcpy_or_zero_initialize(&file_data_node->decrypted.data.data[offset_in_node], + memcpy_or_zero_initialize(&data_node->decrypted.data.bytes[offset_in_node], data_to_write, size_to_write); offset += size_to_write; if (data_to_write) data_to_write += size_to_write; data_left_to_write -= size_to_write; - if (offset > pf->encrypted_part_plain.size) { - pf->encrypted_part_plain.size = offset; // file grew, update the new file size + if (offset > pf->metadata_decrypted_header.file_size) { + pf->metadata_decrypted_header.file_size = offset; // file grew, update new file size } - if (!file_data_node->need_writing) { - file_data_node->need_writing = true; - file_node_t* file_mht_node = file_data_node->parent; - while (file_mht_node->node_number != 0) { - // set all the mht parent nodes as 'need writing' - file_mht_node->need_writing = true; - file_mht_node = file_mht_node->parent; + if (!data_node->need_writing) { + data_node->need_writing = true; + file_node_t* mht_node = data_node->parent; + while (mht_node->logical_node_number != 0) { + // set all the MHT parent nodes as 'need writing' + mht_node->need_writing = true; + mht_node = mht_node->parent; } - pf->root_mht.need_writing = true; + pf->root_mht_node.need_writing = true; pf->need_writing = true; } } @@ -1080,9 +1030,10 @@ static size_t ipf_read(pf_context_t* pf, void* ptr, uint64_t offset, size_t size size_t data_left_to_read = size; - if (((uint64_t)data_left_to_read) > (uint64_t)(pf->encrypted_part_plain.size - offset)) { + if (((uint64_t)data_left_to_read) > + (uint64_t)(pf->metadata_decrypted_header.file_size - offset)) { // the request is bigger than what's left in the file - data_left_to_read = (size_t)(pf->encrypted_part_plain.size - offset); + data_left_to_read = (size_t)(pf->metadata_decrypted_header.file_size - offset); } // used at the end to return how much we actually read @@ -1090,31 +1041,30 @@ static size_t ipf_read(pf_context_t* pf, void* ptr, uint64_t offset, size_t size unsigned char* out_buffer = (unsigned char*)ptr; - // the first block of user data is read from the meta-data encrypted part + // the first 3KB of user data is read from the metadata node's encrypted part if (offset < MD_USER_DATA_SIZE) { - // offset is smaller than MD_USER_DATA_SIZE size_t data_left_in_md = MD_USER_DATA_SIZE - (size_t)offset; size_t size_to_read = MIN(data_left_to_read, data_left_in_md); - memcpy(out_buffer, &pf->encrypted_part_plain.data[offset], size_to_read); + memcpy(out_buffer, &pf->metadata_decrypted_header.file_data[offset], size_to_read); offset += size_to_read; out_buffer += size_to_read; data_left_to_read -= size_to_read; } while (data_left_to_read > 0) { - file_node_t* file_data_node = NULL; + file_node_t* data_node = NULL; // return the data node of the current offset, will read it from disk if needed - // (and also the mht node if needed) - file_data_node = ipf_get_data_node(pf, offset); - if (file_data_node == NULL) + // (and also the MHT node(s) if needed) + data_node = ipf_get_data_node(pf, offset); + if (data_node == NULL) break; uint64_t offset_in_node = (offset - MD_USER_DATA_SIZE) % PF_NODE_SIZE; size_t data_left_in_node = PF_NODE_SIZE - offset_in_node; size_t size_to_read = MIN(data_left_to_read, data_left_in_node); - memcpy(out_buffer, &file_data_node->decrypted.data.data[offset_in_node], size_to_read); + memcpy(out_buffer, &data_node->decrypted.data.bytes[offset_in_node], size_to_read); offset += size_to_read; out_buffer += size_to_read; data_left_to_read -= size_to_read; @@ -1124,9 +1074,9 @@ static size_t ipf_read(pf_context_t* pf, void* ptr, uint64_t offset, size_t size } static void ipf_delete_cache(pf_context_t* pf) { - void* data; - while ((data = lruc_get_last(pf->cache)) != NULL) { - file_node_t* file_node = (file_node_t*)data; + void* node; + while ((node = lruc_get_last(pf->cache)) != NULL) { + file_node_t* file_node = (file_node_t*)node; erase_memory(&file_node->decrypted, sizeof(file_node->decrypted)); free(file_node); lruc_remove_last(pf->cache); @@ -1146,13 +1096,12 @@ static bool ipf_close(pf_context_t* pf) { } } - // omeg: fs close is done by Gramine handler + // fs close is done by Gramine handler pf->file_status = PF_STATUS_UNINITIALIZED; ipf_delete_cache(pf); - // scrub first MD_USER_DATA_SIZE of file data and the gmac_key - erase_memory(&pf->encrypted_part_plain, sizeof(pf->encrypted_part_plain)); + erase_memory(&pf->metadata_decrypted_header, sizeof(pf->metadata_decrypted_header)); lruc_destroy(pf->cache); @@ -1211,7 +1160,7 @@ pf_status_t pf_get_size(pf_context_t* pf, uint64_t* size) { if (!g_initialized) return PF_STATUS_UNINITIALIZED; - *size = pf->encrypted_part_plain.size; + *size = pf->metadata_decrypted_header.file_size; return PF_STATUS_SUCCESS; } @@ -1222,12 +1171,12 @@ pf_status_t pf_set_size(pf_context_t* pf, uint64_t size) { if (!(pf->mode & PF_FILE_MODE_WRITE)) return PF_STATUS_INVALID_MODE; - if (size == pf->encrypted_part_plain.size) + if (size == pf->metadata_decrypted_header.file_size) return PF_STATUS_SUCCESS; - if (size > pf->encrypted_part_plain.size) { + if (size > pf->metadata_decrypted_header.file_size) { // Extend the file. - uint64_t offset = pf->encrypted_part_plain.size; + uint64_t offset = pf->metadata_decrypted_header.file_size; DEBUG_PF("extending the file from %lu to %lu", offset, size); if (ipf_write(pf, NULL, offset, size - offset) != size - offset) return pf->last_error; @@ -1238,7 +1187,7 @@ pf_status_t pf_set_size(pf_context_t* pf, uint64_t size) { // Truncation. // The structure of the protected file is such that we can simply truncate - // the file after the last data block belonging to still-used data. + // the file after the last data node belonging to still-used data. // Some MHT entries will be left with dangling data describing the truncated // nodes, but this is not a problem since they will be unused, and will be // overwritten with new data when the relevant nodes get allocated again. @@ -1258,11 +1207,11 @@ pf_status_t pf_set_size(pf_context_t* pf, uint64_t size) { get_node_numbers(size - 1, NULL, NULL, NULL, &physical_node_number); new_file_size = (physical_node_number + 1) * PF_NODE_SIZE; } - pf_status_t status = g_cb_truncate(pf->file, new_file_size); + pf_status_t status = g_cb_truncate(pf->host_file_handle, new_file_size); if (PF_FAILURE(status)) return status; // If successfully truncated, update our bookkeeping. - pf->encrypted_part_plain.size = size; + pf->metadata_decrypted_header.file_size = size; pf->need_writing = true; return PF_STATUS_SUCCESS; } @@ -1278,8 +1227,9 @@ pf_status_t pf_rename(pf_context_t* pf, const char* new_path) { if (new_path_size > PATH_MAX_SIZE) return PF_STATUS_PATH_TOO_LONG; - memset(pf->encrypted_part_plain.path, 0, sizeof(pf->encrypted_part_plain.path)); - memcpy(pf->encrypted_part_plain.path, new_path, new_path_size); + memset(pf->metadata_decrypted_header.file_path, 0, + sizeof(pf->metadata_decrypted_header.file_path)); + memcpy(pf->metadata_decrypted_header.file_path, new_path, new_path_size); pf->need_writing = true; if (!ipf_internal_flush(pf)) return pf->last_error; @@ -1302,7 +1252,7 @@ pf_status_t pf_read(pf_context_t* pf, uint64_t offset, size_t size, void* output return pf->last_error; } - if (offset >= pf->encrypted_part_plain.size) { + if (offset >= pf->metadata_decrypted_header.file_size) { *bytes_read = 0; return PF_STATUS_SUCCESS; } @@ -1322,7 +1272,7 @@ pf_status_t pf_write(pf_context_t* pf, uint64_t offset, size_t size, const void* if (!ipf_check_writable(pf)) return pf->last_error; - if (offset > pf->encrypted_part_plain.size) { + if (offset > pf->metadata_decrypted_header.file_size) { pf_status_t ret = pf_set_size(pf, offset); if (!PF_SUCCESS(ret)) { pf->last_error = ret; @@ -1348,7 +1298,7 @@ pf_status_t pf_flush(pf_context_t* pf) { * the app issues an actual fsync()/fdatasync() syscalls. The internal `ipf_internal_flush()` is * more broadly used: it's called when file contents must be flushed to the host OS (e.g. during * the rename operation). */ - pf_status_t status = g_cb_fsync(pf->file); + pf_status_t status = g_cb_fsync(pf->host_file_handle); if (PF_FAILURE(status)) { pf->last_error = status; return pf->last_error; @@ -1356,11 +1306,3 @@ pf_status_t pf_flush(pf_context_t* pf) { return PF_STATUS_SUCCESS; } - -pf_status_t pf_get_handle(pf_context_t* pf, pf_handle_t* handle) { - if (!g_initialized) - return PF_STATUS_UNINITIALIZED; - - *handle = pf->file; - return PF_STATUS_SUCCESS; -} diff --git a/common/src/protected_files/protected_files.h b/common/src/protected_files/protected_files.h index 4354f3e6fe..018161687d 100644 --- a/common/src/protected_files/protected_files.h +++ b/common/src/protected_files/protected_files.h @@ -12,8 +12,7 @@ #include #include -/*! Size of the AES-GCM encryption key */ -#define PF_KEY_SIZE 16 +#define PF_NODE_SIZE 4096U /*! Size of IV for AES-GCM */ #define PF_IV_SIZE 12 @@ -21,15 +20,16 @@ /*! Size of MAC fields */ #define PF_MAC_SIZE 16 +/*! Size of the AES-GCM encryption key */ +#define PF_KEY_SIZE 16 + +/*! Size of the salt used in KDF (Key Derivation Function) */ +#define PF_SALT_SIZE 32 + typedef uint8_t pf_iv_t[PF_IV_SIZE]; typedef uint8_t pf_mac_t[PF_MAC_SIZE]; typedef uint8_t pf_key_t[PF_KEY_SIZE]; -typedef uint8_t pf_keyid_t[32]; /* key derivation material */ - -extern pf_key_t g_pf_mrenclave_key; -extern pf_key_t g_pf_mrsigner_key; -extern pf_key_t g_pf_wrap_key; -extern bool g_pf_wrap_key_set; +typedef uint8_t pf_salt_t[PF_SALT_SIZE]; typedef enum _pf_status_t { PF_STATUS_SUCCESS = 0, @@ -55,8 +55,6 @@ typedef enum _pf_status_t { #define PF_SUCCESS(status) ((status) == PF_STATUS_SUCCESS) #define PF_FAILURE(status) ((status) != PF_STATUS_SUCCESS) -#define PF_NODE_SIZE 4096U - /*! PF open modes */ typedef enum _pf_file_mode_t { PF_FILE_MODE_READ = 1, @@ -66,6 +64,9 @@ typedef enum _pf_file_mode_t { /*! Opaque file handle type, interpreted by callbacks as necessary */ typedef void* pf_handle_t; +/*! Context representing an open protected file */ +typedef struct pf_context pf_context_t; + /*! * \brief File read callback. * @@ -197,9 +198,6 @@ void pf_set_callbacks(pf_read_f read_f, pf_write_f write_f, pf_fsync_f fsync_f, pf_aes_gcm_decrypt_f aes_gcm_decrypt_f, pf_random_f random_f, pf_debug_f debug_f); -/*! Context representing an open protected file */ -typedef struct pf_context pf_context_t; - /* Public API */ /*! @@ -296,16 +294,6 @@ pf_status_t pf_set_size(pf_context_t* pf, uint64_t size); */ pf_status_t pf_rename(pf_context_t* pf, const char* new_path); -/*! - * \brief Get underlying handle of a PF. - * - * \param pf PF context. - * \param[out] handle Handle to the backing file. - * - * \returns PF status. - */ -pf_status_t pf_get_handle(pf_context_t* pf, pf_handle_t* handle); - /*! * \brief Flush any pending data of a protected file to disk. * diff --git a/common/src/protected_files/protected_files_format.h b/common/src/protected_files/protected_files_format.h index 4473dc9ae4..581161010e 100644 --- a/common/src/protected_files/protected_files_format.h +++ b/common/src/protected_files/protected_files_format.h @@ -6,6 +6,8 @@ #pragma once +#pragma pack(push, 1) + #ifdef USE_STDLIB #include #else @@ -14,7 +16,6 @@ #include -#include "list.h" #include "protected_files.h" #define PF_FILE_ID 0x46505f5346415247 /* GRAFS_PF */ @@ -23,117 +24,102 @@ #define METADATA_KEY_NAME "SGX-PROTECTED-FS-METADATA-KEY" #define MAX_LABEL_SIZE 64 - static_assert(sizeof(METADATA_KEY_NAME) <= MAX_LABEL_SIZE, "label too long"); -#pragma pack(push, 1) - -typedef struct _metadata_plain { - uint64_t file_id; - uint8_t major_version; - uint8_t minor_version; - pf_keyid_t metadata_key_id; - pf_mac_t metadata_gmac; /* GCM mac */ -} metadata_plain_t; - #define PATH_MAX_SIZE (260 + 512) -// these are all defined as relative to node size, so we can decrease node size in tests -// and have deeper tree -#define MD_USER_DATA_SIZE (PF_NODE_SIZE * 3 / 4) // 3072 +#define MD_USER_DATA_SIZE (PF_NODE_SIZE * 3 / 4) static_assert(MD_USER_DATA_SIZE == 3072, "bad struct size"); -typedef struct _metadata_encrypted { - char path[PATH_MAX_SIZE]; - uint64_t size; - pf_key_t mht_key; - pf_mac_t mht_gmac; - uint8_t data[MD_USER_DATA_SIZE]; -} metadata_encrypted_t; - -typedef uint8_t metadata_encrypted_blob_t[sizeof(metadata_encrypted_t)]; - -#define METADATA_NODE_SIZE PF_NODE_SIZE - -typedef uint8_t metadata_padding_t[METADATA_NODE_SIZE - - (sizeof(metadata_plain_t) + sizeof(metadata_encrypted_blob_t))]; - -typedef struct _metadata_node { - metadata_plain_t plain_part; - metadata_encrypted_blob_t encrypted_part; - metadata_padding_t padding; -} metadata_node_t; +#define MAX_PAGES_IN_CACHE 48 -static_assert(sizeof(metadata_node_t) == PF_NODE_SIZE, "sizeof(metadata_node_t)"); +enum { + FILE_MHT_NODE_TYPE = 1, + FILE_DATA_NODE_TYPE = 2, +}; -typedef struct _data_node_crypto { +typedef struct _gcm_crypto_data { pf_key_t key; pf_mac_t gmac; } gcm_crypto_data_t; -// for PF_NODE_SIZE == 4096, we have 96 attached data nodes and 32 mht child nodes -// for PF_NODE_SIZE == 2048, we have 48 attached data nodes and 16 mht child nodes -// for PF_NODE_SIZE == 1024, we have 24 attached data nodes and 8 mht child nodes -// 3/4 of the node size is dedicated to data nodes +// for PF_NODE_SIZE == 4096, we have 96 attached data nodes and 32 MHT child nodes +// 3/4 of the node is dedicated to data nodes, 1/4 to MHT nodes #define ATTACHED_DATA_NODES_COUNT ((PF_NODE_SIZE / sizeof(gcm_crypto_data_t)) * 3 / 4) +#define CHILD_MHT_NODES_COUNT ((PF_NODE_SIZE / sizeof(gcm_crypto_data_t)) * 1 / 4) static_assert(ATTACHED_DATA_NODES_COUNT == 96, "ATTACHED_DATA_NODES_COUNT"); -// 1/4 of the node size is dedicated to child mht nodes -#define CHILD_MHT_NODES_COUNT ((PF_NODE_SIZE / sizeof(gcm_crypto_data_t)) * 1 / 4) static_assert(CHILD_MHT_NODES_COUNT == 32, "CHILD_MHT_NODES_COUNT"); +typedef struct _metadata_plaintext_header { + uint64_t file_id; + uint8_t major_version; + uint8_t minor_version; + pf_salt_t metadata_key_salt; + pf_mac_t metadata_gmac; /* GCM mac */ +} metadata_plaintext_header_t; + +typedef struct _metadata_decrypted_header { + char file_path[PATH_MAX_SIZE]; + uint64_t file_size; + pf_key_t root_mht_node_key; + pf_mac_t root_mht_node_gmac; + uint8_t file_data[MD_USER_DATA_SIZE]; +} metadata_decrypted_header_t; + +typedef uint8_t metadata_encrypted_blob_t[sizeof(metadata_decrypted_header_t)]; + +typedef uint8_t metadata_padding_t[PF_NODE_SIZE - + (sizeof(metadata_plaintext_header_t) + + sizeof(metadata_encrypted_blob_t))]; + +typedef struct _metadata_node { + metadata_plaintext_header_t plaintext_header; + metadata_encrypted_blob_t encrypted_blob; + metadata_padding_t padding; +} metadata_node_t; +static_assert(sizeof(metadata_node_t) == PF_NODE_SIZE, "sizeof(metadata_node_t)"); + typedef struct _mht_node { gcm_crypto_data_t data_nodes_crypto[ATTACHED_DATA_NODES_COUNT]; gcm_crypto_data_t mht_nodes_crypto[CHILD_MHT_NODES_COUNT]; } mht_node_t; - static_assert(sizeof(mht_node_t) == PF_NODE_SIZE, "sizeof(mht_node_t)"); typedef struct _data_node { - uint8_t data[PF_NODE_SIZE]; + uint8_t bytes[PF_NODE_SIZE]; } data_node_t; - static_assert(sizeof(data_node_t) == PF_NODE_SIZE, "sizeof(data_node_t)"); typedef struct _encrypted_node { - uint8_t cipher[PF_NODE_SIZE]; + uint8_t bytes[PF_NODE_SIZE]; } encrypted_node_t; - static_assert(sizeof(encrypted_node_t) == PF_NODE_SIZE, "sizeof(encrypted_node_t)"); -#define MAX_PAGES_IN_CACHE 48 - -typedef enum { - FILE_MHT_NODE_TYPE = 1, - FILE_DATA_NODE_TYPE = 2, -} mht_node_type_e; +static_assert(sizeof(mht_node_t) == sizeof(data_node_t), "sizes of MHT and data nodes differ"); -// make sure these are the same size -static_assert(sizeof(mht_node_t) == sizeof(data_node_t), - "sizeof(mht_node_t) == sizeof(data_node_t)"); - -DEFINE_LIST(_file_node); +// Data struct that wraps the 4KB encrypted-node buffer (bounce buffer) and the corresponding 4KB +// decrypted-data buffer (plain buffer), plus additional fields. This data struct is used for both +// Data and MHT nodes (but not for Metadata node). typedef struct _file_node { - LIST_TYPE(_file_node) list; uint8_t type; - uint64_t node_number; - struct _file_node* parent; bool need_writing; - struct { - uint64_t physical_node_number; - encrypted_node_t encrypted; // the actual data from the disk - }; - union { // decrypted data + struct _file_node* parent; + + uint64_t logical_node_number; + uint64_t physical_node_number; + + encrypted_node_t encrypted; // encrypted data from storage (bounce buffer) + union { // decrypted data in private memory (plain buffer) mht_node_t mht; data_node_t data; } decrypted; } file_node_t; -DEFINE_LISTP(_file_node); typedef struct { - uint32_t index; + uint32_t index; // always "1"; FIXME: what's the point of this? char label[MAX_LABEL_SIZE]; // must be NULL terminated - pf_keyid_t nonce; - uint32_t output_len; // in bits + pf_salt_t key_salt; // salt for key derivation from KDK, stored in metadata node + uint32_t output_len; // in bits; always 128; FIXME: what's the point of this? } kdf_input_t; #pragma pack(pop) diff --git a/common/src/protected_files/protected_files_internal.h b/common/src/protected_files/protected_files_internal.h index 39b8fde4e1..f8e9d3f182 100644 --- a/common/src/protected_files/protected_files_internal.h +++ b/common/src/protected_files/protected_files_internal.h @@ -14,17 +14,22 @@ #include "protected_files_format.h" struct pf_context { - metadata_node_t file_metadata; // actual data from disk's meta data node - pf_status_t last_error; - metadata_encrypted_t encrypted_part_plain; // encrypted part of metadata node, decrypted - file_node_t root_mht; // the root of the mht is always needed (for files bigger than 3KB) - pf_handle_t file; - pf_file_mode_t mode; - bool need_writing; - pf_status_t file_status; - pf_key_t user_kdk_key; - lruc_context_t* cache; + pf_handle_t host_file_handle; // opaque file handle (e.g. PAL handle) used by callbacks + pf_file_mode_t mode; // read-only, write-only or read-write + bool need_writing; // whether file was modified and thus needs writing to storage + + pf_status_t file_status; // PF_STATUS_SUCCESS, PF_STATUS_CRYPTO_ERROR, etc. + pf_status_t last_error; // FIXME: unclear why this is needed + + pf_key_t kdk; // KDK installed by user of PF (e.g. from Gramine manifest) + + metadata_node_t metadata_node; // plaintext and encrypted metadata from storage (bounce buffer) + metadata_decrypted_header_t metadata_decrypted_header; // contains file path, size, etc. + + file_node_t root_mht_node; // root MHT node is always needed (for files bigger than 3KB) + + lruc_context_t* cache; // up to MAX_PAGES_IN_CACHE nodes are cached for each file #ifdef DEBUG - char* debug_buffer; // buffer for debug output + char* debug_buffer; // buffer for debug output #endif }; diff --git a/tools/sgx/pf_tamper/pf_tamper.c b/tools/sgx/pf_tamper/pf_tamper.c index bfebd6a60a..b4a3945519 100644 --- a/tools/sgx/pf_tamper/pf_tamper.c +++ b/tools/sgx/pf_tamper/pf_tamper.c @@ -58,13 +58,13 @@ pf_key_t g_meta_key; static pf_iv_t g_empty_iv = {0}; -static void derive_main_key(const pf_key_t* kdk, const pf_keyid_t* key_id, pf_key_t* out_key) { +static void derive_main_key(const pf_key_t* kdk, const pf_salt_t* key_salt, pf_key_t* out_key) { kdf_input_t buf = {0}; pf_status_t status; buf.index = 1; strncpy(buf.label, METADATA_KEY_NAME, MAX_LABEL_SIZE); - COPY_ARRAY(buf.nonce, *key_id); + COPY_ARRAY(buf.key_salt, *key_salt); buf.output_len = 0x80; status = mbedtls_aes_cmac(kdk, &buf, sizeof(buf), out_key); @@ -79,8 +79,8 @@ static void make_output_path(const char* suffix) { /* PF layout (node size is PF_NODE_SIZE): * - Node 0: metadata (metadata_node_t) - * - metadata_plain_t - * - metadata_encrypted_t (may include MD_USER_DATA_SIZE bytes of data) + * - metadata_plaintext_header_t + * - metadata_decrypted_header_t (may include MD_USER_DATA_SIZE bytes of data) * - metadata_padding_t * - Node 1: MHT (mht_node_t) * - Node 2-97: data (ATTACHED_DATA_NODES_COUNT == 96) @@ -111,66 +111,80 @@ static void truncate_file(const char* suffix, size_t output_size) { #define DATA_CRYPTO_SIZE (FIELD_SIZEOF(mht_node_t, data_nodes_crypto)) static void tamper_truncate(void) { - size_t mdps = sizeof(metadata_plain_t); - DBG("size(metadata_plain_t) = 0x%04lx\n", sizeof(metadata_plain_t)); - DBG("metadata_plain_t.file_id : 0x%04lx (0x%04lx)\n", - offsetof(metadata_plain_t, file_id), FIELD_SIZEOF(metadata_plain_t, file_id)); - DBG("metadata_plain_t.major_version : 0x%04lx (0x%04lx)\n", - offsetof(metadata_plain_t, major_version), FIELD_SIZEOF(metadata_plain_t, major_version)); - DBG("metadata_plain_t.minor_version : 0x%04lx (0x%04lx)\n", - offsetof(metadata_plain_t, minor_version), FIELD_SIZEOF(metadata_plain_t, minor_version)); - DBG("metadata_plain_t.metadata_key_id : 0x%04lx (0x%04lx)\n", - offsetof(metadata_plain_t, metadata_key_id), - FIELD_SIZEOF(metadata_plain_t, metadata_key_id)); - DBG("metadata_plain_t.metadata_gmac : 0x%04lx (0x%04lx)\n", - offsetof(metadata_plain_t, metadata_gmac), - FIELD_SIZEOF(metadata_plain_t, metadata_gmac)); - - DBG("size(metadata_encrypted_t) = 0x%04lx\n", sizeof(metadata_encrypted_t)); - DBG("metadata_encrypted_t.path : 0x%04lx (0x%04lx)\n", - mdps + offsetof(metadata_encrypted_t, path), - FIELD_SIZEOF(metadata_encrypted_t, path)); - DBG("metadata_encrypted_t.size : 0x%04lx (0x%04lx)\n", - mdps + offsetof(metadata_encrypted_t, size), FIELD_SIZEOF(metadata_encrypted_t, size)); - DBG("metadata_encrypted_t.mht_key : 0x%04lx (0x%04lx)\n", - mdps + offsetof(metadata_encrypted_t, mht_key), - FIELD_SIZEOF(metadata_encrypted_t, mht_key)); - DBG("metadata_encrypted_t.mht_gmac : 0x%04lx (0x%04lx)\n", - mdps + offsetof(metadata_encrypted_t, mht_gmac), - FIELD_SIZEOF(metadata_encrypted_t, mht_gmac)); - DBG("metadata_encrypted_t.data : 0x%04lx (0x%04lx)\n", - mdps + offsetof(metadata_encrypted_t, data), FIELD_SIZEOF(metadata_encrypted_t, data)); + size_t mdps = sizeof(metadata_plaintext_header_t); + DBG("size(metadata_plaintext_header_t) = 0x%04lx\n", sizeof(metadata_plaintext_header_t)); + DBG("metadata_plaintext_header_t.file_id : 0x%04lx (0x%04lx)\n", + offsetof(metadata_plaintext_header_t, file_id), + FIELD_SIZEOF(metadata_plaintext_header_t, file_id)); + DBG("metadata_plaintext_header_t.major_version : 0x%04lx (0x%04lx)\n", + offsetof(metadata_plaintext_header_t, major_version), + FIELD_SIZEOF(metadata_plaintext_header_t, major_version)); + DBG("metadata_plaintext_header_t.minor_version : 0x%04lx (0x%04lx)\n", + offsetof(metadata_plaintext_header_t, minor_version), + FIELD_SIZEOF(metadata_plaintext_header_t, minor_version)); + DBG("metadata_plaintext_header_t.metadata_key_salt : 0x%04lx (0x%04lx)\n", + offsetof(metadata_plaintext_header_t, metadata_key_salt), + FIELD_SIZEOF(metadata_plaintext_header_t, metadata_key_salt)); + DBG("metadata_plaintext_header_t.metadata_gmac : 0x%04lx (0x%04lx)\n", + offsetof(metadata_plaintext_header_t, metadata_gmac), + FIELD_SIZEOF(metadata_plaintext_header_t, metadata_gmac)); + + DBG("size(metadata_decrypted_header_t) = 0x%04lx\n", sizeof(metadata_decrypted_header_t)); + DBG("metadata_decrypted_header_t.file_path : 0x%04lx (0x%04lx)\n", + mdps + offsetof(metadata_decrypted_header_t, file_path), + FIELD_SIZEOF(metadata_decrypted_header_t, file_path)); + DBG("metadata_decrypted_header_t.file_size : 0x%04lx (0x%04lx)\n", + mdps + offsetof(metadata_decrypted_header_t, file_size), + FIELD_SIZEOF(metadata_decrypted_header_t, file_size)); + DBG("metadata_decrypted_header_t.root_mht_node_key : 0x%04lx (0x%04lx)\n", + mdps + offsetof(metadata_decrypted_header_t, root_mht_node_key), + FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_key)); + DBG("metadata_decrypted_header_t.root_mht_node_gmac : 0x%04lx (0x%04lx)\n", + mdps + offsetof(metadata_decrypted_header_t, root_mht_node_gmac), + FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_gmac)); + DBG("metadata_decrypted_header_t.file_data : 0x%04lx (0x%04lx)\n", + mdps + offsetof(metadata_decrypted_header_t, file_data), + FIELD_SIZEOF(metadata_decrypted_header_t, file_data)); DBG("size(metadata_padding_t) = 0x%04lx\n", sizeof(metadata_padding_t)); DBG("metadata_padding_t : 0x%04lx (0x%04lx)\n", - mdps + sizeof(metadata_encrypted_t), sizeof(metadata_padding_t)); + mdps + sizeof(metadata_decrypted_header_t), sizeof(metadata_padding_t)); /* node 0: metadata + 3k of user data */ /* plain metadata */ truncate_file("trunc_meta_plain_0", 0); - truncate_file("trunc_meta_plain_1", FIELD_TRUNCATED(metadata_plain_t, file_id)); - truncate_file("trunc_meta_plain_2", offsetof(metadata_plain_t, major_version)); - truncate_file("trunc_meta_plain_3", offsetof(metadata_plain_t, minor_version)); - truncate_file("trunc_meta_plain_4", offsetof(metadata_plain_t, metadata_key_id)); - truncate_file("trunc_meta_plain_5", FIELD_TRUNCATED(metadata_plain_t, metadata_key_id)); - truncate_file("trunc_meta_plain_6", offsetof(metadata_plain_t, metadata_gmac)); - truncate_file("trunc_meta_plain_7", FIELD_TRUNCATED(metadata_plain_t, metadata_gmac)); + truncate_file("trunc_meta_plain_1", FIELD_TRUNCATED(metadata_plaintext_header_t, file_id)); + truncate_file("trunc_meta_plain_2", offsetof(metadata_plaintext_header_t, major_version)); + truncate_file("trunc_meta_plain_3", offsetof(metadata_plaintext_header_t, minor_version)); + truncate_file("trunc_meta_plain_4", offsetof(metadata_plaintext_header_t, metadata_key_salt)); + truncate_file("trunc_meta_plain_5", FIELD_TRUNCATED(metadata_plaintext_header_t, + metadata_key_salt)); + truncate_file("trunc_meta_plain_6", offsetof(metadata_plaintext_header_t, metadata_gmac)); + truncate_file("trunc_meta_plain_7", FIELD_TRUNCATED(metadata_plaintext_header_t, + metadata_gmac)); /* encrypted metadata */ - truncate_file("trunc_meta_enc_0", mdps + offsetof(metadata_encrypted_t, path)); - truncate_file("trunc_meta_enc_1", mdps + FIELD_TRUNCATED(metadata_encrypted_t, path)); - truncate_file("trunc_meta_enc_2", mdps + offsetof(metadata_encrypted_t, size)); - truncate_file("trunc_meta_enc_3", mdps + FIELD_TRUNCATED(metadata_encrypted_t, size)); - truncate_file("trunc_meta_enc_4", mdps + offsetof(metadata_encrypted_t, mht_key)); - truncate_file("trunc_meta_enc_5", mdps + FIELD_TRUNCATED(metadata_encrypted_t, mht_key)); - truncate_file("trunc_meta_enc_6", mdps + offsetof(metadata_encrypted_t, mht_gmac)); - truncate_file("trunc_meta_enc_7", mdps + FIELD_TRUNCATED(metadata_encrypted_t, mht_gmac)); - truncate_file("trunc_meta_enc_8", mdps + offsetof(metadata_encrypted_t, data)); - truncate_file("trunc_meta_enc_9", mdps + FIELD_TRUNCATED(metadata_encrypted_t, data)); + truncate_file("trunc_meta_enc_0", mdps + offsetof(metadata_decrypted_header_t, file_path)); + truncate_file("trunc_meta_enc_1", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, + file_path)); + truncate_file("trunc_meta_enc_2", mdps + offsetof(metadata_decrypted_header_t, file_size)); + truncate_file("trunc_meta_enc_3", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, + file_size)); + truncate_file("trunc_meta_enc_4", mdps + offsetof(metadata_decrypted_header_t, + root_mht_node_key)); + truncate_file("trunc_meta_enc_5", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, + root_mht_node_key)); + truncate_file("trunc_meta_enc_6", mdps + offsetof(metadata_decrypted_header_t, + root_mht_node_gmac)); + truncate_file("trunc_meta_enc_7", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, + root_mht_node_gmac)); + truncate_file("trunc_meta_enc_8", mdps + offsetof(metadata_decrypted_header_t, file_data)); + truncate_file("trunc_meta_enc_9", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, + file_data)); /* padding */ - truncate_file("trunc_meta_pad_0", mdps + sizeof(metadata_encrypted_t)); - truncate_file("trunc_meta_pad_1", mdps + sizeof(metadata_encrypted_t) + truncate_file("trunc_meta_pad_0", mdps + sizeof(metadata_decrypted_header_t)); + truncate_file("trunc_meta_pad_1", mdps + sizeof(metadata_decrypted_header_t) + sizeof(metadata_padding_t) / 2); /* node 1: mht root */ @@ -255,11 +269,11 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, make_output_path(suffix); \ meta = create_output(g_output_path); \ out = (uint8_t*)meta; \ - pf_decrypt(&meta->encrypted_part, sizeof(meta->encrypted_part), &g_meta_key, \ - &meta->plain_part.metadata_gmac, meta_dec, "metadata"); \ + pf_decrypt(&meta->encrypted_blob, sizeof(meta->encrypted_blob), &g_meta_key, \ + &meta->plaintext_header.metadata_gmac, meta_dec, "metadata"); \ mht_enc = (mht_node_t*)(out + PF_NODE_SIZE); \ - pf_decrypt(mht_enc, sizeof(*mht_enc), &meta_dec->mht_key, &meta_dec->mht_gmac, mht_dec, \ - "mht"); \ + pf_decrypt(mht_enc, sizeof(*mht_enc), &meta_dec->root_mht_node_key, \ + &meta_dec->root_mht_node_gmac, mht_dec, "mht"); \ __VA_ARGS__ \ munmap(meta, g_input_size); \ } while (0) @@ -270,7 +284,7 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, if (update) { \ __BREAK_PF(suffix "_fixed", __VA_ARGS__ { \ pf_encrypt(meta_dec, sizeof(*meta_dec), &g_meta_key, \ - &meta->plain_part.metadata_gmac, meta->encrypted_part, \ + &meta->plaintext_header.metadata_gmac, meta->encrypted_blob, \ "metadata"); \ } ); \ } \ @@ -278,8 +292,8 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, #define BREAK_MHT(suffix, ...) do { \ __BREAK_PF(suffix, __VA_ARGS__ { \ - pf_encrypt(mht_dec, sizeof(*mht_dec), &meta_dec->mht_key, &meta_dec->mht_gmac, \ - mht_enc, "mht"); \ + pf_encrypt(mht_dec, sizeof(*mht_dec), &meta_dec->root_mht_node_key, \ + &meta_dec->root_mht_node_gmac, mht_enc, "mht"); \ } ); \ } while (0) @@ -288,7 +302,7 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, static void tamper_modify(void) { metadata_node_t* meta = NULL; uint8_t* out = NULL; - metadata_encrypted_t* meta_dec = malloc(sizeof(*meta_dec)); + metadata_decrypted_header_t* meta_dec = malloc(sizeof(*meta_dec)); if (!meta_dec) FATAL("Out of memory\n"); mht_node_t* mht_enc = NULL; @@ -298,53 +312,53 @@ static void tamper_modify(void) { /* plain part of the metadata isn't covered by the MAC so no point updating it */ BREAK_PF("meta_plain_id_0", /*update=*/false, - { meta->plain_part.file_id = 0; }); + { meta->plaintext_header.file_id = 0; }); BREAK_PF("meta_plain_id_1", /*update=*/false, - { meta->plain_part.file_id = UINT64_MAX; }); + { meta->plaintext_header.file_id = UINT64_MAX; }); BREAK_PF("meta_plain_version_0", /*update=*/false, - { meta->plain_part.major_version = 0; }); + { meta->plaintext_header.major_version = 0; }); BREAK_PF("meta_plain_version_1", /*update=*/false, - { meta->plain_part.major_version = 0xff; }); + { meta->plaintext_header.major_version = 0xff; }); BREAK_PF("meta_plain_version_2", /*update=*/false, - { meta->plain_part.minor_version = 0xff; }); - - /* metadata_key_id is the keying material for encrypted metadata key derivation, so create also - * PFs with updated MACs */ - BREAK_PF("meta_plain_keyid_0", /*update=*/true, - { meta->plain_part.metadata_key_id[0] ^= 1; }); - BREAK_PF("meta_plain_keyid_1", /*update=*/true, - { LAST_BYTE(meta->plain_part.metadata_key_id) ^= 0xfe; }); + { meta->plaintext_header.minor_version = 0xff; }); + + /* metadata_key_salt is the keying material for encrypted metadata key derivation, so create + * also PFs with updated MACs */ + BREAK_PF("meta_plain_salt_0", /*update=*/true, + { meta->plaintext_header.metadata_key_salt[0] ^= 1; }); + BREAK_PF("meta_plain_salt_1", /*update=*/true, + { LAST_BYTE(meta->plaintext_header.metadata_key_salt) ^= 0xfe; }); BREAK_PF("meta_plain_mac_0", /*update=*/true, - { meta->plain_part.metadata_gmac[0] ^= 0xfe; }); + { meta->plaintext_header.metadata_gmac[0] ^= 0xfe; }); BREAK_PF("meta_plain_mac_1", /*update=*/true, - { LAST_BYTE(meta->plain_part.metadata_gmac) &= 1; }); + { LAST_BYTE(meta->plaintext_header.metadata_gmac) &= 1; }); BREAK_PF("meta_enc_filename_0", /*update=*/true, - { meta_dec->path[0] = 0; }); + { meta_dec->file_path[0] = 0; }); BREAK_PF("meta_enc_filename_1", /*update=*/true, - { meta_dec->path[0] ^= 1; }); + { meta_dec->file_path[0] ^= 1; }); BREAK_PF("meta_enc_filename_2", /*update=*/true, - { LAST_BYTE(meta_dec->path) ^= 0xfe; }); + { LAST_BYTE(meta_dec->file_path) ^= 0xfe; }); BREAK_PF("meta_enc_size_0", /*update=*/true, - { meta_dec->size = 0; }); + { meta_dec->file_size = 0; }); BREAK_PF("meta_enc_size_1", /*update=*/true, - { meta_dec->size = g_input_size - 1; }); + { meta_dec->file_size = g_input_size - 1; }); BREAK_PF("meta_enc_size_2", /*update=*/true, - { meta_dec->size = g_input_size + 1; }); + { meta_dec->file_size = g_input_size + 1; }); BREAK_PF("meta_enc_size_3", /*update=*/true, - { meta_dec->size = UINT64_MAX; }); + { meta_dec->file_size = UINT64_MAX; }); BREAK_PF("meta_enc_mht_key_0", /*update=*/true, - { meta_dec->mht_key[0] ^= 1; }); + { meta_dec->root_mht_node_key[0] ^= 1; }); BREAK_PF("meta_enc_mht_key_1", /*update=*/true, - { LAST_BYTE(meta_dec->mht_key) ^= 0xfe; }); + { LAST_BYTE(meta_dec->root_mht_node_key) ^= 0xfe; }); BREAK_PF("meta_enc_mht_mac_0", /*update=*/true, - { meta_dec->mht_gmac[0] ^= 1; }); + { meta_dec->root_mht_node_gmac[0] ^= 1; }); BREAK_PF("meta_enc_mht_mac_1", /*update=*/true, - { LAST_BYTE(meta_dec->mht_gmac) ^= 0xfe; }); + { LAST_BYTE(meta_dec->root_mht_node_gmac) ^= 0xfe; }); BREAK_PF("meta_enc_data_0", /*update=*/true, - { meta_dec->data[0] ^= 0xfe; }); + { meta_dec->file_data[0] ^= 0xfe; }); BREAK_PF("meta_enc_data_1", /*update=*/true, - { LAST_BYTE(meta_dec->data) ^= 1; }); + { LAST_BYTE(meta_dec->file_data) ^= 1; }); /* padding is ignored */ BREAK_PF("meta_padding_0", /*update=*/false, @@ -461,7 +475,7 @@ int main(int argc, char* argv[]) { } load_wrap_key(wrap_key_path, &g_wrap_key); - derive_main_key(&g_wrap_key, &((metadata_plain_t*)g_input_data)->metadata_key_id, + derive_main_key(&g_wrap_key, &((metadata_plaintext_header_t*)g_input_data)->metadata_key_salt, &g_meta_key); g_input_name = basename(input_path); From 6c008a3ecbc9c148dcc51938487dcc617398fb09 Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Wed, 24 Apr 2024 03:19:01 -0700 Subject: [PATCH 2/4] fixup! [common] Refactor Protected Files slightly Signed-off-by: Dmitrii Kuvaiskii --- common/src/protected_files/protected_files.c | 38 ++++----- common/src/protected_files/protected_files.h | 20 ++--- .../protected_files/protected_files_format.h | 6 +- libos/src/fs/libos_fs_encrypted.c | 16 ++-- tools/sgx/common/pf_util.c | 14 ++-- tools/sgx/common/pf_util.h | 6 +- tools/sgx/pf_tamper/pf_tamper.c | 82 +++++++++---------- 7 files changed, 91 insertions(+), 91 deletions(-) diff --git a/common/src/protected_files/protected_files.c b/common/src/protected_files/protected_files.c index a7f887d19e..02ef7ae115 100644 --- a/common/src/protected_files/protected_files.c +++ b/common/src/protected_files/protected_files.c @@ -52,7 +52,7 @@ static const char* g_pf_error_list[] = { [-PF_STATUS_INVALID_VERSION] = "Invalid version", [-PF_STATUS_INVALID_HEADER] = "Invalid header", [-PF_STATUS_INVALID_PATH] = "Invalid path", - [-PF_STATUS_MAC_MISMATCH] = "MAC mismatch", + [-PF_STATUS_TAG_MISMATCH] = "Authentication tag mismatch", [-PF_STATUS_NOT_IMPLEMENTED] = "Functionality not implemented", [-PF_STATUS_CALLBACK_FAILED] = "Callback failed", [-PF_STATUS_PATH_TOO_LONG] = "Path is too long", @@ -204,7 +204,7 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { void* node; // 1. encrypt the changed data nodes - // 2. set the key + GMAC in the parent MHT nodes + // 2. set the key + tag in the parent MHT nodes // 3. set the need_writing flag for all parent MHT nodes for (node = lruc_get_first(pf->cache); node != NULL; node = lruc_get_next(pf->cache)) { if (((file_node_t*)node)->type != FILE_DATA_NODE_TYPE) @@ -221,10 +221,10 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { if (!ipf_generate_random_key(pf, &gcm_crypto_data->key)) goto out; - // encrypt data node, this also saves GMAC in the corresponding crypto slot of MHT node + // encrypt data node, this also saves tag in the corresponding crypto slot of MHT node status = g_cb_aes_gcm_encrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, // aad &data_node->decrypted.data.bytes, PF_NODE_SIZE, - &data_node->encrypted.bytes, &gcm_crypto_data->gmac); + &data_node->encrypted.bytes, &gcm_crypto_data->tag); if (PF_FAILURE(status)) { pf->last_error = status; goto out; @@ -267,7 +267,7 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { if (dirty_count > 0) sort_nodes(mht_nodes_array, 0, dirty_count - 1); - // update the keys and GMACs in the parents from last node to first (bottom layers first) + // update the keys and tags in the parents from last node to first (bottom layers first) for (dirty_idx = dirty_count; dirty_idx > 0; dirty_idx--) { file_node_t* mht_node = mht_nodes_array[dirty_idx - 1]; @@ -280,14 +280,14 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { status = g_cb_aes_gcm_encrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, &mht_node->decrypted.mht, PF_NODE_SIZE, - &mht_node->encrypted.bytes, &gcm_crypto_data->gmac); + &mht_node->encrypted.bytes, &gcm_crypto_data->tag); if (PF_FAILURE(status)) { pf->last_error = status; goto out; } } - // update root MHT node's key and GMAC in the metadata node's headers + // update root MHT node's key and tag in the metadata node's headers if (!ipf_generate_random_key(pf, &pf->metadata_decrypted_header.root_mht_node_key)) goto out; @@ -295,7 +295,7 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { NULL, 0, &pf->root_mht_node.decrypted.mht, PF_NODE_SIZE, &pf->root_mht_node.encrypted.bytes, - &pf->metadata_decrypted_header.root_mht_node_gmac); + &pf->metadata_decrypted_header.root_mht_node_tag); if (PF_FAILURE(status)) { pf->last_error = status; goto out; @@ -419,11 +419,11 @@ static bool ipf_update_metadata_node(pf_context_t* pf) { return false; } - // encrypt metadata part-to-be-encrypted, also updates the GMAC in metadata plaintext header + // encrypt metadata part-to-be-encrypted, also updates the tag in metadata plaintext header status = g_cb_aes_gcm_encrypt(&key, &g_empty_iv, NULL, 0, &pf->metadata_decrypted_header, sizeof(metadata_decrypted_header_t), &pf->metadata_node.encrypted_blob, - &pf->metadata_node.plaintext_header.metadata_gmac); + &pf->metadata_node.plaintext_header.metadata_tag); if (PF_FAILURE(status)) { pf->last_error = status; return false; @@ -642,15 +642,15 @@ static file_node_t* ipf_read_data_node(pf_context_t* pf, uint64_t offset) { &data_node->parent->decrypted.mht .data_nodes_crypto[data_node->logical_node_number % ATTACHED_DATA_NODES_COUNT]; - // decrypt data and check integrity against the GMAC in corresponding slot in MHT node + // decrypt data and check integrity against the tag in corresponding slot in MHT node status = g_cb_aes_gcm_decrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, &data_node->encrypted.bytes, PF_NODE_SIZE, - &data_node->decrypted.data.bytes, &gcm_crypto_data->gmac); + &data_node->decrypted.data.bytes, &gcm_crypto_data->tag); if (PF_FAILURE(status)) { free(data_node); pf->last_error = status; - if (status == PF_STATUS_MAC_MISMATCH) + if (status == PF_STATUS_TAG_MISMATCH) pf->file_status = PF_STATUS_CORRUPTED; return NULL; } @@ -705,14 +705,14 @@ static file_node_t* ipf_read_mht_node(pf_context_t* pf, uint64_t logical_mht_nod &mht_node->parent->decrypted.mht .mht_nodes_crypto[(mht_node->logical_node_number - 1) % CHILD_MHT_NODES_COUNT]; - // decrypt data and check integrity against the GMAC in corresponding slot in parent MHT node + // decrypt data and check integrity against the tag in corresponding slot in parent MHT node status = g_cb_aes_gcm_decrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, &mht_node->encrypted.bytes, PF_NODE_SIZE, - &mht_node->decrypted.mht, &gcm_crypto_data->gmac); + &mht_node->decrypted.mht, &gcm_crypto_data->tag); if (PF_FAILURE(status)) { free(mht_node); pf->last_error = status; - if (status == PF_STATUS_MAC_MISMATCH) + if (status == PF_STATUS_TAG_MISMATCH) pf->file_status = PF_STATUS_CORRUPTED; return NULL; } @@ -793,7 +793,7 @@ static bool ipf_init_existing_file(pf_context_t* pf, const char* path) { &pf->metadata_node.encrypted_blob, sizeof(pf->metadata_node.encrypted_blob), &pf->metadata_decrypted_header, - &pf->metadata_node.plaintext_header.metadata_gmac); + &pf->metadata_node.plaintext_header.metadata_tag); if (PF_FAILURE(status)) { pf->last_error = status; DEBUG_PF("failed to decrypt metadata: %d", status); @@ -816,12 +816,12 @@ static bool ipf_init_existing_file(pf_context_t* pf, const char* path) { if (!ipf_read_node(pf, /*logical_node_number=*/1, &pf->root_mht_node.encrypted.bytes)) return false; - // also verifies root MHT node's GMAC against the GMAC in metadata node's decrypted header + // also verifies root MHT node's tag against the tag in metadata node's decrypted header status = g_cb_aes_gcm_decrypt(&pf->metadata_decrypted_header.root_mht_node_key, &g_empty_iv, NULL, 0, // aad &pf->root_mht_node.encrypted.bytes, PF_NODE_SIZE, &pf->root_mht_node.decrypted.mht, - &pf->metadata_decrypted_header.root_mht_node_gmac); + &pf->metadata_decrypted_header.root_mht_node_tag); if (PF_FAILURE(status)) { pf->last_error = status; return false; diff --git a/common/src/protected_files/protected_files.h b/common/src/protected_files/protected_files.h index 018161687d..eddda72fff 100644 --- a/common/src/protected_files/protected_files.h +++ b/common/src/protected_files/protected_files.h @@ -17,8 +17,8 @@ /*! Size of IV for AES-GCM */ #define PF_IV_SIZE 12 -/*! Size of MAC fields */ -#define PF_MAC_SIZE 16 +/*! Size of tag fields */ +#define PF_TAG_SIZE 16 /*! Size of the AES-GCM encryption key */ #define PF_KEY_SIZE 16 @@ -27,7 +27,7 @@ #define PF_SALT_SIZE 32 typedef uint8_t pf_iv_t[PF_IV_SIZE]; -typedef uint8_t pf_mac_t[PF_MAC_SIZE]; +typedef uint8_t pf_tag_t[PF_TAG_SIZE]; typedef uint8_t pf_key_t[PF_KEY_SIZE]; typedef uint8_t pf_salt_t[PF_SALT_SIZE]; @@ -41,7 +41,7 @@ typedef enum _pf_status_t { PF_STATUS_INVALID_VERSION = -6, PF_STATUS_INVALID_HEADER = -7, PF_STATUS_INVALID_PATH = -8, - PF_STATUS_MAC_MISMATCH = -9, + PF_STATUS_TAG_MISMATCH = -9, PF_STATUS_NOT_IMPLEMENTED = -10, PF_STATUS_CALLBACK_FAILED = -11, PF_STATUS_PATH_TOO_LONG = -12, @@ -124,12 +124,12 @@ typedef void (*pf_debug_f)(const char* msg); * \param key AES-GCM key. * \param input Plaintext data. * \param input_size Size of \p input in bytes. - * \param[out] mac MAC computed for \p input. + * \param[out] tag Authentication tag computed for \p input. * * \returns PF status. */ typedef pf_status_t (*pf_aes_cmac_f)(const pf_key_t* key, const void* input, size_t input_size, - pf_mac_t* mac); + pf_tag_t* tag); /*! * \brief AES-GCM encrypt callback. @@ -141,13 +141,13 @@ typedef pf_status_t (*pf_aes_cmac_f)(const pf_key_t* key, const void* input, siz * \param input Plaintext data. * \param input_size Size of \p input in bytes. * \param[out] output Buffer for encrypted data (size: \p input_size). - * \param[out] mac MAC computed for \p input and \p aad. + * \param[out] tag Authentication tag computed for \p input and \p aad. * * \returns PF status. */ typedef pf_status_t (*pf_aes_gcm_encrypt_f)(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, pf_mac_t* mac); + void* output, pf_tag_t* tag); /*! * \brief AES-GCM decrypt callback. @@ -159,13 +159,13 @@ typedef pf_status_t (*pf_aes_gcm_encrypt_f)(const pf_key_t* key, const pf_iv_t* * \param input Encrypted data. * \param input_size Size of \p input in bytes. * \param[out] output Buffer for decrypted data (size: \p input_size). - * \param mac Expected MAC. + * \param tag Expected authentication tag. * * \returns PF status. */ typedef pf_status_t (*pf_aes_gcm_decrypt_f)(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, const pf_mac_t* mac); + void* output, const pf_tag_t* tag); /*! * \brief Cryptographic random number generator callback. diff --git a/common/src/protected_files/protected_files_format.h b/common/src/protected_files/protected_files_format.h index 581161010e..38bc7309a9 100644 --- a/common/src/protected_files/protected_files_format.h +++ b/common/src/protected_files/protected_files_format.h @@ -40,7 +40,7 @@ enum { typedef struct _gcm_crypto_data { pf_key_t key; - pf_mac_t gmac; + pf_tag_t tag; } gcm_crypto_data_t; // for PF_NODE_SIZE == 4096, we have 96 attached data nodes and 32 MHT child nodes @@ -55,14 +55,14 @@ typedef struct _metadata_plaintext_header { uint8_t major_version; uint8_t minor_version; pf_salt_t metadata_key_salt; - pf_mac_t metadata_gmac; /* GCM mac */ + pf_tag_t metadata_tag; /* GCM MAC aka Authentication Tag */ } metadata_plaintext_header_t; typedef struct _metadata_decrypted_header { char file_path[PATH_MAX_SIZE]; uint64_t file_size; pf_key_t root_mht_node_key; - pf_mac_t root_mht_node_gmac; + pf_tag_t root_mht_node_tag; uint8_t file_data[MD_USER_DATA_SIZE]; } metadata_decrypted_header_t; diff --git a/libos/src/fs/libos_fs_encrypted.c b/libos/src/fs/libos_fs_encrypted.c index 3926bb780a..30a59a6bf6 100644 --- a/libos/src/fs/libos_fs_encrypted.c +++ b/libos/src/fs/libos_fs_encrypted.c @@ -104,9 +104,9 @@ static pf_status_t cb_fsync(pf_handle_t handle) { } static pf_status_t cb_aes_cmac(const pf_key_t* key, const void* input, size_t input_size, - pf_mac_t* mac) { - int ret = lib_AESCMAC((const uint8_t*)key, sizeof(*key), input, input_size, (uint8_t*)mac, - sizeof(*mac)); + pf_tag_t* tag) { + int ret = lib_AESCMAC((const uint8_t*)key, sizeof(*key), input, input_size, (uint8_t*)tag, + sizeof(*tag)); if (ret != 0) { log_warning("lib_AESCMAC failed: %d", ret); return PF_STATUS_CALLBACK_FAILED; @@ -116,9 +116,9 @@ static pf_status_t cb_aes_cmac(const pf_key_t* key, const void* input, size_t in static pf_status_t cb_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, pf_mac_t* mac) { + void* output, pf_tag_t* tag) { int ret = lib_AESGCMEncrypt((const uint8_t*)key, sizeof(*key), (const uint8_t*)iv, input, - input_size, aad, aad_size, output, (uint8_t*)mac, sizeof(*mac)); + input_size, aad, aad_size, output, (uint8_t*)tag, sizeof(*tag)); if (ret != 0) { log_warning("lib_AESGCMEncrypt failed: %d", ret); return PF_STATUS_CALLBACK_FAILED; @@ -128,10 +128,10 @@ static pf_status_t cb_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, co static pf_status_t cb_aes_gcm_decrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, const pf_mac_t* mac) { + void* output, const pf_tag_t* tag) { int ret = lib_AESGCMDecrypt((const uint8_t*)key, sizeof(*key), (const uint8_t*)iv, input, - input_size, aad, aad_size, output, (const uint8_t*)mac, - sizeof(*mac)); + input_size, aad, aad_size, output, (const uint8_t*)tag, + sizeof(*tag)); if (ret != 0) { log_warning("lib_AESGCMDecrypt failed: %d", ret); return PF_STATUS_CALLBACK_FAILED; diff --git a/tools/sgx/common/pf_util.c b/tools/sgx/common/pf_util.c index eadd0323c3..468198293b 100644 --- a/tools/sgx/common/pf_util.c +++ b/tools/sgx/common/pf_util.c @@ -124,12 +124,12 @@ static pf_status_t linux_truncate(pf_handle_t handle, uint64_t size) { /* Crypto callbacks for mbedTLS */ pf_status_t mbedtls_aes_cmac(const pf_key_t* key, const void* input, size_t input_size, - pf_mac_t* mac) { + pf_tag_t* tag) { const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); int ret = mbedtls_cipher_cmac(cipher_info, (const unsigned char*)key, PF_KEY_SIZE * 8, input, - input_size, (unsigned char*)mac); + input_size, (unsigned char*)tag); if (ret != 0) { ERROR("mbedtls_cipher_cmac failed: %d\n", ret); return PF_STATUS_CALLBACK_FAILED; @@ -140,7 +140,7 @@ pf_status_t mbedtls_aes_cmac(const pf_key_t* key, const void* input, size_t inpu pf_status_t mbedtls_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, pf_mac_t* mac) { + void* output, pf_tag_t* tag) { pf_status_t status = PF_STATUS_CALLBACK_FAILED; mbedtls_gcm_context gcm; @@ -154,8 +154,8 @@ pf_status_t mbedtls_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, cons } ret = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, input_size, (const unsigned char*)iv, - PF_IV_SIZE, aad, aad_size, input, output, PF_MAC_SIZE, - (unsigned char*)mac); + PF_IV_SIZE, aad, aad_size, input, output, PF_TAG_SIZE, + (unsigned char*)tag); if (ret != 0) { ERROR("mbedtls_gcm_crypt_and_tag failed: %d\n", ret); goto out; @@ -169,7 +169,7 @@ pf_status_t mbedtls_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, cons pf_status_t mbedtls_aes_gcm_decrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, const pf_mac_t* mac) { + void* output, const pf_tag_t* tag) { pf_status_t status = PF_STATUS_CALLBACK_FAILED; mbedtls_gcm_context gcm; @@ -183,7 +183,7 @@ pf_status_t mbedtls_aes_gcm_decrypt(const pf_key_t* key, const pf_iv_t* iv, cons } ret = mbedtls_gcm_auth_decrypt(&gcm, input_size, (const unsigned char*)iv, PF_IV_SIZE, aad, - aad_size, (const unsigned char*)mac, PF_MAC_SIZE, input, output); + aad_size, (const unsigned char*)tag, PF_TAG_SIZE, input, output); if (ret != 0) { ERROR("mbedtls_gcm_auth_decrypt failed: %d\n", ret); goto out; diff --git a/tools/sgx/common/pf_util.h b/tools/sgx/common/pf_util.h index 4276407bef..59fcd3cd44 100644 --- a/tools/sgx/common/pf_util.h +++ b/tools/sgx/common/pf_util.h @@ -31,17 +31,17 @@ int pf_decrypt_files(const char* input_dir, const char* output_dir, bool verify_ /*! AES-CMAC */ pf_status_t mbedtls_aes_cmac(const pf_key_t* key, const void* input, size_t input_size, - pf_mac_t* mac); + pf_tag_t* tag); /*! AES-GCM encrypt */ pf_status_t mbedtls_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, pf_mac_t* mac); + void* output, pf_tag_t* tag); /*! AES-GCM decrypt */ pf_status_t mbedtls_aes_gcm_decrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, const pf_mac_t* mac); + void* output, const pf_tag_t* tag); /*! Load PF wrap key from file */ int load_wrap_key(const char* wrap_key_path, pf_key_t* wrap_key); diff --git a/tools/sgx/pf_tamper/pf_tamper.c b/tools/sgx/pf_tamper/pf_tamper.c index b4a3945519..ce8525e128 100644 --- a/tools/sgx/pf_tamper/pf_tamper.c +++ b/tools/sgx/pf_tamper/pf_tamper.c @@ -125,9 +125,9 @@ static void tamper_truncate(void) { DBG("metadata_plaintext_header_t.metadata_key_salt : 0x%04lx (0x%04lx)\n", offsetof(metadata_plaintext_header_t, metadata_key_salt), FIELD_SIZEOF(metadata_plaintext_header_t, metadata_key_salt)); - DBG("metadata_plaintext_header_t.metadata_gmac : 0x%04lx (0x%04lx)\n", - offsetof(metadata_plaintext_header_t, metadata_gmac), - FIELD_SIZEOF(metadata_plaintext_header_t, metadata_gmac)); + DBG("metadata_plaintext_header_t.metadata_tag : 0x%04lx (0x%04lx)\n", + offsetof(metadata_plaintext_header_t, metadata_tag), + FIELD_SIZEOF(metadata_plaintext_header_t, metadata_tag)); DBG("size(metadata_decrypted_header_t) = 0x%04lx\n", sizeof(metadata_decrypted_header_t)); DBG("metadata_decrypted_header_t.file_path : 0x%04lx (0x%04lx)\n", @@ -139,9 +139,9 @@ static void tamper_truncate(void) { DBG("metadata_decrypted_header_t.root_mht_node_key : 0x%04lx (0x%04lx)\n", mdps + offsetof(metadata_decrypted_header_t, root_mht_node_key), FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_key)); - DBG("metadata_decrypted_header_t.root_mht_node_gmac : 0x%04lx (0x%04lx)\n", - mdps + offsetof(metadata_decrypted_header_t, root_mht_node_gmac), - FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_gmac)); + DBG("metadata_decrypted_header_t.root_mht_node_tag : 0x%04lx (0x%04lx)\n", + mdps + offsetof(metadata_decrypted_header_t, root_mht_node_tag), + FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_tag)); DBG("metadata_decrypted_header_t.file_data : 0x%04lx (0x%04lx)\n", mdps + offsetof(metadata_decrypted_header_t, file_data), FIELD_SIZEOF(metadata_decrypted_header_t, file_data)); @@ -159,9 +159,9 @@ static void tamper_truncate(void) { truncate_file("trunc_meta_plain_4", offsetof(metadata_plaintext_header_t, metadata_key_salt)); truncate_file("trunc_meta_plain_5", FIELD_TRUNCATED(metadata_plaintext_header_t, metadata_key_salt)); - truncate_file("trunc_meta_plain_6", offsetof(metadata_plaintext_header_t, metadata_gmac)); + truncate_file("trunc_meta_plain_6", offsetof(metadata_plaintext_header_t, metadata_tag)); truncate_file("trunc_meta_plain_7", FIELD_TRUNCATED(metadata_plaintext_header_t, - metadata_gmac)); + metadata_tag)); /* encrypted metadata */ truncate_file("trunc_meta_enc_0", mdps + offsetof(metadata_decrypted_header_t, file_path)); @@ -175,9 +175,9 @@ static void tamper_truncate(void) { truncate_file("trunc_meta_enc_5", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, root_mht_node_key)); truncate_file("trunc_meta_enc_6", mdps + offsetof(metadata_decrypted_header_t, - root_mht_node_gmac)); + root_mht_node_tag)); truncate_file("trunc_meta_enc_7", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, - root_mht_node_gmac)); + root_mht_node_tag)); truncate_file("trunc_meta_enc_8", mdps + offsetof(metadata_decrypted_header_t, file_data)); truncate_file("trunc_meta_enc_9", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, file_data)); @@ -194,20 +194,20 @@ static void tamper_truncate(void) { truncate_file("trunc_mht_1", PF_NODE_SIZE + PF_KEY_SIZE / 2); /* after data_nodes_crypto[0].key */ truncate_file("trunc_mht_2", PF_NODE_SIZE + PF_KEY_SIZE); - /* middle of data_nodes_crypto[0].gmac */ - truncate_file("trunc_mht_3", PF_NODE_SIZE + PF_KEY_SIZE + PF_MAC_SIZE / 2); - /* after data_nodes_crypto[0].gmac */ - truncate_file("trunc_mht_4", PF_NODE_SIZE + PF_KEY_SIZE + PF_MAC_SIZE); + /* middle of data_nodes_crypto[0].tag */ + truncate_file("trunc_mht_3", PF_NODE_SIZE + PF_KEY_SIZE + PF_TAG_SIZE / 2); + /* after data_nodes_crypto[0].tag */ + truncate_file("trunc_mht_4", PF_NODE_SIZE + PF_KEY_SIZE + PF_TAG_SIZE); /* after data_nodes_crypto */ truncate_file("trunc_mht_5", PF_NODE_SIZE + DATA_CRYPTO_SIZE); /* middle of mht_nodes_crypto[0].key */ truncate_file("trunc_mht_6", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE / 2); /* after mht_nodes_crypto[0].key */ truncate_file("trunc_mht_7", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE); - /* middle of mht_nodes_crypto[0].gmac */ - truncate_file("trunc_mht_8", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_MAC_SIZE / 2); - /* after mht_nodes_crypto[0].gmac */ - truncate_file("trunc_mht_9", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_MAC_SIZE); + /* middle of mht_nodes_crypto[0].tag */ + truncate_file("trunc_mht_8", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_TAG_SIZE / 2); + /* after mht_nodes_crypto[0].tag */ + truncate_file("trunc_mht_9", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_TAG_SIZE); /* node 2-3: data #0, #1 */ /* after mht root */ @@ -246,20 +246,20 @@ static void* create_output(const char* path) { return mem; } -static void pf_decrypt(const void* encrypted, size_t size, const pf_key_t* key, const pf_mac_t* mac, +static void pf_decrypt(const void* encrypted, size_t size, const pf_key_t* key, const pf_tag_t* tag, void* decrypted, const char* msg) { pf_status_t status = mbedtls_aes_gcm_decrypt(key, &g_empty_iv, NULL, 0, encrypted, size, - decrypted, mac); + decrypted, tag); if (PF_FAILURE(status)) FATAL("decrypting %s failed\n", msg); } -static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, pf_mac_t* mac, +static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, pf_tag_t* tag, void* encrypted, const char* msg) { pf_status_t status = mbedtls_aes_gcm_encrypt(key, &g_empty_iv, NULL, 0, decrypted, size, - encrypted, mac); + encrypted, tag); if (PF_FAILURE(status)) FATAL("encrypting %s failed\n", msg); } @@ -270,21 +270,21 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, meta = create_output(g_output_path); \ out = (uint8_t*)meta; \ pf_decrypt(&meta->encrypted_blob, sizeof(meta->encrypted_blob), &g_meta_key, \ - &meta->plaintext_header.metadata_gmac, meta_dec, "metadata"); \ + &meta->plaintext_header.metadata_tag, meta_dec, "metadata"); \ mht_enc = (mht_node_t*)(out + PF_NODE_SIZE); \ pf_decrypt(mht_enc, sizeof(*mht_enc), &meta_dec->root_mht_node_key, \ - &meta_dec->root_mht_node_gmac, mht_dec, "mht"); \ + &meta_dec->root_mht_node_tag, mht_dec, "mht"); \ __VA_ARGS__ \ munmap(meta, g_input_size); \ } while (0) -/* if update is true, also create a file with correct metadata MAC */ +/* if update is true, also create a file with correct metadata tag */ #define BREAK_PF(suffix, update, ...) do { \ __BREAK_PF(suffix, __VA_ARGS__); \ if (update) { \ __BREAK_PF(suffix "_fixed", __VA_ARGS__ { \ pf_encrypt(meta_dec, sizeof(*meta_dec), &g_meta_key, \ - &meta->plaintext_header.metadata_gmac, meta->encrypted_blob, \ + &meta->plaintext_header.metadata_tag, meta->encrypted_blob, \ "metadata"); \ } ); \ } \ @@ -293,7 +293,7 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, #define BREAK_MHT(suffix, ...) do { \ __BREAK_PF(suffix, __VA_ARGS__ { \ pf_encrypt(mht_dec, sizeof(*mht_dec), &meta_dec->root_mht_node_key, \ - &meta_dec->root_mht_node_gmac, mht_enc, "mht"); \ + &meta_dec->root_mht_node_tag, mht_enc, "mht"); \ } ); \ } while (0) @@ -310,7 +310,7 @@ static void tamper_modify(void) { if (!mht_dec) FATAL("Out of memory\n"); - /* plain part of the metadata isn't covered by the MAC so no point updating it */ + /* plain part of the metadata isn't covered by the tag so no point updating it */ BREAK_PF("meta_plain_id_0", /*update=*/false, { meta->plaintext_header.file_id = 0; }); BREAK_PF("meta_plain_id_1", /*update=*/false, @@ -323,15 +323,15 @@ static void tamper_modify(void) { { meta->plaintext_header.minor_version = 0xff; }); /* metadata_key_salt is the keying material for encrypted metadata key derivation, so create - * also PFs with updated MACs */ + * also PFs with updated tags */ BREAK_PF("meta_plain_salt_0", /*update=*/true, { meta->plaintext_header.metadata_key_salt[0] ^= 1; }); BREAK_PF("meta_plain_salt_1", /*update=*/true, { LAST_BYTE(meta->plaintext_header.metadata_key_salt) ^= 0xfe; }); - BREAK_PF("meta_plain_mac_0", /*update=*/true, - { meta->plaintext_header.metadata_gmac[0] ^= 0xfe; }); - BREAK_PF("meta_plain_mac_1", /*update=*/true, - { LAST_BYTE(meta->plaintext_header.metadata_gmac) &= 1; }); + BREAK_PF("meta_plain_tag_0", /*update=*/true, + { meta->plaintext_header.metadata_tag[0] ^= 0xfe; }); + BREAK_PF("meta_plain_tag_1", /*update=*/true, + { LAST_BYTE(meta->plaintext_header.metadata_tag) &= 1; }); BREAK_PF("meta_enc_filename_0", /*update=*/true, { meta_dec->file_path[0] = 0; }); @@ -351,10 +351,10 @@ static void tamper_modify(void) { { meta_dec->root_mht_node_key[0] ^= 1; }); BREAK_PF("meta_enc_mht_key_1", /*update=*/true, { LAST_BYTE(meta_dec->root_mht_node_key) ^= 0xfe; }); - BREAK_PF("meta_enc_mht_mac_0", /*update=*/true, - { meta_dec->root_mht_node_gmac[0] ^= 1; }); - BREAK_PF("meta_enc_mht_mac_1", /*update=*/true, - { LAST_BYTE(meta_dec->root_mht_node_gmac) ^= 0xfe; }); + BREAK_PF("meta_enc_mht_tag_0", /*update=*/true, + { meta_dec->root_mht_node_tag[0] ^= 1; }); + BREAK_PF("meta_enc_mht_tag_1", /*update=*/true, + { LAST_BYTE(meta_dec->root_mht_node_tag) ^= 0xfe; }); BREAK_PF("meta_enc_data_0", /*update=*/true, { meta_dec->file_data[0] ^= 0xfe; }); BREAK_PF("meta_enc_data_1", /*update=*/true, @@ -367,13 +367,13 @@ static void tamper_modify(void) { { LAST_BYTE(meta->padding) ^= 0xfe; }); BREAK_MHT("mht_0", { mht_dec->data_nodes_crypto[0].key[0] ^= 1; }); - BREAK_MHT("mht_1", { mht_dec->data_nodes_crypto[0].gmac[0] ^= 1; }); + BREAK_MHT("mht_1", { mht_dec->data_nodes_crypto[0].tag[0] ^= 1; }); BREAK_MHT("mht_2", { mht_dec->mht_nodes_crypto[0].key[0] ^= 1; }); - BREAK_MHT("mht_3", { mht_dec->mht_nodes_crypto[0].gmac[0] ^= 1; }); + BREAK_MHT("mht_3", { mht_dec->mht_nodes_crypto[0].tag[0] ^= 1; }); BREAK_MHT("mht_4", { mht_dec->data_nodes_crypto[ATTACHED_DATA_NODES_COUNT - 1].key[0] ^= 1; }); - BREAK_MHT("mht_5", { mht_dec->data_nodes_crypto[ATTACHED_DATA_NODES_COUNT - 1].gmac[0] ^= 1; }); + BREAK_MHT("mht_5", { mht_dec->data_nodes_crypto[ATTACHED_DATA_NODES_COUNT - 1].tag[0] ^= 1; }); BREAK_MHT("mht_6", { mht_dec->mht_nodes_crypto[CHILD_MHT_NODES_COUNT - 1].key[0] ^= 1; }); - BREAK_MHT("mht_7", { mht_dec->mht_nodes_crypto[CHILD_MHT_NODES_COUNT - 1].gmac[0] ^= 1; }); + BREAK_MHT("mht_7", { mht_dec->mht_nodes_crypto[CHILD_MHT_NODES_COUNT - 1].tag[0] ^= 1; }); BREAK_MHT("mht_8", { gcm_crypto_data_t crypto; memcpy(&crypto, &mht_dec->data_nodes_crypto[0], sizeof(crypto)); From a14eaa0968e1c1a3b6ec693456ee5937fe94018b Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Wed, 24 Apr 2024 23:24:44 -0700 Subject: [PATCH 3/4] fixup! [common] Refactor Protected Files slightly This reverts commit 6c008a3ecbc9c148dcc51938487dcc617398fb09. --- common/src/protected_files/protected_files.c | 38 ++++----- common/src/protected_files/protected_files.h | 20 ++--- .../protected_files/protected_files_format.h | 6 +- libos/src/fs/libos_fs_encrypted.c | 16 ++-- tools/sgx/common/pf_util.c | 14 ++-- tools/sgx/common/pf_util.h | 6 +- tools/sgx/pf_tamper/pf_tamper.c | 82 +++++++++---------- 7 files changed, 91 insertions(+), 91 deletions(-) diff --git a/common/src/protected_files/protected_files.c b/common/src/protected_files/protected_files.c index 02ef7ae115..a7f887d19e 100644 --- a/common/src/protected_files/protected_files.c +++ b/common/src/protected_files/protected_files.c @@ -52,7 +52,7 @@ static const char* g_pf_error_list[] = { [-PF_STATUS_INVALID_VERSION] = "Invalid version", [-PF_STATUS_INVALID_HEADER] = "Invalid header", [-PF_STATUS_INVALID_PATH] = "Invalid path", - [-PF_STATUS_TAG_MISMATCH] = "Authentication tag mismatch", + [-PF_STATUS_MAC_MISMATCH] = "MAC mismatch", [-PF_STATUS_NOT_IMPLEMENTED] = "Functionality not implemented", [-PF_STATUS_CALLBACK_FAILED] = "Callback failed", [-PF_STATUS_PATH_TOO_LONG] = "Path is too long", @@ -204,7 +204,7 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { void* node; // 1. encrypt the changed data nodes - // 2. set the key + tag in the parent MHT nodes + // 2. set the key + GMAC in the parent MHT nodes // 3. set the need_writing flag for all parent MHT nodes for (node = lruc_get_first(pf->cache); node != NULL; node = lruc_get_next(pf->cache)) { if (((file_node_t*)node)->type != FILE_DATA_NODE_TYPE) @@ -221,10 +221,10 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { if (!ipf_generate_random_key(pf, &gcm_crypto_data->key)) goto out; - // encrypt data node, this also saves tag in the corresponding crypto slot of MHT node + // encrypt data node, this also saves GMAC in the corresponding crypto slot of MHT node status = g_cb_aes_gcm_encrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, // aad &data_node->decrypted.data.bytes, PF_NODE_SIZE, - &data_node->encrypted.bytes, &gcm_crypto_data->tag); + &data_node->encrypted.bytes, &gcm_crypto_data->gmac); if (PF_FAILURE(status)) { pf->last_error = status; goto out; @@ -267,7 +267,7 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { if (dirty_count > 0) sort_nodes(mht_nodes_array, 0, dirty_count - 1); - // update the keys and tags in the parents from last node to first (bottom layers first) + // update the keys and GMACs in the parents from last node to first (bottom layers first) for (dirty_idx = dirty_count; dirty_idx > 0; dirty_idx--) { file_node_t* mht_node = mht_nodes_array[dirty_idx - 1]; @@ -280,14 +280,14 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { status = g_cb_aes_gcm_encrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, &mht_node->decrypted.mht, PF_NODE_SIZE, - &mht_node->encrypted.bytes, &gcm_crypto_data->tag); + &mht_node->encrypted.bytes, &gcm_crypto_data->gmac); if (PF_FAILURE(status)) { pf->last_error = status; goto out; } } - // update root MHT node's key and tag in the metadata node's headers + // update root MHT node's key and GMAC in the metadata node's headers if (!ipf_generate_random_key(pf, &pf->metadata_decrypted_header.root_mht_node_key)) goto out; @@ -295,7 +295,7 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { NULL, 0, &pf->root_mht_node.decrypted.mht, PF_NODE_SIZE, &pf->root_mht_node.encrypted.bytes, - &pf->metadata_decrypted_header.root_mht_node_tag); + &pf->metadata_decrypted_header.root_mht_node_gmac); if (PF_FAILURE(status)) { pf->last_error = status; goto out; @@ -419,11 +419,11 @@ static bool ipf_update_metadata_node(pf_context_t* pf) { return false; } - // encrypt metadata part-to-be-encrypted, also updates the tag in metadata plaintext header + // encrypt metadata part-to-be-encrypted, also updates the GMAC in metadata plaintext header status = g_cb_aes_gcm_encrypt(&key, &g_empty_iv, NULL, 0, &pf->metadata_decrypted_header, sizeof(metadata_decrypted_header_t), &pf->metadata_node.encrypted_blob, - &pf->metadata_node.plaintext_header.metadata_tag); + &pf->metadata_node.plaintext_header.metadata_gmac); if (PF_FAILURE(status)) { pf->last_error = status; return false; @@ -642,15 +642,15 @@ static file_node_t* ipf_read_data_node(pf_context_t* pf, uint64_t offset) { &data_node->parent->decrypted.mht .data_nodes_crypto[data_node->logical_node_number % ATTACHED_DATA_NODES_COUNT]; - // decrypt data and check integrity against the tag in corresponding slot in MHT node + // decrypt data and check integrity against the GMAC in corresponding slot in MHT node status = g_cb_aes_gcm_decrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, &data_node->encrypted.bytes, PF_NODE_SIZE, - &data_node->decrypted.data.bytes, &gcm_crypto_data->tag); + &data_node->decrypted.data.bytes, &gcm_crypto_data->gmac); if (PF_FAILURE(status)) { free(data_node); pf->last_error = status; - if (status == PF_STATUS_TAG_MISMATCH) + if (status == PF_STATUS_MAC_MISMATCH) pf->file_status = PF_STATUS_CORRUPTED; return NULL; } @@ -705,14 +705,14 @@ static file_node_t* ipf_read_mht_node(pf_context_t* pf, uint64_t logical_mht_nod &mht_node->parent->decrypted.mht .mht_nodes_crypto[(mht_node->logical_node_number - 1) % CHILD_MHT_NODES_COUNT]; - // decrypt data and check integrity against the tag in corresponding slot in parent MHT node + // decrypt data and check integrity against the GMAC in corresponding slot in parent MHT node status = g_cb_aes_gcm_decrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, &mht_node->encrypted.bytes, PF_NODE_SIZE, - &mht_node->decrypted.mht, &gcm_crypto_data->tag); + &mht_node->decrypted.mht, &gcm_crypto_data->gmac); if (PF_FAILURE(status)) { free(mht_node); pf->last_error = status; - if (status == PF_STATUS_TAG_MISMATCH) + if (status == PF_STATUS_MAC_MISMATCH) pf->file_status = PF_STATUS_CORRUPTED; return NULL; } @@ -793,7 +793,7 @@ static bool ipf_init_existing_file(pf_context_t* pf, const char* path) { &pf->metadata_node.encrypted_blob, sizeof(pf->metadata_node.encrypted_blob), &pf->metadata_decrypted_header, - &pf->metadata_node.plaintext_header.metadata_tag); + &pf->metadata_node.plaintext_header.metadata_gmac); if (PF_FAILURE(status)) { pf->last_error = status; DEBUG_PF("failed to decrypt metadata: %d", status); @@ -816,12 +816,12 @@ static bool ipf_init_existing_file(pf_context_t* pf, const char* path) { if (!ipf_read_node(pf, /*logical_node_number=*/1, &pf->root_mht_node.encrypted.bytes)) return false; - // also verifies root MHT node's tag against the tag in metadata node's decrypted header + // also verifies root MHT node's GMAC against the GMAC in metadata node's decrypted header status = g_cb_aes_gcm_decrypt(&pf->metadata_decrypted_header.root_mht_node_key, &g_empty_iv, NULL, 0, // aad &pf->root_mht_node.encrypted.bytes, PF_NODE_SIZE, &pf->root_mht_node.decrypted.mht, - &pf->metadata_decrypted_header.root_mht_node_tag); + &pf->metadata_decrypted_header.root_mht_node_gmac); if (PF_FAILURE(status)) { pf->last_error = status; return false; diff --git a/common/src/protected_files/protected_files.h b/common/src/protected_files/protected_files.h index eddda72fff..018161687d 100644 --- a/common/src/protected_files/protected_files.h +++ b/common/src/protected_files/protected_files.h @@ -17,8 +17,8 @@ /*! Size of IV for AES-GCM */ #define PF_IV_SIZE 12 -/*! Size of tag fields */ -#define PF_TAG_SIZE 16 +/*! Size of MAC fields */ +#define PF_MAC_SIZE 16 /*! Size of the AES-GCM encryption key */ #define PF_KEY_SIZE 16 @@ -27,7 +27,7 @@ #define PF_SALT_SIZE 32 typedef uint8_t pf_iv_t[PF_IV_SIZE]; -typedef uint8_t pf_tag_t[PF_TAG_SIZE]; +typedef uint8_t pf_mac_t[PF_MAC_SIZE]; typedef uint8_t pf_key_t[PF_KEY_SIZE]; typedef uint8_t pf_salt_t[PF_SALT_SIZE]; @@ -41,7 +41,7 @@ typedef enum _pf_status_t { PF_STATUS_INVALID_VERSION = -6, PF_STATUS_INVALID_HEADER = -7, PF_STATUS_INVALID_PATH = -8, - PF_STATUS_TAG_MISMATCH = -9, + PF_STATUS_MAC_MISMATCH = -9, PF_STATUS_NOT_IMPLEMENTED = -10, PF_STATUS_CALLBACK_FAILED = -11, PF_STATUS_PATH_TOO_LONG = -12, @@ -124,12 +124,12 @@ typedef void (*pf_debug_f)(const char* msg); * \param key AES-GCM key. * \param input Plaintext data. * \param input_size Size of \p input in bytes. - * \param[out] tag Authentication tag computed for \p input. + * \param[out] mac MAC computed for \p input. * * \returns PF status. */ typedef pf_status_t (*pf_aes_cmac_f)(const pf_key_t* key, const void* input, size_t input_size, - pf_tag_t* tag); + pf_mac_t* mac); /*! * \brief AES-GCM encrypt callback. @@ -141,13 +141,13 @@ typedef pf_status_t (*pf_aes_cmac_f)(const pf_key_t* key, const void* input, siz * \param input Plaintext data. * \param input_size Size of \p input in bytes. * \param[out] output Buffer for encrypted data (size: \p input_size). - * \param[out] tag Authentication tag computed for \p input and \p aad. + * \param[out] mac MAC computed for \p input and \p aad. * * \returns PF status. */ typedef pf_status_t (*pf_aes_gcm_encrypt_f)(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, pf_tag_t* tag); + void* output, pf_mac_t* mac); /*! * \brief AES-GCM decrypt callback. @@ -159,13 +159,13 @@ typedef pf_status_t (*pf_aes_gcm_encrypt_f)(const pf_key_t* key, const pf_iv_t* * \param input Encrypted data. * \param input_size Size of \p input in bytes. * \param[out] output Buffer for decrypted data (size: \p input_size). - * \param tag Expected authentication tag. + * \param mac Expected MAC. * * \returns PF status. */ typedef pf_status_t (*pf_aes_gcm_decrypt_f)(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, const pf_tag_t* tag); + void* output, const pf_mac_t* mac); /*! * \brief Cryptographic random number generator callback. diff --git a/common/src/protected_files/protected_files_format.h b/common/src/protected_files/protected_files_format.h index 38bc7309a9..581161010e 100644 --- a/common/src/protected_files/protected_files_format.h +++ b/common/src/protected_files/protected_files_format.h @@ -40,7 +40,7 @@ enum { typedef struct _gcm_crypto_data { pf_key_t key; - pf_tag_t tag; + pf_mac_t gmac; } gcm_crypto_data_t; // for PF_NODE_SIZE == 4096, we have 96 attached data nodes and 32 MHT child nodes @@ -55,14 +55,14 @@ typedef struct _metadata_plaintext_header { uint8_t major_version; uint8_t minor_version; pf_salt_t metadata_key_salt; - pf_tag_t metadata_tag; /* GCM MAC aka Authentication Tag */ + pf_mac_t metadata_gmac; /* GCM mac */ } metadata_plaintext_header_t; typedef struct _metadata_decrypted_header { char file_path[PATH_MAX_SIZE]; uint64_t file_size; pf_key_t root_mht_node_key; - pf_tag_t root_mht_node_tag; + pf_mac_t root_mht_node_gmac; uint8_t file_data[MD_USER_DATA_SIZE]; } metadata_decrypted_header_t; diff --git a/libos/src/fs/libos_fs_encrypted.c b/libos/src/fs/libos_fs_encrypted.c index 30a59a6bf6..3926bb780a 100644 --- a/libos/src/fs/libos_fs_encrypted.c +++ b/libos/src/fs/libos_fs_encrypted.c @@ -104,9 +104,9 @@ static pf_status_t cb_fsync(pf_handle_t handle) { } static pf_status_t cb_aes_cmac(const pf_key_t* key, const void* input, size_t input_size, - pf_tag_t* tag) { - int ret = lib_AESCMAC((const uint8_t*)key, sizeof(*key), input, input_size, (uint8_t*)tag, - sizeof(*tag)); + pf_mac_t* mac) { + int ret = lib_AESCMAC((const uint8_t*)key, sizeof(*key), input, input_size, (uint8_t*)mac, + sizeof(*mac)); if (ret != 0) { log_warning("lib_AESCMAC failed: %d", ret); return PF_STATUS_CALLBACK_FAILED; @@ -116,9 +116,9 @@ static pf_status_t cb_aes_cmac(const pf_key_t* key, const void* input, size_t in static pf_status_t cb_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, pf_tag_t* tag) { + void* output, pf_mac_t* mac) { int ret = lib_AESGCMEncrypt((const uint8_t*)key, sizeof(*key), (const uint8_t*)iv, input, - input_size, aad, aad_size, output, (uint8_t*)tag, sizeof(*tag)); + input_size, aad, aad_size, output, (uint8_t*)mac, sizeof(*mac)); if (ret != 0) { log_warning("lib_AESGCMEncrypt failed: %d", ret); return PF_STATUS_CALLBACK_FAILED; @@ -128,10 +128,10 @@ static pf_status_t cb_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, co static pf_status_t cb_aes_gcm_decrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, const pf_tag_t* tag) { + void* output, const pf_mac_t* mac) { int ret = lib_AESGCMDecrypt((const uint8_t*)key, sizeof(*key), (const uint8_t*)iv, input, - input_size, aad, aad_size, output, (const uint8_t*)tag, - sizeof(*tag)); + input_size, aad, aad_size, output, (const uint8_t*)mac, + sizeof(*mac)); if (ret != 0) { log_warning("lib_AESGCMDecrypt failed: %d", ret); return PF_STATUS_CALLBACK_FAILED; diff --git a/tools/sgx/common/pf_util.c b/tools/sgx/common/pf_util.c index 468198293b..eadd0323c3 100644 --- a/tools/sgx/common/pf_util.c +++ b/tools/sgx/common/pf_util.c @@ -124,12 +124,12 @@ static pf_status_t linux_truncate(pf_handle_t handle, uint64_t size) { /* Crypto callbacks for mbedTLS */ pf_status_t mbedtls_aes_cmac(const pf_key_t* key, const void* input, size_t input_size, - pf_tag_t* tag) { + pf_mac_t* mac) { const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); int ret = mbedtls_cipher_cmac(cipher_info, (const unsigned char*)key, PF_KEY_SIZE * 8, input, - input_size, (unsigned char*)tag); + input_size, (unsigned char*)mac); if (ret != 0) { ERROR("mbedtls_cipher_cmac failed: %d\n", ret); return PF_STATUS_CALLBACK_FAILED; @@ -140,7 +140,7 @@ pf_status_t mbedtls_aes_cmac(const pf_key_t* key, const void* input, size_t inpu pf_status_t mbedtls_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, pf_tag_t* tag) { + void* output, pf_mac_t* mac) { pf_status_t status = PF_STATUS_CALLBACK_FAILED; mbedtls_gcm_context gcm; @@ -154,8 +154,8 @@ pf_status_t mbedtls_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, cons } ret = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, input_size, (const unsigned char*)iv, - PF_IV_SIZE, aad, aad_size, input, output, PF_TAG_SIZE, - (unsigned char*)tag); + PF_IV_SIZE, aad, aad_size, input, output, PF_MAC_SIZE, + (unsigned char*)mac); if (ret != 0) { ERROR("mbedtls_gcm_crypt_and_tag failed: %d\n", ret); goto out; @@ -169,7 +169,7 @@ pf_status_t mbedtls_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, cons pf_status_t mbedtls_aes_gcm_decrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, const pf_tag_t* tag) { + void* output, const pf_mac_t* mac) { pf_status_t status = PF_STATUS_CALLBACK_FAILED; mbedtls_gcm_context gcm; @@ -183,7 +183,7 @@ pf_status_t mbedtls_aes_gcm_decrypt(const pf_key_t* key, const pf_iv_t* iv, cons } ret = mbedtls_gcm_auth_decrypt(&gcm, input_size, (const unsigned char*)iv, PF_IV_SIZE, aad, - aad_size, (const unsigned char*)tag, PF_TAG_SIZE, input, output); + aad_size, (const unsigned char*)mac, PF_MAC_SIZE, input, output); if (ret != 0) { ERROR("mbedtls_gcm_auth_decrypt failed: %d\n", ret); goto out; diff --git a/tools/sgx/common/pf_util.h b/tools/sgx/common/pf_util.h index 59fcd3cd44..4276407bef 100644 --- a/tools/sgx/common/pf_util.h +++ b/tools/sgx/common/pf_util.h @@ -31,17 +31,17 @@ int pf_decrypt_files(const char* input_dir, const char* output_dir, bool verify_ /*! AES-CMAC */ pf_status_t mbedtls_aes_cmac(const pf_key_t* key, const void* input, size_t input_size, - pf_tag_t* tag); + pf_mac_t* mac); /*! AES-GCM encrypt */ pf_status_t mbedtls_aes_gcm_encrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, pf_tag_t* tag); + void* output, pf_mac_t* mac); /*! AES-GCM decrypt */ pf_status_t mbedtls_aes_gcm_decrypt(const pf_key_t* key, const pf_iv_t* iv, const void* aad, size_t aad_size, const void* input, size_t input_size, - void* output, const pf_tag_t* tag); + void* output, const pf_mac_t* mac); /*! Load PF wrap key from file */ int load_wrap_key(const char* wrap_key_path, pf_key_t* wrap_key); diff --git a/tools/sgx/pf_tamper/pf_tamper.c b/tools/sgx/pf_tamper/pf_tamper.c index ce8525e128..b4a3945519 100644 --- a/tools/sgx/pf_tamper/pf_tamper.c +++ b/tools/sgx/pf_tamper/pf_tamper.c @@ -125,9 +125,9 @@ static void tamper_truncate(void) { DBG("metadata_plaintext_header_t.metadata_key_salt : 0x%04lx (0x%04lx)\n", offsetof(metadata_plaintext_header_t, metadata_key_salt), FIELD_SIZEOF(metadata_plaintext_header_t, metadata_key_salt)); - DBG("metadata_plaintext_header_t.metadata_tag : 0x%04lx (0x%04lx)\n", - offsetof(metadata_plaintext_header_t, metadata_tag), - FIELD_SIZEOF(metadata_plaintext_header_t, metadata_tag)); + DBG("metadata_plaintext_header_t.metadata_gmac : 0x%04lx (0x%04lx)\n", + offsetof(metadata_plaintext_header_t, metadata_gmac), + FIELD_SIZEOF(metadata_plaintext_header_t, metadata_gmac)); DBG("size(metadata_decrypted_header_t) = 0x%04lx\n", sizeof(metadata_decrypted_header_t)); DBG("metadata_decrypted_header_t.file_path : 0x%04lx (0x%04lx)\n", @@ -139,9 +139,9 @@ static void tamper_truncate(void) { DBG("metadata_decrypted_header_t.root_mht_node_key : 0x%04lx (0x%04lx)\n", mdps + offsetof(metadata_decrypted_header_t, root_mht_node_key), FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_key)); - DBG("metadata_decrypted_header_t.root_mht_node_tag : 0x%04lx (0x%04lx)\n", - mdps + offsetof(metadata_decrypted_header_t, root_mht_node_tag), - FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_tag)); + DBG("metadata_decrypted_header_t.root_mht_node_gmac : 0x%04lx (0x%04lx)\n", + mdps + offsetof(metadata_decrypted_header_t, root_mht_node_gmac), + FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_gmac)); DBG("metadata_decrypted_header_t.file_data : 0x%04lx (0x%04lx)\n", mdps + offsetof(metadata_decrypted_header_t, file_data), FIELD_SIZEOF(metadata_decrypted_header_t, file_data)); @@ -159,9 +159,9 @@ static void tamper_truncate(void) { truncate_file("trunc_meta_plain_4", offsetof(metadata_plaintext_header_t, metadata_key_salt)); truncate_file("trunc_meta_plain_5", FIELD_TRUNCATED(metadata_plaintext_header_t, metadata_key_salt)); - truncate_file("trunc_meta_plain_6", offsetof(metadata_plaintext_header_t, metadata_tag)); + truncate_file("trunc_meta_plain_6", offsetof(metadata_plaintext_header_t, metadata_gmac)); truncate_file("trunc_meta_plain_7", FIELD_TRUNCATED(metadata_plaintext_header_t, - metadata_tag)); + metadata_gmac)); /* encrypted metadata */ truncate_file("trunc_meta_enc_0", mdps + offsetof(metadata_decrypted_header_t, file_path)); @@ -175,9 +175,9 @@ static void tamper_truncate(void) { truncate_file("trunc_meta_enc_5", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, root_mht_node_key)); truncate_file("trunc_meta_enc_6", mdps + offsetof(metadata_decrypted_header_t, - root_mht_node_tag)); + root_mht_node_gmac)); truncate_file("trunc_meta_enc_7", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, - root_mht_node_tag)); + root_mht_node_gmac)); truncate_file("trunc_meta_enc_8", mdps + offsetof(metadata_decrypted_header_t, file_data)); truncate_file("trunc_meta_enc_9", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, file_data)); @@ -194,20 +194,20 @@ static void tamper_truncate(void) { truncate_file("trunc_mht_1", PF_NODE_SIZE + PF_KEY_SIZE / 2); /* after data_nodes_crypto[0].key */ truncate_file("trunc_mht_2", PF_NODE_SIZE + PF_KEY_SIZE); - /* middle of data_nodes_crypto[0].tag */ - truncate_file("trunc_mht_3", PF_NODE_SIZE + PF_KEY_SIZE + PF_TAG_SIZE / 2); - /* after data_nodes_crypto[0].tag */ - truncate_file("trunc_mht_4", PF_NODE_SIZE + PF_KEY_SIZE + PF_TAG_SIZE); + /* middle of data_nodes_crypto[0].gmac */ + truncate_file("trunc_mht_3", PF_NODE_SIZE + PF_KEY_SIZE + PF_MAC_SIZE / 2); + /* after data_nodes_crypto[0].gmac */ + truncate_file("trunc_mht_4", PF_NODE_SIZE + PF_KEY_SIZE + PF_MAC_SIZE); /* after data_nodes_crypto */ truncate_file("trunc_mht_5", PF_NODE_SIZE + DATA_CRYPTO_SIZE); /* middle of mht_nodes_crypto[0].key */ truncate_file("trunc_mht_6", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE / 2); /* after mht_nodes_crypto[0].key */ truncate_file("trunc_mht_7", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE); - /* middle of mht_nodes_crypto[0].tag */ - truncate_file("trunc_mht_8", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_TAG_SIZE / 2); - /* after mht_nodes_crypto[0].tag */ - truncate_file("trunc_mht_9", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_TAG_SIZE); + /* middle of mht_nodes_crypto[0].gmac */ + truncate_file("trunc_mht_8", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_MAC_SIZE / 2); + /* after mht_nodes_crypto[0].gmac */ + truncate_file("trunc_mht_9", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_MAC_SIZE); /* node 2-3: data #0, #1 */ /* after mht root */ @@ -246,20 +246,20 @@ static void* create_output(const char* path) { return mem; } -static void pf_decrypt(const void* encrypted, size_t size, const pf_key_t* key, const pf_tag_t* tag, +static void pf_decrypt(const void* encrypted, size_t size, const pf_key_t* key, const pf_mac_t* mac, void* decrypted, const char* msg) { pf_status_t status = mbedtls_aes_gcm_decrypt(key, &g_empty_iv, NULL, 0, encrypted, size, - decrypted, tag); + decrypted, mac); if (PF_FAILURE(status)) FATAL("decrypting %s failed\n", msg); } -static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, pf_tag_t* tag, +static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, pf_mac_t* mac, void* encrypted, const char* msg) { pf_status_t status = mbedtls_aes_gcm_encrypt(key, &g_empty_iv, NULL, 0, decrypted, size, - encrypted, tag); + encrypted, mac); if (PF_FAILURE(status)) FATAL("encrypting %s failed\n", msg); } @@ -270,21 +270,21 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, meta = create_output(g_output_path); \ out = (uint8_t*)meta; \ pf_decrypt(&meta->encrypted_blob, sizeof(meta->encrypted_blob), &g_meta_key, \ - &meta->plaintext_header.metadata_tag, meta_dec, "metadata"); \ + &meta->plaintext_header.metadata_gmac, meta_dec, "metadata"); \ mht_enc = (mht_node_t*)(out + PF_NODE_SIZE); \ pf_decrypt(mht_enc, sizeof(*mht_enc), &meta_dec->root_mht_node_key, \ - &meta_dec->root_mht_node_tag, mht_dec, "mht"); \ + &meta_dec->root_mht_node_gmac, mht_dec, "mht"); \ __VA_ARGS__ \ munmap(meta, g_input_size); \ } while (0) -/* if update is true, also create a file with correct metadata tag */ +/* if update is true, also create a file with correct metadata MAC */ #define BREAK_PF(suffix, update, ...) do { \ __BREAK_PF(suffix, __VA_ARGS__); \ if (update) { \ __BREAK_PF(suffix "_fixed", __VA_ARGS__ { \ pf_encrypt(meta_dec, sizeof(*meta_dec), &g_meta_key, \ - &meta->plaintext_header.metadata_tag, meta->encrypted_blob, \ + &meta->plaintext_header.metadata_gmac, meta->encrypted_blob, \ "metadata"); \ } ); \ } \ @@ -293,7 +293,7 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, #define BREAK_MHT(suffix, ...) do { \ __BREAK_PF(suffix, __VA_ARGS__ { \ pf_encrypt(mht_dec, sizeof(*mht_dec), &meta_dec->root_mht_node_key, \ - &meta_dec->root_mht_node_tag, mht_enc, "mht"); \ + &meta_dec->root_mht_node_gmac, mht_enc, "mht"); \ } ); \ } while (0) @@ -310,7 +310,7 @@ static void tamper_modify(void) { if (!mht_dec) FATAL("Out of memory\n"); - /* plain part of the metadata isn't covered by the tag so no point updating it */ + /* plain part of the metadata isn't covered by the MAC so no point updating it */ BREAK_PF("meta_plain_id_0", /*update=*/false, { meta->plaintext_header.file_id = 0; }); BREAK_PF("meta_plain_id_1", /*update=*/false, @@ -323,15 +323,15 @@ static void tamper_modify(void) { { meta->plaintext_header.minor_version = 0xff; }); /* metadata_key_salt is the keying material for encrypted metadata key derivation, so create - * also PFs with updated tags */ + * also PFs with updated MACs */ BREAK_PF("meta_plain_salt_0", /*update=*/true, { meta->plaintext_header.metadata_key_salt[0] ^= 1; }); BREAK_PF("meta_plain_salt_1", /*update=*/true, { LAST_BYTE(meta->plaintext_header.metadata_key_salt) ^= 0xfe; }); - BREAK_PF("meta_plain_tag_0", /*update=*/true, - { meta->plaintext_header.metadata_tag[0] ^= 0xfe; }); - BREAK_PF("meta_plain_tag_1", /*update=*/true, - { LAST_BYTE(meta->plaintext_header.metadata_tag) &= 1; }); + BREAK_PF("meta_plain_mac_0", /*update=*/true, + { meta->plaintext_header.metadata_gmac[0] ^= 0xfe; }); + BREAK_PF("meta_plain_mac_1", /*update=*/true, + { LAST_BYTE(meta->plaintext_header.metadata_gmac) &= 1; }); BREAK_PF("meta_enc_filename_0", /*update=*/true, { meta_dec->file_path[0] = 0; }); @@ -351,10 +351,10 @@ static void tamper_modify(void) { { meta_dec->root_mht_node_key[0] ^= 1; }); BREAK_PF("meta_enc_mht_key_1", /*update=*/true, { LAST_BYTE(meta_dec->root_mht_node_key) ^= 0xfe; }); - BREAK_PF("meta_enc_mht_tag_0", /*update=*/true, - { meta_dec->root_mht_node_tag[0] ^= 1; }); - BREAK_PF("meta_enc_mht_tag_1", /*update=*/true, - { LAST_BYTE(meta_dec->root_mht_node_tag) ^= 0xfe; }); + BREAK_PF("meta_enc_mht_mac_0", /*update=*/true, + { meta_dec->root_mht_node_gmac[0] ^= 1; }); + BREAK_PF("meta_enc_mht_mac_1", /*update=*/true, + { LAST_BYTE(meta_dec->root_mht_node_gmac) ^= 0xfe; }); BREAK_PF("meta_enc_data_0", /*update=*/true, { meta_dec->file_data[0] ^= 0xfe; }); BREAK_PF("meta_enc_data_1", /*update=*/true, @@ -367,13 +367,13 @@ static void tamper_modify(void) { { LAST_BYTE(meta->padding) ^= 0xfe; }); BREAK_MHT("mht_0", { mht_dec->data_nodes_crypto[0].key[0] ^= 1; }); - BREAK_MHT("mht_1", { mht_dec->data_nodes_crypto[0].tag[0] ^= 1; }); + BREAK_MHT("mht_1", { mht_dec->data_nodes_crypto[0].gmac[0] ^= 1; }); BREAK_MHT("mht_2", { mht_dec->mht_nodes_crypto[0].key[0] ^= 1; }); - BREAK_MHT("mht_3", { mht_dec->mht_nodes_crypto[0].tag[0] ^= 1; }); + BREAK_MHT("mht_3", { mht_dec->mht_nodes_crypto[0].gmac[0] ^= 1; }); BREAK_MHT("mht_4", { mht_dec->data_nodes_crypto[ATTACHED_DATA_NODES_COUNT - 1].key[0] ^= 1; }); - BREAK_MHT("mht_5", { mht_dec->data_nodes_crypto[ATTACHED_DATA_NODES_COUNT - 1].tag[0] ^= 1; }); + BREAK_MHT("mht_5", { mht_dec->data_nodes_crypto[ATTACHED_DATA_NODES_COUNT - 1].gmac[0] ^= 1; }); BREAK_MHT("mht_6", { mht_dec->mht_nodes_crypto[CHILD_MHT_NODES_COUNT - 1].key[0] ^= 1; }); - BREAK_MHT("mht_7", { mht_dec->mht_nodes_crypto[CHILD_MHT_NODES_COUNT - 1].tag[0] ^= 1; }); + BREAK_MHT("mht_7", { mht_dec->mht_nodes_crypto[CHILD_MHT_NODES_COUNT - 1].gmac[0] ^= 1; }); BREAK_MHT("mht_8", { gcm_crypto_data_t crypto; memcpy(&crypto, &mht_dec->data_nodes_crypto[0], sizeof(crypto)); From 0c5d2606f5b58ef9af25c6461d1b52daf6798387 Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Wed, 24 Apr 2024 23:30:56 -0700 Subject: [PATCH 4/4] fixup! [common] Refactor Protected Files slightly Signed-off-by: Dmitrii Kuvaiskii --- common/src/protected_files/protected_files.c | 32 ++++++------ .../protected_files/protected_files_format.h | 6 +-- tools/sgx/pf_tamper/pf_tamper.c | 52 +++++++++---------- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/common/src/protected_files/protected_files.c b/common/src/protected_files/protected_files.c index a7f887d19e..32406b44de 100644 --- a/common/src/protected_files/protected_files.c +++ b/common/src/protected_files/protected_files.c @@ -204,7 +204,7 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { void* node; // 1. encrypt the changed data nodes - // 2. set the key + GMAC in the parent MHT nodes + // 2. set the key + MAC in the parent MHT nodes // 3. set the need_writing flag for all parent MHT nodes for (node = lruc_get_first(pf->cache); node != NULL; node = lruc_get_next(pf->cache)) { if (((file_node_t*)node)->type != FILE_DATA_NODE_TYPE) @@ -221,10 +221,10 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { if (!ipf_generate_random_key(pf, &gcm_crypto_data->key)) goto out; - // encrypt data node, this also saves GMAC in the corresponding crypto slot of MHT node + // encrypt data node, this also saves MAC in the corresponding crypto slot of MHT node status = g_cb_aes_gcm_encrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, // aad &data_node->decrypted.data.bytes, PF_NODE_SIZE, - &data_node->encrypted.bytes, &gcm_crypto_data->gmac); + &data_node->encrypted.bytes, &gcm_crypto_data->mac); if (PF_FAILURE(status)) { pf->last_error = status; goto out; @@ -267,7 +267,7 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { if (dirty_count > 0) sort_nodes(mht_nodes_array, 0, dirty_count - 1); - // update the keys and GMACs in the parents from last node to first (bottom layers first) + // update the keys and MACs in the parents from last node to first (bottom layers first) for (dirty_idx = dirty_count; dirty_idx > 0; dirty_idx--) { file_node_t* mht_node = mht_nodes_array[dirty_idx - 1]; @@ -280,14 +280,14 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { status = g_cb_aes_gcm_encrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, &mht_node->decrypted.mht, PF_NODE_SIZE, - &mht_node->encrypted.bytes, &gcm_crypto_data->gmac); + &mht_node->encrypted.bytes, &gcm_crypto_data->mac); if (PF_FAILURE(status)) { pf->last_error = status; goto out; } } - // update root MHT node's key and GMAC in the metadata node's headers + // update root MHT node's key and MAC in the metadata node's headers if (!ipf_generate_random_key(pf, &pf->metadata_decrypted_header.root_mht_node_key)) goto out; @@ -295,7 +295,7 @@ static bool ipf_update_all_data_and_mht_nodes(pf_context_t* pf) { NULL, 0, &pf->root_mht_node.decrypted.mht, PF_NODE_SIZE, &pf->root_mht_node.encrypted.bytes, - &pf->metadata_decrypted_header.root_mht_node_gmac); + &pf->metadata_decrypted_header.root_mht_node_mac); if (PF_FAILURE(status)) { pf->last_error = status; goto out; @@ -419,11 +419,11 @@ static bool ipf_update_metadata_node(pf_context_t* pf) { return false; } - // encrypt metadata part-to-be-encrypted, also updates the GMAC in metadata plaintext header + // encrypt metadata part-to-be-encrypted, also updates the MAC in metadata plaintext header status = g_cb_aes_gcm_encrypt(&key, &g_empty_iv, NULL, 0, &pf->metadata_decrypted_header, sizeof(metadata_decrypted_header_t), &pf->metadata_node.encrypted_blob, - &pf->metadata_node.plaintext_header.metadata_gmac); + &pf->metadata_node.plaintext_header.metadata_mac); if (PF_FAILURE(status)) { pf->last_error = status; return false; @@ -642,10 +642,10 @@ static file_node_t* ipf_read_data_node(pf_context_t* pf, uint64_t offset) { &data_node->parent->decrypted.mht .data_nodes_crypto[data_node->logical_node_number % ATTACHED_DATA_NODES_COUNT]; - // decrypt data and check integrity against the GMAC in corresponding slot in MHT node + // decrypt data and check integrity against the MAC in corresponding slot in MHT node status = g_cb_aes_gcm_decrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, &data_node->encrypted.bytes, PF_NODE_SIZE, - &data_node->decrypted.data.bytes, &gcm_crypto_data->gmac); + &data_node->decrypted.data.bytes, &gcm_crypto_data->mac); if (PF_FAILURE(status)) { free(data_node); @@ -705,10 +705,10 @@ static file_node_t* ipf_read_mht_node(pf_context_t* pf, uint64_t logical_mht_nod &mht_node->parent->decrypted.mht .mht_nodes_crypto[(mht_node->logical_node_number - 1) % CHILD_MHT_NODES_COUNT]; - // decrypt data and check integrity against the GMAC in corresponding slot in parent MHT node + // decrypt data and check integrity against the MAC in corresponding slot in parent MHT node status = g_cb_aes_gcm_decrypt(&gcm_crypto_data->key, &g_empty_iv, NULL, 0, &mht_node->encrypted.bytes, PF_NODE_SIZE, - &mht_node->decrypted.mht, &gcm_crypto_data->gmac); + &mht_node->decrypted.mht, &gcm_crypto_data->mac); if (PF_FAILURE(status)) { free(mht_node); pf->last_error = status; @@ -793,7 +793,7 @@ static bool ipf_init_existing_file(pf_context_t* pf, const char* path) { &pf->metadata_node.encrypted_blob, sizeof(pf->metadata_node.encrypted_blob), &pf->metadata_decrypted_header, - &pf->metadata_node.plaintext_header.metadata_gmac); + &pf->metadata_node.plaintext_header.metadata_mac); if (PF_FAILURE(status)) { pf->last_error = status; DEBUG_PF("failed to decrypt metadata: %d", status); @@ -816,12 +816,12 @@ static bool ipf_init_existing_file(pf_context_t* pf, const char* path) { if (!ipf_read_node(pf, /*logical_node_number=*/1, &pf->root_mht_node.encrypted.bytes)) return false; - // also verifies root MHT node's GMAC against the GMAC in metadata node's decrypted header + // also verifies root MHT node's MAC against the MAC in metadata node's decrypted header status = g_cb_aes_gcm_decrypt(&pf->metadata_decrypted_header.root_mht_node_key, &g_empty_iv, NULL, 0, // aad &pf->root_mht_node.encrypted.bytes, PF_NODE_SIZE, &pf->root_mht_node.decrypted.mht, - &pf->metadata_decrypted_header.root_mht_node_gmac); + &pf->metadata_decrypted_header.root_mht_node_mac); if (PF_FAILURE(status)) { pf->last_error = status; return false; diff --git a/common/src/protected_files/protected_files_format.h b/common/src/protected_files/protected_files_format.h index 581161010e..5e5e275c86 100644 --- a/common/src/protected_files/protected_files_format.h +++ b/common/src/protected_files/protected_files_format.h @@ -40,7 +40,7 @@ enum { typedef struct _gcm_crypto_data { pf_key_t key; - pf_mac_t gmac; + pf_mac_t mac; } gcm_crypto_data_t; // for PF_NODE_SIZE == 4096, we have 96 attached data nodes and 32 MHT child nodes @@ -55,14 +55,14 @@ typedef struct _metadata_plaintext_header { uint8_t major_version; uint8_t minor_version; pf_salt_t metadata_key_salt; - pf_mac_t metadata_gmac; /* GCM mac */ + pf_mac_t metadata_mac; /* GCM mac */ } metadata_plaintext_header_t; typedef struct _metadata_decrypted_header { char file_path[PATH_MAX_SIZE]; uint64_t file_size; pf_key_t root_mht_node_key; - pf_mac_t root_mht_node_gmac; + pf_mac_t root_mht_node_mac; uint8_t file_data[MD_USER_DATA_SIZE]; } metadata_decrypted_header_t; diff --git a/tools/sgx/pf_tamper/pf_tamper.c b/tools/sgx/pf_tamper/pf_tamper.c index b4a3945519..fa4996ff94 100644 --- a/tools/sgx/pf_tamper/pf_tamper.c +++ b/tools/sgx/pf_tamper/pf_tamper.c @@ -125,9 +125,9 @@ static void tamper_truncate(void) { DBG("metadata_plaintext_header_t.metadata_key_salt : 0x%04lx (0x%04lx)\n", offsetof(metadata_plaintext_header_t, metadata_key_salt), FIELD_SIZEOF(metadata_plaintext_header_t, metadata_key_salt)); - DBG("metadata_plaintext_header_t.metadata_gmac : 0x%04lx (0x%04lx)\n", - offsetof(metadata_plaintext_header_t, metadata_gmac), - FIELD_SIZEOF(metadata_plaintext_header_t, metadata_gmac)); + DBG("metadata_plaintext_header_t.metadata_mac : 0x%04lx (0x%04lx)\n", + offsetof(metadata_plaintext_header_t, metadata_mac), + FIELD_SIZEOF(metadata_plaintext_header_t, metadata_mac)); DBG("size(metadata_decrypted_header_t) = 0x%04lx\n", sizeof(metadata_decrypted_header_t)); DBG("metadata_decrypted_header_t.file_path : 0x%04lx (0x%04lx)\n", @@ -139,9 +139,9 @@ static void tamper_truncate(void) { DBG("metadata_decrypted_header_t.root_mht_node_key : 0x%04lx (0x%04lx)\n", mdps + offsetof(metadata_decrypted_header_t, root_mht_node_key), FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_key)); - DBG("metadata_decrypted_header_t.root_mht_node_gmac : 0x%04lx (0x%04lx)\n", - mdps + offsetof(metadata_decrypted_header_t, root_mht_node_gmac), - FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_gmac)); + DBG("metadata_decrypted_header_t.root_mht_node_mac : 0x%04lx (0x%04lx)\n", + mdps + offsetof(metadata_decrypted_header_t, root_mht_node_mac), + FIELD_SIZEOF(metadata_decrypted_header_t, root_mht_node_mac)); DBG("metadata_decrypted_header_t.file_data : 0x%04lx (0x%04lx)\n", mdps + offsetof(metadata_decrypted_header_t, file_data), FIELD_SIZEOF(metadata_decrypted_header_t, file_data)); @@ -159,9 +159,9 @@ static void tamper_truncate(void) { truncate_file("trunc_meta_plain_4", offsetof(metadata_plaintext_header_t, metadata_key_salt)); truncate_file("trunc_meta_plain_5", FIELD_TRUNCATED(metadata_plaintext_header_t, metadata_key_salt)); - truncate_file("trunc_meta_plain_6", offsetof(metadata_plaintext_header_t, metadata_gmac)); + truncate_file("trunc_meta_plain_6", offsetof(metadata_plaintext_header_t, metadata_mac)); truncate_file("trunc_meta_plain_7", FIELD_TRUNCATED(metadata_plaintext_header_t, - metadata_gmac)); + metadata_mac)); /* encrypted metadata */ truncate_file("trunc_meta_enc_0", mdps + offsetof(metadata_decrypted_header_t, file_path)); @@ -175,9 +175,9 @@ static void tamper_truncate(void) { truncate_file("trunc_meta_enc_5", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, root_mht_node_key)); truncate_file("trunc_meta_enc_6", mdps + offsetof(metadata_decrypted_header_t, - root_mht_node_gmac)); + root_mht_node_mac)); truncate_file("trunc_meta_enc_7", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, - root_mht_node_gmac)); + root_mht_node_mac)); truncate_file("trunc_meta_enc_8", mdps + offsetof(metadata_decrypted_header_t, file_data)); truncate_file("trunc_meta_enc_9", mdps + FIELD_TRUNCATED(metadata_decrypted_header_t, file_data)); @@ -194,9 +194,9 @@ static void tamper_truncate(void) { truncate_file("trunc_mht_1", PF_NODE_SIZE + PF_KEY_SIZE / 2); /* after data_nodes_crypto[0].key */ truncate_file("trunc_mht_2", PF_NODE_SIZE + PF_KEY_SIZE); - /* middle of data_nodes_crypto[0].gmac */ + /* middle of data_nodes_crypto[0].mac */ truncate_file("trunc_mht_3", PF_NODE_SIZE + PF_KEY_SIZE + PF_MAC_SIZE / 2); - /* after data_nodes_crypto[0].gmac */ + /* after data_nodes_crypto[0].mac */ truncate_file("trunc_mht_4", PF_NODE_SIZE + PF_KEY_SIZE + PF_MAC_SIZE); /* after data_nodes_crypto */ truncate_file("trunc_mht_5", PF_NODE_SIZE + DATA_CRYPTO_SIZE); @@ -204,9 +204,9 @@ static void tamper_truncate(void) { truncate_file("trunc_mht_6", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE / 2); /* after mht_nodes_crypto[0].key */ truncate_file("trunc_mht_7", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE); - /* middle of mht_nodes_crypto[0].gmac */ + /* middle of mht_nodes_crypto[0].mac */ truncate_file("trunc_mht_8", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_MAC_SIZE / 2); - /* after mht_nodes_crypto[0].gmac */ + /* after mht_nodes_crypto[0].mac */ truncate_file("trunc_mht_9", PF_NODE_SIZE + DATA_CRYPTO_SIZE + PF_KEY_SIZE + PF_MAC_SIZE); /* node 2-3: data #0, #1 */ @@ -270,10 +270,10 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, meta = create_output(g_output_path); \ out = (uint8_t*)meta; \ pf_decrypt(&meta->encrypted_blob, sizeof(meta->encrypted_blob), &g_meta_key, \ - &meta->plaintext_header.metadata_gmac, meta_dec, "metadata"); \ + &meta->plaintext_header.metadata_mac, meta_dec, "metadata"); \ mht_enc = (mht_node_t*)(out + PF_NODE_SIZE); \ pf_decrypt(mht_enc, sizeof(*mht_enc), &meta_dec->root_mht_node_key, \ - &meta_dec->root_mht_node_gmac, mht_dec, "mht"); \ + &meta_dec->root_mht_node_mac, mht_dec, "mht"); \ __VA_ARGS__ \ munmap(meta, g_input_size); \ } while (0) @@ -284,7 +284,7 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, if (update) { \ __BREAK_PF(suffix "_fixed", __VA_ARGS__ { \ pf_encrypt(meta_dec, sizeof(*meta_dec), &g_meta_key, \ - &meta->plaintext_header.metadata_gmac, meta->encrypted_blob, \ + &meta->plaintext_header.metadata_mac, meta->encrypted_blob, \ "metadata"); \ } ); \ } \ @@ -293,7 +293,7 @@ static void pf_encrypt(const void* decrypted, size_t size, const pf_key_t* key, #define BREAK_MHT(suffix, ...) do { \ __BREAK_PF(suffix, __VA_ARGS__ { \ pf_encrypt(mht_dec, sizeof(*mht_dec), &meta_dec->root_mht_node_key, \ - &meta_dec->root_mht_node_gmac, mht_enc, "mht"); \ + &meta_dec->root_mht_node_mac, mht_enc, "mht"); \ } ); \ } while (0) @@ -329,9 +329,9 @@ static void tamper_modify(void) { BREAK_PF("meta_plain_salt_1", /*update=*/true, { LAST_BYTE(meta->plaintext_header.metadata_key_salt) ^= 0xfe; }); BREAK_PF("meta_plain_mac_0", /*update=*/true, - { meta->plaintext_header.metadata_gmac[0] ^= 0xfe; }); + { meta->plaintext_header.metadata_mac[0] ^= 0xfe; }); BREAK_PF("meta_plain_mac_1", /*update=*/true, - { LAST_BYTE(meta->plaintext_header.metadata_gmac) &= 1; }); + { LAST_BYTE(meta->plaintext_header.metadata_mac) &= 1; }); BREAK_PF("meta_enc_filename_0", /*update=*/true, { meta_dec->file_path[0] = 0; }); @@ -352,9 +352,9 @@ static void tamper_modify(void) { BREAK_PF("meta_enc_mht_key_1", /*update=*/true, { LAST_BYTE(meta_dec->root_mht_node_key) ^= 0xfe; }); BREAK_PF("meta_enc_mht_mac_0", /*update=*/true, - { meta_dec->root_mht_node_gmac[0] ^= 1; }); + { meta_dec->root_mht_node_mac[0] ^= 1; }); BREAK_PF("meta_enc_mht_mac_1", /*update=*/true, - { LAST_BYTE(meta_dec->root_mht_node_gmac) ^= 0xfe; }); + { LAST_BYTE(meta_dec->root_mht_node_mac) ^= 0xfe; }); BREAK_PF("meta_enc_data_0", /*update=*/true, { meta_dec->file_data[0] ^= 0xfe; }); BREAK_PF("meta_enc_data_1", /*update=*/true, @@ -367,13 +367,13 @@ static void tamper_modify(void) { { LAST_BYTE(meta->padding) ^= 0xfe; }); BREAK_MHT("mht_0", { mht_dec->data_nodes_crypto[0].key[0] ^= 1; }); - BREAK_MHT("mht_1", { mht_dec->data_nodes_crypto[0].gmac[0] ^= 1; }); + BREAK_MHT("mht_1", { mht_dec->data_nodes_crypto[0].mac[0] ^= 1; }); BREAK_MHT("mht_2", { mht_dec->mht_nodes_crypto[0].key[0] ^= 1; }); - BREAK_MHT("mht_3", { mht_dec->mht_nodes_crypto[0].gmac[0] ^= 1; }); + BREAK_MHT("mht_3", { mht_dec->mht_nodes_crypto[0].mac[0] ^= 1; }); BREAK_MHT("mht_4", { mht_dec->data_nodes_crypto[ATTACHED_DATA_NODES_COUNT - 1].key[0] ^= 1; }); - BREAK_MHT("mht_5", { mht_dec->data_nodes_crypto[ATTACHED_DATA_NODES_COUNT - 1].gmac[0] ^= 1; }); + BREAK_MHT("mht_5", { mht_dec->data_nodes_crypto[ATTACHED_DATA_NODES_COUNT - 1].mac[0] ^= 1; }); BREAK_MHT("mht_6", { mht_dec->mht_nodes_crypto[CHILD_MHT_NODES_COUNT - 1].key[0] ^= 1; }); - BREAK_MHT("mht_7", { mht_dec->mht_nodes_crypto[CHILD_MHT_NODES_COUNT - 1].gmac[0] ^= 1; }); + BREAK_MHT("mht_7", { mht_dec->mht_nodes_crypto[CHILD_MHT_NODES_COUNT - 1].mac[0] ^= 1; }); BREAK_MHT("mht_8", { gcm_crypto_data_t crypto; memcpy(&crypto, &mht_dec->data_nodes_crypto[0], sizeof(crypto));