diff --git a/repos/gems/src/app/tresor_check/main.cc b/repos/gems/src/app/tresor_check/main.cc index 523833162d..3b51f132b7 100644 --- a/repos/gems/src/app/tresor_check/main.cc +++ b/repos/gems/src/app/tresor_check/main.cc @@ -43,18 +43,25 @@ class Tresor_check::Main : private Vfs::Env::User Vfs::Simple_env _vfs_env { _env, _heap, _config_rom.xml().sub_node("vfs"), *this }; Signal_handler
_sigh { _env.ep(), *this, &Main::_handle_signal }; Tresor::Path const _block_io_path { _config_rom.xml().sub_node("block-io").attribute_value("path", Tresor::Path()) }; + Tresor::Path const _trust_anchor_path { _config_rom.xml().sub_node("trust-anchor").attribute_value("path", Tresor::Path()) }; Vfs::Vfs_handle &_block_io_file { open_file(_vfs_env, _block_io_path, Vfs::Directory_service::OPEN_MODE_RDWR) }; + Vfs::Vfs_handle &_ta_decrypt_file { open_file(_vfs_env, { _trust_anchor_path, "/decrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR) }; + Vfs::Vfs_handle &_ta_encrypt_file { open_file(_vfs_env, { _trust_anchor_path, "/encrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR) }; + Vfs::Vfs_handle &_ta_generate_key_file { open_file(_vfs_env, { _trust_anchor_path, "/generate_key" }, Vfs::Directory_service::OPEN_MODE_RDWR) }; + Vfs::Vfs_handle &_ta_initialize_file { open_file(_vfs_env, { _trust_anchor_path, "/initialize" }, Vfs::Directory_service::OPEN_MODE_RDWR) }; + Vfs::Vfs_handle &_ta_hash_file { open_file(_vfs_env, { _trust_anchor_path, "/hash" }, Vfs::Directory_service::OPEN_MODE_RDWR) }; Block_io _block_io { _block_io_file }; Vbd_check _vbd_check { }; Ft_check _ft_check { }; Sb_check _sb_check { }; + Trust_anchor _trust_anchor { { _ta_decrypt_file, _ta_encrypt_file, _ta_generate_key_file, _ta_initialize_file, _ta_hash_file } }; Sb_check::Check _check_superblocks { }; void _wakeup_back_end_services() { _vfs_env.io().commit(); } void _handle_signal() { - while(_sb_check.execute(_check_superblocks, _vbd_check, _ft_check, _block_io)); + while(_sb_check.execute(_check_superblocks, _vbd_check, _ft_check, _block_io, _trust_anchor)); if (_check_superblocks.complete()) _env.parent().exit(_check_superblocks.success() ? 0 : -1); _wakeup_back_end_services(); diff --git a/repos/gems/src/app/tresor_tester/main.cc b/repos/gems/src/app/tresor_tester/main.cc index c63cc0d484..b7190ee6b1 100644 --- a/repos/gems/src/app/tresor_tester/main.cc +++ b/repos/gems/src/app/tresor_tester/main.cc @@ -868,7 +868,7 @@ class Tresor_tester::Main : Vfs::Env::User, Client_data_interface, Crypto_key_fi case Command::IN_PROGRESS: { Sb_check::Check &req = *cmd.check_superblocks_ptr; - progress |= _sb_check.execute(req, _vbd_check, _ft_check, _block_io); + progress |= _sb_check.execute(req, _vbd_check, _ft_check, _block_io, _trust_anchor); _try_complete_command(cmd, req, progress); break; } diff --git a/repos/gems/src/lib/tresor/include/tresor/sb_check.h b/repos/gems/src/lib/tresor/include/tresor/sb_check.h index 1cace44139..672e68c1e4 100644 --- a/repos/gems/src/lib/tresor/include/tresor/sb_check.h +++ b/repos/gems/src/lib/tresor/include/tresor/sb_check.h @@ -19,6 +19,7 @@ #include #include #include +#include namespace Tresor { class Sb_check; } @@ -34,23 +35,25 @@ struct Tresor::Sb_check : Noncopyable enum State { INIT, COMPLETE, READ_BLK, READ_BLK_SUCCEEDED, CHECK_VBD, CHECK_VBD_SUCCEEDED, CHECK_FT, CHECK_FT_SUCCEEDED, - CHECK_MT, CHECK_MT_SUCCEEDED}; + CHECK_MT, CHECK_MT_SUCCEEDED, READ_SB_HASH, READ_SB_HASH_SUCCEEDED }; using Helper = Request_helper; Helper _helper; - Generation _highest_gen { 0 }; - Superblock_index _highest_gen_sb_idx { 0 }; + Hash _hash { }; bool _scan_for_highest_gen_sb_done { false }; - Superblock_index _sb_idx { 0 }; + Superblock_index _sb_idx { }; Superblock _sb { }; Snapshot_index _snap_idx { 0 }; Constructible _tree_root { }; Block _blk { }; + Generatable_request _read_sb_hash { }; Generatable_request _check_vbd { }; Generatable_request _check_ft { }; Generatable_request _read_block { }; + void _check_snap(bool &); + public: Check() : _helper(*this) { } @@ -59,7 +62,7 @@ struct Tresor::Sb_check : Noncopyable void print(Output &out) const { Genode::print(out, "check"); } - bool execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io); + bool execute(Vbd_check &, Ft_check &, Block_io &, Trust_anchor &); bool complete() const { return _helper.complete(); } bool success() const { return _helper.success(); } @@ -67,7 +70,7 @@ struct Tresor::Sb_check : Noncopyable Sb_check() { } - bool execute(Check &check, Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io) { return check.execute(vbd_check, ft_check, block_io); }; + bool execute(Check &check, Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io, Trust_anchor &trust_anchor) { return check.execute(vbd_check, ft_check, block_io, trust_anchor); }; static constexpr char const *name() { return "sb_check"; } }; diff --git a/repos/gems/src/lib/tresor/sb_check.cc b/repos/gems/src/lib/tresor/sb_check.cc index 310d9e3fbc..4b3dbe9f52 100644 --- a/repos/gems/src/lib/tresor/sb_check.cc +++ b/repos/gems/src/lib/tresor/sb_check.cc @@ -13,62 +13,62 @@ /* tresor includes */ #include +#include using namespace Tresor; -bool Sb_check::Check::execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io) +void Sb_check::Check::_check_snap(bool &progress) +{ + Snapshot &snap { _sb.snapshots.items[_snap_idx] }; + if (!snap.valid) { + _helper.state = CHECK_VBD_SUCCEEDED; + progress = true; + if (VERBOSE_CHECK) + log(" skip snap ", _snap_idx, " as it is unused"); + return; + } + _tree_root.construct(snap.pba, snap.gen, snap.hash, snap.max_level, _sb.degree, snap.nr_of_leaves); + _check_vbd.generate(_helper, CHECK_VBD, CHECK_VBD_SUCCEEDED, progress, *_tree_root); + if (VERBOSE_CHECK) + log(" check snap ", _snap_idx, " (", snap, ")"); +} + + +bool Sb_check::Check::execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io, Trust_anchor &trust_anchor) { bool progress = false; switch (_helper.state) { case INIT: - _highest_gen = 0; - _highest_gen_sb_idx = 0; - _snap_idx = 0; - _sb_idx = 0; - _scan_for_highest_gen_sb_done = false; + _read_sb_hash.generate(_helper, READ_SB_HASH, READ_SB_HASH_SUCCEEDED, progress, _hash); + break; + + case READ_SB_HASH: progress |= _read_sb_hash.execute(trust_anchor); break; + case READ_SB_HASH_SUCCEEDED: + _read_block.generate(_helper, READ_BLK, READ_BLK_SUCCEEDED, progress, _sb_idx, _blk); break; case READ_BLK: progress |= _read_block.execute(block_io); break; case READ_BLK_SUCCEEDED: - _sb.decode_from_blk(_blk); - if (_scan_for_highest_gen_sb_done) { + if (check_hash(_blk, _hash)) { + _sb.decode_from_blk(_blk); + if (VERBOSE_CHECK) + log("check superblock ", _sb_idx, " hash ", _hash, "\n read superblock"); + if (!_sb.valid()) { - _helper.mark_failed(progress, "no valid superblock");; + _helper.mark_failed(progress, "superblock marked invalid");; break; } - Snapshot &snap { _sb.snapshots.items[_snap_idx] }; - if (snap.valid) { - Snapshot &snap { _sb.snapshots.items[_snap_idx] }; - _tree_root.construct(snap.pba, snap.gen, snap.hash, snap.max_level, _sb.degree, snap.nr_of_leaves); - _check_vbd.generate(_helper, CHECK_VBD, CHECK_VBD_SUCCEEDED, progress, *_tree_root); - if (VERBOSE_CHECK) - log(" check snap ", _snap_idx, " (", snap, ")"); - } else { - _helper.state = CHECK_VBD_SUCCEEDED; - progress = true; - if (VERBOSE_CHECK) - log(" skip snap ", _snap_idx, " as it is unused"); - } - } else { - Snapshot &snap { _sb.curr_snap() }; - if (_sb.valid() && snap.gen > _highest_gen) { - _highest_gen = snap.gen; - _highest_gen_sb_idx = _sb_idx; - } + _snap_idx = 0; + _check_snap(progress); + } else if (_sb_idx < MAX_SUPERBLOCK_INDEX) { _sb_idx++; _read_block.generate(_helper, READ_BLK, READ_BLK_SUCCEEDED, progress, _sb_idx, _blk); - progress = true; - } else { - _scan_for_highest_gen_sb_done = true; - _read_block.generate(_helper, READ_BLK, READ_BLK_SUCCEEDED, progress, _highest_gen_sb_idx, _blk); - if (VERBOSE_CHECK) - log("check superblock ", _highest_gen_sb_idx, "\n read superblock"); - } - } + } else + _helper.mark_failed(progress, "superblock not found"); break; case CHECK_VBD: progress |= _check_vbd.execute(vbd_check, block_io); break; @@ -76,10 +76,8 @@ bool Sb_check::Check::execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io if (_snap_idx < MAX_SNAP_IDX) { _snap_idx++; - _helper.state = READ_BLK_SUCCEEDED; - progress = true; + _check_snap(progress); } else { - _snap_idx = 0; _tree_root.construct(_sb.free_number, _sb.free_gen, _sb.free_hash, _sb.free_max_level, _sb.free_degree, _sb.free_leaves); _check_ft.generate(_helper, CHECK_FT, CHECK_FT_SUCCEEDED, progress, *_tree_root); if (VERBOSE_CHECK)