mirror of
https://github.com/RGBCube/serenity
synced 2025-07-10 06:47:34 +00:00
Kernel: Make use of interrupts as an entropy source
Booting old computers without RDRAND/RDSEED and without a disk makes the system severely starved for entropy. Uses interrupts as a source to side-step that issue. Also warn whenever the system is starved of entropy, because that's a non-obvious failure mode.
This commit is contained in:
parent
cb89d3b780
commit
7eaefa5aa6
3 changed files with 16 additions and 2 deletions
|
@ -44,6 +44,7 @@
|
||||||
#include <Kernel/Interrupts/UnhandledInterruptHandler.h>
|
#include <Kernel/Interrupts/UnhandledInterruptHandler.h>
|
||||||
#include <Kernel/KSyms.h>
|
#include <Kernel/KSyms.h>
|
||||||
#include <Kernel/Process.h>
|
#include <Kernel/Process.h>
|
||||||
|
#include <Kernel/Random.h>
|
||||||
#include <Kernel/SpinLock.h>
|
#include <Kernel/SpinLock.h>
|
||||||
#include <Kernel/Thread.h>
|
#include <Kernel/Thread.h>
|
||||||
#include <Kernel/VM/MemoryManager.h>
|
#include <Kernel/VM/MemoryManager.h>
|
||||||
|
@ -58,6 +59,8 @@ static Descriptor s_idt[256];
|
||||||
|
|
||||||
static GenericInterruptHandler* s_interrupt_handler[GENERIC_INTERRUPT_HANDLERS_COUNT];
|
static GenericInterruptHandler* s_interrupt_handler[GENERIC_INTERRUPT_HANDLERS_COUNT];
|
||||||
|
|
||||||
|
static EntropySource s_entropy_source_interrupts{EntropySource::Static::Interrupts};
|
||||||
|
|
||||||
// The compiler can't see the calls to these functions inside assembly.
|
// The compiler can't see the calls to these functions inside assembly.
|
||||||
// Declare them, to avoid dead code warnings.
|
// Declare them, to avoid dead code warnings.
|
||||||
extern "C" void enter_thread_context(Thread* from_thread, Thread* to_thread);
|
extern "C" void enter_thread_context(Thread* from_thread, Thread* to_thread);
|
||||||
|
@ -709,6 +712,7 @@ void handle_interrupt(TrapFrame* trap)
|
||||||
auto& regs = *trap->regs;
|
auto& regs = *trap->regs;
|
||||||
ASSERT(regs.isr_number >= IRQ_VECTOR_BASE && regs.isr_number <= (IRQ_VECTOR_BASE + GENERIC_INTERRUPT_HANDLERS_COUNT));
|
ASSERT(regs.isr_number >= IRQ_VECTOR_BASE && regs.isr_number <= (IRQ_VECTOR_BASE + GENERIC_INTERRUPT_HANDLERS_COUNT));
|
||||||
u8 irq = (u8)(regs.isr_number - 0x50);
|
u8 irq = (u8)(regs.isr_number - 0x50);
|
||||||
|
s_entropy_source_interrupts.add_random_event(irq);
|
||||||
auto* handler = s_interrupt_handler[irq];
|
auto* handler = s_interrupt_handler[irq];
|
||||||
ASSERT(handler);
|
ASSERT(handler);
|
||||||
handler->increment_invoking_counter();
|
handler->increment_invoking_counter();
|
||||||
|
|
|
@ -69,6 +69,7 @@ KernelRng::KernelRng()
|
||||||
void KernelRng::wait_for_entropy()
|
void KernelRng::wait_for_entropy()
|
||||||
{
|
{
|
||||||
if (!resource().is_ready()) {
|
if (!resource().is_ready()) {
|
||||||
|
dbgln("Entropy starvation...");
|
||||||
m_seed_queue.wait_on({}, "KernelRng");
|
m_seed_queue.wait_on({}, "KernelRng");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +81,7 @@ void KernelRng::wake_if_ready()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t EntropySource::next_source { 0 };
|
size_t EntropySource::next_source { static_cast<size_t>(EntropySource::Static::MaxHardcodedSourceIndex) };
|
||||||
|
|
||||||
void get_good_random_bytes(u8* buffer, size_t buffer_size)
|
void get_good_random_bytes(u8* buffer, size_t buffer_size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -147,11 +147,21 @@ class EntropySource {
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class Static : size_t {
|
||||||
|
Interrupts,
|
||||||
|
MaxHardcodedSourceIndex,
|
||||||
|
};
|
||||||
|
|
||||||
EntropySource()
|
EntropySource()
|
||||||
: m_source(next_source++)
|
: m_source(next_source++)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntropySource(Static hardcoded_source)
|
||||||
|
: m_source(static_cast<size_t>(hardcoded_source))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_random_event(const T& event_data)
|
void add_random_event(const T& event_data)
|
||||||
{
|
{
|
||||||
|
@ -166,7 +176,6 @@ private:
|
||||||
static size_t next_source;
|
static size_t next_source;
|
||||||
size_t m_pool { 0 };
|
size_t m_pool { 0 };
|
||||||
size_t m_source;
|
size_t m_source;
|
||||||
Lock m_lock;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: These API's are primarily about expressing intent/needs in the calling code.
|
// NOTE: These API's are primarily about expressing intent/needs in the calling code.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue