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:
Martin Stein 2023-06-09 13:50:34 +02:00 committed by Norman Feske
parent 434a4db637
commit abe163c335
31 changed files with 701 additions and 318 deletions

View File

@ -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):

View File

@ -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"]]

View File

@ -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>

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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:

View File

@ -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);

View File

@ -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:

View 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_ */

View File

@ -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 };
};

View File

@ -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 { };
};

View File

@ -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)
{

View File

@ -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

View File

@ -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);

View File

@ -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 { };
};

View File

@ -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));

View File

@ -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_ */

View File

@ -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; }

View File

@ -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_ */

View File

@ -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 { };
};

View File

@ -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)
{

View File

@ -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,

View File

@ -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;

View File

@ -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 { };

View File

@ -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;

View File

@ -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 { };
}

View File

@ -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;

View File

@ -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:

View File

@ -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);

View File

@ -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;