Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syscall to set the seed of the random number generator #98

Merged
merged 13 commits into from
Sep 12, 2020
55 changes: 0 additions & 55 deletions .github/workflows/build.yml

This file was deleted.

5 changes: 3 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test
name: Build and test

on:
push:
Expand Down Expand Up @@ -55,8 +55,9 @@ jobs:
- name: Check Cargo availability
run: cargo --version
- name: Cargo Test libhermit-rs (Unittests on Host)
run: cargo test --lib
run: cargo test --lib --target x86_64-unknown-linux-gnu
working-directory: libhermit-rs
if: ${{ matrix.os == 'ubuntu-latest' }}
- name: Install qemu/nasm (apt)
run: sudo apt-get update --fix-missing && sudo apt-get install qemu-system-x86 nasm
if: ${{ matrix.os == 'ubuntu-latest' }}
Expand Down
36 changes: 28 additions & 8 deletions src/arch/x86_64/kernel/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -877,15 +877,35 @@ fn print_cpu_information() {
print_information();
}*/

pub fn generate_random_number() -> Option<u32> {
if unsafe { SUPPORTS_RDRAND } {
let value: u32;
unsafe {
llvm_asm!("rdrand $0" : "=r"(value) ::: "volatile");
pub fn generate_random_number32() -> Option<u32> {
unsafe {
if SUPPORTS_RDRAND {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a log message in case we have fall back to pseudo random values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a debug message in src/syscalls/random.rs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these printed every time a random number is generated? Can we print an info message at startup saying we are using either the hardware random generator or park miller lehmer software random generator?

let mut value: u32 = 0;

while core::arch::x86_64::_rdrand32_step(&mut value) == 1 {
spin_loop_hint();
}

Some(value)
} else {
None
}
}
}

pub fn generate_random_number64() -> Option<u64> {
unsafe {
if SUPPORTS_RDRAND {
let mut value: u64 = 0;

while core::arch::x86_64::_rdrand64_step(&mut value) == 1 {
spin_loop_hint();
}

Some(value)
} else {
None
}
Some(value)
} else {
None
}
}

Expand Down
52 changes: 45 additions & 7 deletions src/syscalls/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,65 @@ use crate::arch;
use crate::synch::spinlock::Spinlock;

static PARK_MILLER_LEHMER_SEED: Spinlock<u32> = Spinlock::new(0);
const RAND_MAX: u64 = 2_147_483_647;

fn generate_park_miller_lehmer_random_number() -> u32 {
let mut seed = PARK_MILLER_LEHMER_SEED.lock();
let random = ((u64::from(*seed) * 48271) % 2_147_483_647) as u32;
let random = ((u64::from(*seed) * 48271) % RAND_MAX) as u32;
*seed = random;
random
}

fn __sys_rand32() -> Option<u32> {
arch::processor::generate_random_number32()
}

fn __sys_rand64() -> Option<u64> {
arch::processor::generate_random_number64()
}

fn __sys_rand() -> u32 {
if let Some(value) = arch::processor::generate_random_number() {
value
} else {
generate_park_miller_lehmer_random_number()
}
generate_park_miller_lehmer_random_number()
}

/// Create a cryptographicly secure 32bit random number with the support of
/// the underlying hardware. If the required hardware isn't available,
/// the function returns `None`.
#[cfg(not(feature = "newlib"))]
#[no_mangle]
pub fn sys_secure_rand32() -> Option<u32> {
kernel_function!(__sys_rand32())
}

/// Create a cryptographicly secure 64bit random number with the support of
/// the underlying hardware. If the required hardware isn't available,
/// the function returns `None`.
#[cfg(not(feature = "newlib"))]
#[no_mangle]
pub fn sys_secure_rand64() -> Option<u64> {
kernel_function!(__sys_rand64())
}

/// The function computes a sequence of pseudo-random integers
/// in the range of 0 to RAND_MAX
#[no_mangle]
pub extern "C" fn sys_rand() -> u32 {
kernel_function!(__sys_rand())
}

fn __sys_srand(seed: u32) {
*(PARK_MILLER_LEHMER_SEED.lock()) = seed;
}

/// The function sets its argument as the seed for a new sequence
/// of pseudo-random numbers to be returned by rand()
#[no_mangle]
pub extern "C" fn sys_srand(seed: u32) {
kernel_function!(__sys_srand(seed))
}

pub fn random_init() {
*PARK_MILLER_LEHMER_SEED.lock() = arch::processor::get_timestamp() as u32;
let seed: u32 = arch::processor::get_timestamp() as u32;

*PARK_MILLER_LEHMER_SEED.lock() = seed;
}