mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-21 16:39:39 +00:00
gems: import Genode-specific code of the CBE
The CBE repository contained a lot of Genode-specific code despite the fact that the CBE core logic is not bound to Genode in any way. Therefore the Genode-specific CBE code is moved to the 'gems' repository to form part of Genode mainline. The remaining CBE code becomes a port in Genode instead of being invoked as sub-repository. The commit combines the following work steps: * add all files removed from CBE repository * add CBE port files * make all CBE libs and targets build again * make all CBE run scripts succeed again * make all CBE recipes build again * make CBE autopilot succeed again * let CBE autopilot use 'libsparcrypto' contrib dir and Genode build dir instead of '.ci' dir in CBE contrib dir (remove '.ci' dir from CBE repo) * let CBE autopilot always check for all ports * make CBE autopilot directly executable * fix license headers in all Genode CBE files * remove unused VFS replay component * remove unused CBE test * remove unused external crypto * remove unused files in run dir * remove unused external trust anchor * add cbe_tester test to autopilot list * get rid of directories 'include/cbe_*' and 'include/utils' Fixes #3937
This commit is contained in:
committed by
Christian Helmuth
parent
24181f2bf6
commit
30b8f4efc8
17
repos/gems/src/lib/vfs/cbe/dummy.ads
Normal file
17
repos/gems/src/lib/vfs/cbe/dummy.ads
Normal file
@ -0,0 +1,17 @@
|
||||
--
|
||||
-- \brief Integration of the Consistent Block Encrypter (CBE)
|
||||
-- \author Martin Stein
|
||||
-- \author Josef Soentgen
|
||||
-- \date 2020-11-10
|
||||
--
|
||||
|
||||
--
|
||||
-- Copyright (C) 2020 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.
|
||||
--
|
||||
|
||||
package Dummy
|
||||
is
|
||||
end Dummy;
|
297
repos/gems/src/lib/vfs/cbe/io_job.h
Normal file
297
repos/gems/src/lib/vfs/cbe/io_job.h
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* \brief Integration of the Consistent Block Encrypter (CBE)
|
||||
* \author Martin Stein
|
||||
* \author Josef Soentgen
|
||||
* \date 2020-11-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 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 _CBE_VFS__IO_JOB_
|
||||
#define _CBE_VFS__IO_JOB_
|
||||
|
||||
namespace Vfs_cbe {
|
||||
|
||||
using file_size = Vfs::file_size;
|
||||
using file_offset = Vfs::file_offset;
|
||||
|
||||
struct Io_job
|
||||
{
|
||||
struct Unsupported_Operation : Genode::Exception { };
|
||||
struct Invalid_state : Genode::Exception { };
|
||||
|
||||
enum State { PENDING, IN_PROGRESS, COMPLETE, };
|
||||
|
||||
static State _initial_state(Cbe::Request::Operation const op)
|
||||
{
|
||||
using Op = Cbe::Request::Operation;
|
||||
|
||||
switch (op) {
|
||||
case Op::READ: return State::PENDING;
|
||||
case Op::WRITE: return State::PENDING;
|
||||
case Op::SYNC: return State::PENDING;
|
||||
default: throw Unsupported_Operation();
|
||||
}
|
||||
}
|
||||
|
||||
static char const *_state_to_string(State s)
|
||||
{
|
||||
switch (s) {
|
||||
case State::PENDING: return "PENDING";
|
||||
case State::IN_PROGRESS: return "IN_PROGRESS";
|
||||
case State::COMPLETE: return "COMPLETE";
|
||||
}
|
||||
|
||||
throw Invalid_state();
|
||||
}
|
||||
|
||||
Vfs::Vfs_handle &_handle;
|
||||
|
||||
Cbe::Request::Operation const _op;
|
||||
Cbe::Io_buffer::Index const _index;
|
||||
State _state;
|
||||
file_offset const _base_offset;
|
||||
file_offset _current_offset;
|
||||
file_size _current_count;
|
||||
|
||||
bool _success;
|
||||
bool _complete;
|
||||
|
||||
bool _read(Cbe::Library &cbe, Cbe::Io_buffer &io_data)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
switch (_state) {
|
||||
case State::PENDING:
|
||||
|
||||
_handle.seek(_base_offset + _current_offset);
|
||||
if (!_handle.fs().queue_read(&_handle, _current_count)) {
|
||||
return progress;
|
||||
}
|
||||
|
||||
cbe.io_request_in_progress(_index);
|
||||
|
||||
_state = State::IN_PROGRESS;
|
||||
progress = true;
|
||||
[[fallthrough]];
|
||||
case State::IN_PROGRESS:
|
||||
{
|
||||
using Result = Vfs::File_io_service::Read_result;
|
||||
|
||||
bool completed = false;
|
||||
file_size out = 0;
|
||||
|
||||
char * const data = reinterpret_cast<char *const>(&io_data.item(_index));
|
||||
|
||||
Result const result =
|
||||
_handle.fs().complete_read(&_handle,
|
||||
data + _current_offset,
|
||||
_current_count, out);
|
||||
if ( result == Result::READ_QUEUED
|
||||
|| result == Result::READ_ERR_INTERRUPT
|
||||
|| result == Result::READ_ERR_AGAIN
|
||||
|| result == Result::READ_ERR_WOULD_BLOCK) {
|
||||
return progress;
|
||||
} else
|
||||
|
||||
if (result == Result::READ_OK) {
|
||||
_current_offset += out;
|
||||
_current_count -= out;
|
||||
_success = true;
|
||||
} else
|
||||
|
||||
if ( result == Result::READ_ERR_IO
|
||||
|| result == Result::READ_ERR_INVALID) {
|
||||
_success = false;
|
||||
completed = true;
|
||||
}
|
||||
|
||||
if (_current_count == 0 || completed) {
|
||||
_state = State::COMPLETE;
|
||||
} else {
|
||||
_state = State::PENDING;
|
||||
/* partial read, keep trying */
|
||||
return true;
|
||||
}
|
||||
progress = true;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case State::COMPLETE:
|
||||
|
||||
cbe.io_request_completed(_index, _success);
|
||||
_complete = true;
|
||||
progress = true;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
bool _write(Cbe::Library &cbe, Cbe::Io_buffer &io_data)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
switch (_state) {
|
||||
case State::PENDING:
|
||||
|
||||
_handle.seek(_base_offset + _current_offset);
|
||||
|
||||
cbe.io_request_in_progress(_index);
|
||||
_state = State::IN_PROGRESS;
|
||||
progress = true;
|
||||
[[fallthrough]];
|
||||
case State::IN_PROGRESS:
|
||||
{
|
||||
using Result = Vfs::File_io_service::Write_result;
|
||||
|
||||
bool completed = false;
|
||||
file_size out = 0;
|
||||
|
||||
Result result = Result::WRITE_ERR_INVALID;
|
||||
try {
|
||||
char const * const data =
|
||||
reinterpret_cast<char const * const>(&io_data.item(_index));
|
||||
result = _handle.fs().write(&_handle,
|
||||
data + _current_offset,
|
||||
_current_count, out);
|
||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
||||
return progress;
|
||||
}
|
||||
|
||||
if ( result == Result::WRITE_ERR_AGAIN
|
||||
|| result == Result::WRITE_ERR_INTERRUPT
|
||||
|| result == Result::WRITE_ERR_WOULD_BLOCK) {
|
||||
return progress;
|
||||
} else
|
||||
|
||||
if (result == Result::WRITE_OK) {
|
||||
_current_offset += out;
|
||||
_current_count -= out;
|
||||
_success = true;
|
||||
} else
|
||||
|
||||
if ( result == Result::WRITE_ERR_IO
|
||||
|| result == Result::WRITE_ERR_INVALID) {
|
||||
_success = false;
|
||||
completed = true;
|
||||
}
|
||||
|
||||
if (_current_count == 0 || completed) {
|
||||
_state = State::COMPLETE;
|
||||
} else {
|
||||
_state = State::PENDING;
|
||||
/* partial write, keep trying */
|
||||
return true;
|
||||
}
|
||||
progress = true;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case State::COMPLETE:
|
||||
|
||||
cbe.io_request_completed(_index, _success);
|
||||
_complete = true;
|
||||
progress = true;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
bool _sync(Cbe::Library &cbe, Cbe::Io_buffer &io_data)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
switch (_state) {
|
||||
case State::PENDING:
|
||||
|
||||
if (!_handle.fs().queue_sync(&_handle)) {
|
||||
return progress;
|
||||
}
|
||||
cbe.io_request_in_progress(_index);
|
||||
_state = State::IN_PROGRESS;
|
||||
progress = true;
|
||||
[[fallthrough]];
|
||||
case State::IN_PROGRESS:
|
||||
{
|
||||
using Result = Vfs::File_io_service::Sync_result;
|
||||
Result const result = _handle.fs().complete_sync(&_handle);
|
||||
|
||||
if (result == Result::SYNC_QUEUED) {
|
||||
return progress;
|
||||
} else
|
||||
|
||||
if (result == Result::SYNC_ERR_INVALID) {
|
||||
_success = false;
|
||||
} else
|
||||
|
||||
if (result == Result::SYNC_OK) {
|
||||
_success = true;
|
||||
}
|
||||
|
||||
_state = State::COMPLETE;
|
||||
progress = true;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case State::COMPLETE:
|
||||
|
||||
cbe.io_request_completed(_index, _success);
|
||||
_complete = true;
|
||||
progress = true;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
Io_job(Vfs::Vfs_handle &handle,
|
||||
Cbe::Request::Operation op,
|
||||
Cbe::Io_buffer::Index index,
|
||||
file_offset base_offset,
|
||||
file_size length)
|
||||
:
|
||||
_handle { handle },
|
||||
_op { op },
|
||||
_index { index },
|
||||
_state { _initial_state(op) },
|
||||
_base_offset { base_offset },
|
||||
_current_offset { 0 },
|
||||
_current_count { length },
|
||||
_success { false },
|
||||
_complete { false }
|
||||
{ }
|
||||
|
||||
bool completed() const { return _complete; }
|
||||
bool succeeded() const { return _success; }
|
||||
|
||||
void print(Genode::Output &out) const
|
||||
{
|
||||
Genode::print(out, "(", to_string(_op), ")",
|
||||
" state: ", _state_to_string(_state),
|
||||
" base_offset: ", _base_offset,
|
||||
" current_offset: ", _current_offset,
|
||||
" current_count: ", _current_count,
|
||||
" success: ", _success,
|
||||
" complete: ", _complete);
|
||||
}
|
||||
|
||||
bool execute(Cbe::Library &cbe, Cbe::Io_buffer &io_data)
|
||||
{
|
||||
using Op = Cbe::Request::Operation;
|
||||
|
||||
switch (_op) {
|
||||
case Op::READ: return _read(cbe, io_data);
|
||||
case Op::WRITE: return _write(cbe, io_data);
|
||||
case Op::SYNC: return _sync(cbe, io_data);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace Vfs_cbe */
|
||||
|
||||
#endif /* _CBE_VFS__IO_JOB_ */
|
3
repos/gems/src/lib/vfs/cbe/target.mk
Normal file
3
repos/gems/src/lib/vfs/cbe/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET := lib-vfs-cbe
|
||||
REQUIRES = x86_64
|
||||
LIBS = vfs_cbe
|
3119
repos/gems/src/lib/vfs/cbe/vfs.cc
Normal file
3119
repos/gems/src/lib/vfs/cbe/vfs.cc
Normal file
File diff suppressed because it is too large
Load Diff
284
repos/gems/src/lib/vfs/cbe_crypto/aes_cbc/aes_cbc.cc
Normal file
284
repos/gems/src/lib/vfs/cbe_crypto/aes_cbc/aes_cbc.cc
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* \brief Integration of the Consistent Block Encrypter (CBE)
|
||||
* \author Martin Stein
|
||||
* \author Josef Soentgen
|
||||
* \date 2020-11-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <util/string.h>
|
||||
|
||||
#include <aes_cbc_4k/aes_cbc_4k.h>
|
||||
|
||||
#include <cbe/types.h>
|
||||
#include <cbe/crypto/interface.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Crypto : Cbe_crypto::Interface
|
||||
{
|
||||
struct Buffer_size_mismatch : Genode::Exception { };
|
||||
struct Key_value_size_mismatch : Genode::Exception { };
|
||||
|
||||
struct {
|
||||
uint32_t id { };
|
||||
Aes_cbc_4k::Key key { };
|
||||
bool used { false };
|
||||
} keys [Slots::NUM_SLOTS];
|
||||
|
||||
struct {
|
||||
struct crypt_ring {
|
||||
unsigned head { 0 };
|
||||
unsigned tail { 0 };
|
||||
|
||||
struct {
|
||||
Cbe::Request request { };
|
||||
Cbe::Block_data data { };
|
||||
} queue [4];
|
||||
|
||||
unsigned max() const {
|
||||
return sizeof(queue) / sizeof(queue[0]); }
|
||||
|
||||
bool acceptable() const {
|
||||
return ((head + 1) % max() != tail); }
|
||||
|
||||
template <typename FUNC>
|
||||
bool enqueue(FUNC const &fn)
|
||||
{
|
||||
if (!acceptable())
|
||||
return false;
|
||||
|
||||
fn(queue[head]);
|
||||
head = (head + 1) % max();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename FUNC>
|
||||
bool apply_crypt(FUNC const &fn)
|
||||
{
|
||||
if (head == tail)
|
||||
return false;
|
||||
|
||||
if (!fn(queue[tail]))
|
||||
return false;
|
||||
|
||||
tail = (tail + 1) % max();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct crypt_ring encrypt;
|
||||
struct crypt_ring decrypt;
|
||||
|
||||
template <typename FUNC>
|
||||
bool queue_encrypt(FUNC const &fn) { return encrypt.enqueue(fn); }
|
||||
|
||||
template <typename FUNC>
|
||||
bool apply_encrypt(FUNC const &fn) { return encrypt.apply_crypt(fn); }
|
||||
|
||||
template <typename FUNC>
|
||||
bool queue_decrypt(FUNC const &fn) { return decrypt.enqueue(fn); }
|
||||
|
||||
template <typename FUNC>
|
||||
bool apply_decrypt(FUNC const &fn) { return decrypt.apply_crypt(fn); }
|
||||
} jobs { };
|
||||
|
||||
template <typename FUNC>
|
||||
bool apply_to_unused_key(FUNC const &fn)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
|
||||
if (keys[i].used) continue;
|
||||
|
||||
return fn(keys[i]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename FUNC>
|
||||
bool apply_key(uint32_t const id, FUNC const &fn)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
|
||||
if (!keys[i].used || id != keys[i].id) continue;
|
||||
|
||||
return fn(keys[i]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Crypto() { }
|
||||
|
||||
/***************
|
||||
** interface **
|
||||
***************/
|
||||
|
||||
bool execute() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool add_key(uint32_t const id,
|
||||
char const * const value,
|
||||
size_t value_len) override
|
||||
{
|
||||
return apply_to_unused_key([&](auto &key_slot) {
|
||||
if (value_len != sizeof(key_slot.key))
|
||||
return false;
|
||||
|
||||
if (!_slots.store(id))
|
||||
return false;
|
||||
|
||||
Genode::memcpy(key_slot.key.values, value, sizeof(key_slot.key));
|
||||
key_slot.id = id;
|
||||
key_slot.used = true;
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool remove_key(uint32_t const id) override
|
||||
{
|
||||
return apply_key (id, [&] (auto &meta) {
|
||||
Genode::memset(meta.key.values, 0, sizeof(meta.key.values));
|
||||
|
||||
meta.used = false;
|
||||
|
||||
_slots.remove(id);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool submit_encryption_request(uint64_t const block_number,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) override
|
||||
{
|
||||
if (!src || src_len != sizeof (Cbe::Block_data)) {
|
||||
error("buffer has wrong size");
|
||||
throw Buffer_size_mismatch();
|
||||
}
|
||||
|
||||
if (!jobs.encrypt.acceptable())
|
||||
return false;
|
||||
|
||||
return apply_key (key_id, [&] (auto &meta) {
|
||||
return jobs.queue_encrypt([&] (auto &job) {
|
||||
job.request = Cbe::Request(Cbe::Request::Operation::WRITE,
|
||||
false, block_number, 0, 1, key_id, 0);
|
||||
|
||||
uint64_t block_id = job.request.block_number();
|
||||
|
||||
Aes_cbc_4k::Block_number block_number { block_id };
|
||||
Aes_cbc_4k::Plaintext const &plaintext = *reinterpret_cast<Aes_cbc_4k::Plaintext const *>(src);
|
||||
Aes_cbc_4k::Ciphertext &ciphertext = *reinterpret_cast<Aes_cbc_4k::Ciphertext *>(&job.data);
|
||||
|
||||
/* paranoia */
|
||||
static_assert(sizeof(plaintext) == sizeof(job.data), "size mismatch");
|
||||
|
||||
Aes_cbc_4k::encrypt(meta.key, block_number, plaintext, ciphertext);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Complete_request encryption_request_complete(char * const dst,
|
||||
size_t const dst_len) override
|
||||
{
|
||||
static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Ciphertext), "size mismatch");
|
||||
static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Plaintext), "size mismatch");
|
||||
|
||||
if (dst_len != sizeof (Cbe::Block_data)) {
|
||||
error("buffer has wrong size");
|
||||
throw Buffer_size_mismatch();
|
||||
}
|
||||
|
||||
uint64_t block_id = 0;
|
||||
|
||||
bool const valid = jobs.apply_encrypt([&](auto const &job) {
|
||||
Genode::memcpy(dst, &job.data, sizeof(job.data));
|
||||
|
||||
block_id = job.request.block_number();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return Complete_request { .valid = valid,
|
||||
.block_number = block_id };
|
||||
}
|
||||
|
||||
bool submit_decryption_request(uint64_t const block_number,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) override
|
||||
{
|
||||
if (src_len != sizeof (Cbe::Block_data)) {
|
||||
error("buffer has wrong size");
|
||||
throw Buffer_size_mismatch();
|
||||
}
|
||||
|
||||
if (!jobs.decrypt.acceptable())
|
||||
return false;
|
||||
|
||||
/* use apply_key to make sure key_id is actually known */
|
||||
return apply_key (key_id, [&] (auto &) {
|
||||
return jobs.queue_decrypt([&] (auto &job) {
|
||||
job.request = Cbe::Request(Cbe::Request::Operation::READ,
|
||||
false, block_number, 0, 1, key_id, 0);
|
||||
Genode::memcpy(&job.data, src, sizeof(job.data));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Complete_request decryption_request_complete(char *dst, size_t dst_len) override
|
||||
{
|
||||
static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Ciphertext), "size mismatch");
|
||||
static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Plaintext), "size mismatch");
|
||||
|
||||
if (dst_len != sizeof (Cbe::Block_data)) {
|
||||
error("buffer has wrong size");
|
||||
throw Buffer_size_mismatch();
|
||||
}
|
||||
|
||||
uint64_t block_id = 0;
|
||||
|
||||
bool const valid = jobs.apply_decrypt([&](auto const &job) {
|
||||
bool ok = apply_key (job.request.key_id(), [&] (auto &meta) {
|
||||
block_id = job.request.block_number();
|
||||
|
||||
Aes_cbc_4k::Block_number block_number { block_id };
|
||||
Aes_cbc_4k::Ciphertext const &ciphertext = *reinterpret_cast<Aes_cbc_4k::Ciphertext const *>(&job.data);
|
||||
Aes_cbc_4k::Plaintext &plaintext = *reinterpret_cast<Aes_cbc_4k::Plaintext *>(dst);
|
||||
|
||||
/* paranoia */
|
||||
static_assert(sizeof(ciphertext) == sizeof(job.data), "size mismatch");
|
||||
|
||||
Aes_cbc_4k::decrypt(meta.key, block_number, ciphertext, plaintext);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return ok;
|
||||
});
|
||||
|
||||
return Complete_request { .valid = valid,
|
||||
.block_number = block_id };
|
||||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
|
||||
Cbe_crypto::Interface &Cbe_crypto::get_interface()
|
||||
{
|
||||
static Crypto inst;
|
||||
return inst;
|
||||
}
|
17
repos/gems/src/lib/vfs/cbe_crypto/aes_cbc/dummy.ads
Normal file
17
repos/gems/src/lib/vfs/cbe_crypto/aes_cbc/dummy.ads
Normal file
@ -0,0 +1,17 @@
|
||||
--
|
||||
-- \brief Integration of the Consistent Block Encrypter (CBE)
|
||||
-- \author Martin Stein
|
||||
-- \author Josef Soentgen
|
||||
-- \date 2020-11-10
|
||||
--
|
||||
|
||||
--
|
||||
-- Copyright (C) 2020 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.
|
||||
--
|
||||
|
||||
package Dummy
|
||||
is
|
||||
end Dummy;
|
3
repos/gems/src/lib/vfs/cbe_crypto/aes_cbc/target.mk
Normal file
3
repos/gems/src/lib/vfs/cbe_crypto/aes_cbc/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET := lib-vfs-cbe_crypto-aes_cbc
|
||||
REQUIRES = x86_64
|
||||
LIBS = vfs_cbe_crypto_aes_cbc
|
141
repos/gems/src/lib/vfs/cbe_crypto/memcopy/memcopy.cc
Normal file
141
repos/gems/src/lib/vfs/cbe_crypto/memcopy/memcopy.cc
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* \brief Integration of the Consistent Block Encrypter (CBE)
|
||||
* \author Martin Stein
|
||||
* \author Josef Soentgen
|
||||
* \date 2020-11-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* cbe_crypto includes */
|
||||
#include <cbe/crypto/interface.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Crypto : Cbe_crypto::Interface
|
||||
{
|
||||
char _internal_buffer[Cbe_crypto::BLOCK_SIZE] { };
|
||||
|
||||
struct Request
|
||||
{
|
||||
uint64_t block_number;
|
||||
bool pending;
|
||||
};
|
||||
|
||||
Request _request { 0, false };
|
||||
|
||||
Crypto() { }
|
||||
|
||||
/***************
|
||||
** interface **
|
||||
***************/
|
||||
|
||||
bool execute() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool add_key(uint32_t const id, char const *, size_t) override
|
||||
{
|
||||
if (!_slots.store(id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
log("Add key: id " , id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool remove_key(uint32_t const id) override
|
||||
{
|
||||
log("Remove key: id " , id);
|
||||
_slots.remove(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _submit_request(uint64_t const block_number,
|
||||
uint32_t const /* key_id */,
|
||||
char const *src,
|
||||
size_t const src_len)
|
||||
{
|
||||
if (_request.pending) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (src_len < sizeof (_internal_buffer)) {
|
||||
error("buffer too small");
|
||||
throw Buffer_too_small();
|
||||
}
|
||||
|
||||
_request.pending = true;
|
||||
_request.block_number = block_number;
|
||||
|
||||
Genode::memcpy(_internal_buffer, src, sizeof (_internal_buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool submit_encryption_request(uint64_t const block_number,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) override
|
||||
{
|
||||
return _submit_request(block_number, key_id, src, src_len);
|
||||
}
|
||||
|
||||
Complete_request _request_complete(char *dst, size_t const dst_len)
|
||||
{
|
||||
if (!_request.pending) {
|
||||
return Complete_request { .valid = false, .block_number = 0 };
|
||||
}
|
||||
|
||||
if (dst_len < sizeof (_internal_buffer)) {
|
||||
error("buffer too small");
|
||||
throw Buffer_too_small();
|
||||
}
|
||||
|
||||
Genode::memcpy(dst, _internal_buffer, sizeof (_internal_buffer));
|
||||
|
||||
_request.pending = false;
|
||||
|
||||
return Complete_request {
|
||||
.valid = true,
|
||||
.block_number = _request.block_number };
|
||||
}
|
||||
|
||||
Complete_request encryption_request_complete(char *dst, size_t const dst_len) override
|
||||
{
|
||||
return _request_complete(dst, dst_len);
|
||||
}
|
||||
|
||||
bool submit_decryption_request(uint64_t const block_number,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) override
|
||||
{
|
||||
return _submit_request(block_number, key_id, src, src_len);
|
||||
}
|
||||
|
||||
Complete_request decryption_request_complete(char *dst, size_t dst_len) override
|
||||
{
|
||||
return _request_complete(dst, dst_len);
|
||||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
|
||||
Cbe_crypto::Interface &Cbe_crypto::get_interface()
|
||||
{
|
||||
static Crypto inst;
|
||||
return inst;
|
||||
}
|
3
repos/gems/src/lib/vfs/cbe_crypto/memcopy/target.mk
Normal file
3
repos/gems/src/lib/vfs/cbe_crypto/memcopy/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET := lib-vfs-cbe_crypto-memcopy
|
||||
REQUIRES = x86_64
|
||||
LIBS = vfs_cbe_crypto_memcopy
|
1172
repos/gems/src/lib/vfs/cbe_crypto/vfs.cc
Normal file
1172
repos/gems/src/lib/vfs/cbe_crypto/vfs.cc
Normal file
File diff suppressed because it is too large
Load Diff
3
repos/gems/src/lib/vfs/cbe_trust_anchor/target.mk
Normal file
3
repos/gems/src/lib/vfs/cbe_trust_anchor/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET := lib-vfs-cbe_trust_anchor
|
||||
REQUIRES = x86_64
|
||||
LIBS = vfs_cbe_trust_anchor
|
1751
repos/gems/src/lib/vfs/cbe_trust_anchor/vfs.cc
Normal file
1751
repos/gems/src/lib/vfs/cbe_trust_anchor/vfs.cc
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user