diff options
Diffstat (limited to 'drivers/char/random.c')
-rw-r--r-- | drivers/char/random.c | 129 |
1 files changed, 50 insertions, 79 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 |