Skip to content

Commit

Permalink
kernel: Move rand driver to platform module.
Browse files Browse the repository at this point in the history
Signed-off-by: Jean-Pierre De Jesus DIAZ <me@jeandudey.tech>
  • Loading branch information
jeandudey committed Nov 2, 2022
1 parent b334e5b commit d8807e6
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 80 deletions.
2 changes: 0 additions & 2 deletions kernel/src/arch/riscv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ pub mod exception;
pub mod irq;
pub mod mem;
pub mod process;
pub mod rand;
pub mod syscall;

pub use process::Thread;
Expand Down Expand Up @@ -49,7 +48,6 @@ pub fn init() {
sie::set_ssoft();
sie::set_sext();
}
rand::init();
}

/// Put the core to sleep until an interrupt hits. Returns `true`
Expand Down
69 changes: 0 additions & 69 deletions kernel/src/arch/riscv/rand.rs

This file was deleted.

4 changes: 2 additions & 2 deletions kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ pub unsafe extern "C" fn init(arg_offset: *const u32, init_offset: *const u32, r
println!("KMAIN (clean boot): Supervisor mode started...");

// rand::init() already clears the initial pipe, but pump the TRNG a little more out of no other reason than sheer paranoia
arch::rand::get_u32();
arch::rand::get_u32();
platform::rand::get_u32();
platform::rand::get_u32();
}

/// Loop through the SystemServices list to determine the next PID to be run.
Expand Down
2 changes: 2 additions & 0 deletions kernel/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#[cfg(any(feature="precursor", feature="renode"))]
pub mod precursor;

pub mod rand;

/// Platform specific initialization.
#[cfg(not(any(unix, windows)))]
pub fn init() {
Expand Down
2 changes: 2 additions & 0 deletions kernel/src/platform/precursor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

#[cfg(any(feature = "debug-print", feature = "print-panics"))]
pub mod uart;
pub mod rand;

/// Precursor specific initialization.
pub fn init() {
self::rand::init();
#[cfg(any(feature = "debug-print", feature = "print-panics"))]
self::uart::init();
}
98 changes: 98 additions & 0 deletions kernel/src/platform/precursor/rand.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// SPDX-FileCopyrightText: 2020 Sean Cross <sean@xobs.io>
// SPDX-FileCopyrightText: 2022 Foundation Devices, Inc. <hello@foundationdevices.com>
// SPDX-License-Identifier: Apache-2.0

use crate::mem::MemoryManager;
use utralib::generated::*;
use xous_kernel::{MemoryFlags, MemoryType, PID};

/// The manually chosen virtual address has to be in the top 4MiB as it is the
/// only page shared among all processes.
///
/// See https://github.com/betrusted-io/xous-core/blob/master/docs/memory.md
pub const TRNG_KERNEL_ADDR: usize = 0xffce_0000;
pub static mut TRNG_KERNEL: Option<TrngKernel> = None;

pub struct TrngKernel {
pub trng_kernel_csr: CSR<u32>,
}

impl TrngKernel {
pub fn new(addr: usize) -> TrngKernel {
TrngKernel {
trng_kernel_csr: CSR::new(addr as *mut u32),
}
}

pub fn init(&mut self) {
if false { // raw random path - left in for debugging urandom, can strip out later
while self.trng_kernel_csr.rf(utra::trng_kernel::STATUS_AVAIL) == 0 {}
// discard the first entry, as it is always 0x0000_0000
// this is because the read register is a pipeline stage behind the FIFO
// once the pipeline has been filled, there is no need to prime it again.
self.trng_kernel_csr.rf(utra::trng_kernel::DATA_DATA);
} else { // urandom path (recommended)
// simulations show this isn't strictly necessary, but I prefer to have it
// just in case a subtle bug in the reset logic leaves something deterministic
// in the connecting logic: the simulation coverage stops at the edge of the TRNG block.
for _ in 0..4 {
// wait until the urandom port is initialized
while self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_VALID_URANDOM_VALID) == 0 {}
// pull a dummy piece of data
self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_URANDOM);
}
}
}

pub fn get_u32(&mut self) -> u32 {
if false { // raw random path
while self.trng_kernel_csr.rf(utra::trng_kernel::STATUS_AVAIL) == 0 {}
self.trng_kernel_csr.rf(utra::trng_kernel::DATA_DATA)
} else { // urandom path (recommended)
while self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_VALID_URANDOM_VALID) == 0 {}
self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_URANDOM)
}
}
}

/// Initialize TRNG driver.
///
/// Needed so that the kernel can allocate names.
pub fn init() {
// Map the TRNG so that we can allocate names
// hardware guarantees that:
// - TRNG will automatically power on
// - Both TRNGs are enabled, with conservative defaults
// - Kernel FIFO will fill with TRNGs such that at least the next 512 calls to get_u32() will succeed without delay
// - The kernel will start a TRNG server
// - All further security decisions and policies are 100% delegated to this new server.
MemoryManager::with_mut(|memory_manager| {
memory_manager
.map_range(
utra::trng_kernel::HW_TRNG_KERNEL_BASE as *mut u8,
(TRNG_KERNEL_ADDR & !4095) as *mut u8,
4096,
PID::new(1).unwrap(),
MemoryFlags::R | MemoryFlags::W,
MemoryType::Default,
)
.expect("unable to map TRNG_KERNEL")
});

let mut trng_kernel = TrngKernel::new(TRNG_KERNEL_ADDR);
trng_kernel.init();

unsafe {
TRNG_KERNEL = Some(trng_kernel);
}
}

/// Retrieve random `u32`.
pub fn get_u32() -> u32 {
unsafe {
TRNG_KERNEL
.as_mut()
.expect("TRNG_KERNEL driver not initialized")
.get_u32()
}
}
6 changes: 3 additions & 3 deletions kernel/src/platform/precursor/uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ pub fn init() {
.expect("unable to map serial port")
});

unsafe {
let mut uart = Uart::new(UART_ADDR, process_characters);
uart.init();
let mut uart = Uart::new(UART_ADDR, process_characters);
uart.init();

unsafe {
UART = Some(uart);
crate::debug::shell::init(UART.as_mut().unwrap());

Expand Down
11 changes: 11 additions & 0 deletions kernel/src/platform/rand.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-FileCopyrightText: 2022 Foundation Devices, Inc. <hello@foundationdevices.com>
// SPDX-License-Identifier: Apache-2.0

pub fn get_u32() -> u32 {
// hosted rand code is coupled with arch code.
#[cfg(any(windows, unix))]
let rand = crate::arch::rand::get_u32();
#[cfg(any(feature="precursor", feature="renode"))]
let rand = crate::platform::precursor::rand::get_u32();
rand
}
9 changes: 5 additions & 4 deletions kernel/src/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::arch;
use crate::arch::mem::MemoryMapping;
pub use crate::arch::process::Process as ArchProcess;
pub use crate::arch::process::Thread;
use crate::platform;
use xous_kernel::arch::ProcessStartup;
use xous_kernel::MemoryRange;

Expand Down Expand Up @@ -1742,10 +1743,10 @@ impl SystemServices {
/// any processes.
pub fn create_server_id(&mut self) -> Result<SID, xous_kernel::Error> {
let sid = SID::from_u32(
arch::rand::get_u32(),
arch::rand::get_u32(),
arch::rand::get_u32(),
arch::rand::get_u32(),
platform::rand::get_u32(),
platform::rand::get_u32(),
platform::rand::get_u32(),
platform::rand::get_u32(),
);
Ok(sid)
}
Expand Down

0 comments on commit d8807e6

Please sign in to comment.