diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-27 18:11:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-27 18:11:55 -0400 |
commit | 818e607b57c94ade9824dad63a96c2ea6b21baf3 (patch) | |
tree | 2c83a38a1d090da464c435486e4a2e6f4afbacd2 | |
parent | ff9a082fda424257976f08fce942609f358015e0 (diff) | |
parent | 86a574de4590ffe6fd3f3ca34cdcf655a78e36ec (diff) |
Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random
Pull random driver updates from Ted Ts'o:
"A number of improvements for the /dev/random driver; the most
important is the use of a ChaCha20-based CRNG for /dev/urandom, which
is faster, more efficient, and easier to make scalable for
silly/abusive userspace programs that want to read from /dev/urandom
in a tight loop on NUMA systems.
This set of patches also improves entropy gathering on VM's running on
Microsoft Azure, and will take advantage of a hw random number
generator (if present) to initialize the /dev/urandom pool"
(It turns out that the random tree hadn't been in linux-next this time
around, because it had been dropped earlier as being too quiet. Oh
well).
* tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random:
random: strengthen input validation for RNDADDTOENTCNT
random: add backtracking protection to the CRNG
random: make /dev/urandom scalable for silly userspace programs
random: replace non-blocking pool with a Chacha20-based CRNG
random: properly align get_random_int_hash
random: add interrupt callback to VMBus IRQ handler
random: print a warning for the first ten uninitialized random users
random: initialize the non-blocking pool via add_hwgenerator_randomness()
-rw-r--r-- | crypto/chacha20_generic.c | 61 | ||||
-rw-r--r-- | drivers/char/random.c | 482 | ||||
-rw-r--r-- | drivers/hv/vmbus_drv.c | 3 | ||||
-rw-r--r-- | include/crypto/chacha20.h | 1 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/chacha20.c | 79 |
6 files changed, 468 insertions, 160 deletions
diff --git a/crypto/chacha20_generic.c b/crypto/chacha20_generic.c index da9c89968223..1cab83146e33 100644 --- a/crypto/chacha20_generic.c +++ b/crypto/chacha20_generic.c | |||
@@ -15,72 +15,11 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <crypto/chacha20.h> | 16 | #include <crypto/chacha20.h> |
17 | 17 | ||
18 | static inline u32 rotl32(u32 v, u8 n) | ||
19 | { | ||
20 | return (v << n) | (v >> (sizeof(v) * 8 - n)); | ||
21 | } | ||
22 | |||
23 | static inline u32 le32_to_cpuvp(const void *p) | 18 | static inline u32 le32_to_cpuvp(const void *p) |
24 | { | 19 | { |
25 | return le32_to_cpup(p); | 20 | return le32_to_cpup(p); |
26 | } | 21 | } |
27 | 22 | ||
28 | static void chacha20_block(u32 *state, void *stream) | ||
29 | { | ||
30 | u32 x[16], *out = stream; | ||
31 | int i; | ||
32 | |||
33 | for (i = 0; i < ARRAY_SIZE(x); i++) | ||
34 | x[i] = state[i]; | ||
35 | |||
36 | for (i = 0; i < 20; i += 2) { | ||
37 | x[0] += x[4]; x[12] = rotl32(x[12] ^ x[0], 16); | ||
38 | x[1] += x[5]; x[13] = rotl32(x[13] ^ x[1], 16); | ||
39 | x[2] += x[6]; x[14] = rotl32(x[14] ^ x[2], 16); | ||
40 | x[3] += x[7]; x[15] = rotl32(x[15] ^ x[3], 16); | ||
41 | |||
42 | x[8] += x[12]; x[4] = rotl32(x[4] ^ x[8], 12); | ||
43 | x[9] += x[13]; x[5] = rotl32(x[5] ^ x[9], 12); | ||
44 | x[10] += x[14]; x[6] = rotl32(x[6] ^ x[10], 12); | ||
45 | x[11] += x[15]; x[7] = rotl32(x[7] ^ x[11], 12); | ||
46 | |||
47 | x[0] += x[4]; x[12] = rotl32(x[12] ^ x[0], 8); | ||
48 | x[1] += x[5]; x[13] = rotl32(x[13] ^ x[1], 8); | ||
49 | x[2] += x[6]; x[14] = rotl32(x[14] ^ x[2], 8); | ||
50 | x[3] += x[7]; x[15] = rotl32(x[15] ^ x[3], 8); | ||
51 | |||
52 | x[8] += x[12]; x[4] = rotl32(x[4] ^ x[8], 7); | ||
53 | x[9] += x[13]; x[5] = rotl32(x[5] ^ x[9], 7); | ||
54 | x[10] += x[14]; x[6] = rotl32(x[6] ^ x[10], 7); | ||
55 | x[11] += x[15]; x[7] = rotl32(x[7] ^ x[11], 7); | ||
56 | |||
57 | x[0] += x[5]; x[15] = rotl32(x[15] ^ x[0], 16); | ||
58 | x[1] += x[6]; x[12] = rotl32(x[12] ^ x[1], 16); | ||
59 | x[2] += x[7]; x[13] = rotl32(x[13] ^ x[2], 16); | ||
60 | x[3] += x[4]; x[14] = rotl32(x[14] ^ x[3], 16); | ||
61 | |||
62 | x[10] += x[15]; x[5] = rotl32(x[5] ^ x[10], 12); | ||
63 | x[11] += x[12]; x[6] = rotl32(x[6] ^ x[11], 12); | ||
64 | x[8] += x[13]; x[7] = rotl32(x[7] ^ x[8], 12); | ||
65 | x[9] += x[14]; x[4] = rotl32(x[4] ^ x[9], 12); | ||
66 | |||
67 | x[0] += x[5]; x[15] = rotl32(x[15] ^ x[0], 8); | ||
68 | x[1] += x[6]; x[12] = rotl32(x[12] ^ x[1], 8); | ||
69 | x[2] += x[7]; x[13] = rotl32(x[13] ^ x[2], 8); | ||
70 | x[3] += x[4]; x[14] = rotl32(x[14] ^ x[3], 8); | ||
71 | |||
72 | x[10] += x[15]; x[5] = rotl32(x[5] ^ x[10], 7); | ||
73 | x[11] += x[12]; x[6] = rotl32(x[6] ^ x[11], 7); | ||
74 | x[8] += x[13]; x[7] = rotl32(x[7] ^ x[8], 7); | ||
75 | x[9] += x[14]; x[4] = rotl32(x[4] ^ x[9], 7); | ||
76 | } | ||
77 | |||
78 | for (i = 0; i < ARRAY_SIZE(x); i++) | ||
79 | out[i] = cpu_to_le32(x[i] + state[i]); | ||
80 | |||
81 | state[12]++; | ||
82 | } | ||
83 | |||
84 | static void chacha20_docrypt(u32 *state, u8 *dst, const u8 *src, | 23 | static void chacha20_docrypt(u32 *state, u8 *dst, const u8 *src, |
85 | unsigned int bytes) | 24 | unsigned int bytes) |
86 | { | 25 | { |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 0158d3bff7e5..8d0af74f6569 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -261,6 +261,7 @@ | |||
261 | #include <linux/syscalls.h> | 261 | #include <linux/syscalls.h> |
262 | #include <linux/completion.h> | 262 | #include <linux/completion.h> |
263 | #include <linux/uuid.h> | 263 | #include <linux/uuid.h> |
264 | #include <crypto/chacha20.h> | ||
264 | 265 | ||
265 | #include <asm/processor.h> | 266 | #include <asm/processor.h> |
266 | #include <asm/uaccess.h> | 267 | #include <asm/uaccess.h> |
@@ -413,6 +414,34 @@ static struct fasync_struct *fasync; | |||
413 | static DEFINE_SPINLOCK(random_ready_list_lock); | 414 | static DEFINE_SPINLOCK(random_ready_list_lock); |
414 | static LIST_HEAD(random_ready_list); | 415 | static LIST_HEAD(random_ready_list); |
415 | 416 | ||
417 | struct crng_state { | ||
418 | __u32 state[16]; | ||
419 | unsigned long init_time; | ||
420 | spinlock_t lock; | ||
421 | }; | ||
422 | |||
423 | struct crng_state primary_crng = { | ||
424 | .lock = __SPIN_LOCK_UNLOCKED(primary_crng.lock), | ||
425 | }; | ||
426 | |||
427 | /* | ||
428 | * crng_init = 0 --> Uninitialized | ||
429 | * 1 --> Initialized | ||
430 | * 2 --> Initialized from input_pool | ||
431 | * | ||
432 | * crng_init is protected by primary_crng->lock, and only increases | ||
433 | * its value (from 0->1->2). | ||
434 | */ | ||
435 | static int crng_init = 0; | ||
436 | #define crng_ready() (likely(crng_init > 0)) | ||
437 | static int crng_init_cnt = 0; | ||
438 | #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) | ||
439 | static void _extract_crng(struct crng_state *crng, | ||
440 | __u8 out[CHACHA20_BLOCK_SIZE]); | ||
441 | static void _crng_backtrack_protect(struct crng_state *crng, | ||
442 | __u8 tmp[CHACHA20_BLOCK_SIZE], int used); | ||
443 | static void process_random_ready_list(void); | ||
444 | |||
416 | /********************************************************************** | 445 | /********************************************************************** |
417 | * | 446 | * |
418 | * OS independent entropy store. Here are the functions which handle | 447 | * OS independent entropy store. Here are the functions which handle |
@@ -442,10 +471,15 @@ struct entropy_store { | |||
442 | __u8 last_data[EXTRACT_SIZE]; | 471 | __u8 last_data[EXTRACT_SIZE]; |
443 | }; | 472 | }; |
444 | 473 | ||
474 | static ssize_t extract_entropy(struct entropy_store *r, void *buf, | ||
475 | size_t nbytes, int min, int rsvd); | ||
476 | static ssize_t _extract_entropy(struct entropy_store *r, void *buf, | ||
477 | size_t nbytes, int fips); | ||
478 | |||
479 | static void crng_reseed(struct crng_state *crng, struct entropy_store *r); | ||
445 | static void push_to_pool(struct work_struct *work); | 480 | static void push_to_pool(struct work_struct *work); |
446 | static __u32 input_pool_data[INPUT_POOL_WORDS]; | 481 | static __u32 input_pool_data[INPUT_POOL_WORDS]; |
447 | static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; | 482 | static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; |
448 | static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS]; | ||
449 | 483 | ||
450 | static struct entropy_store input_pool = { | 484 | static struct entropy_store input_pool = { |
451 | .poolinfo = &poolinfo_table[0], | 485 | .poolinfo = &poolinfo_table[0], |
@@ -466,16 +500,6 @@ static struct entropy_store blocking_pool = { | |||
466 | push_to_pool), | 500 | push_to_pool), |
467 | }; | 501 | }; |
468 | 502 | ||
469 | static struct entropy_store nonblocking_pool = { | ||
470 | .poolinfo = &poolinfo_table[1], | ||
471 | .name = "nonblocking", | ||
472 | .pull = &input_pool, | ||
473 | .lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock), | ||
474 | .pool = nonblocking_pool_data, | ||
475 | .push_work = __WORK_INITIALIZER(nonblocking_pool.push_work, | ||
476 | push_to_pool), | ||
477 | }; | ||
478 | |||
479 | static __u32 const twist_table[8] = { | 503 | static __u32 const twist_table[8] = { |
480 | 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, | 504 | 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, |
481 | 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; | 505 | 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; |
@@ -678,12 +702,6 @@ retry: | |||
678 | if (!r->initialized && r->entropy_total > 128) { | 702 | if (!r->initialized && r->entropy_total > 128) { |
679 | r->initialized = 1; | 703 | r->initialized = 1; |
680 | r->entropy_total = 0; | 704 | r->entropy_total = 0; |
681 | if (r == &nonblocking_pool) { | ||
682 | prandom_reseed_late(); | ||
683 | process_random_ready_list(); | ||
684 | wake_up_all(&urandom_init_wait); | ||
685 | pr_notice("random: %s pool is initialized\n", r->name); | ||
686 | } | ||
687 | } | 705 | } |
688 | 706 | ||
689 | trace_credit_entropy_bits(r->name, nbits, | 707 | trace_credit_entropy_bits(r->name, nbits, |
@@ -693,47 +711,264 @@ retry: | |||
693 | if (r == &input_pool) { | 711 | if (r == &input_pool) { |
694 | int entropy_bits = entropy_count >> ENTROPY_SHIFT; | 712 | int entropy_bits = entropy_count >> ENTROPY_SHIFT; |
695 | 713 | ||
714 | if (crng_init < 2 && entropy_bits >= 128) { | ||
715 | crng_reseed(&primary_crng, r); | ||
716 | entropy_bits = r->entropy_count >> ENTROPY_SHIFT; | ||
717 | } | ||
718 | |||
696 | /* should we wake readers? */ | 719 | /* should we wake readers? */ |
697 | if (entropy_bits >= random_read_wakeup_bits) { | 720 | if (entropy_bits >= random_read_wakeup_bits) { |
698 | wake_up_interruptible(&random_read_wait); | 721 | wake_up_interruptible(&random_read_wait); |
699 | kill_fasync(&fasync, SIGIO, POLL_IN); | 722 | kill_fasync(&fasync, SIGIO, POLL_IN); |
700 | } | 723 | } |
701 | /* If the input pool is getting full, send some | 724 | /* If the input pool is getting full, send some |
702 | * entropy to the two output pools, flipping back and | 725 | * entropy to the blocking pool until it is 75% full. |
703 | * forth between them, until the output pools are 75% | ||
704 | * full. | ||
705 | */ | 726 | */ |
706 | if (entropy_bits > random_write_wakeup_bits && | 727 | if (entropy_bits > random_write_wakeup_bits && |
707 | r->initialized && | 728 | r->initialized && |
708 | r->entropy_total >= 2*random_read_wakeup_bits) { | 729 | r->entropy_total >= 2*random_read_wakeup_bits) { |
709 | static struct entropy_store *last = &blocking_pool; | ||
710 | struct entropy_store *other = &blocking_pool; | 730 | struct entropy_store *other = &blocking_pool; |
711 | 731 | ||
712 | if (last == &blocking_pool) | ||
713 | other = &nonblocking_pool; | ||
714 | if (other->entropy_count <= | 732 | if (other->entropy_count <= |
715 | 3 * other->poolinfo->poolfracbits / 4) | 733 | 3 * other->poolinfo->poolfracbits / 4) { |
716 | last = other; | 734 | schedule_work(&other->push_work); |
717 | if (last->entropy_count <= | ||
718 | 3 * last->poolinfo->poolfracbits / 4) { | ||
719 | schedule_work(&last->push_work); | ||
720 | r->entropy_total = 0; | 735 | r->entropy_total = 0; |
721 | } | 736 | } |
722 | } | 737 | } |
723 | } | 738 | } |
724 | } | 739 | } |
725 | 740 | ||
726 | static void credit_entropy_bits_safe(struct entropy_store *r, int nbits) | 741 | static int credit_entropy_bits_safe(struct entropy_store *r, int nbits) |
727 | { | 742 | { |
728 | const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1)); | 743 | const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1)); |
729 | 744 | ||
745 | if (nbits < 0) | ||
746 | return -EINVAL; | ||
747 | |||
730 | /* Cap the value to avoid overflows */ | 748 | /* Cap the value to avoid overflows */ |
731 | nbits = min(nbits, nbits_max); | 749 | nbits = min(nbits, nbits_max); |
732 | nbits = max(nbits, -nbits_max); | ||
733 | 750 | ||
734 | credit_entropy_bits(r, nbits); | 751 | credit_entropy_bits(r, nbits); |
752 | return 0; | ||
753 | } | ||
754 | |||
755 | /********************************************************************* | ||
756 | * | ||
757 | * CRNG using CHACHA20 | ||
758 | * | ||
759 | *********************************************************************/ | ||
760 | |||
761 | #define CRNG_RESEED_INTERVAL (300*HZ) | ||
762 | |||
763 | static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); | ||
764 | |||
765 | #ifdef CONFIG_NUMA | ||
766 | /* | ||
767 | * Hack to deal with crazy userspace progams when they are all trying | ||
768 | * to access /dev/urandom in parallel. The programs are almost | ||
769 | * certainly doing something terribly wrong, but we'll work around | ||
770 | * their brain damage. | ||
771 | */ | ||
772 | static struct crng_state **crng_node_pool __read_mostly; | ||
773 | #endif | ||
774 | |||
775 | static void crng_initialize(struct crng_state *crng) | ||
776 | { | ||
777 | int i; | ||
778 | unsigned long rv; | ||
779 | |||
780 | memcpy(&crng->state[0], "expand 32-byte k", 16); | ||
781 | if (crng == &primary_crng) | ||
782 | _extract_entropy(&input_pool, &crng->state[4], | ||
783 | sizeof(__u32) * 12, 0); | ||
784 | else | ||
785 | get_random_bytes(&crng->state[4], sizeof(__u32) * 12); | ||
786 | for (i = 4; i < 16; i++) { | ||
787 | if (!arch_get_random_seed_long(&rv) && | ||
788 | !arch_get_random_long(&rv)) | ||
789 | rv = random_get_entropy(); | ||
790 | crng->state[i] ^= rv; | ||
791 | } | ||
792 | crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; | ||
793 | } | ||
794 | |||
795 | static int crng_fast_load(const char *cp, size_t len) | ||
796 | { | ||
797 | unsigned long flags; | ||
798 | char *p; | ||
799 | |||
800 | if (!spin_trylock_irqsave(&primary_crng.lock, flags)) | ||
801 | return 0; | ||
802 | if (crng_ready()) { | ||
803 | spin_unlock_irqrestore(&primary_crng.lock, flags); | ||
804 | return 0; | ||
805 | } | ||
806 | p = (unsigned char *) &primary_crng.state[4]; | ||
807 | while (len > 0 && crng_init_cnt < CRNG_INIT_CNT_THRESH) { | ||
808 | p[crng_init_cnt % CHACHA20_KEY_SIZE] ^= *cp; | ||
809 | cp++; crng_init_cnt++; len--; | ||
810 | } | ||
811 | if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { | ||
812 | crng_init = 1; | ||
813 | wake_up_interruptible(&crng_init_wait); | ||
814 | pr_notice("random: fast init done\n"); | ||
815 | } | ||
816 | spin_unlock_irqrestore(&primary_crng.lock, flags); | ||
817 | return 1; | ||
818 | } | ||
819 | |||
820 | static void crng_reseed(struct crng_state *crng, struct entropy_store *r) | ||
821 | { | ||
822 | unsigned long flags; | ||
823 | int i, num; | ||
824 | union { | ||
825 | __u8 block[CHACHA20_BLOCK_SIZE]; | ||
826 | __u32 key[8]; | ||
827 | } buf; | ||
828 | |||
829 | if (r) { | ||
830 | num = extract_entropy(r, &buf, 32, 16, 0); | ||
831 | if (num == 0) | ||
832 | return; | ||
833 | } else { | ||
834 | _extract_crng(&primary_crng, buf.block); | ||
835 | _crng_backtrack_protect(&primary_crng, buf.block, | ||
836 | CHACHA20_KEY_SIZE); | ||
837 | } | ||
838 | spin_lock_irqsave(&primary_crng.lock, flags); | ||
839 | for (i = 0; i < 8; i++) { | ||
840 | unsigned long rv; | ||
841 | if (!arch_get_random_seed_long(&rv) && | ||
842 | !arch_get_random_long(&rv)) | ||
843 | rv = random_get_entropy(); | ||
844 | crng->state[i+4] ^= buf.key[i] ^ rv; | ||
845 | } | ||
846 | memzero_explicit(&buf, sizeof(buf)); | ||
847 | crng->init_time = jiffies; | ||
848 | if (crng == &primary_crng && crng_init < 2) { | ||
849 | crng_init = 2; | ||
850 | process_random_ready_list(); | ||
851 | wake_up_interruptible(&crng_init_wait); | ||
852 | pr_notice("random: crng init done\n"); | ||
853 | } | ||
854 | spin_unlock_irqrestore(&primary_crng.lock, flags); | ||
855 | } | ||
856 | |||
857 | static inline void maybe_reseed_primary_crng(void) | ||
858 | { | ||
859 | if (crng_init > 2 && | ||
860 | time_after(jiffies, primary_crng.init_time + CRNG_RESEED_INTERVAL)) | ||
861 | crng_reseed(&primary_crng, &input_pool); | ||
862 | } | ||
863 | |||
864 | static inline void crng_wait_ready(void) | ||
865 | { | ||
866 | wait_event_interruptible(crng_init_wait, crng_ready()); | ||
867 | } | ||
868 | |||
869 | static void _extract_crng(struct crng_state *crng, | ||
870 | __u8 out[CHACHA20_BLOCK_SIZE]) | ||
871 | { | ||
872 | unsigned long v, flags; | ||
873 | |||
874 | if (crng_init > 1 && | ||
875 | time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) | ||
876 | crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); | ||
877 | spin_lock_irqsave(&crng->lock, flags); | ||
878 | if (arch_get_random_long(&v)) | ||
879 | crng->state[14] ^= v; | ||
880 | chacha20_block(&crng->state[0], out); | ||
881 | if (crng->state[12] == 0) | ||
882 | crng->state[13]++; | ||
883 | spin_unlock_irqrestore(&crng->lock, flags); | ||
884 | } | ||
885 | |||
886 | static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE]) | ||
887 | { | ||
888 | struct crng_state *crng = NULL; | ||
889 | |||
890 | #ifdef CONFIG_NUMA | ||
891 | if (crng_node_pool) | ||
892 | crng = crng_node_pool[numa_node_id()]; | ||
893 | if (crng == NULL) | ||
894 | #endif | ||
895 | crng = &primary_crng; | ||
896 | _extract_crng(crng, out); | ||
897 | } | ||
898 | |||
899 | /* | ||
900 | * Use the leftover bytes from the CRNG block output (if there is | ||
901 | * enough) to mutate the CRNG key to provide backtracking protection. | ||
902 | */ | ||
903 | static void _crng_backtrack_protect(struct crng_state *crng, | ||
904 | __u8 tmp[CHACHA20_BLOCK_SIZE], int used) | ||
905 | { | ||
906 | unsigned long flags; | ||
907 | __u32 *s, *d; | ||
908 | int i; | ||
909 | |||
910 | used = round_up(used, sizeof(__u32)); | ||
911 | if (used + CHACHA20_KEY_SIZE > CHACHA20_BLOCK_SIZE) { | ||
912 | extract_crng(tmp); | ||
913 | used = 0; | ||
914 | } | ||
915 | spin_lock_irqsave(&crng->lock, flags); | ||
916 | s = (__u32 *) &tmp[used]; | ||
917 | d = &crng->state[4]; | ||
918 | for (i=0; i < 8; i++) | ||
919 | *d++ ^= *s++; | ||
920 | spin_unlock_irqrestore(&crng->lock, flags); | ||
921 | } | ||
922 | |||
923 | static void crng_backtrack_protect(__u8 tmp[CHACHA20_BLOCK_SIZE], int used) | ||
924 | { | ||
925 | struct crng_state *crng = NULL; | ||
926 | |||
927 | #ifdef CONFIG_NUMA | ||
928 | if (crng_node_pool) | ||
929 | crng = crng_node_pool[numa_node_id()]; | ||
930 | if (crng == NULL) | ||
931 | #endif | ||
932 | crng = &primary_crng; | ||
933 | _crng_backtrack_protect(crng, tmp, used); | ||
934 | } | ||
935 | |||
936 | static ssize_t extract_crng_user(void __user *buf, size_t nbytes) | ||
937 | { | ||
938 | ssize_t ret = 0, i = CHACHA20_BLOCK_SIZE; | ||
939 | __u8 tmp[CHACHA20_BLOCK_SIZE]; | ||
940 | int large_request = (nbytes > 256); | ||
941 | |||
942 | while (nbytes) { | ||
943 | if (large_request && need_resched()) { | ||
944 | if (signal_pending(current)) { | ||
945 | if (ret == 0) | ||
946 | ret = -ERESTARTSYS; | ||
947 | break; | ||
948 | } | ||
949 | schedule(); | ||
950 | } | ||
951 | |||
952 | extract_crng(tmp); | ||
953 | i = min_t(int, nbytes, CHACHA20_BLOCK_SIZE); | ||
954 | if (copy_to_user(buf, tmp, i)) { | ||
955 | ret = -EFAULT; | ||
956 | break; | ||
957 | } | ||
958 | |||
959 | nbytes -= i; | ||
960 | buf += i; | ||
961 | ret += i; | ||
962 | } | ||
963 | crng_backtrack_protect(tmp, i); | ||
964 | |||
965 | /* Wipe data just written to memory */ | ||
966 | memzero_explicit(tmp, sizeof(tmp)); | ||
967 | |||
968 | return ret; | ||
735 | } | 969 | } |
736 | 970 | ||
971 | |||
737 | /********************************************************************* | 972 | /********************************************************************* |
738 | * | 973 | * |
739 | * Entropy input management | 974 | * Entropy input management |
@@ -750,12 +985,12 @@ struct timer_rand_state { | |||
750 | #define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, }; | 985 | #define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, }; |
751 | 986 | ||
752 | /* | 987 | /* |
753 | * Add device- or boot-specific data to the input and nonblocking | 988 | * Add device- or boot-specific data to the input pool to help |
754 | * pools to help initialize them to unique values. | 989 | * initialize it. |
755 | * | 990 | * |
756 | * None of this adds any entropy, it is meant to avoid the | 991 | * None of this adds any entropy; it is meant to avoid the problem of |
757 | * problem of the nonblocking pool having similar initial state | 992 | * the entropy pool having similar initial state across largely |
758 | * across largely identical devices. | 993 | * identical devices. |
759 | */ | 994 | */ |
760 | void add_device_randomness(const void *buf, unsigned int size) | 995 | void add_device_randomness(const void *buf, unsigned int size) |
761 | { | 996 | { |
@@ -767,11 +1002,6 @@ void add_device_randomness(const void *buf, unsigned int size) | |||
767 | _mix_pool_bytes(&input_pool, buf, size); | 1002 | _mix_pool_bytes(&input_pool, buf, size); |
768 | _mix_pool_bytes(&input_pool, &time, sizeof(time)); | 1003 | _mix_pool_bytes(&input_pool, &time, sizeof(time)); |
769 | spin_unlock_irqrestore(&input_pool.lock, flags); | 1004 | spin_unlock_irqrestore(&input_pool.lock, flags); |
770 | |||
771 | spin_lock_irqsave(&nonblocking_pool.lock, flags); | ||
772 | _mix_pool_bytes(&nonblocking_pool, buf, size); | ||
773 | _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time)); | ||
774 | spin_unlock_irqrestore(&nonblocking_pool.lock, flags); | ||
775 | } | 1005 | } |
776 | EXPORT_SYMBOL(add_device_randomness); | 1006 | EXPORT_SYMBOL(add_device_randomness); |
777 | 1007 | ||
@@ -802,7 +1032,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
802 | sample.jiffies = jiffies; | 1032 | sample.jiffies = jiffies; |
803 | sample.cycles = random_get_entropy(); | 1033 | sample.cycles = random_get_entropy(); |
804 | sample.num = num; | 1034 | sample.num = num; |
805 | r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; | 1035 | r = &input_pool; |
806 | mix_pool_bytes(r, &sample, sizeof(sample)); | 1036 | mix_pool_bytes(r, &sample, sizeof(sample)); |
807 | 1037 | ||
808 | /* | 1038 | /* |
@@ -918,11 +1148,21 @@ void add_interrupt_randomness(int irq, int irq_flags) | |||
918 | fast_mix(fast_pool); | 1148 | fast_mix(fast_pool); |
919 | add_interrupt_bench(cycles); | 1149 | add_interrupt_bench(cycles); |
920 | 1150 | ||
1151 | if (!crng_ready()) { | ||
1152 | if ((fast_pool->count >= 64) && | ||
1153 | crng_fast_load((char *) fast_pool->pool, | ||
1154 | sizeof(fast_pool->pool))) { | ||
1155 | fast_pool->count = 0; | ||
1156 | fast_pool->last = now; | ||
1157 | } | ||
1158 | return; | ||
1159 | } | ||
1160 | |||
921 | if ((fast_pool->count < 64) && | 1161 | if ((fast_pool->count < 64) && |
922 | !time_after(now, fast_pool->last + HZ)) | 1162 | !time_after(now, fast_pool->last + HZ)) |
923 | return; | 1163 | return; |
924 | 1164 | ||
925 | r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; | 1165 | r = &input_pool; |
926 | if (!spin_trylock(&r->lock)) | 1166 | if (!spin_trylock(&r->lock)) |
927 | return; | 1167 | return; |
928 | 1168 | ||
@@ -946,6 +1186,7 @@ void add_interrupt_randomness(int irq, int irq_flags) | |||
946 | /* award one bit for the contents of the fast pool */ | 1186 | /* award one bit for the contents of the fast pool */ |
947 | credit_entropy_bits(r, credit + 1); | 1187 | credit_entropy_bits(r, credit + 1); |
948 | } | 1188 | } |
1189 | EXPORT_SYMBOL_GPL(add_interrupt_randomness); | ||
949 | 1190 | ||
950 | #ifdef CONFIG_BLOCK | 1191 | #ifdef CONFIG_BLOCK |
951 | void add_disk_randomness(struct gendisk *disk) | 1192 | void add_disk_randomness(struct gendisk *disk) |
@@ -965,9 +1206,6 @@ EXPORT_SYMBOL_GPL(add_disk_randomness); | |||
965 | * | 1206 | * |
966 | *********************************************************************/ | 1207 | *********************************************************************/ |
967 | 1208 | ||
968 | static ssize_t extract_entropy(struct entropy_store *r, void *buf, | ||
969 | size_t nbytes, int min, int rsvd); | ||
970 | |||
971 | /* | 1209 | /* |
972 | * This utility inline function is responsible for transferring entropy | 1210 | * This utility inline function is responsible for transferring entropy |
973 | * from the primary pool to the secondary extraction pool. We make | 1211 | * from the primary pool to the secondary extraction pool. We make |
@@ -1142,6 +1380,36 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
1142 | memzero_explicit(&hash, sizeof(hash)); | 1380 | memzero_explicit(&hash, sizeof(hash)); |
1143 | } | 1381 | } |
1144 | 1382 | ||
1383 | static ssize_t _extract_entropy(struct entropy_store *r, void *buf, | ||
1384 | size_t nbytes, int fips) | ||
1385 | { | ||
1386 | ssize_t ret = 0, i; | ||
1387 | __u8 tmp[EXTRACT_SIZE]; | ||
1388 | unsigned long flags; | ||
1389 | |||
1390 | while (nbytes) { | ||
1391 | extract_buf(r, tmp); | ||
1392 | |||
1393 | if (fips) { | ||
1394 | spin_lock_irqsave(&r->lock, flags); | ||
1395 | if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) | ||
1396 | panic("Hardware RNG duplicated output!\n"); | ||
1397 | memcpy(r->last_data, tmp, EXTRACT_SIZE); | ||
1398 | spin_unlock_irqrestore(&r->lock, flags); | ||
1399 | } | ||
1400 | i = min_t(int, nbytes, EXTRACT_SIZE); | ||
1401 | memcpy(buf, tmp, i); | ||
1402 | nbytes -= i; | ||
1403 | buf += i; | ||
1404 | ret += i; | ||
1405 | } | ||
1406 | |||
1407 | /* Wipe data just returned from memory */ | ||
1408 | memzero_explicit(tmp, sizeof(tmp)); | ||
1409 | |||
1410 | return ret; | ||
1411 | } | ||
1412 | |||
1145 | /* | 1413 | /* |
1146 | * This function extracts randomness from the "entropy pool", and | 1414 | * This function extracts randomness from the "entropy pool", and |
1147 | * returns it in a buffer. | 1415 | * returns it in a buffer. |
@@ -1154,7 +1422,6 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
1154 | static ssize_t extract_entropy(struct entropy_store *r, void *buf, | 1422 | static ssize_t extract_entropy(struct entropy_store *r, void *buf, |
1155 | size_t nbytes, int min, int reserved) | 1423 | size_t nbytes, int min, int reserved) |
1156 | { | 1424 | { |
1157 | ssize_t ret = 0, i; | ||
1158 | __u8 tmp[EXTRACT_SIZE]; | 1425 | __u8 tmp[EXTRACT_SIZE]; |
1159 | unsigned long flags; | 1426 | unsigned long flags; |
1160 | 1427 | ||
@@ -1178,27 +1445,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
1178 | xfer_secondary_pool(r, nbytes); | 1445 | xfer_secondary_pool(r, nbytes); |
1179 | nbytes = account(r, nbytes, min, reserved); | 1446 | nbytes = account(r, nbytes, min, reserved); |
1180 | 1447 | ||
1181 | while (nbytes) { | 1448 | return _extract_entropy(r, buf, nbytes, fips_enabled); |
1182 | extract_buf(r, tmp); | ||
1183 | |||
1184 | if (fips_enabled) { | ||
1185 | spin_lock_irqsave(&r->lock, flags); | ||
1186 | if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) | ||
1187 | panic("Hardware RNG duplicated output!\n"); | ||
1188 | memcpy(r->last_data, tmp, EXTRACT_SIZE); | ||
1189 | spin_unlock_irqrestore(&r->lock, flags); | ||
1190 | } | ||
1191 | i = min_t(int, nbytes, EXTRACT_SIZE); | ||
1192 | memcpy(buf, tmp, i); | ||
1193 | nbytes -= i; | ||
1194 | buf += i; | ||
1195 | ret += i; | ||
1196 | } | ||
1197 | |||
1198 | /* Wipe data just returned from memory */ | ||
1199 | memzero_explicit(tmp, sizeof(tmp)); | ||
1200 | |||
1201 | return ret; | ||
1202 | } | 1449 | } |
1203 | 1450 | ||
1204 | /* | 1451 | /* |
@@ -1253,15 +1500,28 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, | |||
1253 | */ | 1500 | */ |
1254 | void get_random_bytes(void *buf, int nbytes) | 1501 | void get_random_bytes(void *buf, int nbytes) |
1255 | { | 1502 | { |
1503 | __u8 tmp[CHACHA20_BLOCK_SIZE]; | ||
1504 | |||
1256 | #if DEBUG_RANDOM_BOOT > 0 | 1505 | #if DEBUG_RANDOM_BOOT > 0 |
1257 | if (unlikely(nonblocking_pool.initialized == 0)) | 1506 | if (!crng_ready()) |
1258 | printk(KERN_NOTICE "random: %pF get_random_bytes called " | 1507 | printk(KERN_NOTICE "random: %pF get_random_bytes called " |
1259 | "with %d bits of entropy available\n", | 1508 | "with crng_init = %d\n", (void *) _RET_IP_, crng_init); |
1260 | (void *) _RET_IP_, | ||
1261 | nonblocking_pool.entropy_total); | ||
1262 | #endif | 1509 | #endif |
1263 | trace_get_random_bytes(nbytes, _RET_IP_); | 1510 | trace_get_random_bytes(nbytes, _RET_IP_); |
1264 | extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); | 1511 | |
1512 | while (nbytes >= CHACHA20_BLOCK_SIZE) { | ||
1513 | extract_crng(buf); | ||
1514 | buf += CHACHA20_BLOCK_SIZE; | ||
1515 | nbytes -= CHACHA20_BLOCK_SIZE; | ||
1516 | } | ||
1517 | |||
1518 | if (nbytes > 0) { | ||
1519 | extract_crng(tmp); | ||
1520 | memcpy(buf, tmp, nbytes); | ||
1521 | crng_backtrack_protect(tmp, nbytes); | ||
1522 | } else | ||
1523 | crng_backtrack_protect(tmp, CHACHA20_BLOCK_SIZE); | ||
1524 | memzero_explicit(tmp, sizeof(tmp)); | ||
1265 | } | 1525 | } |
1266 | EXPORT_SYMBOL(get_random_bytes); | 1526 | EXPORT_SYMBOL(get_random_bytes); |
1267 | 1527 | ||
@@ -1279,7 +1539,7 @@ int add_random_ready_callback(struct random_ready_callback *rdy) | |||
1279 | unsigned long flags; | 1539 | unsigned long flags; |
1280 | int err = -EALREADY; | 1540 | int err = -EALREADY; |
1281 | 1541 | ||
1282 | if (likely(nonblocking_pool.initialized)) | 1542 | if (crng_ready()) |
1283 | return err; | 1543 | return err; |
1284 | 1544 | ||
1285 | owner = rdy->owner; | 1545 | owner = rdy->owner; |
@@ -1287,7 +1547,7 @@ int add_random_ready_callback(struct random_ready_callback *rdy) | |||
1287 | return -ENOENT; | 1547 | return -ENOENT; |
1288 | 1548 | ||
1289 | spin_lock_irqsave(&random_ready_list_lock, flags); | 1549 | spin_lock_irqsave(&random_ready_list_lock, flags); |
1290 | if (nonblocking_pool.initialized) | 1550 | if (crng_ready()) |
1291 | goto out; | 1551 | goto out; |
1292 | 1552 | ||
1293 | owner = NULL; | 1553 | owner = NULL; |
@@ -1351,7 +1611,7 @@ void get_random_bytes_arch(void *buf, int nbytes) | |||
1351 | } | 1611 | } |
1352 | 1612 | ||
1353 | if (nbytes) | 1613 | if (nbytes) |
1354 | extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); | 1614 | get_random_bytes(p, nbytes); |
1355 | } | 1615 | } |
1356 | EXPORT_SYMBOL(get_random_bytes_arch); | 1616 | EXPORT_SYMBOL(get_random_bytes_arch); |
1357 | 1617 | ||
@@ -1394,9 +1654,31 @@ static void init_std_data(struct entropy_store *r) | |||
1394 | */ | 1654 | */ |
1395 | static int rand_initialize(void) | 1655 | static int rand_initialize(void) |
1396 | { | 1656 | { |
1657 | #ifdef CONFIG_NUMA | ||
1658 | int i; | ||
1659 | int num_nodes = num_possible_nodes(); | ||
1660 | struct crng_state *crng; | ||
1661 | struct crng_state **pool; | ||
1662 | #endif | ||
1663 | |||
1397 | init_std_data(&input_pool); | 1664 | init_std_data(&input_pool); |
1398 | init_std_data(&blocking_pool); | 1665 | init_std_data(&blocking_pool); |
1399 | init_std_data(&nonblocking_pool); | 1666 | crng_initialize(&primary_crng); |
1667 | |||
1668 | #ifdef CONFIG_NUMA | ||
1669 | pool = kmalloc(num_nodes * sizeof(void *), | ||
1670 | GFP_KERNEL|__GFP_NOFAIL|__GFP_ZERO); | ||
1671 | for (i=0; i < num_nodes; i++) { | ||
1672 | crng = kmalloc_node(sizeof(struct crng_state), | ||
1673 | GFP_KERNEL | __GFP_NOFAIL, i); | ||
1674 | spin_lock_init(&crng->lock); | ||
1675 | crng_initialize(crng); | ||
1676 | pool[i] = crng; | ||
1677 | |||
1678 | } | ||
1679 | mb(); | ||
1680 | crng_node_pool = pool; | ||
1681 | #endif | ||
1400 | return 0; | 1682 | return 0; |
1401 | } | 1683 | } |
1402 | early_initcall(rand_initialize); | 1684 | early_initcall(rand_initialize); |
@@ -1458,18 +1740,22 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1458 | static ssize_t | 1740 | static ssize_t |
1459 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | 1741 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
1460 | { | 1742 | { |
1743 | unsigned long flags; | ||
1744 | static int maxwarn = 10; | ||
1461 | int ret; | 1745 | int ret; |
1462 | 1746 | ||
1463 | if (unlikely(nonblocking_pool.initialized == 0)) | 1747 | if (!crng_ready() && maxwarn > 0) { |
1464 | printk_once(KERN_NOTICE "random: %s urandom read " | 1748 | maxwarn--; |
1465 | "with %d bits of entropy available\n", | 1749 | printk(KERN_NOTICE "random: %s: uninitialized urandom read " |
1466 | current->comm, nonblocking_pool.entropy_total); | 1750 | "(%zd bytes read)\n", |
1467 | 1751 | current->comm, nbytes); | |
1752 | spin_lock_irqsave(&primary_crng.lock, flags); | ||
1753 | crng_init_cnt = 0; | ||
1754 | spin_unlock_irqrestore(&primary_crng.lock, flags); | ||
1755 | } | ||
1468 | nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3)); | 1756 | nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3)); |
1469 | ret = extract_entropy_user(&nonblocking_pool, buf, nbytes); | 1757 | ret = extract_crng_user(buf, nbytes); |
1470 | 1758 | trace_urandom_read(8 * nbytes, 0, ENTROPY_BITS(&input_pool)); | |
1471 | trace_urandom_read(8 * nbytes, ENTROPY_BITS(&nonblocking_pool), | ||
1472 | ENTROPY_BITS(&input_pool)); | ||
1473 | return ret; | 1759 | return ret; |
1474 | } | 1760 | } |
1475 | 1761 | ||
@@ -1515,10 +1801,7 @@ static ssize_t random_write(struct file *file, const char __user *buffer, | |||
1515 | { | 1801 | { |
1516 | size_t ret; | 1802 | size_t ret; |
1517 | 1803 | ||
1518 | ret = write_pool(&blocking_pool, buffer, count); | 1804 | ret = write_pool(&input_pool, buffer, count); |
1519 | if (ret) | ||
1520 | return ret; | ||
1521 | ret = write_pool(&nonblocking_pool, buffer, count); | ||
1522 | if (ret) | 1805 | if (ret) |
1523 | return ret; | 1806 | return ret; |
1524 | 1807 | ||
@@ -1543,8 +1826,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
1543 | return -EPERM; | 1826 | return -EPERM; |
1544 | if (get_user(ent_count, p)) | 1827 | if (get_user(ent_count, p)) |
1545 | return -EFAULT; | 1828 | return -EFAULT; |
1546 | credit_entropy_bits_safe(&input_pool, ent_count); | 1829 | return credit_entropy_bits_safe(&input_pool, ent_count); |
1547 | return 0; | ||
1548 | case RNDADDENTROPY: | 1830 | case RNDADDENTROPY: |
1549 | if (!capable(CAP_SYS_ADMIN)) | 1831 | if (!capable(CAP_SYS_ADMIN)) |
1550 | return -EPERM; | 1832 | return -EPERM; |
@@ -1558,8 +1840,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
1558 | size); | 1840 | size); |
1559 | if (retval < 0) | 1841 | if (retval < 0) |
1560 | return retval; | 1842 | return retval; |
1561 | credit_entropy_bits_safe(&input_pool, ent_count); | 1843 | return credit_entropy_bits_safe(&input_pool, ent_count); |
1562 | return 0; | ||
1563 | case RNDZAPENTCNT: | 1844 | case RNDZAPENTCNT: |
1564 | case RNDCLEARPOOL: | 1845 | case RNDCLEARPOOL: |
1565 | /* | 1846 | /* |
@@ -1569,7 +1850,6 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
1569 | if (!capable(CAP_SYS_ADMIN)) | 1850 | if (!capable(CAP_SYS_ADMIN)) |
1570 | return -EPERM; | 1851 | return -EPERM; |
1571 | input_pool.entropy_count = 0; | 1852 | input_pool.entropy_count = 0; |
1572 | nonblocking_pool.entropy_count = 0; | ||
1573 | blocking_pool.entropy_count = 0; | 1853 | blocking_pool.entropy_count = 0; |
1574 | return 0; | 1854 | return 0; |
1575 | default: | 1855 | default: |
@@ -1611,11 +1891,10 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, | |||
1611 | if (flags & GRND_RANDOM) | 1891 | if (flags & GRND_RANDOM) |
1612 | return _random_read(flags & GRND_NONBLOCK, buf, count); | 1892 | return _random_read(flags & GRND_NONBLOCK, buf, count); |
1613 | 1893 | ||
1614 | if (unlikely(nonblocking_pool.initialized == 0)) { | 1894 | if (!crng_ready()) { |
1615 | if (flags & GRND_NONBLOCK) | 1895 | if (flags & GRND_NONBLOCK) |
1616 | return -EAGAIN; | 1896 | return -EAGAIN; |
1617 | wait_event_interruptible(urandom_init_wait, | 1897 | crng_wait_ready(); |
1618 | nonblocking_pool.initialized); | ||
1619 | if (signal_pending(current)) | 1898 | if (signal_pending(current)) |
1620 | return -ERESTARTSYS; | 1899 | return -ERESTARTSYS; |
1621 | } | 1900 | } |
@@ -1773,13 +2052,15 @@ int random_int_secret_init(void) | |||
1773 | return 0; | 2052 | return 0; |
1774 | } | 2053 | } |
1775 | 2054 | ||
2055 | static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) | ||
2056 | __aligned(sizeof(unsigned long)); | ||
2057 | |||
1776 | /* | 2058 | /* |
1777 | * Get a random word for internal kernel use only. Similar to urandom but | 2059 | * Get a random word for internal kernel use only. Similar to urandom but |
1778 | * with the goal of minimal entropy pool depletion. As a result, the random | 2060 | * with the goal of minimal entropy pool depletion. As a result, the random |
1779 | * value is not cryptographically secure but for several uses the cost of | 2061 | * value is not cryptographically secure but for several uses the cost of |
1780 | * depleting entropy is too high | 2062 | * depleting entropy is too high |
1781 | */ | 2063 | */ |
1782 | static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); | ||
1783 | unsigned int get_random_int(void) | 2064 | unsigned int get_random_int(void) |
1784 | { | 2065 | { |
1785 | __u32 *hash; | 2066 | __u32 *hash; |
@@ -1849,6 +2130,11 @@ void add_hwgenerator_randomness(const char *buffer, size_t count, | |||
1849 | { | 2130 | { |
1850 | struct entropy_store *poolp = &input_pool; | 2131 | struct entropy_store *poolp = &input_pool; |
1851 | 2132 | ||
2133 | if (!crng_ready()) { | ||
2134 | crng_fast_load(buffer, count); | ||
2135 | return; | ||
2136 | } | ||
2137 | |||
1852 | /* Suspend writing if we're above the trickle threshold. | 2138 | /* Suspend writing if we're above the trickle threshold. |
1853 | * We'll be woken up again once below random_write_wakeup_thresh, | 2139 | * We'll be woken up again once below random_write_wakeup_thresh, |
1854 | * or when the calling thread is about to terminate. | 2140 | * or when the calling thread is about to terminate. |
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 952f20fdc7e3..e82f7e1c217c 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/screen_info.h> | 42 | #include <linux/screen_info.h> |
43 | #include <linux/kdebug.h> | 43 | #include <linux/kdebug.h> |
44 | #include <linux/efi.h> | 44 | #include <linux/efi.h> |
45 | #include <linux/random.h> | ||
45 | #include "hyperv_vmbus.h" | 46 | #include "hyperv_vmbus.h" |
46 | 47 | ||
47 | static struct acpi_device *hv_acpi_dev; | 48 | static struct acpi_device *hv_acpi_dev; |
@@ -806,6 +807,8 @@ static void vmbus_isr(void) | |||
806 | else | 807 | else |
807 | tasklet_schedule(hv_context.msg_dpc[cpu]); | 808 | tasklet_schedule(hv_context.msg_dpc[cpu]); |
808 | } | 809 | } |
810 | |||
811 | add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0); | ||
809 | } | 812 | } |
810 | 813 | ||
811 | 814 | ||
diff --git a/include/crypto/chacha20.h b/include/crypto/chacha20.h index 274bbaeeed0f..20d20f681a72 100644 --- a/include/crypto/chacha20.h +++ b/include/crypto/chacha20.h | |||
@@ -16,6 +16,7 @@ struct chacha20_ctx { | |||
16 | u32 key[8]; | 16 | u32 key[8]; |
17 | }; | 17 | }; |
18 | 18 | ||
19 | void chacha20_block(u32 *state, void *stream); | ||
19 | void crypto_chacha20_init(u32 *state, struct chacha20_ctx *ctx, u8 *iv); | 20 | void crypto_chacha20_init(u32 *state, struct chacha20_ctx *ctx, u8 *iv); |
20 | int crypto_chacha20_setkey(struct crypto_tfm *tfm, const u8 *key, | 21 | int crypto_chacha20_setkey(struct crypto_tfm *tfm, const u8 *key, |
21 | unsigned int keysize); | 22 | unsigned int keysize); |
diff --git a/lib/Makefile b/lib/Makefile index 07d06a8b9788..cfa68eb269e4 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -19,7 +19,7 @@ KCOV_INSTRUMENT_dynamic_debug.o := n | |||
19 | lib-y := ctype.o string.o vsprintf.o cmdline.o \ | 19 | lib-y := ctype.o string.o vsprintf.o cmdline.o \ |
20 | rbtree.o radix-tree.o dump_stack.o timerqueue.o\ | 20 | rbtree.o radix-tree.o dump_stack.o timerqueue.o\ |
21 | idr.o int_sqrt.o extable.o \ | 21 | idr.o int_sqrt.o extable.o \ |
22 | sha1.o md5.o irq_regs.o argv_split.o \ | 22 | sha1.o chacha20.o md5.o irq_regs.o argv_split.o \ |
23 | flex_proportions.o ratelimit.o show_mem.o \ | 23 | flex_proportions.o ratelimit.o show_mem.o \ |
24 | is_single_threaded.o plist.o decompress.o kobject_uevent.o \ | 24 | is_single_threaded.o plist.o decompress.o kobject_uevent.o \ |
25 | earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o | 25 | earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o |
diff --git a/lib/chacha20.c b/lib/chacha20.c new file mode 100644 index 000000000000..250ceed9ec9a --- /dev/null +++ b/lib/chacha20.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * ChaCha20 256-bit cipher algorithm, RFC7539 | ||
3 | * | ||
4 | * Copyright (C) 2015 Martin Willi | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/export.h> | ||
14 | #include <linux/bitops.h> | ||
15 | #include <linux/cryptohash.h> | ||
16 | #include <asm/unaligned.h> | ||
17 | #include <crypto/chacha20.h> | ||
18 | |||
19 | static inline u32 rotl32(u32 v, u8 n) | ||
20 | { | ||
21 | return (v << n) | (v >> (sizeof(v) * 8 - n)); | ||
22 | } | ||
23 | |||
24 | extern void chacha20_block(u32 *state, void *stream) | ||
25 | { | ||
26 | u32 x[16], *out = stream; | ||
27 | int i; | ||
28 | |||
29 | for (i = 0; i < ARRAY_SIZE(x); i++) | ||
30 | x[i] = state[i]; | ||
31 | |||
32 | for (i = 0; i < 20; i += 2) { | ||
33 | x[0] += x[4]; x[12] = rotl32(x[12] ^ x[0], 16); | ||
34 | x[1] += x[5]; x[13] = rotl32(x[13] ^ x[1], 16); | ||
35 | x[2] += x[6]; x[14] = rotl32(x[14] ^ x[2], 16); | ||
36 | x[3] += x[7]; x[15] = rotl32(x[15] ^ x[3], 16); | ||
37 | |||
38 | x[8] += x[12]; x[4] = rotl32(x[4] ^ x[8], 12); | ||
39 | x[9] += x[13]; x[5] = rotl32(x[5] ^ x[9], 12); | ||
40 | x[10] += x[14]; x[6] = rotl32(x[6] ^ x[10], 12); | ||
41 | x[11] += x[15]; x[7] = rotl32(x[7] ^ x[11], 12); | ||
42 | |||
43 | x[0] += x[4]; x[12] = rotl32(x[12] ^ x[0], 8); | ||
44 | x[1] += x[5]; x[13] = rotl32(x[13] ^ x[1], 8); | ||
45 | x[2] += x[6]; x[14] = rotl32(x[14] ^ x[2], 8); | ||
46 | x[3] += x[7]; x[15] = rotl32(x[15] ^ x[3], 8); | ||
47 | |||
48 | x[8] += x[12]; x[4] = rotl32(x[4] ^ x[8], 7); | ||
49 | x[9] += x[13]; x[5] = rotl32(x[5] ^ x[9], 7); | ||
50 | x[10] += x[14]; x[6] = rotl32(x[6] ^ x[10], 7); | ||
51 | x[11] += x[15]; x[7] = rotl32(x[7] ^ x[11], 7); | ||
52 | |||
53 | x[0] += x[5]; x[15] = rotl32(x[15] ^ x[0], 16); | ||
54 | x[1] += x[6]; x[12] = rotl32(x[12] ^ x[1], 16); | ||
55 | x[2] += x[7]; x[13] = rotl32(x[13] ^ x[2], 16); | ||
56 | x[3] += x[4]; x[14] = rotl32(x[14] ^ x[3], 16); | ||
57 | |||
58 | x[10] += x[15]; x[5] = rotl32(x[5] ^ x[10], 12); | ||
59 | x[11] += x[12]; x[6] = rotl32(x[6] ^ x[11], 12); | ||
60 | x[8] += x[13]; x[7] = rotl32(x[7] ^ x[8], 12); | ||
61 | x[9] += x[14]; x[4] = rotl32(x[4] ^ x[9], 12); | ||
62 | |||
63 | x[0] += x[5]; x[15] = rotl32(x[15] ^ x[0], 8); | ||
64 | x[1] += x[6]; x[12] = rotl32(x[12] ^ x[1], 8); | ||
65 | x[2] += x[7]; x[13] = rotl32(x[13] ^ x[2], 8); | ||
66 | x[3] += x[4]; x[14] = rotl32(x[14] ^ x[3], 8); | ||
67 | |||
68 | x[10] += x[15]; x[5] = rotl32(x[5] ^ x[10], 7); | ||
69 | x[11] += x[12]; x[6] = rotl32(x[6] ^ x[11], 7); | ||
70 | x[8] += x[13]; x[7] = rotl32(x[7] ^ x[8], 7); | ||
71 | x[9] += x[14]; x[4] = rotl32(x[4] ^ x[9], 7); | ||
72 | } | ||
73 | |||
74 | for (i = 0; i < ARRAY_SIZE(x); i++) | ||
75 | out[i] = cpu_to_le32(x[i] + state[i]); | ||
76 | |||
77 | state[12]++; | ||
78 | } | ||
79 | EXPORT_SYMBOL(chacha20_block); | ||