diff options
| -rw-r--r-- | drivers/char/random.c | 84 | ||||
| -rw-r--r-- | include/linux/random.h | 1 | ||||
| -rw-r--r-- | init/main.c | 1 |
3 files changed, 43 insertions, 43 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 9d147d456598..b800e5479b7d 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
| @@ -2016,63 +2016,65 @@ struct ctl_table random_table[] = { | |||
| 2016 | }; | 2016 | }; |
| 2017 | #endif /* CONFIG_SYSCTL */ | 2017 | #endif /* CONFIG_SYSCTL */ |
| 2018 | 2018 | ||
| 2019 | static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; | 2019 | struct batched_entropy { |
| 2020 | 2020 | union { | |
| 2021 | int random_int_secret_init(void) | 2021 | unsigned long entropy_long[CHACHA20_BLOCK_SIZE / sizeof(unsigned long)]; |
| 2022 | { | 2022 | unsigned int entropy_int[CHACHA20_BLOCK_SIZE / sizeof(unsigned int)]; |
| 2023 | get_random_bytes(random_int_secret, sizeof(random_int_secret)); | 2023 | }; |
| 2024 | return 0; | 2024 | unsigned int position; |
| 2025 | } | 2025 | }; |
| 2026 | |||
| 2027 | static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) | ||
| 2028 | __aligned(sizeof(unsigned long)); | ||
| 2029 | 2026 | ||
| 2030 | /* | 2027 | /* |
| 2031 | * Get a random word for internal kernel use only. Similar to urandom but | 2028 | * Get a random word for internal kernel use only. The quality of the random |
| 2032 | * with the goal of minimal entropy pool depletion. As a result, the random | 2029 | * number is either as good as RDRAND or as good as /dev/urandom, with the |
| 2033 | * value is not cryptographically secure but for several uses the cost of | 2030 | * goal of being quite fast and not depleting entropy. |
| 2034 | * depleting entropy is too high | ||
| 2035 | */ | 2031 | */ |
| 2036 | unsigned int get_random_int(void) | 2032 | static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long); |
| 2033 | unsigned long get_random_long(void) | ||
| 2037 | { | 2034 | { |
| 2038 | __u32 *hash; | 2035 | unsigned long ret; |
| 2039 | unsigned int ret; | 2036 | struct batched_entropy *batch; |
| 2040 | 2037 | ||
| 2041 | if (arch_get_random_int(&ret)) | 2038 | if (arch_get_random_long(&ret)) |
| 2042 | return ret; | 2039 | return ret; |
| 2043 | 2040 | ||
| 2044 | hash = get_cpu_var(get_random_int_hash); | 2041 | batch = &get_cpu_var(batched_entropy_long); |
| 2045 | 2042 | if (batch->position % ARRAY_SIZE(batch->entropy_long) == 0) { | |
| 2046 | hash[0] += current->pid + jiffies + random_get_entropy(); | 2043 | extract_crng((u8 *)batch->entropy_long); |
| 2047 | md5_transform(hash, random_int_secret); | 2044 | batch->position = 0; |
| 2048 | ret = hash[0]; | 2045 | } |
| 2049 | put_cpu_var(get_random_int_hash); | 2046 | ret = batch->entropy_long[batch->position++]; |
| 2050 | 2047 | put_cpu_var(batched_entropy_long); | |
| 2051 | return ret; | 2048 | return ret; |
| 2052 | } | 2049 | } |
| 2053 | EXPORT_SYMBOL(get_random_int); | 2050 | EXPORT_SYMBOL(get_random_long); |
| 2054 | 2051 | ||
| 2055 | /* | 2052 | #if BITS_PER_LONG == 32 |
| 2056 | * Same as get_random_int(), but returns unsigned long. | 2053 | unsigned int get_random_int(void) |
| 2057 | */ | ||
| 2058 | unsigned long get_random_long(void) | ||
| 2059 | { | 2054 | { |
| 2060 | __u32 *hash; | 2055 | return get_random_long(); |
| 2061 | unsigned long ret; | 2056 | } |
| 2057 | #else | ||
| 2058 | static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int); | ||
| 2059 | unsigned int get_random_int(void) | ||
| 2060 | { | ||
| 2061 | unsigned int ret; | ||
| 2062 | struct batched_entropy *batch; | ||
| 2062 | 2063 | ||
| 2063 | if (arch_get_random_long(&ret)) | 2064 | if (arch_get_random_int(&ret)) |
| 2064 | return ret; | 2065 | return ret; |
| 2065 | 2066 | ||
| 2066 | hash = get_cpu_var(get_random_int_hash); | 2067 | batch = &get_cpu_var(batched_entropy_int); |
| 2067 | 2068 | if (batch->position % ARRAY_SIZE(batch->entropy_int) == 0) { | |
| 2068 | hash[0] += current->pid + jiffies + random_get_entropy(); | 2069 | extract_crng((u8 *)batch->entropy_int); |
| 2069 | md5_transform(hash, random_int_secret); | 2070 | batch->position = 0; |
| 2070 | ret = *(unsigned long *)hash; | 2071 | } |
| 2071 | put_cpu_var(get_random_int_hash); | 2072 | ret = batch->entropy_int[batch->position++]; |
| 2072 | 2073 | put_cpu_var(batched_entropy_int); | |
| 2073 | return ret; | 2074 | return ret; |
| 2074 | } | 2075 | } |
| 2075 | EXPORT_SYMBOL(get_random_long); | 2076 | #endif |
| 2077 | EXPORT_SYMBOL(get_random_int); | ||
| 2076 | 2078 | ||
| 2077 | /** | 2079 | /** |
| 2078 | * randomize_page - Generate a random, page aligned address | 2080 | * randomize_page - Generate a random, page aligned address |
diff --git a/include/linux/random.h b/include/linux/random.h index 7bd2403e4fef..16ab429735a7 100644 --- a/include/linux/random.h +++ b/include/linux/random.h | |||
| @@ -37,7 +37,6 @@ extern void get_random_bytes(void *buf, int nbytes); | |||
| 37 | extern int add_random_ready_callback(struct random_ready_callback *rdy); | 37 | extern int add_random_ready_callback(struct random_ready_callback *rdy); |
| 38 | extern void del_random_ready_callback(struct random_ready_callback *rdy); | 38 | extern void del_random_ready_callback(struct random_ready_callback *rdy); |
| 39 | extern void get_random_bytes_arch(void *buf, int nbytes); | 39 | extern void get_random_bytes_arch(void *buf, int nbytes); |
| 40 | extern int random_int_secret_init(void); | ||
| 41 | 40 | ||
| 42 | #ifndef MODULE | 41 | #ifndef MODULE |
| 43 | extern const struct file_operations random_fops, urandom_fops; | 42 | extern const struct file_operations random_fops, urandom_fops; |
diff --git a/init/main.c b/init/main.c index b0c9d6facef9..09beb7fc6e8c 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -879,7 +879,6 @@ static void __init do_basic_setup(void) | |||
| 879 | do_ctors(); | 879 | do_ctors(); |
| 880 | usermodehelper_enable(); | 880 | usermodehelper_enable(); |
| 881 | do_initcalls(); | 881 | do_initcalls(); |
| 882 | random_int_secret_init(); | ||
| 883 | } | 882 | } |
| 884 | 883 | ||
| 885 | static void __init do_pre_smp_initcalls(void) | 884 | static void __init do_pre_smp_initcalls(void) |
