mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-10 21:01:49 +00:00
tresor: do not use on-disc-layouted structs
* Removes all previous structs that represented an on-disc block layout and were therfore subject to a number of layout restrictions (packed, padding members, enum representations, etc.). * Adds a replacement struct without any layout restrictions for each of the removed structs. The new structs are named similar to the old structs. * Adds block encoding and decoding utilities for easily converting from the new structs to on-disc blocks and vice-versa (Block_scanner, Block_generator, T::decode_to_blk, T::encode_from_blk) * Adapts all affected places in the library to encode and decode proberly instead of simply casting pointers. * Thereby cleans up the hashing utilities to use typed-reference args instead of void pointers. * Re-enables run/tresor_tester and test-file_vault_vonfig_report for platforms rpi, imx53_qsb, imx53_qsb_tz, imx6q_sabrelite, imx7d_sabre. Ref #4819
This commit is contained in:
parent
434a4db637
commit
abe163c335
@ -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):
|
||||
|
@ -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"]]
|
||||
|
@ -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 {
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="IO_PORT"> <parent/> </service>
|
||||
<service name="IO_MEM"> <parent/> </service>
|
||||
<service name="IRQ"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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<Block_io_request*>(&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:
|
||||
|
@ -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<Block_io_request>(
|
||||
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);
|
||||
|
@ -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<Block_io_request>(
|
||||
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<Block_io_request>(
|
||||
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<Block_io_request *>(&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:
|
||||
|
35
repos/gems/src/lib/tresor/include/tresor/assertion.h
Normal file
35
repos/gems/src/lib/tresor/include/tresor/assertion.h
Normal file
@ -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 <base/log.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
#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_ */
|
@ -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 };
|
||||
};
|
||||
|
||||
|
@ -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 { };
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 { };
|
||||
};
|
||||
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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_ */
|
||||
|
@ -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; }
|
||||
|
@ -22,6 +22,7 @@
|
||||
/* tresor includes */
|
||||
#include <tresor/verbosity.h>
|
||||
#include <tresor/math.h>
|
||||
#include <tresor/assertion.h>
|
||||
|
||||
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<typename T>
|
||||
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<typename T>
|
||||
void fetch(T &dst);
|
||||
|
||||
template<typename T>
|
||||
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>(bool &dst) { dst = _decode_bool(fetch_value<On_disc_bool>()); }
|
||||
template <> inline void Tresor::Block_scanner::fetch<Genode::uint8_t>(uint8_t &dst) { _fetch_copy(dst); }
|
||||
template <> inline void Tresor::Block_scanner::fetch<Genode::uint16_t>(uint16_t &dst) { _fetch_copy(dst); }
|
||||
template <> inline void Tresor::Block_scanner::fetch<Genode::uint32_t>(uint32_t &dst) { _fetch_copy(dst); }
|
||||
template <> inline void Tresor::Block_scanner::fetch<Genode::uint64_t>(uint64_t &dst) { _fetch_copy(dst); }
|
||||
template <> inline void Tresor::Block_scanner::fetch<Tresor::Hash>(Hash &dst) { _fetch_copy(dst); }
|
||||
template <> inline void Tresor::Block_scanner::fetch<Tresor::Key_value>(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<typename T>
|
||||
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<typename T>
|
||||
void append(T const &src);
|
||||
|
||||
template<typename T>
|
||||
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>(bool const &src) { append_value(_encode_bool(src)); }
|
||||
template <> inline void Tresor::Block_generator::append<Genode::uint8_t>(uint8_t const &src) { _append_copy(src); }
|
||||
template <> inline void Tresor::Block_generator::append<Genode::uint16_t>(uint16_t const &src) { _append_copy(src); }
|
||||
template <> inline void Tresor::Block_generator::append<Genode::uint32_t>(uint32_t const &src) { _append_copy(src); }
|
||||
template <> inline void Tresor::Block_generator::append<Genode::uint64_t>(uint64_t const &src) { _append_copy(src); }
|
||||
template <> inline void Tresor::Block_generator::append<Tresor::Hash>(Hash const &src) { _append_copy(src); }
|
||||
template <> inline void Tresor::Block_generator::append<Tresor::Key_value>(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<On_disc_state>());
|
||||
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_ */
|
||||
|
@ -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 { };
|
||||
};
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -110,7 +110,7 @@ bool Meta_tree::_peek_generated_request(uint8_t *buf_ptr,
|
||||
construct_in_buf<Block_io_request>(
|
||||
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;
|
||||
|
@ -325,7 +325,7 @@ bool Sb_check::_peek_generated_request(uint8_t *buf_ptr,
|
||||
construct_in_buf<Block_io_request>(
|
||||
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<Block_io_request*>(&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 { };
|
||||
|
@ -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<Block_io_request>(
|
||||
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;
|
||||
|
@ -11,41 +11,39 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* tresor includes */
|
||||
#include <tresor/sha256_4k_hash.h>
|
||||
#include <tresor/types.h>
|
||||
|
||||
/* base includes */
|
||||
#include <util/string.h>
|
||||
|
||||
/* libcrypto */
|
||||
#include <openssl/sha.h>
|
||||
|
||||
/* tresor includes */
|
||||
#include <tresor/sha256_4k_hash.h>
|
||||
|
||||
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<unsigned char *>(hash_ptr), &context)) {
|
||||
if (!SHA256_Final((unsigned char *)(&hash), &context)) {
|
||||
class Calc_sha256_4k_hash_final_error { };
|
||||
throw Calc_sha256_4k_hash_final_error { };
|
||||
}
|
||||
|
@ -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<Block_io_request>(
|
||||
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<Block_io_request>(
|
||||
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<Block_io_request*>(&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;
|
||||
|
@ -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<Block_io_request*>(&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:
|
||||
|
@ -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<Block_io_request>(
|
||||
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);
|
||||
|
@ -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<Block_io_request>(
|
||||
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<Block_io_request *>(&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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user