This repository was archived by the owner on Mar 7, 2021. It is now read-only.
File tree Expand file tree Collapse file tree 8 files changed +125
-0
lines changed Expand file tree Collapse file tree 8 files changed +125
-0
lines changed Original file line number Diff line number Diff line change @@ -25,12 +25,16 @@ const INCLUDED_FUNCTIONS: &[&str] = &[
2525 "_copy_from_user" ,
2626 "alloc_chrdev_region" ,
2727 "unregister_chrdev_region" ,
28+ "wait_for_random_bytes" ,
29+ "get_random_bytes" ,
30+ "rng_is_initialized" ,
2831] ;
2932const INCLUDED_VARS : & [ & str ] = & [
3033 "EINVAL" ,
3134 "ENOMEM" ,
3235 "ESPIPE" ,
3336 "EFAULT" ,
37+ "EAGAIN" ,
3438 "__this_module" ,
3539 "FS_REQUIRES_DEV" ,
3640 "FS_BINARY_MOUNTDATA" ,
Original file line number Diff line number Diff line change 11#include <linux/cdev.h>
22#include <linux/fs.h>
33#include <linux/module.h>
4+ #include <linux/random.h>
45#include <linux/slab.h>
56#include <linux/uaccess.h>
67#include <linux/version.h>
Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ impl Error {
1010 pub const ENOMEM : Self = Error ( -( bindings:: ENOMEM as i32 ) ) ;
1111 pub const EFAULT : Self = Error ( -( bindings:: EFAULT as i32 ) ) ;
1212 pub const ESPIPE : Self = Error ( -( bindings:: ESPIPE as i32 ) ) ;
13+ pub const EAGAIN : Self = Error ( -( bindings:: EAGAIN as i32 ) ) ;
1314
1415 pub fn from_kernel_errno ( errno : c_types:: c_int ) -> Error {
1516 Error ( errno)
Original file line number Diff line number Diff line change @@ -13,6 +13,7 @@ mod error;
1313pub mod file_operations;
1414pub mod filesystem;
1515pub mod printk;
16+ pub mod random;
1617pub mod sysctl;
1718mod types;
1819pub mod user_ptr;
Original file line number Diff line number Diff line change 1+ use core:: convert:: TryInto ;
2+
3+ use crate :: { bindings, c_types, error} ;
4+
5+ /// Fills `dest` with random bytes generated from the kernel's CSPRNG. Ensures
6+ /// that the CSPRNG has been seeded before generating any random bytes, and
7+ /// will block until it's ready.
8+ pub fn getrandom ( dest : & mut [ u8 ] ) -> error:: KernelResult < ( ) > {
9+ let res = unsafe { bindings:: wait_for_random_bytes ( ) } ;
10+ if res != 0 {
11+ return Err ( error:: Error :: from_kernel_errno ( res) ) ;
12+ }
13+
14+ unsafe {
15+ bindings:: get_random_bytes (
16+ dest. as_mut_ptr ( ) as * mut c_types:: c_void ,
17+ dest. len ( ) . try_into ( ) ?,
18+ ) ;
19+ }
20+ Ok ( ( ) )
21+ }
22+
23+ /// Fills `dest` with random bytes generated from the kernel's CSPRNG. If the
24+ /// CSPRNG is not yet seeded, returns an `Err(EAGAIN)` immediately. Only
25+ /// available on 4.19 and later kernels.
26+ #[ cfg( kernel_4_19_0_or_greater) ]
27+ pub fn getrandom_nonblock ( dest : & mut [ u8 ] ) -> error:: KernelResult < ( ) > {
28+ if !unsafe { bindings:: rng_is_initialized ( ) } {
29+ return Err ( error:: Error :: EAGAIN ) ;
30+ }
31+ getrandom ( dest)
32+ }
Original file line number Diff line number Diff line change 1+ [package ]
2+ name = " random-tests"
3+ version = " 0.1.0"
4+ authors = [" Alex Gaynor <alex.gaynor@gmail.com>" , " Geoffrey Thomas <geofft@ldpreload.com>" ]
5+ edition = " 2018"
6+
7+ [lib ]
8+ crate-type = [" staticlib" ]
9+ test = false
10+
11+ [features ]
12+ default = [" linux-kernel-module" ]
13+
14+ [dependencies ]
15+ linux-kernel-module = { path = " ../.." , optional = true }
16+
17+ [dev-dependencies ]
18+ kernel-module-testlib = { path = " ../../testlib" }
Original file line number Diff line number Diff line change 1+ #![ no_std]
2+
3+ use alloc:: vec;
4+
5+ use linux_kernel_module:: sysctl:: { Sysctl , SysctlStorage } ;
6+ use linux_kernel_module:: { self , cstr, random, Mode } ;
7+
8+ struct EntropySource ;
9+
10+ impl SysctlStorage for EntropySource {
11+ fn store_value ( & self , _data : & [ u8 ] ) -> ( usize , linux_kernel_module:: KernelResult < ( ) > ) {
12+ ( 0 , Err ( linux_kernel_module:: Error :: EINVAL ) )
13+ }
14+
15+ fn read_value (
16+ & self ,
17+ data : & mut linux_kernel_module:: user_ptr:: UserSlicePtrWriter ,
18+ ) -> ( usize , linux_kernel_module:: KernelResult < ( ) > ) {
19+ let mut storage = vec ! [ 0 ; data. len( ) ] ;
20+ if let Err ( e) = random:: getrandom ( & mut storage) {
21+ return ( 0 , Err ( e) ) ;
22+ }
23+ ( storage. len ( ) , data. write ( & storage) )
24+ }
25+ }
26+
27+ struct RandomTestModule {
28+ _sysctl_entropy : Sysctl < EntropySource > ,
29+ }
30+
31+ impl linux_kernel_module:: KernelModule for RandomTestModule {
32+ fn init ( ) -> linux_kernel_module:: KernelResult < Self > {
33+ Ok ( RandomTestModule {
34+ _sysctl_entropy : Sysctl :: register (
35+ cstr ! ( "rust/random-tests" ) ,
36+ cstr ! ( "entropy" ) ,
37+ EntropySource ,
38+ Mode :: from_int ( 0o444 ) ,
39+ ) ?,
40+ } )
41+ }
42+ }
43+
44+ linux_kernel_module:: kernel_module!(
45+ RandomTestModule ,
46+ author: "Fish in a Barrel Contributors" ,
47+ description: "A module for testing the CSPRNG" ,
48+ license: "GPL"
49+ ) ;
Original file line number Diff line number Diff line change 1+ use std:: collections:: HashSet ;
2+ use std:: fs;
3+ use std:: io:: Read ;
4+
5+ use kernel_module_testlib:: with_kernel_module;
6+
7+ #[ test]
8+ fn test_random_entropy ( ) {
9+ with_kernel_module ( || {
10+ let mut keys = HashSet :: new ( ) ;
11+ for _ in 0 ..1024 {
12+ let mut key = [ 0 ; 16 ] ;
13+ let mut f = fs:: File :: open ( "/proc/sys/rust/random-tests/entropy" ) . unwrap ( ) ;
14+ f. read_exact ( & mut key) . unwrap ( ) ;
15+ keys. insert ( key) ;
16+ }
17+ assert_eq ! ( keys. len( ) , 1024 ) ;
18+ } ) ;
19+ }
You can’t perform that action at this time.
0 commit comments