aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/random.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2018-04-11 14:58:27 -0400
committerTheodore Ts'o <tytso@mit.edu>2018-04-14 11:59:09 -0400
commitdc12baacb95f205948f64dc936a47d89ee110117 (patch)
tree1e2e7e65b48e21064e337dae6f4e4a93fa7ce54a /drivers/char/random.c
parent43838a23a05fbd13e47d750d3dfd77001536dd33 (diff)
random: use a different mixing algorithm for add_device_randomness()
add_device_randomness() use of crng_fast_load() was highly problematic. Some callers of add_device_randomness() can pass in a large amount of static information. This would immediately promote the crng_init state from 0 to 1, without really doing much to initialize the primary_crng's internal state with something even vaguely unpredictable. Since we don't have the speed constraints of add_interrupt_randomness(), we can do a better job mixing in the what unpredictability a device driver or architecture maintainer might see fit to give us, and do it in a way which does not bump the crng_init_cnt variable. Also, since add_device_randomness() doesn't bump any entropy accounting in crng_init state 0, mix the device randomness into the input_pool entropy pool as well. This is related to CVE-2018-1108. Reported-by: Jann Horn <jannh@google.com> Fixes: ee7998c50c26 ("random: do not ignore early device randomness") Cc: stable@kernel.org # 4.13+ Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'drivers/char/random.c')
-rw-r--r--drivers/char/random.c55
1 files changed, 51 insertions, 4 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index c8ec1e70abde..6baa828c0493 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -787,6 +787,10 @@ static void crng_initialize(struct crng_state *crng)
787 crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; 787 crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
788} 788}
789 789
790/*
791 * crng_fast_load() can be called by code in the interrupt service
792 * path. So we can't afford to dilly-dally.
793 */
790static int crng_fast_load(const char *cp, size_t len) 794static int crng_fast_load(const char *cp, size_t len)
791{ 795{
792 unsigned long flags; 796 unsigned long flags;
@@ -813,6 +817,51 @@ static int crng_fast_load(const char *cp, size_t len)
813 return 1; 817 return 1;
814} 818}
815 819
820/*
821 * crng_slow_load() is called by add_device_randomness, which has two
822 * attributes. (1) We can't trust the buffer passed to it is
823 * guaranteed to be unpredictable (so it might not have any entropy at
824 * all), and (2) it doesn't have the performance constraints of
825 * crng_fast_load().
826 *
827 * So we do something more comprehensive which is guaranteed to touch
828 * all of the primary_crng's state, and which uses a LFSR with a
829 * period of 255 as part of the mixing algorithm. Finally, we do
830 * *not* advance crng_init_cnt since buffer we may get may be something
831 * like a fixed DMI table (for example), which might very well be
832 * unique to the machine, but is otherwise unvarying.
833 */
834static int crng_slow_load(const char *cp, size_t len)
835{
836 unsigned long flags;
837 static unsigned char lfsr = 1;
838 unsigned char tmp;
839 unsigned i, max = CHACHA20_KEY_SIZE;
840 const char * src_buf = cp;
841 char * dest_buf = (char *) &primary_crng.state[4];
842
843 if (!spin_trylock_irqsave(&primary_crng.lock, flags))
844 return 0;
845 if (crng_init != 0) {
846 spin_unlock_irqrestore(&primary_crng.lock, flags);
847 return 0;
848 }
849 if (len > max)
850 max = len;
851
852 for (i = 0; i < max ; i++) {
853 tmp = lfsr;
854 lfsr >>= 1;
855 if (tmp & 1)
856 lfsr ^= 0xE1;
857 tmp = dest_buf[i % CHACHA20_KEY_SIZE];
858 dest_buf[i % CHACHA20_KEY_SIZE] ^= src_buf[i % len] ^ lfsr;
859 lfsr += (tmp << 3) | (tmp >> 5);
860 }
861 spin_unlock_irqrestore(&primary_crng.lock, flags);
862 return 1;
863}
864
816static void crng_reseed(struct crng_state *crng, struct entropy_store *r) 865static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
817{ 866{
818 unsigned long flags; 867 unsigned long flags;
@@ -981,10 +1030,8 @@ void add_device_randomness(const void *buf, unsigned int size)
981 unsigned long time = random_get_entropy() ^ jiffies; 1030 unsigned long time = random_get_entropy() ^ jiffies;
982 unsigned long flags; 1031 unsigned long flags;
983 1032
984 if (!crng_ready()) { 1033 if (!crng_ready() && size)
985 crng_fast_load(buf, size); 1034 crng_slow_load(buf, size);
986 return;
987 }
988 1035
989 trace_add_device_randomness(size, _RET_IP_); 1036 trace_add_device_randomness(size, _RET_IP_);
990 spin_lock_irqsave(&input_pool.lock, flags); 1037 spin_lock_irqsave(&input_pool.lock, flags);