diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-11 12:08:47 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-11 12:08:47 -0500 |
| commit | 84c37c168c0e49a412d7021cda3183a72adac0d0 (patch) | |
| tree | 2a50857925f3b89c9b5b3b0cc7e2e7f485a95b50 | |
| parent | 434fd6353b4c83938029ca6ea7dfa4fc82d602bd (diff) | |
| parent | db61ffe3a71c697aaa91c42c862a5f7557a0e562 (diff) | |
Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random
Pull random updates from Ted Ts'o:
"Change get_random_{int,log} to use the CRNG used by /dev/urandom and
getrandom(2). It's faster and arguably more secure than cut-down MD5
that we had been using.
Also do some code cleanup"
* tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random:
random: move random_min_urandom_seed into CONFIG_SYSCTL ifdef block
random: convert get_random_int/long into get_random_u32/u64
random: use chacha20 for get_random_int/long
random: fix comment for unused random_min_urandom_seed
random: remove variable limit
random: remove stale urandom_init_wait
random: remove stale maybe_reseed_primary_crng
| -rw-r--r-- | drivers/char/random.c | 129 | ||||
| -rw-r--r-- | include/linux/random.h | 18 | ||||
| -rw-r--r-- | init/main.c | 1 |
3 files changed, 65 insertions, 83 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 1ef26403bcc8..0ab024918907 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
| @@ -313,13 +313,6 @@ static int random_read_wakeup_bits = 64; | |||
| 313 | static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS; | 313 | static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS; |
| 314 | 314 | ||
| 315 | /* | 315 | /* |
| 316 | * The minimum number of seconds between urandom pool reseeding. We | ||
| 317 | * do this to limit the amount of entropy that can be drained from the | ||
| 318 | * input pool even if there are heavy demands on /dev/urandom. | ||
| 319 | */ | ||
| 320 | static int random_min_urandom_seed = 60; | ||
| 321 | |||
| 322 | /* | ||
| 323 | * Originally, we used a primitive polynomial of degree .poolwords | 316 | * Originally, we used a primitive polynomial of degree .poolwords |
| 324 | * over GF(2). The taps for various sizes are defined below. They | 317 | * over GF(2). The taps for various sizes are defined below. They |
| 325 | * were chosen to be evenly spaced except for the last tap, which is 1 | 318 | * were chosen to be evenly spaced except for the last tap, which is 1 |
| @@ -409,7 +402,6 @@ static struct poolinfo { | |||
| 409 | */ | 402 | */ |
| 410 | static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); | 403 | static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); |
| 411 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); | 404 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); |
| 412 | static DECLARE_WAIT_QUEUE_HEAD(urandom_init_wait); | ||
| 413 | static struct fasync_struct *fasync; | 405 | static struct fasync_struct *fasync; |
| 414 | 406 | ||
| 415 | static DEFINE_SPINLOCK(random_ready_list_lock); | 407 | static DEFINE_SPINLOCK(random_ready_list_lock); |
| @@ -467,7 +459,6 @@ struct entropy_store { | |||
| 467 | int entropy_count; | 459 | int entropy_count; |
| 468 | int entropy_total; | 460 | int entropy_total; |
| 469 | unsigned int initialized:1; | 461 | unsigned int initialized:1; |
| 470 | unsigned int limit:1; | ||
| 471 | unsigned int last_data_init:1; | 462 | unsigned int last_data_init:1; |
| 472 | __u8 last_data[EXTRACT_SIZE]; | 463 | __u8 last_data[EXTRACT_SIZE]; |
| 473 | }; | 464 | }; |
| @@ -485,7 +476,6 @@ static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; | |||
| 485 | static struct entropy_store input_pool = { | 476 | static struct entropy_store input_pool = { |
| 486 | .poolinfo = &poolinfo_table[0], | 477 | .poolinfo = &poolinfo_table[0], |
| 487 | .name = "input", | 478 | .name = "input", |
| 488 | .limit = 1, | ||
| 489 | .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock), | 479 | .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock), |
| 490 | .pool = input_pool_data | 480 | .pool = input_pool_data |
| 491 | }; | 481 | }; |
| @@ -493,7 +483,6 @@ static struct entropy_store input_pool = { | |||
| 493 | static struct entropy_store blocking_pool = { | 483 | static struct entropy_store blocking_pool = { |
| 494 | .poolinfo = &poolinfo_table[1], | 484 | .poolinfo = &poolinfo_table[1], |
| 495 | .name = "blocking", | 485 | .name = "blocking", |
| 496 | .limit = 1, | ||
| 497 | .pull = &input_pool, | 486 | .pull = &input_pool, |
| 498 | .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock), | 487 | .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock), |
| 499 | .pool = blocking_pool_data, | 488 | .pool = blocking_pool_data, |
| @@ -855,13 +844,6 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) | |||
| 855 | spin_unlock_irqrestore(&primary_crng.lock, flags); | 844 | spin_unlock_irqrestore(&primary_crng.lock, flags); |
| 856 | } | 845 | } |
| 857 | 846 | ||
| 858 | static inline void maybe_reseed_primary_crng(void) | ||
| 859 | { | ||
| 860 | if (crng_init > 2 && | ||
| 861 | time_after(jiffies, primary_crng.init_time + CRNG_RESEED_INTERVAL)) | ||
| 862 | crng_reseed(&primary_crng, &input_pool); | ||
| 863 | } | ||
| 864 | |||
| 865 | static inline void crng_wait_ready(void) | 847 | static inline void crng_wait_ready(void) |
| 866 | { | 848 | { |
| 867 | wait_event_interruptible(crng_init_wait, crng_ready()); | 849 | wait_event_interruptible(crng_init_wait, crng_ready()); |
| @@ -1220,15 +1202,6 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | |||
| 1220 | r->entropy_count > r->poolinfo->poolfracbits) | 1202 | r->entropy_count > r->poolinfo->poolfracbits) |
| 1221 | return; | 1203 | return; |
| 1222 | 1204 | ||
| 1223 | if (r->limit == 0 && random_min_urandom_seed) { | ||
| 1224 | unsigned long now = jiffies; | ||
| 1225 | |||
| 1226 | if (time_before(now, | ||
| 1227 | r->last_pulled + random_min_urandom_seed * HZ)) | ||
| 1228 | return; | ||
| 1229 | r->last_pulled = now; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | _xfer_secondary_pool(r, nbytes); | 1205 | _xfer_secondary_pool(r, nbytes); |
| 1233 | } | 1206 | } |
| 1234 | 1207 | ||
| @@ -1236,8 +1209,6 @@ static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | |||
| 1236 | { | 1209 | { |
| 1237 | __u32 tmp[OUTPUT_POOL_WORDS]; | 1210 | __u32 tmp[OUTPUT_POOL_WORDS]; |
| 1238 | 1211 | ||
| 1239 | /* For /dev/random's pool, always leave two wakeups' worth */ | ||
| 1240 | int rsvd_bytes = r->limit ? 0 : random_read_wakeup_bits / 4; | ||
| 1241 | int bytes = nbytes; | 1212 | int bytes = nbytes; |
| 1242 | 1213 | ||
| 1243 | /* pull at least as much as a wakeup */ | 1214 | /* pull at least as much as a wakeup */ |
| @@ -1248,7 +1219,7 @@ static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | |||
| 1248 | trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8, | 1219 | trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8, |
| 1249 | ENTROPY_BITS(r), ENTROPY_BITS(r->pull)); | 1220 | ENTROPY_BITS(r), ENTROPY_BITS(r->pull)); |
| 1250 | bytes = extract_entropy(r->pull, tmp, bytes, | 1221 | bytes = extract_entropy(r->pull, tmp, bytes, |
| 1251 | random_read_wakeup_bits / 8, rsvd_bytes); | 1222 | random_read_wakeup_bits / 8, 0); |
| 1252 | mix_pool_bytes(r, tmp, bytes); | 1223 | mix_pool_bytes(r, tmp, bytes); |
| 1253 | credit_entropy_bits(r, bytes*8); | 1224 | credit_entropy_bits(r, bytes*8); |
| 1254 | } | 1225 | } |
| @@ -1276,7 +1247,7 @@ static void push_to_pool(struct work_struct *work) | |||
| 1276 | static size_t account(struct entropy_store *r, size_t nbytes, int min, | 1247 | static size_t account(struct entropy_store *r, size_t nbytes, int min, |
| 1277 | int reserved) | 1248 | int reserved) |
| 1278 | { | 1249 | { |
| 1279 | int entropy_count, orig; | 1250 | int entropy_count, orig, have_bytes; |
| 1280 | size_t ibytes, nfrac; | 1251 | size_t ibytes, nfrac; |
| 1281 | 1252 | ||
| 1282 | BUG_ON(r->entropy_count > r->poolinfo->poolfracbits); | 1253 | BUG_ON(r->entropy_count > r->poolinfo->poolfracbits); |
| @@ -1285,14 +1256,12 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
| 1285 | retry: | 1256 | retry: |
| 1286 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); | 1257 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); |
| 1287 | ibytes = nbytes; | 1258 | ibytes = nbytes; |
| 1288 | /* If limited, never pull more than available */ | 1259 | /* never pull more than available */ |
| 1289 | if (r->limit) { | 1260 | have_bytes = entropy_count >> (ENTROPY_SHIFT + 3); |
| 1290 | int have_bytes = entropy_count >> (ENTROPY_SHIFT + 3); | ||
| 1291 | 1261 | ||
| 1292 | if ((have_bytes -= reserved) < 0) | 1262 | if ((have_bytes -= reserved) < 0) |
| 1293 | have_bytes = 0; | 1263 | have_bytes = 0; |
| 1294 | ibytes = min_t(size_t, ibytes, have_bytes); | 1264 | ibytes = min_t(size_t, ibytes, have_bytes); |
| 1295 | } | ||
| 1296 | if (ibytes < min) | 1265 | if (ibytes < min) |
| 1297 | ibytes = 0; | 1266 | ibytes = 0; |
| 1298 | 1267 | ||
| @@ -1912,6 +1881,7 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, | |||
| 1912 | static int min_read_thresh = 8, min_write_thresh; | 1881 | static int min_read_thresh = 8, min_write_thresh; |
| 1913 | static int max_read_thresh = OUTPUT_POOL_WORDS * 32; | 1882 | static int max_read_thresh = OUTPUT_POOL_WORDS * 32; |
| 1914 | static int max_write_thresh = INPUT_POOL_WORDS * 32; | 1883 | static int max_write_thresh = INPUT_POOL_WORDS * 32; |
| 1884 | static int random_min_urandom_seed = 60; | ||
| 1915 | static char sysctl_bootid[16]; | 1885 | static char sysctl_bootid[16]; |
| 1916 | 1886 | ||
| 1917 | /* | 1887 | /* |
| @@ -2042,63 +2012,64 @@ struct ctl_table random_table[] = { | |||
| 2042 | }; | 2012 | }; |
| 2043 | #endif /* CONFIG_SYSCTL */ | 2013 | #endif /* CONFIG_SYSCTL */ |
| 2044 | 2014 | ||
| 2045 | static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; | 2015 | struct batched_entropy { |
| 2046 | 2016 | union { | |
| 2047 | int random_int_secret_init(void) | 2017 | u64 entropy_u64[CHACHA20_BLOCK_SIZE / sizeof(u64)]; |
| 2048 | { | 2018 | u32 entropy_u32[CHACHA20_BLOCK_SIZE / sizeof(u32)]; |
| 2049 | get_random_bytes(random_int_secret, sizeof(random_int_secret)); | 2019 | }; |
| 2050 | return 0; | 2020 | unsigned int position; |
| 2051 | } | 2021 | }; |
| 2052 | |||
| 2053 | static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) | ||
| 2054 | __aligned(sizeof(unsigned long)); | ||
| 2055 | 2022 | ||
| 2056 | /* | 2023 | /* |
| 2057 | * Get a random word for internal kernel use only. Similar to urandom but | 2024 | * Get a random word for internal kernel use only. The quality of the random |
| 2058 | * with the goal of minimal entropy pool depletion. As a result, the random | 2025 | * number is either as good as RDRAND or as good as /dev/urandom, with the |
| 2059 | * value is not cryptographically secure but for several uses the cost of | 2026 | * goal of being quite fast and not depleting entropy. |
| 2060 | * depleting entropy is too high | ||
| 2061 | */ | 2027 | */ |
| 2062 | unsigned int get_random_int(void) | 2028 | static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64); |
| 2029 | u64 get_random_u64(void) | ||
| 2063 | { | 2030 | { |
| 2064 | __u32 *hash; | 2031 | u64 ret; |
| 2065 | unsigned int ret; | 2032 | struct batched_entropy *batch; |
| 2066 | 2033 | ||
| 2067 | if (arch_get_random_int(&ret)) | 2034 | #if BITS_PER_LONG == 64 |
| 2035 | if (arch_get_random_long((unsigned long *)&ret)) | ||
| 2068 | return ret; | 2036 | return ret; |
| 2037 | #else | ||
| 2038 | if (arch_get_random_long((unsigned long *)&ret) && | ||
| 2039 | arch_get_random_long((unsigned long *)&ret + 1)) | ||
| 2040 | return ret; | ||
| 2041 | #endif | ||
| 2069 | 2042 | ||
| 2070 | hash = get_cpu_var(get_random_int_hash); | 2043 | batch = &get_cpu_var(batched_entropy_u64); |
| 2071 | 2044 | if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) { | |
| 2072 | hash[0] += current->pid + jiffies + random_get_entropy(); | 2045 | extract_crng((u8 *)batch->entropy_u64); |
| 2073 | md5_transform(hash, random_int_secret); | 2046 | batch->position = 0; |
| 2074 | ret = hash[0]; | 2047 | } |
| 2075 | put_cpu_var(get_random_int_hash); | 2048 | ret = batch->entropy_u64[batch->position++]; |
| 2076 | 2049 | put_cpu_var(batched_entropy_u64); | |
| 2077 | return ret; | 2050 | return ret; |
| 2078 | } | 2051 | } |
| 2079 | EXPORT_SYMBOL(get_random_int); | 2052 | EXPORT_SYMBOL(get_random_u64); |
| 2080 | 2053 | ||
| 2081 | /* | 2054 | static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32); |
| 2082 | * Same as get_random_int(), but returns unsigned long. | 2055 | u32 get_random_u32(void) |
| 2083 | */ | ||
| 2084 | unsigned long get_random_long(void) | ||
| 2085 | { | 2056 | { |
| 2086 | __u32 *hash; | 2057 | u32 ret; |
| 2087 | unsigned long ret; | 2058 | struct batched_entropy *batch; |
| 2088 | 2059 | ||
| 2089 | if (arch_get_random_long(&ret)) | 2060 | if (arch_get_random_int(&ret)) |
| 2090 | return ret; | 2061 | return ret; |
| 2091 | 2062 | ||
| 2092 | hash = get_cpu_var(get_random_int_hash); | 2063 | batch = &get_cpu_var(batched_entropy_u32); |
| 2093 | 2064 | if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) { | |
| 2094 | hash[0] += current->pid + jiffies + random_get_entropy(); | 2065 | extract_crng((u8 *)batch->entropy_u32); |
| 2095 | md5_transform(hash, random_int_secret); | 2066 | batch->position = 0; |
| 2096 | ret = *(unsigned long *)hash; | 2067 | } |
| 2097 | put_cpu_var(get_random_int_hash); | 2068 | ret = batch->entropy_u32[batch->position++]; |
| 2098 | 2069 | put_cpu_var(batched_entropy_u32); | |
| 2099 | return ret; | 2070 | return ret; |
| 2100 | } | 2071 | } |
| 2101 | EXPORT_SYMBOL(get_random_long); | 2072 | EXPORT_SYMBOL(get_random_u32); |
| 2102 | 2073 | ||
| 2103 | /** | 2074 | /** |
| 2104 | * randomize_page - Generate a random, page aligned address | 2075 | * randomize_page - Generate a random, page aligned address |
diff --git a/include/linux/random.h b/include/linux/random.h index 7bd2403e4fef..ed5c3838780d 100644 --- a/include/linux/random.h +++ b/include/linux/random.h | |||
| @@ -37,14 +37,26 @@ 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; |
| 44 | #endif | 43 | #endif |
| 45 | 44 | ||
| 46 | unsigned int get_random_int(void); | 45 | u32 get_random_u32(void); |
| 47 | unsigned long get_random_long(void); | 46 | u64 get_random_u64(void); |
| 47 | static inline unsigned int get_random_int(void) | ||
| 48 | { | ||
| 49 | return get_random_u32(); | ||
| 50 | } | ||
| 51 | static inline unsigned long get_random_long(void) | ||
| 52 | { | ||
| 53 | #if BITS_PER_LONG == 64 | ||
| 54 | return get_random_u64(); | ||
| 55 | #else | ||
| 56 | return get_random_u32(); | ||
| 57 | #endif | ||
| 58 | } | ||
| 59 | |||
| 48 | unsigned long randomize_page(unsigned long start, unsigned long range); | 60 | unsigned long randomize_page(unsigned long start, unsigned long range); |
| 49 | 61 | ||
| 50 | u32 prandom_u32(void); | 62 | u32 prandom_u32(void); |
diff --git a/init/main.c b/init/main.c index eae2f15657c6..f9c9d9948203 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -882,7 +882,6 @@ static void __init do_basic_setup(void) | |||
| 882 | do_ctors(); | 882 | do_ctors(); |
| 883 | usermodehelper_enable(); | 883 | usermodehelper_enable(); |
| 884 | do_initcalls(); | 884 | do_initcalls(); |
| 885 | random_int_secret_init(); | ||
| 886 | } | 885 | } |
| 887 | 886 | ||
| 888 | static void __init do_pre_smp_initcalls(void) | 887 | static void __init do_pre_smp_initcalls(void) |
