| @@ -250,6 +250,7 @@ · 249 unmodified lines |
| 250 | 250 | #include <linux/interrupt.h> |
| 251 | 251 | #include <linux/mm.h> |
| 252 | 252 | #include <linux/spinlock.h> |
| 253 | +#include <linux/kthread.h> |
| 253 | 254 | #include <linux/percpu.h> |
| 254 | 255 | #include <linux/cryptohash.h> |
| 255 | 256 | #include <linux/fips.h> |
| @@ -257,6 +258,8 @@ · 1 unmodified line |
| 257 | 258 | #include <linux/kmemcheck.h> |
| 258 | 259 | #include <linux/workqueue.h> |
| 259 | 260 | #include <linux/irq.h> |
| 261 | +#include <linux/syscalls.h> |
| 262 | +#include <linux/completion.h> |
| 260 | 263 | |
| 261 | 264 | #include <asm/processor.h> |
| 262 | 265 | #include <asm/uaccess.h> |
| @@ -267,6 +270,8 @@ · 4 unmodified lines |
| 267 | 270 | #define CREATE_TRACE_POINTS |
| 268 | 271 | #include <trace/events/random.h> |
| 269 | 272 | |
| 273 | +/* #define ADD_INTERRUPT_BENCH */ |
| 274 | + |
| 270 | 275 | /* |
| 271 | 276 | * Configuration information |
| 272 | 277 | */ |
| @@ -401,6 +406,7 @@ static struct poolinfo { · 128 unmodified lines |
| 401 | 406 | */ |
| 402 | 407 | static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); |
| 403 | 408 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); |
| 409 | +static DECLARE_WAIT_QUEUE_HEAD(urandom_init_wait); |
| 404 | 410 | static struct fasync_struct *fasync; |
| 405 | 411 | |
| 406 | 412 | /********************************************************************** |
| @@ -481,9 +487,9 @@ static __u32 const twist_table[8] = { · 74 unmodified lines |
| 481 | 487 | * the entropy is concentrated in the low-order bits. |
| 482 | 488 | */ |
| 483 | 489 | static void _mix_pool_bytes(struct entropy_store *r, const void *in, |
| 484 | | − int nbytes, __u8 out[64]) |
| 490 | + int nbytes) |
| 485 | 491 | { |
| 486 | | − unsigned long i, j, tap1, tap2, tap3, tap4, tap5; |
| 492 | + unsigned long i, tap1, tap2, tap3, tap4, tap5; |
| 487 | 493 | int input_rotate; |
| 488 | 494 | int wordmask = r->poolinfo->poolwords - 1; |
| 489 | 495 | const char *bytes = in; |
| @@ -495,9 +501,8 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in, · 5 unmodified lines |
| 495 | 501 | tap4 = r->poolinfo->tap4; |
| 496 | 502 | tap5 = r->poolinfo->tap5; |
| 497 | 503 | |
| 498 | | − smp_rmb(); |
| 499 | | − input_rotate = ACCESS_ONCE(r->input_rotate); |
| 500 | | − i = ACCESS_ONCE(r->add_ptr); |
| 504 | + input_rotate = r->input_rotate; |
| 505 | + i = r->add_ptr; |
| 501 | 506 | |
| 502 | 507 | /* mix one byte at a time to simplify size handling and churn faster */ |
| 503 | 508 | while (nbytes--) { |
| @@ -524,39 +529,33 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in, · 20 unmodified lines |
| 524 | 529 | input_rotate = (input_rotate + (i ? 7 : 14)) & 31; |
| 525 | 530 | } |
| 526 | 531 | |
| 527 | | − ACCESS_ONCE(r->input_rotate) = input_rotate; |
| 528 | | − ACCESS_ONCE(r->add_ptr) = i; |
| 529 | | − smp_wmb(); |
| 530 | | − |
| 531 | | − if (out) |
| 532 | | − for (j = 0; j < 16; j++) |
| 533 | | − ((__u32 *)out)[j] = r->pool[(i - j) & wordmask]; |
| 532 | + r->input_rotate = input_rotate; |
| 533 | + r->add_ptr = i; |
| 534 | 534 | } |
| 535 | 535 | |
| 536 | 536 | static void __mix_pool_bytes(struct entropy_store *r, const void *in, |
| 537 | | − int nbytes, __u8 out[64]) |
| 537 | + int nbytes) |
| 538 | 538 | { |
| 539 | 539 | trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_); |
| 540 | | − _mix_pool_bytes(r, in, nbytes, out); |
| 540 | + _mix_pool_bytes(r, in, nbytes); |
| 541 | 541 | } |
| 542 | 542 | |
| 543 | 543 | static void mix_pool_bytes(struct entropy_store *r, const void *in, |
| 544 | | − int nbytes, __u8 out[64]) |
| 544 | + int nbytes) |
| 545 | 545 | { |
| 546 | 546 | unsigned long flags; |
| 547 | 547 | |
| 548 | 548 | trace_mix_pool_bytes(r->name, nbytes, _RET_IP_); |
| 549 | 549 | spin_lock_irqsave(&r->lock, flags); |
| 550 | | − _mix_pool_bytes(r, in, nbytes, out); |
| 550 | + _mix_pool_bytes(r, in, nbytes); |
| 551 | 551 | spin_unlock_irqrestore(&r->lock, flags); |
| 552 | 552 | } |
| 553 | 553 | |
| 554 | 554 | struct fast_pool { |
| 555 | 555 | __u32 pool[4]; |
| 556 | 556 | unsigned long last; |
| 557 | | − unsigned short count; |
| 558 | | − unsigned char rotate; |
| 559 | | − unsigned char last_timer_intr; |
| 557 | + unsigned short reg_idx; |
| 558 | + unsigned char count; |
| 560 | 559 | }; |
| 561 | 560 | |
| 562 | 561 | /* |
| @@ -564,25 +563,29 @@ struct fast_pool { · 1 unmodified line |
| 564 | 563 | * collector. It's hardcoded for an 128 bit pool and assumes that any |
| 565 | 564 | * locks that might be needed are taken by the caller. |
| 566 | 565 | */ |
| 567 | | −static void fast_mix(struct fast_pool *f, __u32 input[4]) |
| 566 | +static void fast_mix(struct fast_pool *f) |
| 568 | 567 | { |
| 569 | | − __u32 w; |
| 570 | | − unsigned input_rotate = f->rotate; |
| 571 | | − |
| 572 | | − w = rol32(input[0], input_rotate) ^ f->pool[0] ^ f->pool[3]; |
| 573 | | − f->pool[0] = (w >> 3) ^ twist_table[w & 7]; |
| 574 | | − input_rotate = (input_rotate + 14) & 31; |
| 575 | | − w = rol32(input[1], input_rotate) ^ f->pool[1] ^ f->pool[0]; |
| 576 | | − f->pool[1] = (w >> 3) ^ twist_table[w & 7]; |
| 577 | | − input_rotate = (input_rotate + 7) & 31; |
| 578 | | − w = rol32(input[2], input_rotate) ^ f->pool[2] ^ f->pool[1]; |
| 579 | | − f->pool[2] = (w >> 3) ^ twist_table[w & 7]; |
| 580 | | − input_rotate = (input_rotate + 7) & 31; |
| 581 | | − w = rol32(input[3], input_rotate) ^ f->pool[3] ^ f->pool[2]; |
| 582 | | − f->pool[3] = (w >> 3) ^ twist_table[w & 7]; |
| 583 | | − input_rotate = (input_rotate + 7) & 31; |
| 584 | | − |
| 585 | | − f->rotate = input_rotate; |
| 568 | + __u32 a = f->pool[0], b = f->pool[1]; |
| 569 | + __u32 c = f->pool[2], d = f->pool[3]; |
| 570 | + |
| 571 | + a += b; c += d; |
| 572 | + b = rol32(a, 6); d = rol32(c, 27); |
| 573 | + d ^= a; b ^= c; |
| 574 | + |
| 575 | + a += b; c += d; |
| 576 | + b = rol32(a, 16); d = rol32(c, 14); |
| 577 | + d ^= a; b ^= c; |
| 578 | + |
| 579 | + a += b; c += d; |
| 580 | + b = rol32(a, 6); d = rol32(c, 27); |
| 581 | + d ^= a; b ^= c; |
| 582 | + |
| 583 | + a += b; c += d; |
| 584 | + b = rol32(a, 16); d = rol32(c, 14); |
| 585 | + d ^= a; b ^= c; |
| 586 | + |
| 587 | + f->pool[0] = a; f->pool[1] = b; |
| 588 | + f->pool[2] = c; f->pool[3] = d; |
| 586 | 589 | f->count++; |
| 587 | 590 | } |
| 588 | 591 | |
| @@ -657,6 +660,7 @@ retry: · 68 unmodified lines |
| 657 | 660 | r->entropy_total = 0; |
| 658 | 661 | if (r == &nonblocking_pool) { |
| 659 | 662 | prandom_reseed_late(); |
| 663 | + wake_up_interruptible(&urandom_init_wait); |
| 660 | 664 | pr_notice("random: %s pool is initialized\n", r->name); |
| 661 | 665 | } |
| 662 | 666 | } |
| @@ -739,13 +743,13 @@ void add_device_randomness(const void *buf, unsigned int size) · 76 unmodified lines |
| 739 | 743 | |
| 740 | 744 | trace_add_device_randomness(size, _RET_IP_); |
| 741 | 745 | spin_lock_irqsave(&input_pool.lock, flags); |
| 742 | | − _mix_pool_bytes(&input_pool, buf, size, NULL); |
| 743 | | − _mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); |
| 746 | + _mix_pool_bytes(&input_pool, buf, size); |
| 747 | + _mix_pool_bytes(&input_pool, &time, sizeof(time)); |
| 744 | 748 | spin_unlock_irqrestore(&input_pool.lock, flags); |
| 745 | 749 | |
| 746 | 750 | spin_lock_irqsave(&nonblocking_pool.lock, flags); |
| 747 | | − _mix_pool_bytes(&nonblocking_pool, buf, size, NULL); |
| 748 | | − _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); |
| 751 | + _mix_pool_bytes(&nonblocking_pool, buf, size); |
| 752 | + _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time)); |
| 749 | 753 | spin_unlock_irqrestore(&nonblocking_pool.lock, flags); |
| 750 | 754 | } |
| 751 | 755 | EXPORT_SYMBOL(add_device_randomness); |
| @@ -778,7 +782,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) · 26 unmodified lines |
| 778 | 782 | sample.cycles = random_get_entropy(); |
| 779 | 783 | sample.num = num; |
| 780 | 784 | r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; |
| 781 | | − mix_pool_bytes(r, &sample, sizeof(sample), NULL); |
| 785 | + mix_pool_bytes(r, &sample, sizeof(sample)); |
| 782 | 786 | |
| 783 | 787 | /* |
| 784 | 788 | * Calculate number of bits of randomness we probably added. |
| @@ -835,6 +839,38 @@ EXPORT_SYMBOL_GPL(add_input_randomness); · 50 unmodified lines |
| 835 | 839 | |
| 836 | 840 | static DEFINE_PER_CPU(struct fast_pool, irq_randomness); |
| 837 | 841 | |
| 842 | +#ifdef ADD_INTERRUPT_BENCH |
| 843 | +static unsigned long avg_cycles, avg_deviation; |
| 844 | + |
| 845 | +#define AVG_SHIFT 8 /* Exponential average factor k=1/256 */ |
| 846 | +#define FIXED_1_2 (1 << (AVG_SHIFT-1)) |
| 847 | + |
| 848 | +static void add_interrupt_bench(cycles_t start) |
| 849 | +{ |
| 850 | + long delta = random_get_entropy() - start; |
| 851 | + |
| 852 | + /* Use a weighted moving average */ |
| 853 | + delta = delta - ((avg_cycles + FIXED_1_2) >> AVG_SHIFT); |
| 854 | + avg_cycles += delta; |
| 855 | + /* And average deviation */ |
| 856 | + delta = abs(delta) - ((avg_deviation + FIXED_1_2) >> AVG_SHIFT); |
| 857 | + avg_deviation += delta; |
| 858 | +} |
| 859 | +#else |
| 860 | +#define add_interrupt_bench(x) |
| 861 | +#endif |
| 862 | + |
| 863 | +static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs) |
| 864 | +{ |
| 865 | + __u32 *ptr = (__u32 *) regs; |
| 866 | + |
| 867 | + if (regs == NULL) |
| 868 | + return 0; |
| 869 | + if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32)) |
| 870 | + f->reg_idx = 0; |
| 871 | + return *(ptr + f->reg_idx++); |
| 872 | +} |
| 873 | + |
| 838 | 874 | void add_interrupt_randomness(int irq, int irq_flags) |
| 839 | 875 | { |
| 840 | 876 | struct entropy_store *r; |
| @@ -842,55 +878,52 @@ void add_interrupt_randomness(int irq, int irq_flags) · 1 unmodified line |
| 842 | 878 | struct pt_regs *regs = get_irq_regs(); |
| 843 | 879 | unsigned long now = jiffies; |
| 844 | 880 | cycles_t cycles = random_get_entropy(); |
| 845 | | − __u32 input[4], c_high, j_high; |
| 881 | + __u32 c_high, j_high; |
| 846 | 882 | __u64 ip; |
| 847 | 883 | unsigned long seed; |
| 848 | | − int credit; |
| 884 | + int credit = 0; |
| 849 | 885 | |
| 886 | + if (cycles == 0) |
| 887 | + cycles = get_reg(fast_pool, regs); |
| 850 | 888 | c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0; |
| 851 | 889 | j_high = (sizeof(now) > 4) ? now >> 32 : 0; |
| 852 | | − input[0] = cycles ^ j_high ^ irq; |
| 853 | | − input[1] = now ^ c_high; |
| 890 | + fast_pool->pool[0] ^= cycles ^ j_high ^ irq; |
| 891 | + fast_pool->pool[1] ^= now ^ c_high; |
| 854 | 892 | ip = regs ? instruction_pointer(regs) : _RET_IP_; |
| 855 | | − input[2] = ip; |
| 856 | | − input[3] = ip >> 32; |
| 893 | + fast_pool->pool[2] ^= ip; |
| 894 | + fast_pool->pool[3] ^= (sizeof(ip) > 4) ? ip >> 32 : |
| 895 | + get_reg(fast_pool, regs); |
| 857 | 896 | |
| 858 | | − fast_mix(fast_pool, input); |
| 897 | + fast_mix(fast_pool); |
| 898 | + add_interrupt_bench(cycles); |
| 859 | 899 | |
| 860 | | − if ((fast_pool->count & 63) && !time_after(now, fast_pool->last + HZ)) |
| 900 | + if ((fast_pool->count < 64) && |
| 901 | + !time_after(now, fast_pool->last + HZ)) |
| 861 | 902 | return; |
| 862 | 903 | |
| 863 | | − fast_pool->last = now; |
| 864 | | − |
| 865 | 904 | r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; |
| 866 | | − __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL); |
| 905 | + if (!spin_trylock(&r->lock)) |
| 906 | + return; |
| 867 | 907 | |
| 868 | | − /* |
| 869 | | − * If we don't have a valid cycle counter, and we see |
| 870 | | − * back-to-back timer interrupts, then skip giving credit for |
| 871 | | − * any entropy, otherwise credit 1 bit. |
| 872 | | − */ |
| 873 | | − credit = 1; |
| 874 | | − if (cycles == 0) { |
| 875 | | − if (irq_flags & __IRQF_TIMER) { |
| 876 | | − if (fast_pool->last_timer_intr) |
| 877 | | − credit = 0; |
| 878 | | − fast_pool->last_timer_intr = 1; |
| 879 | | − } else |
| 880 | | − fast_pool->last_timer_intr = 0; |
| 881 | | − } |
| 908 | + fast_pool->last = now; |
| 909 | + __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool)); |
| 882 | 910 | |
| 883 | 911 | /* |
| 884 | 912 | * If we have architectural seed generator, produce a seed and |
| 885 | | − * add it to the pool. For the sake of paranoia count it as |
| 886 | | − * 50% entropic. |
| 913 | + * add it to the pool. For the sake of paranoia don't let the |
| 914 | + * architectural seed generator dominate the input from the |
| 915 | + * interrupt noise. |
| 887 | 916 | */ |
| 888 | 917 | if (arch_get_random_seed_long(&seed)) { |
| 889 | | − __mix_pool_bytes(r, &seed, sizeof(seed), NULL); |
| 890 | | − credit += sizeof(seed) * 4; |
| 918 | + __mix_pool_bytes(r, &seed, sizeof(seed)); |
| 919 | + credit = 1; |
| 891 | 920 | } |
| 921 | + spin_unlock(&r->lock); |
| 892 | 922 | |
| 893 | | − credit_entropy_bits(r, credit); |
| 923 | + fast_pool->count = 0; |
| 924 | + |
| 925 | + /* award one bit for the contents of the fast pool */ |
| 926 | + credit_entropy_bits(r, credit + 1); |
| 894 | 927 | } |
| 895 | 928 | |
| 896 | 929 | #ifdef CONFIG_BLOCK |
| @@ -922,6 +955,11 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, · 25 unmodified lines |
| 922 | 955 | static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes); |
| 923 | 956 | static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) |
| 924 | 957 | { |
| 958 | + if (!r->pull || |
| 959 | + r->entropy_count >= (nbytes << (ENTROPY_SHIFT + 3)) || |
| 960 | + r->entropy_count > r->poolinfo->poolfracbits) |
| 961 | + return; |
| 962 | + |
| 925 | 963 | if (r->limit == 0 && random_min_urandom_seed) { |
| 926 | 964 | unsigned long now = jiffies; |
| 927 | 965 | |
| @@ -930,10 +968,8 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) · 2 unmodified lines |
| 930 | 968 | return; |
| 931 | 969 | r->last_pulled = now; |
| 932 | 970 | } |
| 933 | | − if (r->pull && |
| 934 | | − r->entropy_count < (nbytes << (ENTROPY_SHIFT + 3)) && |
| 935 | | − r->entropy_count < r->poolinfo->poolfracbits) |
| 936 | | − _xfer_secondary_pool(r, nbytes); |
| 971 | + |
| 972 | + _xfer_secondary_pool(r, nbytes); |
| 937 | 973 | } |
| 938 | 974 | |
| 939 | 975 | static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) |
| @@ -953,7 +989,7 @@ static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) · 13 unmodified lines |
| 953 | 989 | ENTROPY_BITS(r), ENTROPY_BITS(r->pull)); |
| 954 | 990 | bytes = extract_entropy(r->pull, tmp, bytes, |
| 955 | 991 | random_read_wakeup_bits / 8, rsvd_bytes); |
| 956 | | − mix_pool_bytes(r, tmp, bytes, NULL); |
| 992 | + mix_pool_bytes(r, tmp, bytes); |
| 957 | 993 | credit_entropy_bits(r, bytes*8); |
| 958 | 994 | } |
| 959 | 995 | |
| @@ -1039,7 +1075,6 @@ static void extract_buf(struct entropy_store *r, __u8 *out) · 79 unmodified lines |
| 1039 | 1075 | unsigned long l[LONGS(20)]; |
| 1040 | 1076 | } hash; |
| 1041 | 1077 | __u32 workspace[SHA_WORKSPACE_WORDS]; |
| 1042 | | − __u8 extract[64]; |
| 1043 | 1078 | unsigned long flags; |
| 1044 | 1079 | |
| 1045 | 1080 | /* |
| @@ -1068,15 +1103,9 @@ static void extract_buf(struct entropy_store *r, __u8 *out) · 22 unmodified lines |
| 1068 | 1103 | * brute-forcing the feedback as hard as brute-forcing the |
| 1069 | 1104 | * hash. |
| 1070 | 1105 | */ |
| 1071 | | − __mix_pool_bytes(r, hash.w, sizeof(hash.w), extract); |
| 1106 | + __mix_pool_bytes(r, hash.w, sizeof(hash.w)); |
| 1072 | 1107 | spin_unlock_irqrestore(&r->lock, flags); |
| 1073 | 1108 | |
| 1074 | | − /* |
| 1075 | | − * To avoid duplicates, we atomically extract a portion of the |
| 1076 | | − * pool while mixing, and hash one final time. |
| 1077 | | − */ |
| 1078 | | − sha_transform(hash.w, extract, workspace); |
| 1079 | | − memset(extract, 0, sizeof(extract)); |
| 1080 | 1109 | memset(workspace, 0, sizeof(workspace)); |
| 1081 | 1110 | |
| 1082 | 1111 | /* |
| @@ -1160,13 +1189,14 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, · 77 unmodified lines |
| 1160 | 1189 | { |
| 1161 | 1190 | ssize_t ret = 0, i; |
| 1162 | 1191 | __u8 tmp[EXTRACT_SIZE]; |
| 1192 | + int large_request = (nbytes > 256); |
| 1163 | 1193 | |
| 1164 | 1194 | trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_); |
| 1165 | 1195 | xfer_secondary_pool(r, nbytes); |
| 1166 | 1196 | nbytes = account(r, nbytes, 0, 0); |
| 1167 | 1197 | |
| 1168 | 1198 | while (nbytes) { |
| 1169 | | − if (need_resched()) { |
| 1199 | + if (large_request && need_resched()) { |
| 1170 | 1200 | if (signal_pending(current)) { |
| 1171 | 1201 | if (ret == 0) |
| 1172 | 1202 | ret = -ERESTARTSYS; |
| @@ -1263,14 +1293,14 @@ static void init_std_data(struct entropy_store *r) · 90 unmodified lines |
| 1263 | 1293 | unsigned long rv; |
| 1264 | 1294 | |
| 1265 | 1295 | r->last_pulled = jiffies; |
| 1266 | | − mix_pool_bytes(r, &now, sizeof(now), NULL); |
| 1296 | + mix_pool_bytes(r, &now, sizeof(now)); |
| 1267 | 1297 | for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) { |
| 1268 | 1298 | if (!arch_get_random_seed_long(&rv) && |
| 1269 | 1299 | !arch_get_random_long(&rv)) |
| 1270 | 1300 | rv = random_get_entropy(); |
| 1271 | | − mix_pool_bytes(r, &rv, sizeof(rv), NULL); |
| 1301 | + mix_pool_bytes(r, &rv, sizeof(rv)); |
| 1272 | 1302 | } |
| 1273 | | − mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); |
| 1303 | + mix_pool_bytes(r, utsname(), sizeof(*(utsname()))); |
| 1274 | 1304 | } |
| 1275 | 1305 | |
| 1276 | 1306 | /* |
| @@ -1309,39 +1339,8 @@ void rand_initialize_disk(struct gendisk *disk) · 32 unmodified lines |
| 1309 | 1339 | } |
| 1310 | 1340 | #endif |
| 1311 | 1341 | |
| 1312 | | −/* |
| 1313 | | − * Attempt an emergency refill using arch_get_random_seed_long(). |
| 1314 | | − * |
| 1315 | | − * As with add_interrupt_randomness() be paranoid and only |
| 1316 | | − * credit the output as 50% entropic. |
| 1317 | | − */ |
| 1318 | | −static int arch_random_refill(void) |
| 1319 | | −{ |
| 1320 | | − const unsigned int nlongs = 64; /* Arbitrary number */ |
| 1321 | | − unsigned int n = 0; |
| 1322 | | − unsigned int i; |
| 1323 | | − unsigned long buf[nlongs]; |
| 1324 | | − |
| 1325 | | − if (!arch_has_random_seed()) |
| 1326 | | − return 0; |
| 1327 | | − |
| 1328 | | − for (i = 0; i < nlongs; i++) { |
| 1329 | | − if (arch_get_random_seed_long(&buf[n])) |
| 1330 | | − n++; |
| 1331 | | − } |
| 1332 | | − |
| 1333 | | − if (n) { |
| 1334 | | − unsigned int rand_bytes = n * sizeof(unsigned long); |
| 1335 | | − |
| 1336 | | − mix_pool_bytes(&input_pool, buf, rand_bytes, NULL); |
| 1337 | | − credit_entropy_bits(&input_pool, rand_bytes*4); |
| 1338 | | − } |
| 1339 | | − |
| 1340 | | − return n; |
| 1341 | | −} |
| 1342 | | − |
| 1343 | 1342 | static ssize_t |
| 1344 | | −random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
| 1343 | +_random_read(int nonblock, char __user *buf, size_t nbytes) |
| 1345 | 1344 | { |
| 1346 | 1345 | ssize_t n; |
| 1347 | 1346 | |
| @@ -1360,12 +1359,7 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) · 12 unmodified lines |
| 1360 | 1359 | return n; |
| 1361 | 1360 | |
| 1362 | 1361 | /* Pool is (near) empty. Maybe wait and retry. */ |
| 1363 | | − |
| 1364 | | − /* First try an emergency refill */ |
| 1365 | | − if (arch_random_refill()) |
| 1366 | | − continue; |
| 1367 | | − |
| 1368 | | − if (file->f_flags & O_NONBLOCK) |
| 1362 | + if (nonblock) |
| 1369 | 1363 | return -EAGAIN; |
| 1370 | 1364 | |
| 1371 | 1365 | wait_event_interruptible(random_read_wait, |
| @@ -1376,6 +1370,12 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) · 4 unmodified lines |
| 1376 | 1370 | } |
| 1377 | 1371 | } |
| 1378 | 1372 | |
| 1373 | +static ssize_t |
| 1374 | +random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
| 1375 | +{ |
| 1376 | + return _random_read(file->f_flags & O_NONBLOCK, buf, nbytes); |
| 1377 | +} |
| 1378 | + |
| 1379 | 1379 | static ssize_t |
| 1380 | 1380 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
| 1381 | 1381 | { |
| @@ -1424,7 +1424,7 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count) · 42 unmodified lines |
| 1424 | 1424 | count -= bytes; |
| 1425 | 1425 | p += bytes; |
| 1426 | 1426 | |
| 1427 | | − mix_pool_bytes(r, buf, bytes, NULL); |
| 1427 | + mix_pool_bytes(r, buf, bytes); |
| 1428 | 1428 | cond_resched(); |
| 1429 | 1429 | } |
| 1430 | 1430 | |
| @@ -1520,6 +1520,29 @@ const struct file_operations urandom_fops = { · 89 unmodified lines |
| 1520 | 1520 | .llseek = noop_llseek, |
| 1521 | 1521 | }; |
| 1522 | 1522 | |
| 1523 | +SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, |
| 1524 | + unsigned int, flags) |
| 1525 | +{ |
| 1526 | + if (flags & ~(GRND_NONBLOCK|GRND_RANDOM)) |
| 1527 | + return -EINVAL; |
| 1528 | + |
| 1529 | + if (count > INT_MAX) |
| 1530 | + count = INT_MAX; |
| 1531 | + |
| 1532 | + if (flags & GRND_RANDOM) |
| 1533 | + return _random_read(flags & GRND_NONBLOCK, buf, count); |
| 1534 | + |
| 1535 | + if (unlikely(nonblocking_pool.initialized == 0)) { |
| 1536 | + if (flags & GRND_NONBLOCK) |
| 1537 | + return -EAGAIN; |
| 1538 | + wait_event_interruptible(urandom_init_wait, |
| 1539 | + nonblocking_pool.initialized); |
| 1540 | + if (signal_pending(current)) |
| 1541 | + return -ERESTARTSYS; |
| 1542 | + } |
| 1543 | + return urandom_read(NULL, buf, count, NULL); |
| 1544 | +} |
| 1545 | + |
| 1523 | 1546 | /*************************************************************** |
| 1524 | 1547 | * Random UUID interface |
| 1525 | 1548 | * |
| @@ -1663,6 +1686,22 @@ struct ctl_table random_table[] = { · 137 unmodified lines |
| 1663 | 1686 | .mode = 0444, |
| 1664 | 1687 | .proc_handler = proc_do_uuid, |
| 1665 | 1688 | }, |
| 1689 | +#ifdef ADD_INTERRUPT_BENCH |
| 1690 | + { |
| 1691 | + .procname = "add_interrupt_avg_cycles", |
| 1692 | + .data = &avg_cycles, |
| 1693 | + .maxlen = sizeof(avg_cycles), |
| 1694 | + .mode = 0444, |
| 1695 | + .proc_handler = proc_doulongvec_minmax, |
| 1696 | + }, |
| 1697 | + { |
| 1698 | + .procname = "add_interrupt_avg_deviation", |
| 1699 | + .data = &avg_deviation, |
| 1700 | + .maxlen = sizeof(avg_deviation), |
| 1701 | + .mode = 0444, |
| 1702 | + .proc_handler = proc_doulongvec_minmax, |
| 1703 | + }, |
| 1704 | +#endif |
| 1666 | 1705 | { } |
| 1667 | 1706 | }; |
| 1668 | 1707 | #endif /* CONFIG_SYSCTL */ |
| @@ -1719,3 +1758,23 @@ randomize_range(unsigned long start, unsigned long end, unsigned long len) · 50 unmodified lines |
| 1719 | 1758 | return 0; |
| 1720 | 1759 | return PAGE_ALIGN(get_random_int() % range + start); |
| 1721 | 1760 | } |
| 1761 | + |
| 1762 | +/* Interface for in-kernel drivers of true hardware RNGs. |
| 1763 | + * Those devices may produce endless random bits and will be throttled |
| 1764 | + * when our pool is full. |
| 1765 | + */ |
| 1766 | +void add_hwgenerator_randomness(const char *buffer, size_t count, |
| 1767 | + size_t entropy) |
| 1768 | +{ |
| 1769 | + struct entropy_store *poolp = &input_pool; |
| 1770 | + |
| 1771 | + /* Suspend writing if we're above the trickle threshold. |
| 1772 | + * We'll be woken up again once below random_write_wakeup_thresh, |
| 1773 | + * or when the calling thread is about to terminate. |
| 1774 | + */ |
| 1775 | + wait_event_interruptible(random_write_wait, kthread_should_stop() || |
| 1776 | + ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits); |
| 1777 | + mix_pool_bytes(poolp, buffer, count); |
| 1778 | + credit_entropy_bits(poolp, entropy); |
| 1779 | +} |
| 1780 | +EXPORT_SYMBOL_GPL(add_hwgenerator_randomness); |