Patch "random: use chacha20 for get_random_int/long" has been added to the 4.10-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
random: use chacha20 for get_random_int/long
to the 4.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
random-use-chacha20-for-get_random_int-long.patch
and it can be found in the queue-4.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
f5b98461cb8167ba362ad9f74c41d126b7becea7Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld" <[email protected]>
Date: Fri, 6 Jan 2017 19:32:01 +0100
Subject: random: use chacha20 for get_random_int/long
From: Jason A. Donenfeld <[email protected]>
commit f5b98461cb8167ba362ad9f74c41d126b7becea7 upstream.
Now that our crng uses chacha20, we can rely on its speedy characteristics for replacing MD5, while simultaneously achieving a higher security guarantee. Before the idea was to use these functions if you wanted random integers that aren't stupidly insecure but aren't necessarily secure either, a vague gray zone, that hopefully was "good enough" for its users. With chacha20, we can strengthen this claim, since either we're using an rdrand-like instruction, or we're using the same crng as /dev/urandom. And it's faster than what was before.
We could have chosen to replace this with a SipHash-derived function, which might be slightly faster, but at the cost of having yet another RNG construction in the kernel. By moving to chacha20, we have a single RNG to analyze and verify, and we also already get good performance improvements on all platforms.
Implementation-wise, rather than use a generic buffer for both get_random_int/long and memcpy based on the size needs, we use a specific buffer for 32-bit reads and for 64-bit reads. This way, we're guaranteed to always have aligned accesses on all platforms. While slightly more verbose in C, the assembly this generates is a lot simpler than otherwise.
Finally, on 32-bit platforms where longs and ints are the same size, we simply alias get_random_int to get_random_long.
--- drivers/char/random.c | 84 +++++++++++++++++++++++++------------------------ include/linux/random.h | 1 init/main.c | 1 3 files changed, 43 insertions(+), 43 deletions(-)
drivers/char/random.c +43 -41
@@ -2042,63 +2042,65 @@ struct ctl_table random_table[] = { };#endif /* CONFIG_SYSCTL */ -static u32 random_int_secret[MD5_MESSAGE_BYTES /4 ]____cacheline_aligned ; - -int random_int_secret_init (void ) -{ -get_random_bytes (random_int_secret,sizeof (random_int_secret)); -return 0 ; -} - -static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) -__aligned(sizeof(unsigned long)) ; +struct batched_entropy { +union { +unsigned long entropy_long[CHACHA20_BLOCK_SIZE /sizeof (unsigned long )]; +unsigned int entropy_int[CHACHA20_BLOCK_SIZE /sizeof (unsigned int )]; + }; +unsigned int position; +};/* -* Get a random word for internal kernel use only. Similar to urandom but -* with the goal of minimal entropy pool depletion. As a result, the random -* value is not cryptographically secure but for several uses the cost of -* depleting entropy is too high +* Get a random word for internal kernel use only. The quality of the random +* number is either as good as RDRAND or as good as /dev/urandom, with the +* goal of being quite fast and not depleting entropy. */ -unsigned int get_random_int (void ) +static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long); +unsigned long get_random_long (void ) { -__u32 *hash; -unsigned int ret; +unsigned long ret; +struct batched_entropy *batch; -if (arch_get_random_int (&ret)) +if (arch_get_random_long (&ret))return ret; - hash =get_cpu_var (get_random_int_hash); - - hash[0 ] += current->pid + jiffies +random_get_entropy (); -md5_transform (hash, random_int_secret); - ret = hash[0 ]; -put_cpu_var (get_random_int_hash); - + batch = &get_cpu_var (batched_entropy_long); +if (batch->position %ARRAY_SIZE (batch->entropy_long) ==0 ) { +extract_crng ((u8 *)batch->entropy_long); + batch->position =0 ; + } + ret = batch->entropy_long[batch->position++]; +put_cpu_var (batched_entropy_long);return ret; } -EXPORT_SYMBOL (get_random_int); +EXPORT_SYMBOL (get_random_long); -/* -* Same as get_random_int(), but returns unsigned long. -*/ -unsigned long get_random_long (void ) +#if BITS_PER_LONG ==32 +unsigned int get_random_int (void ) { -__u32 *hash; -unsigned long ret; +return get_random_long (); +} +#else +static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int); +unsigned int get_random_int (void ) +{ +unsigned int ret; +struct batched_entropy *batch; -if (arch_get_random_long (&ret)) +if (arch_get_random_int (&ret))return ret; - hash =get_cpu_var (get_random_int_hash); - - hash[0 ] += current->pid + jiffies +random_get_entropy (); -md5_transform (hash, random_int_secret); - ret = *(unsigned long *)hash; -put_cpu_var (get_random_int_hash); - + batch = &get_cpu_var (batched_entropy_int); +if (batch->position %ARRAY_SIZE (batch->entropy_int) ==0 ) { +extract_crng ((u8 *)batch->entropy_int); + batch->position =0 ; + } + ret = batch->entropy_int[batch->position++]; +put_cpu_var (batched_entropy_int);return ret; } -EXPORT_SYMBOL (get_random_long); +#endif +EXPORT_SYMBOL (get_random_int);/** * randomize_page - Generate a random, page aligned address
include/linux/random.h +0 -1
@@ -37,7 +37,6 @@ extern void get_random_bytes(void *buf,extern int add_random_ready_callback (struct random_ready_callback *rdy);extern void del_random_ready_callback (struct random_ready_callback *rdy);extern void get_random_bytes_arch (void *buf,int nbytes); -extern int random_int_secret_init (void );#ifndef MODULE extern const struct file_operations random_fops, urandom_fops;
init/main.c +0 -1
@@ -879,7 +879,6 @@ static void __init do_basic_setup(void)do_ctors ();usermodehelper_enable ();do_initcalls (); -random_int_secret_init (); }static void __init do_pre_smp_initcalls (void )
Patches currently in stable-queue which might be from [email protected] are
queue-4.10/random-use-chacha20-for-get_random_int-long.patch