From f3baa5d8c915285ea109cf12553e497adb7051ca Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Tue, 31 Aug 2021 23:28:47 -0700 Subject: [PATCH] Kernel: Convert random bytes interface to use AK::Bytes --- Kernel/Devices/RandomDevice.cpp | 2 +- Kernel/Random.cpp | 16 ++++++++-------- Kernel/Random.h | 17 +++++++++-------- Kernel/Syscalls/execve.cpp | 2 +- Kernel/Syscalls/getrandom.cpp | 2 +- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/Kernel/Devices/RandomDevice.cpp b/Kernel/Devices/RandomDevice.cpp index f0ea6f1281e..caf06614b7d 100644 --- a/Kernel/Devices/RandomDevice.cpp +++ b/Kernel/Devices/RandomDevice.cpp @@ -32,7 +32,7 @@ bool RandomDevice::can_read(const FileDescription&, size_t) const KResultOr RandomDevice::read(FileDescription&, u64, UserOrKernelBuffer& buffer, size_t size) { return buffer.write_buffered<256>(size, [&](u8* data, size_t data_size) { - get_good_random_bytes(data, data_size); + get_good_random_bytes({ data, data_size }); return data_size; }); } diff --git a/Kernel/Random.cpp b/Kernel/Random.cpp index 516975b7ab2..2933e9d595b 100644 --- a/Kernel/Random.cpp +++ b/Kernel/Random.cpp @@ -87,7 +87,7 @@ void KernelRng::wake_if_ready() size_t EntropySource::next_source { static_cast(EntropySource::Static::MaxHardcodedSourceIndex) }; -static void do_get_fast_random_bytes(u8* buffer, size_t buffer_size) +static void do_get_fast_random_bytes(Bytes buffer) { union { @@ -95,7 +95,7 @@ static void do_get_fast_random_bytes(u8* buffer, size_t buffer_size) u32 value; } u; size_t offset = 4; - for (size_t i = 0; i < buffer_size; ++i) { + for (size_t i = 0; i < buffer.size(); ++i) { if (offset >= 4) { auto current_next = s_next_random_value.load(); for (;;) { @@ -111,7 +111,7 @@ static void do_get_fast_random_bytes(u8* buffer, size_t buffer_size) } } -bool get_good_random_bytes(u8* buffer, size_t buffer_size, bool allow_wait, bool fallback_to_fast) +bool get_good_random_bytes(Bytes buffer, bool allow_wait, bool fallback_to_fast) { bool result = false; auto& kernel_rng = KernelRng::the(); @@ -127,7 +127,7 @@ bool get_good_random_bytes(u8* buffer, size_t buffer_size, bool allow_wait, bool for (;;) { { MutexLocker locker(KernelRng::the().lock()); - if (kernel_rng.resource().get_random_bytes(buffer, buffer_size)) { + if (kernel_rng.resource().get_random_bytes(buffer)) { result = true; break; } @@ -136,11 +136,11 @@ bool get_good_random_bytes(u8* buffer, size_t buffer_size, bool allow_wait, bool } } else { // We can't wait/block here, or we are not allowed to block/wait - if (kernel_rng.resource().get_random_bytes(buffer, buffer_size)) { + if (kernel_rng.resource().get_random_bytes(buffer)) { result = true; } else if (fallback_to_fast) { // If interrupts are disabled - do_get_fast_random_bytes(buffer, buffer_size); + do_get_fast_random_bytes(buffer); result = true; } } @@ -152,11 +152,11 @@ bool get_good_random_bytes(u8* buffer, size_t buffer_size, bool allow_wait, bool return result; } -void get_fast_random_bytes(u8* buffer, size_t buffer_size) +void get_fast_random_bytes(Bytes buffer) { // Try to get good randomness, but don't block if we can't right now // and allow falling back to fast randomness - auto result = get_good_random_bytes(buffer, buffer_size, false, true); + auto result = get_good_random_bytes(buffer, false, true); VERIFY(result); } diff --git a/Kernel/Random.h b/Kernel/Random.h index ff13d774ebb..17a0e3e2eef 100644 --- a/Kernel/Random.h +++ b/Kernel/Random.h @@ -35,7 +35,7 @@ public: { } - bool get_random_bytes(u8* buffer, size_t n) + bool get_random_bytes(Bytes buffer) { SpinlockLocker lock(m_lock); if (!is_ready()) @@ -47,13 +47,12 @@ public: VERIFY(is_seeded()); // FIXME: More than 2^20 bytes cannot be generated without refreshing the key. - VERIFY(n < (1 << 20)); + VERIFY(buffer.size() < (1 << 20)); typename CipherType::CTRMode cipher(m_key, KeySize, Crypto::Cipher::Intent::Encryption); - Bytes buffer_span { buffer, n }; auto counter_span = m_counter.bytes(); - cipher.key_stream(buffer_span, counter_span, &counter_span); + cipher.key_stream(buffer, counter_span, &counter_span); // Extract a new key from the prng stream. Bytes key_span = m_key.bytes(); @@ -173,14 +172,15 @@ private: // NOTE: These API's are primarily about expressing intent/needs in the calling code. // The only difference is that get_fast_random is guaranteed not to block. -void get_fast_random_bytes(u8*, size_t); -bool get_good_random_bytes(u8*, size_t, bool allow_wait = true, bool fallback_to_fast = true); +void get_fast_random_bytes(Bytes); +bool get_good_random_bytes(Bytes bytes, bool allow_wait = true, bool fallback_to_fast = true); template inline T get_fast_random() { T value; - get_fast_random_bytes(reinterpret_cast(&value), sizeof(T)); + Bytes bytes { reinterpret_cast(&value), sizeof(T) }; + get_fast_random_bytes(bytes); return value; } @@ -188,7 +188,8 @@ template inline T get_good_random() { T value; - get_good_random_bytes(reinterpret_cast(&value), sizeof(T)); + Bytes bytes { reinterpret_cast(&value), sizeof(T) }; + get_good_random_bytes(bytes); return value; } diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index a8b8f7e7a57..19f2ed940d2 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -724,7 +724,7 @@ static Vector generate_auxiliary_vector(FlatPtr load_base, auxv.append({ ELF::AuxiliaryValue::Secure, ((uid != euid) || (gid != egid)) ? 1 : 0 }); char random_bytes[16] {}; - get_fast_random_bytes((u8*)random_bytes, sizeof(random_bytes)); + get_fast_random_bytes({ (u8*)random_bytes, sizeof(random_bytes) }); auxv.append({ ELF::AuxiliaryValue::Random, String(random_bytes, sizeof(random_bytes)) }); diff --git a/Kernel/Syscalls/getrandom.cpp b/Kernel/Syscalls/getrandom.cpp index 942ffd02024..f5175981aac 100644 --- a/Kernel/Syscalls/getrandom.cpp +++ b/Kernel/Syscalls/getrandom.cpp @@ -24,7 +24,7 @@ KResultOr Process::sys$getrandom(Userspace buffer, size_t buffer if (!data_buffer.has_value()) return EFAULT; auto result = data_buffer.value().write_buffered<1024>(buffer_size, [&](u8* buffer, size_t buffer_bytes) { - get_good_random_bytes(buffer, buffer_bytes); + get_good_random_bytes({ buffer, buffer_bytes }); return buffer_bytes; }); if (result.is_error())