From 37d47fd2ea8af4cfd724f9c1681318c08274bf08 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 11 Sep 2020 16:33:26 +0200 Subject: [PATCH 01/13] add syscall to set the seed of the random number generator --- src/syscalls/random.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/syscalls/random.rs b/src/syscalls/random.rs index 7f50438a46..465b3c1bfc 100644 --- a/src/syscalls/random.rs +++ b/src/syscalls/random.rs @@ -7,6 +7,7 @@ use crate::arch; use crate::synch::spinlock::Spinlock; +use core::convert::TryInto; static PARK_MILLER_LEHMER_SEED: Spinlock = Spinlock::new(0); @@ -30,6 +31,17 @@ pub extern "C" fn sys_rand() -> u32 { kernel_function!(__sys_rand()) } +fn __sys_srand(seed: u32) { + *(PARK_MILLER_LEHMER_SEED.lock()) = seed; +} + +#[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().try_into().unwrap(); + + *PARK_MILLER_LEHMER_SEED.lock() = seed; } From 98e80af64c6b7a388fe74a662223ecd8f18c880e Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 11 Sep 2020 16:34:00 +0200 Subject: [PATCH 02/13] use function of the core library to create a random number --- src/arch/x86_64/kernel/processor.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/arch/x86_64/kernel/processor.rs b/src/arch/x86_64/kernel/processor.rs index 68d424ff72..017a8cc6cc 100644 --- a/src/arch/x86_64/kernel/processor.rs +++ b/src/arch/x86_64/kernel/processor.rs @@ -878,14 +878,18 @@ fn print_cpu_information() { }*/ pub fn generate_random_number() -> Option { - if unsafe { SUPPORTS_RDRAND } { - let value: u32; - unsafe { - llvm_asm!("rdrand $0" : "=r"(value) ::: "volatile"); + unsafe { + if SUPPORTS_RDRAND { + let mut value: u32 = 0; + + while core::arch::x86_64::_rdrand32_step(&mut value) == 1 { + spin_loop_hint(); + } + + Some(value) + } else { + None } - Some(value) - } else { - None } } From d949a698a62b5a01a2fa48e8d6be58ee4d4a1a47 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 11 Sep 2020 17:40:26 +0200 Subject: [PATCH 03/13] add support of 64bit random numbers --- src/arch/x86_64/kernel/processor.rs | 18 +++++++++++++++++- src/syscalls/random.rs | 23 +++++++++++++++++++---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/arch/x86_64/kernel/processor.rs b/src/arch/x86_64/kernel/processor.rs index 017a8cc6cc..6492b463e9 100644 --- a/src/arch/x86_64/kernel/processor.rs +++ b/src/arch/x86_64/kernel/processor.rs @@ -877,7 +877,7 @@ fn print_cpu_information() { print_information(); }*/ -pub fn generate_random_number() -> Option { +pub fn generate_random_number32() -> Option { unsafe { if SUPPORTS_RDRAND { let mut value: u32 = 0; @@ -893,6 +893,22 @@ pub fn generate_random_number() -> Option { } } +pub fn generate_random_number64() -> Option { + 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 + } + } +} + #[inline] pub fn get_linear_address_bits() -> u8 { unsafe { LINEAR_ADDRESS_BITS } diff --git a/src/syscalls/random.rs b/src/syscalls/random.rs index 465b3c1bfc..b189c63bef 100644 --- a/src/syscalls/random.rs +++ b/src/syscalls/random.rs @@ -18,17 +18,32 @@ fn generate_park_miller_lehmer_random_number() -> u32 { random } -fn __sys_rand() -> u32 { - if let Some(value) = arch::processor::generate_random_number() { +fn __sys_rand32() -> u32 { + if let Some(value) = arch::processor::generate_random_number32() { value } else { + debug!("Fallback to a software-based random number generator"); generate_park_miller_lehmer_random_number() } } +fn __sys_rand64() -> u64 { + if let Some(value) = arch::processor::generate_random_number64() { + value + } else { + debug!("Fallback to a software-based random number generator"); + generate_park_miller_lehmer_random_number() as u64 + } +} + +#[no_mangle] +pub extern "C" fn sys_rand32() -> u32 { + kernel_function!(__sys_rand32()) +} + #[no_mangle] -pub extern "C" fn sys_rand() -> u32 { - kernel_function!(__sys_rand()) +pub extern "C" fn sys_rand64() -> u64 { + kernel_function!(__sys_rand64()) } fn __sys_srand(seed: u32) { From fa3ecb7e6eaeb43692143163be5f72d4136501a7 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 11 Sep 2020 17:47:02 +0200 Subject: [PATCH 04/13] add basic newlib support --- src/syscalls/random.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/syscalls/random.rs b/src/syscalls/random.rs index b189c63bef..43728e3ed0 100644 --- a/src/syscalls/random.rs +++ b/src/syscalls/random.rs @@ -36,20 +36,34 @@ fn __sys_rand64() -> u64 { } } +#[cfg(not(feature = "newlib"))] #[no_mangle] -pub extern "C" fn sys_rand32() -> u32 { +pub fn sys_rand32() -> u32 { kernel_function!(__sys_rand32()) } +#[cfg(not(feature = "newlib"))] #[no_mangle] -pub extern "C" fn sys_rand64() -> u64 { +pub fn sys_rand64() -> u64 { kernel_function!(__sys_rand64()) } +#[cfg(feature = "newlib")] +pub extern "C" fn sys_srand(seed: u32) { + kernel_function!(__sys_srand32(seed)) +} + fn __sys_srand(seed: u32) { *(PARK_MILLER_LEHMER_SEED.lock()) = seed; } +#[cfg(feature = "newlib")] +#[no_mangle] +pub fn sys_srand(seed: u32) { + kernel_function!(__sys_srand(seed)) +} + +#[cfg(not(feature = "newlib"))] #[no_mangle] pub extern "C" fn sys_srand(seed: u32) { kernel_function!(__sys_srand(seed)) From 8fcefd5e83d612a1e23a8612c7f0dcaf187f93e6 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 11 Sep 2020 22:41:08 +0200 Subject: [PATCH 05/13] minor modification to increase the readability --- src/syscalls/random.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/syscalls/random.rs b/src/syscalls/random.rs index 43728e3ed0..cfe1d6d72c 100644 --- a/src/syscalls/random.rs +++ b/src/syscalls/random.rs @@ -7,7 +7,6 @@ use crate::arch; use crate::synch::spinlock::Spinlock; -use core::convert::TryInto; static PARK_MILLER_LEHMER_SEED: Spinlock = Spinlock::new(0); @@ -70,7 +69,7 @@ pub extern "C" fn sys_srand(seed: u32) { } pub fn random_init() { - let seed: u32 = arch::processor::get_timestamp().try_into().unwrap(); + let seed: u32 = arch::processor::get_timestamp() as u32; *PARK_MILLER_LEHMER_SEED.lock() = seed; } From bf1fdb56e97158503e806ae9c2b10b15a0b98a05 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 12 Sep 2020 11:19:56 +0200 Subject: [PATCH 06/13] reduce the number of warnings --- src/arch/x86_64/kernel/processor.rs | 4 ++++ src/syscalls/random.rs | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/arch/x86_64/kernel/processor.rs b/src/arch/x86_64/kernel/processor.rs index 6492b463e9..0ea1b57116 100644 --- a/src/arch/x86_64/kernel/processor.rs +++ b/src/arch/x86_64/kernel/processor.rs @@ -866,6 +866,10 @@ pub fn print_information() { if supports_1gib_pages() { "Yes" } else { "No" } ); infofooter!(); + + if unsafe { SUPPORTS_RDRAND == false } { + warn!("RDRAND support is missing! Switch to a software-based random number generator!"); + } } /*#[cfg(not(target_os = "hermit"))] diff --git a/src/syscalls/random.rs b/src/syscalls/random.rs index cfe1d6d72c..8eb02a508a 100644 --- a/src/syscalls/random.rs +++ b/src/syscalls/random.rs @@ -30,7 +30,6 @@ fn __sys_rand64() -> u64 { if let Some(value) = arch::processor::generate_random_number64() { value } else { - debug!("Fallback to a software-based random number generator"); generate_park_miller_lehmer_random_number() as u64 } } From 874505c5f417f91fc82f7b1e663b408077424bfe Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 12 Sep 2020 14:43:02 +0200 Subject: [PATCH 07/13] add functions to determine cryptographicly secure random numbers --- src/syscalls/random.rs | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/syscalls/random.rs b/src/syscalls/random.rs index 8eb02a508a..4f91c28221 100644 --- a/src/syscalls/random.rs +++ b/src/syscalls/random.rs @@ -17,51 +17,43 @@ fn generate_park_miller_lehmer_random_number() -> u32 { random } -fn __sys_rand32() -> u32 { - if let Some(value) = arch::processor::generate_random_number32() { - value - } else { - debug!("Fallback to a software-based random number generator"); - generate_park_miller_lehmer_random_number() - } +fn __sys_rand32() -> Option { + arch::processor::generate_random_number32() +} + +fn __sys_rand64() -> Option { + arch::processor::generate_random_number64() } -fn __sys_rand64() -> u64 { - if let Some(value) = arch::processor::generate_random_number64() { +fn __sys_rand() -> u32 { + if let Some(value) = arch::processor::generate_random_number32() { value } else { - generate_park_miller_lehmer_random_number() as u64 + generate_park_miller_lehmer_random_number() } } #[cfg(not(feature = "newlib"))] #[no_mangle] -pub fn sys_rand32() -> u32 { +pub fn sys_secure_rand32() -> Option { kernel_function!(__sys_rand32()) } #[cfg(not(feature = "newlib"))] #[no_mangle] -pub fn sys_rand64() -> u64 { +pub fn sys_secure_rand64() -> Option { kernel_function!(__sys_rand64()) } -#[cfg(feature = "newlib")] -pub extern "C" fn sys_srand(seed: u32) { - kernel_function!(__sys_srand32(seed)) +#[no_mangle] +pub extern "C" fn sys_rand() -> u32 { + kernel_function!(__sys_rand()) } fn __sys_srand(seed: u32) { *(PARK_MILLER_LEHMER_SEED.lock()) = seed; } -#[cfg(feature = "newlib")] -#[no_mangle] -pub fn sys_srand(seed: u32) { - kernel_function!(__sys_srand(seed)) -} - -#[cfg(not(feature = "newlib"))] #[no_mangle] pub extern "C" fn sys_srand(seed: u32) { kernel_function!(__sys_srand(seed)) From 05a71e5e8e32c20a2da9112015587ba103556f26 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 12 Sep 2020 14:48:19 +0200 Subject: [PATCH 08/13] remove obsolete build stage --- .github/workflows/build.yml | 55 ------------------------------------- .github/workflows/test.yml | 2 +- 2 files changed, 1 insertion(+), 56 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 0d32bc82df..0000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Build - -on: - push: - branches: - - master - pull_request: - branches: - - master - schedule: - - cron: '0 0 * * 6' - -jobs: - build: - - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] - rust: [nightly] - include: - - os: macOS-latest - rust: 'nightly' - components: 'rust-src' - targets: 'x86_64-apple-darwin' - - os: windows-latest - rust: 'nightly' - components: 'rust-src' - targets: 'x86_64-pc-windows-msvc' - - os: ubuntu-latest - rust: 'nightly' - components: 'rust-src' - targets: 'x86_64-unknown-linux-gnu' - - - steps: - - uses: hecrj/setup-rust-action@v1.3.1 - with: - rust-version: ${{ matrix.rust }} - components: ${{ matrix.components || '' }} - targets: ${{ matrix.targets || '' }} - - uses: actions/checkout@v1 - with: - submodules: true - - name: Check Cargo availability - run: cargo --version - - name: Building dev version - run: - cargo build -Z build-std=core,alloc --target x86_64-unknown-hermit-kernel - - name: Building release version - run: - cargo build -Z build-std=core,alloc --target x86_64-unknown-hermit-kernel --release - env: - RUSTFLAGS: -Clinker-plugin-lto diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5a79f94fb7..0eb5c75f71 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Test +name: Build and test on: push: From 4b7c8e497bf66aeffdd0e8ef919e867c46213788 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 12 Sep 2020 14:52:56 +0200 Subject: [PATCH 09/13] sys_rand creates only pseudo random numbers - this function isn't cryptographicly secure - use sys_sys_secure_rand32/sys_secure_rand64 to cryptographicly secure random number --- src/syscalls/random.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/syscalls/random.rs b/src/syscalls/random.rs index 4f91c28221..2f9d919201 100644 --- a/src/syscalls/random.rs +++ b/src/syscalls/random.rs @@ -26,11 +26,7 @@ fn __sys_rand64() -> Option { } fn __sys_rand() -> u32 { - if let Some(value) = arch::processor::generate_random_number32() { - value - } else { - generate_park_miller_lehmer_random_number() - } + generate_park_miller_lehmer_random_number() } #[cfg(not(feature = "newlib"))] From f1dfea9c6992301cb5969e869b288f1c89ae80aa Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 12 Sep 2020 15:14:14 +0200 Subject: [PATCH 10/13] remove obsolete warning --- src/arch/x86_64/kernel/processor.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/arch/x86_64/kernel/processor.rs b/src/arch/x86_64/kernel/processor.rs index 0ea1b57116..6492b463e9 100644 --- a/src/arch/x86_64/kernel/processor.rs +++ b/src/arch/x86_64/kernel/processor.rs @@ -866,10 +866,6 @@ pub fn print_information() { if supports_1gib_pages() { "Yes" } else { "No" } ); infofooter!(); - - if unsafe { SUPPORTS_RDRAND == false } { - warn!("RDRAND support is missing! Switch to a software-based random number generator!"); - } } /*#[cfg(not(target_os = "hermit"))] From 4fc783416fccf22bff0081758f5af881078d547e Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 12 Sep 2020 16:31:47 +0200 Subject: [PATCH 11/13] run unit tests only on Ubuntu --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0eb5c75f71..b46fc76546 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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' }} From 16db309f6b14570edea2b531e8775e5a0249cf05 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 12 Sep 2020 16:51:26 +0200 Subject: [PATCH 12/13] add comments to explain the functions --- src/syscalls/random.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/syscalls/random.rs b/src/syscalls/random.rs index 2f9d919201..a7d515b301 100644 --- a/src/syscalls/random.rs +++ b/src/syscalls/random.rs @@ -9,10 +9,11 @@ use crate::arch; use crate::synch::spinlock::Spinlock; static PARK_MILLER_LEHMER_SEED: Spinlock = Spinlock::new(0); +const RAND_MAX: u32 = 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 } @@ -29,18 +30,26 @@ fn __sys_rand() -> u32 { 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 { 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 { 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()) @@ -50,6 +59,8 @@ 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)) From 3acb19100a6f57f189ec6c33f4f17583735c7b74 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 12 Sep 2020 17:01:56 +0200 Subject: [PATCH 13/13] remove typo --- src/syscalls/random.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/syscalls/random.rs b/src/syscalls/random.rs index a7d515b301..ae55259e53 100644 --- a/src/syscalls/random.rs +++ b/src/syscalls/random.rs @@ -9,7 +9,7 @@ use crate::arch; use crate::synch::spinlock::Spinlock; static PARK_MILLER_LEHMER_SEED: Spinlock = Spinlock::new(0); -const RAND_MAX: u32 = 2_147_483_647; +const RAND_MAX: u64 = 2_147_483_647; fn generate_park_miller_lehmer_random_number() -> u32 { let mut seed = PARK_MILLER_LEHMER_SEED.lock();