diff --git a/repos/gems/recipes/src/file_vault/content.mk b/repos/gems/recipes/src/file_vault/content.mk index 4c46012021..ce3d54c880 100644 --- a/repos/gems/recipes/src/file_vault/content.mk +++ b/repos/gems/recipes/src/file_vault/content.mk @@ -1,10 +1,5 @@ SRC_DIR := src/app/file_vault -MIRROR_FROM_REP_DIR := \ - src/lib/tresor/include/tresor/types.h \ - src/lib/tresor/include/tresor/math.h \ - src/lib/tresor/include/tresor/verbosity.h - content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): diff --git a/repos/gems/run/depot_autopilot.run b/repos/gems/run/depot_autopilot.run index 5202200054..3dd2f67646 100644 --- a/repos/gems/run/depot_autopilot.run +++ b/repos/gems/run/depot_autopilot.run @@ -773,11 +773,9 @@ proc skip_test_if { condition test } { skip_test_if [expr ([have_board pbxa9] || [have_board zynq_qemu])] test-file_vault_config_report skip_test_if [expr !([have_board pbxa9] || [have_board zynq_qemu])] test-file_vault_config_report_no_entropy -# -# rpi, imx6q_sabrelite, imx53_qsb(_tz), imx7d_sabre have problems with the yet unfixed unaligned-access issue in tresor -# -skip_test_if [expr ([have_board rpi] || [have_board imx6q_sabrelite] || [have_board imx53_qsb] || [have_board imx53_qsb_tz] || [have_board imx7d_sabre])] test-file_vault_config_report -skip_test_if [expr ([have_board rpi] || [have_board imx6q_sabrelite] || [have_board imx53_qsb] || [have_board imx53_qsb_tz] || [have_board imx7d_sabre])] test-file_vault_config_report_no_entropy +# rpi has a quite limited amount of RAM +skip_test_if [have_board rpi] test-file_vault_config_report +skip_test_if [have_board rpi] test-file_vault_config_report_no_entropy set skip_test(test-fault_detection) [expr [have_spec pistachio] || [have_spec fiasco]] set skip_test(test-fs_packet) [expr ![interactive] && [have_include "power_on/qemu"]] diff --git a/repos/gems/run/tresor_tester.run b/repos/gems/run/tresor_tester.run index aed91bd7c2..5f39f5b5b1 100644 --- a/repos/gems/run/tresor_tester.run +++ b/repos/gems/run/tresor_tester.run @@ -4,33 +4,6 @@ if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { exit 0 } -# -# The following platforms trigger alignment faults that come from a not yet -# solved deficiency of the tresor lib: The lib uses the on-disc datastructures -# directly in code without translating them to naturally aligned structs -# beforehand. -# -if {[get_cmd_switch --autopilot] && [have_board rpi]} { - puts "Autopilot mode is not supported on this platform." - exit 0 -} -if {[get_cmd_switch --autopilot] && [have_board imx6q_sabrelite]} { - puts "Autopilot mode is not supported on this platform." - exit 0 -} -if {[get_cmd_switch --autopilot] && [have_board imx53_qsb]} { - puts "Autopilot mode is not supported on this platform." - exit 0 -} -if {[get_cmd_switch --autopilot] && [have_board imx53_qsb_tz]} { - puts "Autopilot mode is not supported on this platform." - exit 0 -} -if {[get_cmd_switch --autopilot] && [have_board imx7d_sabre]} { - puts "Autopilot mode is not supported on this platform." - exit 0 -} - set dd [installed_command dd] proc tresor_image_name { } { @@ -130,6 +103,7 @@ append config { + diff --git a/repos/gems/src/app/file_vault/target.mk b/repos/gems/src/app/file_vault/target.mk index 01bdb98872..d926d10c8c 100644 --- a/repos/gems/src/app/file_vault/target.mk +++ b/repos/gems/src/app/file_vault/target.mk @@ -3,7 +3,7 @@ TARGET := file_vault SRC_CC += main.cc menu_view_dialog.cc capacity.cc INC_DIR += $(PRG_DIR) -INC_DIR += $(REP_DIR)/src/lib/tresor/include +INC_DIR += $(call select_from_repositories,/src/lib/tresor/include) LIBS += base sandbox vfs diff --git a/repos/gems/src/lib/tresor/block_io.cc b/repos/gems/src/lib/tresor/block_io.cc index 39c6cef4dc..9aa9dbb274 100644 --- a/repos/gems/src/lib/tresor/block_io.cc +++ b/repos/gems/src/lib/tresor/block_io.cc @@ -99,7 +99,7 @@ bool Block_io::_peek_generated_request(uint8_t *buf_ptr, buf_ptr, buf_size, BLOCK_IO, id, crypto_req_type, req._client_req_offset, req._client_req_tag, req._key_id, nullptr, req._pba, req._vba, nullptr, - (void *)channel._blk_buf); + (void *)&channel._blk_buf); return true; } @@ -299,7 +299,7 @@ void Block_io::_execute_read_client_data(Channel &channel, size_t nr_of_read_bytes { 0 }; Byte_range_ptr dst { - (char *)channel._blk_buf + channel._nr_of_processed_bytes, + (char *)&channel._blk_buf + channel._nr_of_processed_bytes, channel._nr_of_remaining_bytes }; Result const result { @@ -377,7 +377,7 @@ void Block_io::_execute_write_client_data(Channel &channel, _mark_req_failed(channel, progress, "encrypt client data"); return; } - calc_sha256_4k_hash((void *)channel._blk_buf, (void *)req._hash_ptr); + calc_sha256_4k_hash(channel._blk_buf, *(Hash *)req._hash_ptr); _vfs_handle.seek(req._pba * BLOCK_SIZE + channel._nr_of_processed_bytes); @@ -390,7 +390,7 @@ void Block_io::_execute_write_client_data(Channel &channel, size_t nr_of_written_bytes { 0 }; Const_byte_range_ptr src { - (char const *)channel._blk_buf + channel._nr_of_processed_bytes, + (char const *)&channel._blk_buf + channel._nr_of_processed_bytes, channel._nr_of_remaining_bytes }; Result const result = @@ -619,7 +619,7 @@ bool Block_io::_peek_completed_request(uint8_t *buf_ptr, case Request::WRITE: { Hash hash; - calc_sha256_4k_hash((void *)req._blk_ptr, &hash); + calc_sha256_4k_hash(*(Block *)req._blk_ptr, hash); log("block_io: ", req.type_name(), " pba ", req._pba, " data ", *(Block *)req._blk_ptr, " hash ", hash); @@ -629,9 +629,9 @@ bool Block_io::_peek_completed_request(uint8_t *buf_ptr, case Request::WRITE_CLIENT_DATA: { Hash hash; - calc_sha256_4k_hash((void *)channel._blk_buf, &hash); + calc_sha256_4k_hash(channel._blk_buf, hash); log("block_io: ", req.type_name(), " pba ", req._pba, - " data ", *(Block *)channel._blk_buf, + " data ", channel._blk_buf, " hash ", hash); break; diff --git a/repos/gems/src/lib/tresor/free_tree.cc b/repos/gems/src/lib/tresor/free_tree.cc index a012ce6b3b..fb5fe95947 100644 --- a/repos/gems/src/lib/tresor/free_tree.cc +++ b/repos/gems/src/lib/tresor/free_tree.cc @@ -192,7 +192,8 @@ void Free_tree::_populate_lower_n_stack(Type_1_info_stack &stack, Generation current_gen) { stack.reset(); - memcpy(&entries, &block_data, BLOCK_SIZE); + entries.decode_from_blk(block_data); + for (Tree_node_index idx = 0; idx < NR_OF_T1_NODES_PER_BLK; idx++) { if (entries.nodes[idx].pba != 0) { @@ -246,7 +247,8 @@ void Free_tree::_populate_level_0_stack(Type_2_info_stack &stack, Virtual_block_address rekeying_vba) { stack.reset(); - memcpy(&entries, &block_data, BLOCK_SIZE); + entries.decode_from_blk(block_data); + for (Tree_node_index idx = 0; idx < NR_OF_T1_NODES_PER_BLK; idx++) { if (_check_type_2_leaf_usable(active_snaps, secured_gen, entries.nodes[idx], rekeying, @@ -505,7 +507,7 @@ void Free_tree::_update_upper_n_stack(Type_1_info const &t, { entries.nodes[t.index].pba = t.node.pba; entries.nodes[t.index].gen = gen; - calc_sha256_4k_hash(&block_data, &entries.nodes[t.index].hash); + calc_sha256_4k_hash(block_data, entries.nodes[t.index].hash); } @@ -629,24 +631,23 @@ void Free_tree::_execute_update(Channel &chan, } } if (l >= 2) { - memcpy(&chan._cache_block_data, - &chan._level_n_nodes[l - 1], BLOCK_SIZE); + + chan._level_n_nodes[l - 1].encode_to_blk(chan._cache_block_data); if (l < req._ft_max_level) { _update_upper_n_stack( n, req._current_gen, chan._cache_block_data, chan._level_n_nodes[l]); } else { - calc_sha256_4k_hash(&chan._cache_block_data, - (void *)req._ft_root_hash_ptr); + calc_sha256_4k_hash(chan._cache_block_data, + *(Hash *)req._ft_root_hash_ptr); *(Generation *)req._ft_root_gen_ptr = req._current_gen; *(Physical_block_address *)req._ft_root_pba_ptr = n.node.pba; } } else { - memcpy(&chan._cache_block_data, - &chan._level_0_node, BLOCK_SIZE); + chan._level_0_node.encode_to_blk(chan._cache_block_data); _update_upper_n_stack( n, req._current_gen, chan._cache_block_data, @@ -934,7 +935,7 @@ void Free_tree::generated_request_complete(Module_request &mod_req) case Local_cache_request::READ: - if (check_sha256_4k_hash(&channel._cache_block_data, &n.node.hash)) { + if (check_sha256_4k_hash(channel._cache_block_data, n.node.hash)) { n.state = Type_1_info::AVAILABLE; channel._level_n_stacks[local_req.level].update_top(n); diff --git a/repos/gems/src/lib/tresor/ft_check.cc b/repos/gems/src/lib/tresor/ft_check.cc index 23faee22d2..73340589de 100644 --- a/repos/gems/src/lib/tresor/ft_check.cc +++ b/repos/gems/src/lib/tresor/ft_check.cc @@ -124,8 +124,11 @@ void Ft_check::_execute_inner_t2_child(Channel &chan, } else if (child_state == Channel::CHECK_HASH) { + Block blk { }; + child_lvl.children.encode_to_blk(blk); + if (child.gen == INITIAL_GENERATION || - check_sha256_4k_hash(&child_lvl.children, &child.hash)) { + check_sha256_4k_hash(blk, child.hash)) { child_state = Channel::DONE; progress = true; @@ -212,8 +215,11 @@ void Ft_check::_execute_inner_t1_child(Channel &chan, } else if (child_state == Channel::CHECK_HASH) { + Block blk { }; + child_lvl.children.encode_to_blk(blk); + if (child.gen == INITIAL_GENERATION || - check_sha256_4k_hash(&child_lvl.children, &child.hash)) { + check_sha256_4k_hash(blk, child.hash)) { child_state = Channel::DONE; if (&child_state == &chan._root_state) { @@ -399,10 +405,7 @@ bool Ft_check::_peek_generated_request(uint8_t *buf_ptr, buf_ptr, buf_size, FT_CHECK, id, Block_io_request::READ, 0, 0, 0, chan._gen_prim.blk_nr, 0, 1, - chan._lvl_to_read == 1 ? - (void *)&chan._t2_lvl.children : - (void *)&chan._t1_lvls[chan._lvl_to_read].children, - nullptr); + (void *)&chan._encoded_blk, nullptr); return true; @@ -441,6 +444,10 @@ void Ft_check::generated_request_complete(Module_request &mod_req) { Block_io_request &gen_req { *static_cast(&mod_req) }; chan._gen_prim.success = gen_req.success(); + if (chan._lvl_to_read == 1) + chan._t2_lvl.children.decode_from_blk(chan._encoded_blk); + else + chan._t1_lvls[chan._lvl_to_read].children.decode_from_blk(chan._encoded_blk); break; } default: diff --git a/repos/gems/src/lib/tresor/ft_initializer.cc b/repos/gems/src/lib/tresor/ft_initializer.cc index 214f7320ad..4df42f8f2f 100644 --- a/repos/gems/src/lib/tresor/ft_initializer.cc +++ b/repos/gems/src/lib/tresor/ft_initializer.cc @@ -191,6 +191,7 @@ void Ft_initializer::_execute_inner_t2_child(Channel break; case Channel::BLOCK_ALLOC_COMPLETE: + { /* bail early in case the allocator failed */ if (!channel._generated_req_success) { _mark_req_failed(channel, progress, @@ -201,7 +202,11 @@ void Ft_initializer::_execute_inner_t2_child(Channel Ft_initializer_channel::reset_node(child); child.pba = channel._blk_nr; - calc_sha256_4k_hash(&child_level.children, &child.hash); + + Block blk { }; + child_level.children.encode_to_blk(blk); + calc_sha256_4k_hash(blk, child.hash); + child_state = CS::WRITE_BLOCK; progress = true; @@ -209,7 +214,7 @@ void Ft_initializer::_execute_inner_t2_child(Channel log("[ft_init] node: ", level_index, " ", child_index, " assign pba: ", channel._blk_nr); break; - + } default: break; } @@ -316,6 +321,7 @@ void Ft_initializer::_execute_inner_t1_child(Channel break; case Channel::BLOCK_ALLOC_COMPLETE: + { /* bail early in case the allocator failed */ if (!channel._generated_req_success) { _mark_req_failed(channel, progress, @@ -326,7 +332,11 @@ void Ft_initializer::_execute_inner_t1_child(Channel Ft_initializer_channel::reset_node(child); child.pba = channel._blk_nr; - calc_sha256_4k_hash(&child_level.children, &child.hash); + + Block blk { }; + child_level.children.encode_to_blk(blk); + calc_sha256_4k_hash(blk, child.hash); + child_state = CS::WRITE_BLOCK; progress = true; @@ -334,7 +344,7 @@ void Ft_initializer::_execute_inner_t1_child(Channel log("[ft_init] node: ", level_index, " ", child_index, " assign pba: ", channel._blk_nr); break; - + } default: break; } @@ -591,7 +601,7 @@ bool Ft_initializer::_peek_generated_request(uint8_t *buf_ptr, { for (Module_request_id id { 0 }; id < NR_OF_CHANNELS; id++) { - Channel const &channel { _channels[id] }; + Channel &channel { _channels[id] }; if (channel._state != Ft_initializer_channel::State::INACTIVE) @@ -612,13 +622,15 @@ bool Ft_initializer::_peek_generated_request(uint8_t *buf_ptr, Block_io_request::Type const block_io_req_type { Block_io_request::WRITE }; - void *data = (channel._level_to_write == 1) - ? (void *)&channel._t2_level.children - : (void *)&channel._t1_levels[channel._level_to_write].children; + if (channel._level_to_write == 1) + channel._t2_level.children.encode_to_blk(channel._encoded_blk); + else + channel._t1_levels[channel._level_to_write].children.encode_to_blk(channel._encoded_blk); construct_in_buf( buf_ptr, buf_size, FT_INITIALIZER, id, block_io_req_type, 0, - 0, 0, channel._child_pba, 0, 1, data, nullptr); + 0, 0, channel._child_pba, 0, 1, + (void *)&channel._encoded_blk, nullptr); if (DEBUG) { log("BLOCK_IO_PENDING write ", channel._child_pba); diff --git a/repos/gems/src/lib/tresor/ft_resizing.cc b/repos/gems/src/lib/tresor/ft_resizing.cc index 2c939cec14..bdcffcab74 100644 --- a/repos/gems/src/lib/tresor/ft_resizing.cc +++ b/repos/gems/src/lib/tresor/ft_resizing.cc @@ -90,8 +90,8 @@ void Ft_resizing::_execute_ft_ext_step_read_inner_node_completed(Channel if (channel._lvl_idx == req._ft_max_lvl) { - if (not check_sha256_4k_hash(&channel._t1_blks.items[channel._lvl_idx], - &req._ft_root.hash)) { + if (not check_sha256_4k_hash(channel._encoded_blk, + req._ft_root.hash)) { class Program_error_ft_resizing_hash_mismatch { }; throw Program_error_ft_resizing_hash_mismatch { }; } @@ -102,8 +102,8 @@ void Ft_resizing::_execute_ft_ext_step_read_inner_node_completed(Channel Tree_node_index const child_idx = t1_child_idx_for_vba(channel._vba, parent_lvl_idx, req._ft_degree); Type_1_node const &child = channel._t1_blks.items[parent_lvl_idx].nodes[child_idx]; - if (not check_sha256_4k_hash(&channel._t1_blks.items[channel._lvl_idx], - &child.hash)) { + if (not check_sha256_4k_hash(channel._encoded_blk, + child.hash)) { class Program_error_ft_resizing_hash_mismatch_2 { }; throw Program_error_ft_resizing_hash_mismatch_2 { }; } @@ -181,8 +181,8 @@ void Ft_resizing::_execute_ft_ext_step_read_inner_node_completed(Channel Tree_level_index const parent_lvl_idx = channel._lvl_idx + 1; Tree_node_index const child_idx = t1_child_idx_for_vba(channel._vba, parent_lvl_idx, req._ft_degree); - if (not check_sha256_4k_hash(&channel._t2_blk, - &channel._t1_blks.items[parent_lvl_idx].nodes[child_idx].hash)) { + if (not check_sha256_4k_hash(channel._encoded_blk, + channel._t1_blks.items[parent_lvl_idx].nodes[child_idx].hash)) { class Program_error_ft_resizing_hash_mismatch_3 { }; throw Program_error_ft_resizing_hash_mismatch_3 { }; } @@ -502,23 +502,6 @@ void Ft_resizing::_execute_ft_extension_step(Channel &chan, if (VERBOSE_FT_EXTENSION) log(" pbas allocated: curr gen ", req._curr_gen); -/* -log("YYY ", -chan._alloc_lvl_idx, " ", -req._ft_max_lvl, " ", -req._ft_degree, " ", -req._pba, " ", -req._nr_of_pbas, " ", -(uint64_t)chan._new_pbas.pbas[0], " ", - (uint64_t)chan._new_pbas.pbas[1], " ", - (uint64_t)chan._new_pbas.pbas[2], " ", - (uint64_t)chan._new_pbas.pbas[3], " ", - (uint64_t)chan._new_pbas.pbas[4], " ", - (uint64_t)chan._new_pbas.pbas[5], " ", - (uint64_t)chan._new_pbas.pbas[6], " ", -chan._lvl_idx, " ", -req._nr_of_leaves); -*/ _set_args_for_write_back_of_inner_lvl(req._ft_max_lvl, chan._lvl_idx, @@ -550,11 +533,9 @@ req._nr_of_leaves); .pba = chan._new_pbas.pbas[child_lvl_idx], .gen = req._curr_gen, .hash = { }, - .padding = { } }; - calc_sha256_4k_hash(&chan._t1_blks.items[child_lvl_idx], - &child.hash); + calc_sha256_4k_hash(chan._encoded_blk, child.hash); if (VERBOSE_FT_EXTENSION) log(" set lvl a ", parent_lvl_idx, " child ", child_idx, @@ -579,10 +560,9 @@ req._nr_of_leaves); child = { .pba = chan._new_pbas.pbas[child_lvl_idx], .gen = req._curr_gen, - .padding = {} }; - calc_sha256_4k_hash(&chan._t2_blk, &child.hash); + calc_sha256_4k_hash(chan._encoded_blk, child.hash); if (VERBOSE_FT_EXTENSION) log(" set lvl b ", parent_lvl_idx, " child ", child_idx, @@ -613,10 +593,9 @@ req._nr_of_leaves); req._ft_root = { .pba = child_pba, .gen = req._curr_gen, - .padding = {} }; - calc_sha256_4k_hash(&chan._t1_blks.items[child_lvl_idx], &req._ft_root.hash); + calc_sha256_4k_hash(chan._encoded_blk, req._ft_root.hash); req._ft_nr_of_leaves += req._nr_of_leaves; @@ -703,14 +682,15 @@ bool Ft_resizing::_peek_generated_request(uint8_t *buf_ptr, case Channel::WRITE_ROOT_NODE_PENDING: case Channel::WRITE_INNER_NODE_PENDING: + if (chan._lvl_idx > 1) + chan._t1_blks.items[chan._lvl_idx].encode_to_blk(chan._encoded_blk); + else + chan._t2_blk.encode_to_blk(chan._encoded_blk); construct_in_buf( buf_ptr, buf_size, FT_RESIZING, id, Block_io_request::WRITE, 0, 0, 0, chan._generated_prim.blk_nr, 0, 1, - chan._lvl_idx > 1 ? - (void *)&chan._t1_blks.items[chan._lvl_idx] : - (void *)&chan._t2_blk, - nullptr); + (void *)&chan._encoded_blk, nullptr); return true; @@ -720,8 +700,7 @@ bool Ft_resizing::_peek_generated_request(uint8_t *buf_ptr, buf_ptr, buf_size, FT_RESIZING, id, Block_io_request::READ, 0, 0, 0, chan._generated_prim.blk_nr, 0, 1, - (void *)&chan._t1_blks.items[chan._lvl_idx], - nullptr); + (void *)&chan._encoded_blk, nullptr); return true; @@ -730,10 +709,7 @@ bool Ft_resizing::_peek_generated_request(uint8_t *buf_ptr, construct_in_buf( buf_ptr, buf_size, FT_RESIZING, id, Block_io_request::READ, 0, 0, 0, - chan._generated_prim.blk_nr, 0, 1, - chan._lvl_idx > 1 ? - (void *)&chan._t1_blks.items[chan._lvl_idx] : - (void *)&chan._t2_blk, + chan._generated_prim.blk_nr, 0, 1, (void *)&chan._encoded_blk, nullptr); return true; @@ -800,8 +776,17 @@ void Ft_resizing::generated_request_complete(Module_request &mod_req) Block_io_request &blk_io_req { *static_cast(&mod_req) }; chan._generated_prim.succ = blk_io_req.success(); switch (chan._state) { - case Channel::READ_ROOT_NODE_IN_PROGRESS: chan._state = Channel::READ_ROOT_NODE_COMPLETED; break; - case Channel::READ_INNER_NODE_IN_PROGRESS: chan._state = Channel::READ_INNER_NODE_COMPLETED; break; + case Channel::READ_ROOT_NODE_IN_PROGRESS: + chan._t1_blks.items[chan._lvl_idx].decode_from_blk(chan._encoded_blk); + chan._state = Channel::READ_ROOT_NODE_COMPLETED; + break; + case Channel::READ_INNER_NODE_IN_PROGRESS: + if (chan._lvl_idx > 1) + chan._t1_blks.items[chan._lvl_idx].decode_from_blk(chan._encoded_blk); + else + chan._t2_blk.decode_from_blk(chan._encoded_blk); + chan._state = Channel::READ_INNER_NODE_COMPLETED; + break; case Channel::WRITE_ROOT_NODE_IN_PROGRESS: chan._state = Channel::WRITE_ROOT_NODE_COMPLETED; break; case Channel::WRITE_INNER_NODE_IN_PROGRESS: chan._state = Channel::WRITE_INNER_NODE_COMPLETED; break; default: diff --git a/repos/gems/src/lib/tresor/include/tresor/assertion.h b/repos/gems/src/lib/tresor/include/tresor/assertion.h new file mode 100644 index 0000000000..b3e6477cc3 --- /dev/null +++ b/repos/gems/src/lib/tresor/include/tresor/assertion.h @@ -0,0 +1,35 @@ +/* + * \brief Assertion macros + * \author Martin Stein + * \date 2023-06-09 + */ + +/* + * Copyright (C) 2023 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _TRESOR__ASSERTION_H_ +#define _TRESOR__ASSERTION_H_ + +/* base includes */ +#include +#include + +#define ASSERT(condition) \ + do { \ + if (!(condition)) { \ + Genode::error(__FILE__, ":", __LINE__, ": ", " assertion \"", #condition, "\" failed "); \ + Genode::sleep_forever(); \ + } \ + } while (false) + +#define ASSERT_NEVER_REACHED \ + do { \ + Genode::error(__FILE__, ":", __LINE__, ": ", " should have never been reached"); \ + Genode::sleep_forever(); \ + } while (false) + +#endif /* _TRESOR__ASSERTION_H_ */ diff --git a/repos/gems/src/lib/tresor/include/tresor/block_io.h b/repos/gems/src/lib/tresor/include/tresor/block_io.h index 72c2d92456..a3500fadec 100644 --- a/repos/gems/src/lib/tresor/include/tresor/block_io.h +++ b/repos/gems/src/lib/tresor/include/tresor/block_io.h @@ -102,7 +102,7 @@ class Tresor::Block_io_channel Block_io_request _request { }; Vfs::file_offset _nr_of_processed_bytes { 0 }; size_t _nr_of_remaining_bytes { 0 }; - char _blk_buf[BLOCK_SIZE] { 0 }; + Block _blk_buf { }; bool _generated_req_success { false }; }; diff --git a/repos/gems/src/lib/tresor/include/tresor/ft_check.h b/repos/gems/src/lib/tresor/include/tresor/ft_check.h index 95f8760cfc..5de5f26c70 100644 --- a/repos/gems/src/lib/tresor/include/tresor/ft_check.h +++ b/repos/gems/src/lib/tresor/include/tresor/ft_check.h @@ -131,6 +131,7 @@ class Tresor::Ft_check_channel Type_1_level _t1_lvls[TREE_MAX_LEVEL] { }; Number_of_leaves _nr_of_leaves { 0 }; Request _request { }; + Block _encoded_blk { }; }; diff --git a/repos/gems/src/lib/tresor/include/tresor/ft_initializer.h b/repos/gems/src/lib/tresor/include/tresor/ft_initializer.h index 8405a4307d..2fb457f65c 100644 --- a/repos/gems/src/lib/tresor/include/tresor/ft_initializer.h +++ b/repos/gems/src/lib/tresor/include/tresor/ft_initializer.h @@ -125,6 +125,7 @@ class Tresor::Ft_initializer_channel uint64_t _blk_nr { 0 }; uint64_t _child_pba { 0 }; bool _generated_req_success { false }; + Block _encoded_blk { }; static void reset_node(Tresor::Type_1_node &node) { diff --git a/repos/gems/src/lib/tresor/include/tresor/ft_resizing.h b/repos/gems/src/lib/tresor/include/tresor/ft_resizing.h index 276f714742..4d582f9c75 100644 --- a/repos/gems/src/lib/tresor/include/tresor/ft_resizing.h +++ b/repos/gems/src/lib/tresor/include/tresor/ft_resizing.h @@ -175,6 +175,7 @@ class Tresor::Ft_resizing_channel Tree_walk_pbas _old_pbas { }; Generations _old_generations { }; Tree_walk_pbas _new_pbas { }; + Block _encoded_blk { }; }; class Tresor::Ft_resizing : public Module diff --git a/repos/gems/src/lib/tresor/include/tresor/meta_tree.h b/repos/gems/src/lib/tresor/include/tresor/meta_tree.h index 94c2fd6254..13036f9b85 100644 --- a/repos/gems/src/lib/tresor/include/tresor/meta_tree.h +++ b/repos/gems/src/lib/tresor/include/tresor/meta_tree.h @@ -132,19 +132,19 @@ class Tresor::Meta_tree_channel enum State { INVALID, PENDING, IN_PROGRESS }; enum Op { READ, WRITE, SYNC }; - State state { INVALID }; - Op op { READ }; - bool success { false }; - uint64_t pba { 0 }; - uint64_t level { 0 }; - uint8_t block_data[BLOCK_SIZE] { 0 }; + State state { INVALID }; + Op op { READ }; + bool success { false }; + uint64_t pba { 0 }; + uint64_t level { 0 }; + Block block_data { }; - Local_cache_request(State state, - Op op, - bool success, - uint64_t pba, - uint64_t level, - uint8_t *blk_ptr) + Local_cache_request(State state, + Op op, + bool success, + uint64_t pba, + uint64_t level, + Block const *blk_ptr) : state { state }, op { op }, @@ -153,7 +153,7 @@ class Tresor::Meta_tree_channel level { level } { if (blk_ptr != nullptr) { - memcpy(&block_data, blk_ptr, BLOCK_SIZE); + block_data = *blk_ptr; } } @@ -207,7 +207,7 @@ class Tresor::Meta_tree : public Module bool &handled); void _update_parent(Type_1_node &node, - uint8_t const *blk_ptr, + Block const &blk, uint64_t gen, uint64_t pba); diff --git a/repos/gems/src/lib/tresor/include/tresor/sb_check.h b/repos/gems/src/lib/tresor/include/tresor/sb_check.h index 12c9898297..d2d9ed2b9a 100644 --- a/repos/gems/src/lib/tresor/include/tresor/sb_check.h +++ b/repos/gems/src/lib/tresor/include/tresor/sb_check.h @@ -102,6 +102,7 @@ class Tresor::Sb_check_channel Type_1_node _mt { }; Physical_block_address _gen_prim_blk_nr { 0 }; bool _gen_prim_success { false }; + Block _encoded_blk { }; }; diff --git a/repos/gems/src/lib/tresor/include/tresor/sb_initializer.h b/repos/gems/src/lib/tresor/include/tresor/sb_initializer.h index 6337678203..2ef86d80e4 100644 --- a/repos/gems/src/lib/tresor/include/tresor/sb_initializer.h +++ b/repos/gems/src/lib/tresor/include/tresor/sb_initializer.h @@ -127,8 +127,7 @@ class Tresor::Sb_initializer_channel Sb_initializer_request _request { }; Superblock_index _sb_slot_index { 0 }; Superblock _sb { }; - Block _sb_slot { }; - Block _blk_io_data { }; + Block _encoded_blk { }; Key _key_plain { }; Key _key_cipher { }; Hash _sb_hash { }; @@ -140,9 +139,7 @@ class Tresor::Sb_initializer_channel void clean_data() { _sb = Superblock { }; - memset(&_sb_slot, 0, sizeof(_sb_slot)); - memset(&_blk_io_data, 0, sizeof(_blk_io_data)); memset(&_key_plain, 0, sizeof(_key_plain)); memset(&_key_cipher, 0, sizeof(_key_cipher)); memset(&_sb_hash, 0, sizeof(_sb_hash)); diff --git a/repos/gems/src/lib/tresor/include/tresor/sha256_4k_hash.h b/repos/gems/src/lib/tresor/include/tresor/sha256_4k_hash.h index 815943f0e4..850b9485dd 100644 --- a/repos/gems/src/lib/tresor/include/tresor/sha256_4k_hash.h +++ b/repos/gems/src/lib/tresor/include/tresor/sha256_4k_hash.h @@ -16,12 +16,15 @@ namespace Tresor { - void calc_sha256_4k_hash(void const *data_ptr, - void *hash_ptr); + class Block; + class Hash; + + void calc_sha256_4k_hash(Block const &blk, + Hash &hash); - bool check_sha256_4k_hash(void const *data_ptr, - void const *exp_hash_ptr); + bool check_sha256_4k_hash(Block const &blk, + Hash const &expected_hash); } #endif /* _TRESOR__SHAE256_4K_HASH_ */ diff --git a/repos/gems/src/lib/tresor/include/tresor/superblock_control.h b/repos/gems/src/lib/tresor/include/tresor/superblock_control.h index 431466178f..8518876516 100644 --- a/repos/gems/src/lib/tresor/include/tresor/superblock_control.h +++ b/repos/gems/src/lib/tresor/include/tresor/superblock_control.h @@ -49,7 +49,7 @@ class Tresor::Superblock_control_request : public Module_request uint64_t _client_req_offset { 0 }; uint64_t _client_req_tag { 0 }; Virtual_block_address _vba { 0 }; - Superblock::State _sb_state { INVALID }; + Superblock::State _sb_state { Superblock::INVALID }; Number_of_blocks _nr_of_blks { 0 }; bool _success { false }; bool _request_finished { false }; @@ -211,7 +211,8 @@ class Tresor::Superblock_control_channel Superblock_control_request _request { }; Generated_prim _generated_prim { }; Key _key_plaintext { }; - Block _sb_ciphertext_blk { }; + Superblock _sb_ciphertext { }; + Block _encoded_blk { }; Superblock_index _sb_idx { 0 }; bool _sb_found { false }; Superblock_index _read_sb_idx { 0 }; @@ -226,8 +227,6 @@ class Tresor::Superblock_control_channel Tree_level_index _ft_max_lvl { 0 }; Number_of_leaves _ft_nr_of_leaves { 0 }; - Superblock &_sb_ciphertext() { return *(Superblock *)&_sb_ciphertext_blk; } - public: Superblock_control_request const &request() const { return _request; } diff --git a/repos/gems/src/lib/tresor/include/tresor/types.h b/repos/gems/src/lib/tresor/include/tresor/types.h index 90dc9bef3c..9d96f31b7c 100644 --- a/repos/gems/src/lib/tresor/include/tresor/types.h +++ b/repos/gems/src/lib/tresor/include/tresor/types.h @@ -22,6 +22,7 @@ /* tresor includes */ #include #include +#include namespace Tresor { @@ -41,6 +42,7 @@ namespace Tresor { using Snapshot_id = uint32_t; using Snapshot_index = uint32_t; using Superblock_index = uint8_t; + using On_disc_bool = uint8_t; enum { BLOCK_SIZE = 4096 }; enum { INVALID_KEY_ID = 0 }; @@ -81,6 +83,8 @@ namespace Tresor { struct Key; struct Hash; struct Block; + struct Block_scanner; + struct Block_generator; struct Superblock; struct Superblock_info; struct Snapshot; @@ -206,21 +210,12 @@ struct Tresor::Key_value { Genode::print(out, Byte_range { bytes, KEY_SIZE }); } -} -__attribute__((packed)); - - -struct Tresor::Key -{ - Key_value value; - Key_id id; -} -__attribute__((packed)); +}; struct Tresor::Hash { - uint8_t bytes[HASH_SIZE] { }; + uint8_t bytes[HASH_SIZE] { 0 }; void print(Output &out) const { @@ -236,57 +231,283 @@ struct Tresor::Hash { return !(*this == other); } -} -__attribute__((packed)); +}; + + +struct Tresor::Block +{ + uint8_t bytes[BLOCK_SIZE] { 0 }; + + void print(Output &out) const + { + Genode::print(out, Byte_range { bytes, 16 }, "…"); + } +}; + + +class Tresor::Block_scanner +{ + private: + + Block const &_blk; + size_t _offset { 0 }; + + void const *_current_position() const + { + return (void const *)((addr_t)&_blk + _offset); + } + + void _advance_position(size_t num_bytes) + { + ASSERT(_offset <= sizeof(_blk) - num_bytes); + _offset += num_bytes; + } + + template + void _fetch_copy(T &dst) + { + void const *blk_pos { _current_position() }; + _advance_position(sizeof(dst)); + memcpy(&dst, blk_pos, sizeof(dst)); + } + + static bool _decode_bool(On_disc_bool val) + { + switch (val) { + case 0: return false; + case 1: return true; + default: break; + } + ASSERT_NEVER_REACHED; + } + + public: + + Block_scanner(Block const &blk) + : + _blk { blk } + { } + + template + void fetch(T &dst); + + template + T fetch_value() + { + T dst; + fetch(dst); + return dst; + } + + void skip_bytes(size_t num_bytes) + { + _advance_position(num_bytes); + } + + ~Block_scanner() + { + ASSERT(_offset == sizeof(_blk)); + } +}; + + +template <> inline void Tresor::Block_scanner::fetch(bool &dst) { dst = _decode_bool(fetch_value()); } +template <> inline void Tresor::Block_scanner::fetch(uint8_t &dst) { _fetch_copy(dst); } +template <> inline void Tresor::Block_scanner::fetch(uint16_t &dst) { _fetch_copy(dst); } +template <> inline void Tresor::Block_scanner::fetch(uint32_t &dst) { _fetch_copy(dst); } +template <> inline void Tresor::Block_scanner::fetch(uint64_t &dst) { _fetch_copy(dst); } +template <> inline void Tresor::Block_scanner::fetch(Hash &dst) { _fetch_copy(dst); } +template <> inline void Tresor::Block_scanner::fetch(Key_value &dst) { _fetch_copy(dst); } + + +class Tresor::Block_generator +{ + private: + + Block &_blk; + size_t _offset { 0 }; + + void *_current_position() const + { + return (void *)((addr_t)&_blk + _offset); + } + + void _advance_position(size_t num_bytes) + { + ASSERT(_offset <= sizeof(_blk) - num_bytes); + _offset += num_bytes; + } + + template + void _append_copy(T const &src) + { + void *blk_pos { _current_position() }; + _advance_position(sizeof(src)); + memcpy(blk_pos, &src, sizeof(src)); + } + + static On_disc_bool _encode_bool(bool val) + { + return val ? 1 : 0; + } + + public: + + Block_generator(Block &blk) + : + _blk { blk } + { } + + template + void append(T const &src); + + template + void append_value(T src) + { + append(src); + } + + void append_zero_bytes(size_t num_bytes) + { + void *blk_pos { _current_position() }; + _advance_position(num_bytes); + memset(blk_pos, 0, num_bytes); + } + + ~Block_generator() + { + ASSERT(_offset == sizeof(_blk)); + } +}; + + +template <> inline void Tresor::Block_generator::append(bool const &src) { append_value(_encode_bool(src)); } +template <> inline void Tresor::Block_generator::append(uint8_t const &src) { _append_copy(src); } +template <> inline void Tresor::Block_generator::append(uint16_t const &src) { _append_copy(src); } +template <> inline void Tresor::Block_generator::append(uint32_t const &src) { _append_copy(src); } +template <> inline void Tresor::Block_generator::append(uint64_t const &src) { _append_copy(src); } +template <> inline void Tresor::Block_generator::append(Hash const &src) { _append_copy(src); } +template <> inline void Tresor::Block_generator::append(Key_value const &src) { _append_copy(src); } + + +struct Tresor::Key +{ + Key_value value { }; + Key_id id { INVALID_KEY_ID }; + + void decode_from_blk(Block_scanner &scanner) + { + scanner.fetch(value); + scanner.fetch(id); + } + + void encode_to_blk(Block_generator &generator) const + { + generator.append(value); + generator.append(id); + } +}; struct Tresor::Type_1_node { - Physical_block_address pba { 0 }; - Generation gen { 0 }; - Hash hash { }; - uint8_t padding[16] { 0 }; + Physical_block_address pba { 0 }; + Generation gen { 0 }; + Hash hash { }; + + void decode_from_blk(Block_scanner &scanner) + { + scanner.fetch(pba); + scanner.fetch(gen); + scanner.fetch(hash); + scanner.skip_bytes(16); + } + + void encode_to_blk(Block_generator &generator) const + { + generator.append(pba); + generator.append(gen); + generator.append(hash); + generator.append_zero_bytes(16); + } bool valid() const { - Type_1_node node { }; + Type_1_node const node { }; return - pba != node.pba || gen != node.gen || hash != node.hash; + pba != node.pba || + gen != node.gen || + hash != node.hash; } void print(Output &out) const { Genode::print(out, "pba ", pba, " gen ", gen, " hash ", hash); } -} -__attribute__((packed)); - -static_assert(sizeof(Tresor::Type_1_node) == Tresor::T1_NODE_STORAGE_SIZE); +}; struct Tresor::Type_1_node_block { Type_1_node nodes[NR_OF_T1_NODES_PER_BLK] { }; -} -__attribute__((packed)); -static_assert(sizeof(Tresor::Type_1_node_block) == Tresor::BLOCK_SIZE); + void decode_from_blk(Block const &blk) + { + Block_scanner scanner { blk }; + for (Type_1_node &node : nodes) + node.decode_from_blk(scanner); + } + + void encode_to_blk(Block &blk) const + { + Block_generator generator { blk }; + for (Type_1_node const &node : nodes) + node.encode_to_blk(generator); + } +}; struct Tresor::Type_2_node { - uint64_t pba { 0 }; - uint64_t last_vba { 0 }; - uint64_t alloc_gen { 0 }; - uint64_t free_gen { 0 }; - uint32_t last_key_id { 0 }; - uint8_t reserved { 0 }; - uint8_t padding[27] { 0 }; + Physical_block_address pba { 0 }; + Virtual_block_address last_vba { 0 }; + Generation alloc_gen { 0 }; + Generation free_gen { 0 }; + Key_id last_key_id { 0 }; + bool reserved { false }; + + void decode_from_blk(Block_scanner &scanner) + { + scanner.fetch(pba); + scanner.fetch(last_vba); + scanner.fetch(alloc_gen); + scanner.fetch(free_gen); + scanner.fetch(last_key_id); + scanner.fetch(reserved); + scanner.skip_bytes(27); + } + + void encode_to_blk(Block_generator &generator) const + { + generator.append(pba); + generator.append(last_vba); + generator.append(alloc_gen); + generator.append(free_gen); + generator.append(last_key_id); + generator.append(reserved); + generator.append_zero_bytes(27); + } bool valid() const { - Type_2_node node { }; - return memcmp(this, &node, sizeof(node)) != 0; + Type_2_node const node { }; + return + pba != node.pba || + last_vba != node.last_vba || + alloc_gen != node.alloc_gen || + free_gen != node.free_gen || + last_key_id != node.last_key_id || + reserved != node.reserved; } void print(Output &out) const @@ -295,32 +516,27 @@ struct Tresor::Type_2_node out, "pba ", pba, " last_vba ", last_vba, " alloc_gen ", alloc_gen, " free_gen ", free_gen, " last_key ", last_key_id); } - -} -__attribute__((packed)); - -static_assert(sizeof(Tresor::Type_2_node) == Tresor::T2_NODE_STORAGE_SIZE); +}; struct Tresor::Type_2_node_block { Type_2_node nodes[NR_OF_T2_NODES_PER_BLK] { }; -} -__attribute__((packed)); -static_assert(sizeof(Tresor::Type_2_node_block) == Tresor::BLOCK_SIZE); - - -struct Tresor::Block -{ - uint8_t bytes[BLOCK_SIZE] { }; - - void print(Output &out) const + void decode_from_blk(Block const &blk) { - Genode::print(out, Byte_range { bytes, 16 }, "…"); + Block_scanner scanner { blk }; + for (Type_2_node &node : nodes) + node.decode_from_blk(scanner); } -} -__attribute__((packed)); + + void encode_to_blk(Block &blk) const + { + Block_generator generator { blk }; + for (Type_2_node const &node : nodes) + node.encode_to_blk(generator); + } +}; struct Tresor::Snapshot @@ -333,7 +549,32 @@ struct Tresor::Snapshot bool valid { false }; Snapshot_id id { MAX_SNAP_ID }; bool keep { false }; - uint8_t padding[6] { 0 }; + + void decode_from_blk(Block_scanner &scanner) + { + scanner.fetch(hash); + scanner.fetch(pba); + scanner.fetch(gen); + scanner.fetch(nr_of_leaves); + scanner.fetch(max_level); + scanner.fetch(valid); + scanner.fetch(id); + scanner.fetch(keep); + scanner.skip_bytes(6); + } + + void encode_to_blk(Block_generator &generator) const + { + generator.append(hash); + generator.append(pba); + generator.append(gen); + generator.append(nr_of_leaves); + generator.append(max_level); + generator.append(valid); + generator.append(id); + generator.append(keep); + generator.append_zero_bytes(6); + } void print(Output &out) const { @@ -350,16 +591,25 @@ struct Tresor::Snapshot { return vba <= nr_of_leaves - 1; } -} -__attribute__((packed)); - -static_assert(sizeof(Tresor::Snapshot) == Tresor::SNAPSHOT_STORAGE_SIZE); +}; struct Tresor::Snapshots { Snapshot items[MAX_NR_OF_SNAPSHOTS]; + void decode_from_blk(Block_scanner &scanner) + { + for (Snapshot &snap : items) + snap.decode_from_blk(scanner); + } + + void encode_to_blk(Block_generator &generator) const + { + for (Snapshot const &snap : items) + snap.encode_to_blk(generator); + } + void discard_disposable_snapshots(Generation curr_gen, Generation last_secured_gen) { @@ -424,20 +674,15 @@ struct Tresor::Snapshots class Exception_1 { }; throw Exception_1 { }; } -} -__attribute__((packed)); +}; struct Tresor::Superblock { - enum State : uint8_t - { - INVALID = 0, - NORMAL = 1, - REKEYING = 2, - EXTENDING_VBD = 3, - EXTENDING_FT = 4, - }; + using On_disc_state = uint8_t; + + enum State { + INVALID, NORMAL, REKEYING, EXTENDING_VBD, EXTENDING_FT }; State state { INVALID }; // offset 0 Virtual_block_address rekeying_vba { 0 }; // offset 1 @@ -463,7 +708,93 @@ struct Tresor::Superblock Tree_level_index meta_max_level { 0 }; // offset 3697 Tree_degree meta_degree { TREE_MIN_DEGREE }; // offset 3701 Number_of_leaves meta_leaves { 0 }; // offset 3705 - uint8_t padding[383] { 0 }; // offset 3713 + // offset 3713 + + static State decode_state(On_disc_state val) + { + switch (val) { + case 0: return INVALID; + case 1: return NORMAL; + case 2: return REKEYING; + case 3: return EXTENDING_VBD; + case 4: return EXTENDING_FT; + default: break; + } + ASSERT_NEVER_REACHED; + } + + static On_disc_state encode_state(State val) + { + switch (val) { + case INVALID : return 0; + case NORMAL : return 1; + case REKEYING : return 2; + case EXTENDING_VBD: return 3; + case EXTENDING_FT : return 4; + default: break; + } + ASSERT_NEVER_REACHED; + } + + void decode_from_blk(Block const &blk) + { + Block_scanner scanner { blk }; + state = decode_state(scanner.fetch_value()); + scanner.fetch(rekeying_vba); + scanner.fetch(resizing_nr_of_pbas); + scanner.fetch(resizing_nr_of_leaves); + previous_key.decode_from_blk(scanner); + current_key.decode_from_blk(scanner); + snapshots.decode_from_blk(scanner); + scanner.fetch(last_secured_generation); + scanner.fetch(curr_snap); + scanner.fetch(degree); + scanner.fetch(first_pba); + scanner.fetch(nr_of_pbas); + scanner.fetch(free_gen); + scanner.fetch(free_number); + scanner.fetch(free_hash); + scanner.fetch(free_max_level); + scanner.fetch(free_degree); + scanner.fetch(free_leaves); + scanner.fetch(meta_gen); + scanner.fetch(meta_number); + scanner.fetch(meta_hash); + scanner.fetch(meta_max_level); + scanner.fetch(meta_degree); + scanner.fetch(meta_leaves); + scanner.skip_bytes(383); + } + + void encode_to_blk(Block &blk) const + { + Block_generator generator { blk }; + generator.append_value(encode_state(state)); + generator.append(rekeying_vba); + generator.append(resizing_nr_of_pbas); + generator.append(resizing_nr_of_leaves); + previous_key.encode_to_blk(generator); + current_key.encode_to_blk(generator); + snapshots.encode_to_blk(generator); + generator.append(last_secured_generation); + generator.append(curr_snap); + generator.append(degree); + generator.append(first_pba); + generator.append(nr_of_pbas); + generator.append(free_gen); + generator.append(free_number); + generator.append(free_hash); + generator.append(free_max_level); + generator.append(free_degree); + generator.append(free_leaves); + generator.append(meta_gen); + generator.append(meta_number); + generator.append(meta_hash); + generator.append(meta_max_level); + generator.append(meta_degree); + generator.append(meta_leaves); + generator.append_zero_bytes(383); + } bool valid() const { return state != INVALID; } @@ -489,10 +820,7 @@ struct Tresor::Superblock if (snap.valid) Genode::print(out, " ", snap); } -} -__attribute__((packed)); - -static_assert(sizeof(Tresor::Superblock) == Tresor::BLOCK_SIZE); +}; struct Tresor::Type_1_node_walk @@ -525,4 +853,5 @@ struct Tresor::Level_indent } }; + #endif /* _TRESOR__TYPES_H_ */ diff --git a/repos/gems/src/lib/tresor/include/tresor/vbd_check.h b/repos/gems/src/lib/tresor/include/tresor/vbd_check.h index bd2a2dd4ad..224d489a33 100644 --- a/repos/gems/src/lib/tresor/include/tresor/vbd_check.h +++ b/repos/gems/src/lib/tresor/include/tresor/vbd_check.h @@ -116,6 +116,7 @@ class Tresor::Vbd_check_channel Tree_level_index _lvl_to_read { 0 }; Child_state _root_state { DONE }; Block _leaf_lvl { }; + Block _encoded_blk { }; Type_1_level _t1_lvls[TREE_MAX_LEVEL] { }; Request _request { }; }; diff --git a/repos/gems/src/lib/tresor/include/tresor/vbd_initializer.h b/repos/gems/src/lib/tresor/include/tresor/vbd_initializer.h index f67608bacb..c990627b97 100644 --- a/repos/gems/src/lib/tresor/include/tresor/vbd_initializer.h +++ b/repos/gems/src/lib/tresor/include/tresor/vbd_initializer.h @@ -110,14 +110,15 @@ class Tresor::Vbd_initializer_channel Child_state state { DONE }; }; - State _state { INACTIVE }; - Vbd_initializer_request _request { }; - Root_node _root_node { }; - Type_1_level _t1_levels[TREE_MAX_LEVEL] { }; - uint64_t _level_to_write { 0 }; - uint64_t _blk_nr { 0 }; - uint64_t _child_pba { 0 }; - bool _generated_req_success { false }; + State _state { INACTIVE }; + Vbd_initializer_request _request { }; + Root_node _root_node { }; + Type_1_level _t1_levels[TREE_MAX_LEVEL] { }; + uint64_t _level_to_write { 0 }; + uint64_t _blk_nr { 0 }; + uint64_t _child_pba { 0 }; + bool _generated_req_success { false }; + Block _encoded_blk { }; static void reset_node(Type_1_node &node) { diff --git a/repos/gems/src/lib/tresor/include/tresor/virtual_block_device.h b/repos/gems/src/lib/tresor/include/tresor/virtual_block_device.h index 6290b8b91a..79fa7edf88 100644 --- a/repos/gems/src/lib/tresor/include/tresor/virtual_block_device.h +++ b/repos/gems/src/lib/tresor/include/tresor/virtual_block_device.h @@ -243,6 +243,7 @@ class Tresor::Virtual_block_device_channel Number_of_blocks _nr_of_blks { 0 }; Generation _last_secured_gen { 0 }; Generation _free_gen { 0 }; + Block _encoded_blk { }; Block _data_blk { }; Physical_block_address _data_blk_old_pba { 0 }; bool _first_snapshot { false }; @@ -326,7 +327,8 @@ class Tresor::Virtual_block_device : public Module void _add_new_root_lvl_to_snap_using_pba_contingent(Channel &chan); - void _check_hash_of_read_type_1_node(Snapshot const &snapshot, + void _check_hash_of_read_type_1_node(Channel &chan, + Snapshot const &snapshot, uint64_t const snapshots_degree, uint64_t const t1_blk_idx, Channel::Type_1_node_blocks const &t1_blks, diff --git a/repos/gems/src/lib/tresor/meta_tree.cc b/repos/gems/src/lib/tresor/meta_tree.cc index 3159c3d7ae..8ea2b212b8 100644 --- a/repos/gems/src/lib/tresor/meta_tree.cc +++ b/repos/gems/src/lib/tresor/meta_tree.cc @@ -110,7 +110,7 @@ bool Meta_tree::_peek_generated_request(uint8_t *buf_ptr, construct_in_buf( buf_ptr, buf_size, META_TREE, id, blk_io_req_type, 0, 0, 0, local_req.pba, 0, 1, - channel._cache_request.block_data, nullptr); + (void *)&channel._cache_request.block_data, nullptr); return true; } @@ -174,25 +174,25 @@ void Meta_tree::generated_request_complete(Module_request &mod_req) if (local_req.level > T2_NODE_LVL) { - if (!check_sha256_4k_hash(channel._cache_request.block_data, &t1_info.node.hash)) { + if (!check_sha256_4k_hash(channel._cache_request.block_data, t1_info.node.hash)) { channel._state = Channel::TREE_HASH_MISMATCH; } else { - memcpy(&t1_info.entries, channel._cache_request.block_data, BLOCK_SIZE); + t1_info.entries.decode_from_blk(channel._cache_request.block_data); t1_info.index = 0; t1_info.state = Type_1_info::READ_COMPLETE; } } else if (local_req.level == T2_NODE_LVL) { - if (!check_sha256_4k_hash(channel._cache_request.block_data, &t2_info.node.hash)) { + if (!check_sha256_4k_hash(channel._cache_request.block_data, t2_info.node.hash)) { channel._state = Channel::TREE_HASH_MISMATCH; } else { - memcpy(&t2_info.entries, channel._cache_request.block_data, BLOCK_SIZE); + t2_info.entries.decode_from_blk(channel._cache_request.block_data); t2_info.index = 0; t2_info.state = Type_2_info::READ_COMPLETE; } @@ -245,12 +245,12 @@ void Meta_tree::_mark_req_successful(Channel &channel, } -void Meta_tree::_update_parent(Type_1_node &node, - uint8_t const *blk_ptr, - uint64_t gen, - uint64_t pba) +void Meta_tree::_update_parent(Type_1_node &node, + Block const &blk, + uint64_t gen, + uint64_t pba) { - calc_sha256_4k_hash(blk_ptr, &node.hash); + calc_sha256_4k_hash(blk, node.hash); node.gen = gen; node.pba = pba; } @@ -401,16 +401,16 @@ void Meta_tree::_handle_level_1_node(Channel &channel, case Type_2_info::WRITE: { - uint8_t block_data[BLOCK_SIZE]; - memcpy(block_data, &t2_info.entries, BLOCK_SIZE); + Block block_data { }; + t2_info.entries.encode_to_blk(block_data); _update_parent( - t1_info.entries.nodes[t1_info.index], block_data, req._current_gen, - t2_info.node.pba); + t1_info.entries.nodes[t1_info.index], block_data, + req._current_gen, t2_info.node.pba); channel._cache_request = Local_cache_request { Local_cache_request::PENDING, Local_cache_request::WRITE, false, - t2_info.node.pba, 1, block_data }; + t2_info.node.pba, 1, &block_data }; t1_info.dirty = true; handled = true; @@ -615,8 +615,8 @@ void Meta_tree::_handle_level_n_nodes(Channel &channel, case Type_1_info::WRITE: { - uint8_t block_data[BLOCK_SIZE]; - memcpy(&block_data, &t1_info.entries, BLOCK_SIZE); + Block block_data; + t1_info.entries.encode_to_blk(block_data); if (lvl == req._mt_max_lvl) { @@ -648,7 +648,7 @@ void Meta_tree::_handle_level_n_nodes(Channel &channel, } channel._cache_request = Local_cache_request { Local_cache_request::PENDING, Local_cache_request::WRITE, - false, t1_info.node.pba, lvl, block_data }; + false, t1_info.node.pba, lvl, &block_data }; handled = true; return; diff --git a/repos/gems/src/lib/tresor/sb_check.cc b/repos/gems/src/lib/tresor/sb_check.cc index 16b2547028..aba72805bc 100644 --- a/repos/gems/src/lib/tresor/sb_check.cc +++ b/repos/gems/src/lib/tresor/sb_check.cc @@ -325,7 +325,7 @@ bool Sb_check::_peek_generated_request(uint8_t *buf_ptr, construct_in_buf( buf_ptr, buf_size, SB_CHECK, id, Block_io_request::READ, 0, 0, 0, - chan._gen_prim_blk_nr, 0, 1, &chan._sb_slot, + chan._gen_prim_blk_nr, 0, 1, &chan._encoded_blk, nullptr); return true; @@ -416,7 +416,10 @@ void Sb_check::generated_request_complete(Module_request &mod_req) Block_io_request &gen_req { *static_cast(&mod_req) }; chan._gen_prim_success = gen_req.success(); switch (chan._sb_slot_state) { - case Channel::READ_DROPPED: chan._sb_slot_state = Channel::READ_DONE; break; + case Channel::READ_DROPPED: + chan._sb_slot.decode_from_blk(chan._encoded_blk); + chan._sb_slot_state = Channel::READ_DONE; + break; default: class Exception_2 { }; throw Exception_2 { }; diff --git a/repos/gems/src/lib/tresor/sb_initializer.cc b/repos/gems/src/lib/tresor/sb_initializer.cc index 24d00f5a7d..c4ffbd7da4 100644 --- a/repos/gems/src/lib/tresor/sb_initializer.cc +++ b/repos/gems/src/lib/tresor/sb_initializer.cc @@ -143,8 +143,7 @@ void Sb_initializer::_execute(Channel &channel, if (channel._sb_slot_index == 0) { channel._state = CS::VBD_REQUEST_PENDING; } else { - memset(&channel._sb_slot, 0, sizeof(channel._sb_slot)); - memcpy(&channel._sb_slot, &channel._sb, sizeof(channel._sb)); + channel._sb.encode_to_blk(channel._encoded_blk); channel._state = CS::WRITE_REQUEST_PENDING; } progress = true; @@ -179,8 +178,9 @@ void Sb_initializer::_execute(Channel &channel, _populate_sb_slot(channel, Physical_block_address { block_allocator_first_block() } - NR_OF_SUPERBLOCK_SLOTS, Number_of_blocks { (uint32_t)block_allocator_nr_of_blks() + NR_OF_SUPERBLOCK_SLOTS }); - memcpy(&channel._sb_slot, &channel._sb, sizeof(channel._sb)); - calc_sha256_4k_hash(&channel._sb_slot, (void*)&channel._sb_hash); + + channel._sb.encode_to_blk(channel._encoded_blk); + calc_sha256_4k_hash(channel._encoded_blk, channel._sb_hash); channel._state = CS::WRITE_REQUEST_PENDING; progress = true; @@ -429,7 +429,7 @@ bool Sb_initializer::_peek_generated_request(uint8_t *buf_ptr, construct_in_buf( buf_ptr, buf_size, SB_INITIALIZER, id, block_io_req_type, 0, 0, - 0, channel._sb_slot_index, 0, 1, (void*)&channel._sb_slot, + 0, channel._sb_slot_index, 0, 1, (void *)&channel._encoded_blk, nullptr); return true; diff --git a/repos/gems/src/lib/tresor/sha256_4k_hash.cc b/repos/gems/src/lib/tresor/sha256_4k_hash.cc index cdaf384b7f..8a3ed0f99b 100644 --- a/repos/gems/src/lib/tresor/sha256_4k_hash.cc +++ b/repos/gems/src/lib/tresor/sha256_4k_hash.cc @@ -11,41 +11,39 @@ * under the terms of the GNU Affero General Public License version 3. */ +/* tresor includes */ +#include +#include + /* base includes */ #include /* libcrypto */ #include -/* tresor includes */ -#include -using namespace Genode; -using namespace Tresor; - - -bool Tresor::check_sha256_4k_hash(void const *data_ptr, - void const *exp_hash_ptr) +bool Tresor::check_sha256_4k_hash(Block const &blk, + Hash const &expected_hash) { - uint8_t got_hash[32]; - calc_sha256_4k_hash(data_ptr, &got_hash); - return !memcmp(&got_hash, exp_hash_ptr, sizeof(got_hash)); + Hash got_hash; + calc_sha256_4k_hash(blk, got_hash); + return got_hash == expected_hash; } -void Tresor::calc_sha256_4k_hash(void const * const data_ptr, - void * const hash_ptr) +void Tresor::calc_sha256_4k_hash(Block const &blk, + Hash &hash) { SHA256_CTX context { }; if (!SHA256_Init(&context)) { class Calc_sha256_4k_hash_init_error { }; throw Calc_sha256_4k_hash_init_error { }; } - if (!SHA256_Update(&context, data_ptr, 4096)) { + if (!SHA256_Update(&context, &blk, BLOCK_SIZE)) { class Calc_sha256_4k_hash_update_error { }; throw Calc_sha256_4k_hash_update_error { }; } - if (!SHA256_Final(static_cast(hash_ptr), &context)) { + if (!SHA256_Final((unsigned char *)(&hash), &context)) { class Calc_sha256_4k_hash_final_error { }; throw Calc_sha256_4k_hash_final_error { }; } diff --git a/repos/gems/src/lib/tresor/superblock_control.cc b/repos/gems/src/lib/tresor/superblock_control.cc index d82111b60a..6b8a709c3c 100644 --- a/repos/gems/src/lib/tresor/superblock_control.cc +++ b/repos/gems/src/lib/tresor/superblock_control.cc @@ -599,7 +599,7 @@ void Superblock_control::_secure_sb_init(Channel &chan, bool &progress) { _sb.snapshots.items[_sb.curr_snap].gen = _curr_gen; - _init_sb_without_key_values(_sb, chan._sb_ciphertext()); + _init_sb_without_key_values(_sb, chan._sb_ciphertext); chan._key_plaintext = _sb.current_key; chan._generated_prim = { .op = Generated_prim::READ, @@ -700,7 +700,10 @@ void Superblock_control::_secure_sb_sync_blk_io_compl(Channel &chan, _mark_req_failed(chan, progress, "sync block io"); return; } - calc_sha256_4k_hash(&chan._sb_ciphertext_blk, &chan._hash); + Block blk { }; + chan._sb_ciphertext.encode_to_blk(blk); + calc_sha256_4k_hash(blk, chan._hash); + chan._generated_prim = { .op = Generated_prim::READ, .succ = false, @@ -844,7 +847,7 @@ void Superblock_control::_execute_sync(Channel &channel, sb.last_secured_generation = curr_gen; sb.snapshots.items[sb.curr_snap].gen = curr_gen; - _init_sb_without_key_values(sb, channel._sb_ciphertext()); + _init_sb_without_key_values(sb, channel._sb_ciphertext); channel._key_plaintext = sb.current_key; channel._generated_prim = { @@ -946,12 +949,15 @@ void Superblock_control::_execute_sync(Channel &channel, break; case Channel::State::SYNC_BLK_IO_COMPLETED: - + { if (!channel._generated_prim.succ) { class Sync_blk_io_completed_error { }; throw Sync_blk_io_completed_error { }; } - calc_sha256_4k_hash(&channel._sb_ciphertext_blk, &channel._hash); + Block blk { }; + channel._sb_ciphertext.encode_to_blk(blk); + calc_sha256_4k_hash(blk, channel._hash); + channel._generated_prim = { .op = Channel::Generated_prim::Type::READ, .succ = false, @@ -970,7 +976,7 @@ void Superblock_control::_execute_sync(Channel &channel, curr_gen = curr_gen + 1; progress = true; break; - + } case Channel::State::SECURE_SB_COMPLETED: if (!channel._generated_prim.succ) { @@ -1032,13 +1038,13 @@ void Superblock_control::_execute_initialize(Channel &channel, class Execute_initialize_error { }; throw Execute_initialize_error { }; } - if (channel._sb_ciphertext().state != Superblock::INVALID) { + if (channel._sb_ciphertext.state != Superblock::INVALID) { - Superblock const &cipher { channel._sb_ciphertext() }; + Superblock const &cipher { channel._sb_ciphertext }; Snapshot_index const snap_index { cipher.snapshots.newest_snapshot_idx() }; Generation const sb_generation { cipher.snapshots.items[snap_index].gen }; - if (check_sha256_4k_hash(&channel._sb_ciphertext_blk, channel._hash.bytes)) { + if (check_sha256_4k_hash(channel._encoded_blk, channel._hash)) { channel._generation = sb_generation; channel._sb_idx = channel._read_sb_idx; channel._sb_found = true; @@ -1102,7 +1108,7 @@ void Superblock_control::_execute_initialize(Channel &channel, throw Execute_initialize_decrypt_current_key_error { }; } - channel._curr_key_plaintext.id = channel._sb_ciphertext().current_key.id; + channel._curr_key_plaintext.id = channel._sb_ciphertext.current_key.id; channel._generated_prim = { .op = Channel::Generated_prim::Type::READ, @@ -1122,7 +1128,7 @@ void Superblock_control::_execute_initialize(Channel &channel, throw Execute_add_current_key_at_crypto_error { }; } - switch (channel._sb_ciphertext().state) { + switch (channel._sb_ciphertext.state) { case Superblock::INVALID: class Execute_add_current_key_at_crypto_invalid_error { }; throw Execute_add_current_key_at_crypto_invalid_error { }; @@ -1146,7 +1152,7 @@ void Superblock_control::_execute_initialize(Channel &channel, case Superblock::EXTENDING_VBD: case Superblock::EXTENDING_FT: - _init_sb_without_key_values(channel._sb_ciphertext(), sb); + _init_sb_without_key_values(channel._sb_ciphertext, sb); sb.current_key.value = channel._curr_key_plaintext.value; sb_idx = channel._sb_idx; @@ -1194,7 +1200,7 @@ void Superblock_control::_execute_initialize(Channel &channel, throw Add_previous_key_at_crypto_module_error { }; } - _init_sb_without_key_values(channel._sb_ciphertext(), sb); + _init_sb_without_key_values(channel._sb_ciphertext, sb); sb.current_key.value = channel._curr_key_plaintext.value; sb.previous_key.value = channel._prev_key_plaintext.value; @@ -1231,7 +1237,7 @@ void Superblock_control::_execute_deinitialize(Channel &channel, sb.last_secured_generation = curr_gen; sb.snapshots.items[sb.curr_snap].gen = curr_gen; - _init_sb_without_key_values(sb, channel._sb_ciphertext()); + _init_sb_without_key_values(sb, channel._sb_ciphertext); channel._key_plaintext = sb.current_key; channel._generated_prim = { @@ -1343,12 +1349,14 @@ void Superblock_control::_execute_deinitialize(Channel &channel, break; case Channel::State::SYNC_BLK_IO_COMPLETED: - + { if (!channel._generated_prim.succ) { class Deinitialize_sync_blk_io_error { }; throw Deinitialize_sync_blk_io_error { }; } - calc_sha256_4k_hash(&channel._sb_ciphertext_blk, &channel._hash); + Block blk { }; + channel._sb_ciphertext.encode_to_blk(blk); + calc_sha256_4k_hash(blk, channel._hash); channel._generated_prim = { .op = Channel::Generated_prim::Type::READ, @@ -1371,6 +1379,7 @@ void Superblock_control::_execute_deinitialize(Channel &channel, progress = true; break; + } case Channel::State::SECURE_SB_COMPLETED: if (!channel._generated_prim.succ) { @@ -1493,7 +1502,7 @@ bool Superblock_control::_peek_generated_request(uint8_t *buf_ptr, Trust_anchor_request::create( buf_ptr, buf_size, SUPERBLOCK_CONTROL, id, Trust_anchor_request::DECRYPT_KEY, - nullptr, &chan._sb_ciphertext().current_key.value, + nullptr, &chan._sb_ciphertext.current_key.value, nullptr, nullptr); return 1; @@ -1503,7 +1512,7 @@ bool Superblock_control::_peek_generated_request(uint8_t *buf_ptr, Trust_anchor_request::create( buf_ptr, buf_size, SUPERBLOCK_CONTROL, id, Trust_anchor_request::DECRYPT_KEY, - nullptr, &chan._sb_ciphertext().previous_key.value, + nullptr, &chan._sb_ciphertext.previous_key.value, nullptr, nullptr); return 1; @@ -1642,7 +1651,7 @@ bool Superblock_control::_peek_generated_request(uint8_t *buf_ptr, construct_in_buf( buf_ptr, buf_size, SUPERBLOCK_CONTROL, id, Block_io_request::READ, 0, 0, 0, - chan._generated_prim.blk_nr, 0, 1, &chan._sb_ciphertext_blk, + chan._generated_prim.blk_nr, 0, 1, &chan._encoded_blk, nullptr); return true; @@ -1659,10 +1668,11 @@ bool Superblock_control::_peek_generated_request(uint8_t *buf_ptr, case Channel::WRITE_SB_PENDING: + chan._sb_ciphertext.encode_to_blk(chan._encoded_blk); construct_in_buf( buf_ptr, buf_size, SUPERBLOCK_CONTROL, id, Block_io_request::WRITE, 0, 0, 0, - chan._generated_prim.blk_nr, 0, 1, &chan._sb_ciphertext_blk, + chan._generated_prim.blk_nr, 0, 1, &chan._encoded_blk, nullptr); return true; @@ -1876,11 +1886,11 @@ void Superblock_control::generated_request_complete(Module_request &mod_req) break; case Channel::ENCRYPT_CURRENT_KEY_IN_PROGRESS: chan._state = Channel::ENCRYPT_CURRENT_KEY_COMPLETED; - memcpy(&chan._sb_ciphertext().current_key.value, gen_req.key_ciphertext_ptr(), KEY_SIZE); + memcpy(&chan._sb_ciphertext.current_key.value, gen_req.key_ciphertext_ptr(), KEY_SIZE); break; case Channel::ENCRYPT_PREVIOUS_KEY_IN_PROGRESS: chan._state = Channel::ENCRYPT_PREVIOUS_KEY_COMPLETED; - memcpy(&chan._sb_ciphertext().previous_key.value, gen_req.key_ciphertext_ptr(), KEY_SIZE); + memcpy(&chan._sb_ciphertext.previous_key.value, gen_req.key_ciphertext_ptr(), KEY_SIZE); break; case Channel::DECRYPT_CURRENT_KEY_IN_PROGRESS: chan._state = Channel::DECRYPT_CURRENT_KEY_COMPLETED; @@ -1969,8 +1979,14 @@ void Superblock_control::generated_request_complete(Module_request &mod_req) Block_io_request &gen_req { *static_cast(&mod_req) }; chan._generated_prim.succ = gen_req.success(); switch (chan._state) { - case Channel::READ_SB_IN_PROGRESS: chan._state = Channel::READ_SB_COMPLETED; break; - case Channel::READ_CURRENT_SB_IN_PROGRESS: chan._state = Channel::READ_CURRENT_SB_COMPLETED; break; + case Channel::READ_SB_IN_PROGRESS: + chan._sb_ciphertext.decode_from_blk(chan._encoded_blk); + chan._state = Channel::READ_SB_COMPLETED; + break; + case Channel::READ_CURRENT_SB_IN_PROGRESS: + chan._sb_ciphertext.decode_from_blk(chan._encoded_blk); + chan._state = Channel::READ_CURRENT_SB_COMPLETED; + break; case Channel::SYNC_BLK_IO_IN_PROGRESS: chan._state = Channel::SYNC_BLK_IO_COMPLETED; break; case Channel::SYNC_CACHE_IN_PROGRESS: chan._state = Channel::SYNC_CACHE_COMPLETED; break; case Channel::WRITE_SB_IN_PROGRESS: chan._state = Channel::WRITE_SB_COMPLETED; break; diff --git a/repos/gems/src/lib/tresor/vbd_check.cc b/repos/gems/src/lib/tresor/vbd_check.cc index fd171ba6bc..2f20e08e58 100644 --- a/repos/gems/src/lib/tresor/vbd_check.cc +++ b/repos/gems/src/lib/tresor/vbd_check.cc @@ -124,8 +124,11 @@ void Vbd_check::_execute_inner_t1_child(Channel &chan, } else if (child_state == Channel::CHECK_HASH) { + Block blk { }; + child_lvl.children.encode_to_blk(blk); + if (child.gen == INITIAL_GENERATION || - check_sha256_4k_hash(&child_lvl.children, &child.hash)) { + check_sha256_4k_hash(blk, child.hash)) { child_state = Channel::DONE; if (&child_state == &chan._root_state) { @@ -142,7 +145,7 @@ void Vbd_check::_execute_inner_t1_child(Channel &chan, if (VERBOSE_CHECK) { Hash hash; - calc_sha256_4k_hash(&child_lvl.children, &hash); + calc_sha256_4k_hash(blk, hash); log(Level_indent { lvl, req._max_lvl }, " lvl ", lvl, " child ", child_idx, " (", child, "): bad hash ", hash); } @@ -226,7 +229,7 @@ void Vbd_check::_execute_leaf_child(Channel &chan, } else if (child_state == Channel::CHECK_HASH) { - if (check_sha256_4k_hash(&child_lvl, &child.hash)) { + if (check_sha256_4k_hash(child_lvl, child.hash)) { req._nr_of_leaves--; child_state = Channel::DONE; @@ -241,7 +244,7 @@ void Vbd_check::_execute_leaf_child(Channel &chan, if (VERBOSE_CHECK) { Hash hash; - calc_sha256_4k_hash(&child_lvl, &hash); + calc_sha256_4k_hash(child_lvl, hash); log(Level_indent { lvl, req._max_lvl }, " lvl ", lvl, " child ", child_idx, " (", child, "): bad hash ", hash); } @@ -364,7 +367,7 @@ bool Vbd_check::_peek_generated_request(uint8_t *buf_ptr, chan._gen_prim.blk_nr, 0, 1, chan._lvl_to_read == 0 ? (void *)&chan._leaf_lvl : - (void *)&chan._t1_lvls[chan._lvl_to_read].children, + (void *)&chan._encoded_blk, nullptr); return true; @@ -404,6 +407,8 @@ void Vbd_check::generated_request_complete(Module_request &mod_req) { Block_io_request &gen_req { *static_cast(&mod_req) }; chan._gen_prim.success = gen_req.success(); + if (chan._lvl_to_read > 0) + chan._t1_lvls[chan._lvl_to_read].children.decode_from_blk(chan._encoded_blk); break; } default: diff --git a/repos/gems/src/lib/tresor/vbd_initializer.cc b/repos/gems/src/lib/tresor/vbd_initializer.cc index 0be043a83b..cc21f8f764 100644 --- a/repos/gems/src/lib/tresor/vbd_initializer.cc +++ b/repos/gems/src/lib/tresor/vbd_initializer.cc @@ -192,6 +192,7 @@ void Vbd_initializer::_execute_inner_t1_child(Channel break; case Channel::BLOCK_ALLOC_COMPLETE: + { /* bail early in case the allocator failed */ if (!channel._generated_req_success) { _mark_req_failed(channel, progress, @@ -202,7 +203,11 @@ void Vbd_initializer::_execute_inner_t1_child(Channel Vbd_initializer_channel::reset_node(child); child.pba = channel._blk_nr; - calc_sha256_4k_hash(&child_level.children, &child.hash); + + Block blk { }; + child_level.children.encode_to_blk(blk); + calc_sha256_4k_hash(blk, child.hash); + child_state = CS::WRITE_BLOCK; progress = true; @@ -210,7 +215,7 @@ void Vbd_initializer::_execute_inner_t1_child(Channel log("[vbd_init] node: ", level_index, " ", child_index, " assign pba: ", channel._blk_nr); break; - + } default: break; } @@ -463,12 +468,11 @@ bool Vbd_initializer::_peek_generated_request(uint8_t *buf_ptr, Block_io_request::Type const block_io_req_type { Block_io_request::WRITE }; + channel._t1_levels[channel._level_to_write].children.encode_to_blk(channel._encoded_blk); construct_in_buf( buf_ptr, buf_size, VBD_INITIALIZER, id, block_io_req_type, 0, 0, 0, - channel._child_pba, 0, - 1, &channel._t1_levels[channel._level_to_write].children, - nullptr); + channel._child_pba, 0, 1, &channel._encoded_blk, nullptr); if (DEBUG) { log("BLOCK_IO_PENDING write ", channel._child_pba); diff --git a/repos/gems/src/lib/tresor/virtual_block_device.cc b/repos/gems/src/lib/tresor/virtual_block_device.cc index dacdb657bf..cb73a3cb05 100644 --- a/repos/gems/src/lib/tresor/virtual_block_device.cc +++ b/repos/gems/src/lib/tresor/virtual_block_device.cc @@ -210,7 +210,7 @@ void Virtual_block_device::_execute_read_vba_read_inner_node_completed (Channel auto &snapshot = channel.snapshots(channel._snapshot_idx); - _check_hash_of_read_type_1_node(snapshot, + _check_hash_of_read_type_1_node(channel, snapshot, channel._request._snapshots_degree, channel._t1_blk_idx, channel._t1_blks, channel._vba); @@ -351,13 +351,19 @@ void Virtual_block_device::_update_nodes_of_branch_of_written_vba(Snapshot &snap node.pba = new_pbas.pbas[lvl]; node.gen = curr_gen; - calc_sha256_4k_hash(&t1_blks.items[lvl], &node.hash); + + Block blk { }; + t1_blks.items[lvl].encode_to_blk(blk); + calc_sha256_4k_hash(blk, node.hash); } else { snapshot.pba = new_pbas.pbas[lvl]; snapshot.gen = curr_gen; - calc_sha256_4k_hash(&t1_blks.items[lvl], &snapshot.hash); + + Block blk { }; + t1_blks.items[lvl].encode_to_blk(blk); + calc_sha256_4k_hash(blk, snapshot.hash); } } } @@ -394,21 +400,22 @@ _check_that_primitive_was_successful(Channel::Generated_prim const &prim) } -void Virtual_block_device::_check_hash_of_read_type_1_node(Snapshot const &snapshot, +void Virtual_block_device::_check_hash_of_read_type_1_node(Channel &chan, + Snapshot const &snapshot, uint64_t const snapshots_degree, uint64_t const t1_blk_idx, Channel::Type_1_node_blocks const &t1_blks, uint64_t const vba) { if (t1_blk_idx == snapshot.max_level) { - if (!check_sha256_4k_hash(&t1_blks.items[t1_blk_idx], &snapshot.hash)) { + if (!check_sha256_4k_hash(chan._encoded_blk, snapshot.hash)) { class Program_error_hash_of_read_type_1 { }; throw Program_error_hash_of_read_type_1 { }; } } else { uint64_t const child_idx = t1_child_idx_for_vba(vba, t1_blk_idx + 1, snapshots_degree); Type_1_node const &child = t1_blks.items[t1_blk_idx + 1].nodes[child_idx]; - if (!check_sha256_4k_hash(&t1_blks.items[t1_blk_idx], &child.hash)) { + if (!check_sha256_4k_hash(chan._encoded_blk, child.hash)) { class Program_error_hash_of_read_type_1_B { }; throw Program_error_hash_of_read_type_1_B { }; } @@ -593,7 +600,7 @@ void Virtual_block_device::_execute_write_vba(Channel &chan, case Channel::State::READ_INNER_NODE_COMPLETED: _check_that_primitive_was_successful(chan._generated_prim); - _check_hash_of_read_type_1_node(chan.snapshots(chan._snapshot_idx), + _check_hash_of_read_type_1_node(chan, chan.snapshots(chan._snapshot_idx), chan._request._snapshots_degree, chan._t1_blk_idx, chan._t1_blks, chan._vba); @@ -965,7 +972,7 @@ void Virtual_block_device::_execute_rekey_vba(Channel &chan, Snapshot const &snap { req._snapshots.items[chan._snapshot_idx] }; if (chan._t1_blk_idx == snap.max_level) { - if (!check_sha256_4k_hash(&chan._t1_blks.items[chan._t1_blk_idx], &snap.hash)) { + if (!check_sha256_4k_hash(chan._encoded_blk, snap.hash)) { _mark_req_failed(chan, progress, "check root node hash"); break; @@ -977,8 +984,8 @@ void Virtual_block_device::_execute_rekey_vba(Channel &chan, Tree_node_index const child_idx { t1_child_idx_for_vba(req._vba, parent_lvl, req._snapshots_degree) }; - if (!check_sha256_4k_hash(&chan._t1_blks.items[chan._t1_blk_idx], - &chan._t1_blks.items[parent_lvl].nodes[child_idx].hash)) { + if (!check_sha256_4k_hash(chan._encoded_blk, + chan._t1_blks.items[parent_lvl].nodes[child_idx].hash)) { _mark_req_failed(chan, progress, "check inner node hash"); break; @@ -1090,7 +1097,7 @@ void Virtual_block_device::_execute_rekey_vba(Channel &chan, Type_1_node &node { chan._t1_blks.items[parent_lvl].nodes[child_idx] }; - if (!check_sha256_4k_hash(&chan._data_blk, &node.hash)) { + if (!check_sha256_4k_hash(chan._data_blk, node.hash)) { _mark_req_failed(chan, progress, "check leaf node hash"); break; @@ -1190,7 +1197,7 @@ void Virtual_block_device::_execute_rekey_vba(Channel &chan, Type_1_node &node { chan._t1_blks.items[parent_lvl].nodes[child_idx] }; node.pba = child_pba; - calc_sha256_4k_hash(&chan._data_blk, &node.hash); + calc_sha256_4k_hash(chan._data_blk, node.hash); if (VERBOSE_REKEYING) log(" lvl ", parent_lvl, @@ -1222,7 +1229,7 @@ void Virtual_block_device::_execute_rekey_vba(Channel &chan, Type_1_node &node { chan._t1_blks.items[parent_lvl].nodes[child_idx] }; node.pba = child_pba; - calc_sha256_4k_hash(&chan._t1_blks.items[child_lvl], &node.hash); + calc_sha256_4k_hash(chan._encoded_blk, node.hash); if (VERBOSE_REKEYING) log(" lvl ", parent_lvl, @@ -1254,7 +1261,7 @@ void Virtual_block_device::_execute_rekey_vba(Channel &chan, Physical_block_address const child_pba { chan._new_pbas.pbas[child_lvl] }; snap.pba = child_pba; - calc_sha256_4k_hash(&chan._t1_blks.items[child_lvl], &snap.hash); + calc_sha256_4k_hash(chan._encoded_blk, snap.hash); if (VERBOSE_REKEYING) log(" lvl ", (Tree_level_index)snap.max_level + 1, @@ -1604,7 +1611,7 @@ void Virtual_block_device::_execute_vbd_extension_step(Channel &chan, if (chan._t1_blk_idx == chan.snap().max_level) { - if (!check_sha256_4k_hash(&chan._t1_blks.items[chan._t1_blk_idx], &chan.snap().hash)) { + if (!check_sha256_4k_hash(chan._encoded_blk, chan.snap().hash)) { _mark_req_failed(chan, progress, "check root node hash"); break; @@ -1616,8 +1623,8 @@ void Virtual_block_device::_execute_vbd_extension_step(Channel &chan, Tree_node_index const child_idx { t1_child_idx_for_vba(chan._vba, parent_lvl, req._snapshots_degree) }; - if (!check_sha256_4k_hash(&chan._t1_blks.items[chan._t1_blk_idx], - &chan._t1_blks.items[parent_lvl].nodes[child_idx].hash)) { + if (!check_sha256_4k_hash(chan._encoded_blk, + chan._t1_blks.items[parent_lvl].nodes[child_idx].hash)) { _mark_req_failed(chan, progress, "check inner node hash"); break; @@ -1712,7 +1719,7 @@ void Virtual_block_device::_execute_vbd_extension_step(Channel &chan, Physical_block_address const parent_pba { chan._new_pbas.pbas[parent_lvl] }; Type_1_node &child { chan._t1_blks.items[parent_lvl].nodes[child_idx] }; - calc_sha256_4k_hash(&chan._t1_blks.items[child_lvl], &child.hash); + calc_sha256_4k_hash(chan._encoded_blk, child.hash); child.pba = child_pba; if (VERBOSE_VBD_EXTENSION) { @@ -1760,7 +1767,7 @@ void Virtual_block_device::_execute_vbd_extension_step(Channel &chan, old_snap.nr_of_leaves + req._nr_of_leaves, old_snap.max_level, true, 0, false }; - calc_sha256_4k_hash(&chan._t1_blks.items[child_lvl], &new_snap.hash); + calc_sha256_4k_hash(chan._encoded_blk, new_snap.hash); if (VERBOSE_VBD_EXTENSION) log(" update snap ", chan._snapshot_idx, " ", new_snap); @@ -1816,11 +1823,12 @@ bool Virtual_block_device::_peek_generated_request(uint8_t *buf_ptr, case Channel::WRITE_ROOT_NODE_PENDING: case Channel::WRITE_INNER_NODE_PENDING: + chan._t1_blks.items[chan._t1_blk_idx].encode_to_blk(chan._encoded_blk); construct_in_buf( buf_ptr, buf_size, VIRTUAL_BLOCK_DEVICE, id, Block_io_request::WRITE, 0, 0, 0, chan._generated_prim.blk_nr, 0, 1, - &chan._t1_blks.items[chan._t1_blk_idx], nullptr); + &chan._encoded_blk, nullptr); return true; @@ -1852,7 +1860,7 @@ bool Virtual_block_device::_peek_generated_request(uint8_t *buf_ptr, buf_ptr, buf_size, VIRTUAL_BLOCK_DEVICE, id, Block_io_request::READ, 0, 0, 0, chan._generated_prim.blk_nr, 0, 1, - &chan._t1_blks.items[chan._t1_blk_idx], nullptr); + &chan._encoded_blk, nullptr); return true; @@ -1991,8 +1999,14 @@ void Virtual_block_device::generated_request_complete(Module_request &mod_req) Block_io_request &blk_io_req { *static_cast(&mod_req) }; chan._generated_prim.succ = blk_io_req.success(); switch (chan._state) { - case Channel::READ_ROOT_NODE_IN_PROGRESS: chan._state = Channel::READ_ROOT_NODE_COMPLETED; break; - case Channel::READ_INNER_NODE_IN_PROGRESS: chan._state = Channel::READ_INNER_NODE_COMPLETED; break; + case Channel::READ_ROOT_NODE_IN_PROGRESS: + chan._t1_blks.items[chan._t1_blk_idx].decode_from_blk(chan._encoded_blk); + chan._state = Channel::READ_ROOT_NODE_COMPLETED; + break; + case Channel::READ_INNER_NODE_IN_PROGRESS: + chan._t1_blks.items[chan._t1_blk_idx].decode_from_blk(chan._encoded_blk); + chan._state = Channel::READ_INNER_NODE_COMPLETED; + break; case Channel::WRITE_ROOT_NODE_IN_PROGRESS: chan._state = Channel::WRITE_ROOT_NODE_COMPLETED; break; case Channel::WRITE_INNER_NODE_IN_PROGRESS: chan._state = Channel::WRITE_INNER_NODE_COMPLETED; break; case Channel::READ_LEAF_NODE_IN_PROGRESS: chan._state = Channel::READ_LEAF_NODE_COMPLETED; break;