diff --git a/repos/gems/run/cbe_tester.run b/repos/gems/run/cbe_tester.run
index 9b7a63de97..36983536b0 100644
--- a/repos/gems/run/cbe_tester.run
+++ b/repos/gems/run/cbe_tester.run
@@ -58,6 +58,7 @@ append build_components {
lib/vfs/cbe_crypto/aes_cbc
lib/vfs/cbe_trust_anchor
lib/vfs/import
+ lib/vfs/jitterentropy
}
build $build_components
@@ -124,6 +125,7 @@ append config {
+
@@ -1046,6 +1048,7 @@ append boot_modules {
vfs_cbe_trust_anchor.lib.so
vfs_cbe_crypto_aes_cbc.lib.so
vfs_import.lib.so
+ vfs_jitterentropy.lib.so
}
append boot_modules [cbe_image_name]
diff --git a/repos/gems/src/lib/vfs/cbe_trust_anchor/vfs.cc b/repos/gems/src/lib/vfs/cbe_trust_anchor/vfs.cc
index 00bacf9f76..e46382347c 100644
--- a/repos/gems/src/lib/vfs/cbe_trust_anchor/vfs.cc
+++ b/repos/gems/src/lib/vfs/cbe_trust_anchor/vfs.cc
@@ -31,18 +31,6 @@ static void xor_bytes(unsigned char const *p, int p_len,
}
-static void fill_bytes(unsigned char *v, int v_len)
-{
- static unsigned char _fill_counter = 0x23;
-
- for (int i = 0; i < v_len; i++) {
- v[i] = _fill_counter;
- }
-
- ++_fill_counter;
-}
-
-
namespace Vfs_cbe_trust_anchor {
using namespace Vfs;
@@ -141,11 +129,6 @@ class Trust_anchor
key.value, (int)Key::KEY_LEN);
}
- void _fill_key(Key &key)
- {
- fill_bytes(key.value, (int)Key::KEY_LEN);
- }
-
bool _execute_xcrypt(Key &key)
{
switch (_job_state) {
@@ -168,22 +151,47 @@ class Trust_anchor
bool _execute_generate(Key &key)
{
+ bool progress = false;
+
switch (_job_state) {
case Job_state::PENDING:
- _fill_key(key);
+ {
+ if (!_open_jitterentropy_file_and_queue_read()) {
+ break;
+ }
+ _job_state = Job_state::IN_PROGRESS;
+ progress = true;
+ }
+ [[fallthrough]];
+
+ case Job_state::IN_PROGRESS:
+ {
+ if (!_read_jitterentropy_file_finished()) {
+ break;
+ }
+ if (_jitterentropy_io_job_buffer.size != (size_t)Key::KEY_LEN) {
+ class Bad_jitterentropy_io_buffer_size { };
+ throw Bad_jitterentropy_io_buffer_size { };
+ }
+ Genode::memcpy(key.value,
+ _jitterentropy_io_job_buffer.base,
+ _jitterentropy_io_job_buffer.size);
+
_job_state = Job_state::COMPLETE;
_job_success = true;
- [[fallthrough]];
+ progress = true;
+ }
+
+ [[fallthrough]];
case Job_state::COMPLETE:
return true;
- case Job_state::IN_PROGRESS: [[fallthrough]];
case Job_state::NONE: [[fallthrough]];
- default: return false;
+ default: break;
}
/* never reached */
- return false;
+ return progress;
}
bool _execute_unlock()
@@ -452,6 +460,21 @@ class Trust_anchor
(*handle) = nullptr;
}
+ struct Jitterentropy_io_job_buffer : Util::Io_job::Buffer
+ {
+ char buffer[32] { };
+
+ Jitterentropy_io_job_buffer()
+ {
+ Buffer::base = buffer;
+ Buffer::size = sizeof (buffer);
+ }
+ };
+
+ Vfs::Vfs_handle *_jitterentropy_handle { nullptr };
+ Genode::Constructible _jitterentropy_io_job { };
+ Jitterentropy_io_job_buffer _jitterentropy_io_job_buffer { };
+
/* key */
Vfs::Vfs_handle *_key_handle { nullptr };
@@ -491,6 +514,35 @@ class Trust_anchor
return false;
}
+ bool _open_jitterentropy_file_and_queue_read()
+ {
+ Path file_path = "/dev/jitterentropy";
+ using Result = Vfs::Directory_service::Open_result;
+
+ Result const res =
+ _vfs_env.root_dir().open(file_path.string(),
+ Vfs::Directory_service::OPEN_MODE_RDONLY,
+ (Vfs::Vfs_handle **)&_jitterentropy_handle,
+ _vfs_env.alloc());
+ if (res != Result::OPEN_OK) {
+ Genode::error("could not open '", file_path.string(), "'");
+ return false;
+ }
+
+ _jitterentropy_handle->handler(&_io_response_handler);
+ _jitterentropy_io_job.construct(*_jitterentropy_handle, Util::Io_job::Operation::READ,
+ _jitterentropy_io_job_buffer, 0,
+ Util::Io_job::Partial_result::ALLOW);
+
+ if (_jitterentropy_io_job->execute() && _jitterentropy_io_job->completed()) {
+ _close_handle(&_jitterentropy_handle);
+ _jitterentropy_io_job_buffer.size = _jitterentropy_io_job->current_offset();
+ _jitterentropy_io_job.destruct();
+ return true;
+ }
+ return true;
+ }
+
bool _open_key_file_and_queue_read(Path const &path)
{
Path file_path = path;
@@ -520,6 +572,25 @@ class Trust_anchor
return true;
}
+ bool _read_jitterentropy_file_finished()
+ {
+ if (!_jitterentropy_io_job.constructed()) {
+ return true;
+ }
+
+ // XXX trigger sync
+
+ bool const progress = _jitterentropy_io_job->execute();
+ bool const completed = _jitterentropy_io_job->completed();
+ if (completed) {
+ _close_handle(&_jitterentropy_handle);
+ _jitterentropy_io_job_buffer.size = _jitterentropy_io_job->current_offset();
+ _jitterentropy_io_job.destruct();
+ }
+
+ return progress && completed;
+ }
+
bool _read_key_file_finished()
{
if (!_key_io_job.constructed()) {