aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/random.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2013-09-10 23:16:17 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-10-10 14:32:14 -0400
commita283b5c459784f9762a74c312b134e9a524f5a5f (patch)
tree4d95a6686ce716f1ca69a7a23120647b1aa6220d /drivers/char/random.c
parent9ed17b70b409dc48c134a80b5a6df582ba759de2 (diff)
random: allow fractional bits to be tracked
Allow fractional bits of entropy to be tracked by scaling the entropy counter (fixed point). This will be used in a subsequent patch that accounts for entropy lost due to overwrites. [ Modified by tytso to fix up a few missing places where the entropy_count wasn't properly converted from fractional bits to bits. ] Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'drivers/char/random.c')
-rw-r--r--drivers/char/random.c138
1 files changed, 92 insertions, 46 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 20651a2fd8a7..c2957656c5bc 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -280,6 +280,15 @@
280#define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long)) 280#define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long))
281 281
282/* 282/*
283 * To allow fractional bits to be tracked, the following fields contain
284 * this many fractional bits:
285 *
286 * entropy_count, trickle_thresh
287 */
288#define ENTROPY_SHIFT 3
289#define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT)
290
291/*
283 * The minimum number of bits of entropy before we wake up a read on 292 * The minimum number of bits of entropy before we wake up a read on
284 * /dev/random. Should be enough to do a significant reseed. 293 * /dev/random. Should be enough to do a significant reseed.
285 */ 294 */
@@ -296,8 +305,7 @@ static int random_write_wakeup_thresh = 128;
296 * When the input pool goes over trickle_thresh, start dropping most 305 * When the input pool goes over trickle_thresh, start dropping most
297 * samples to avoid wasting CPU time and reduce lock contention. 306 * samples to avoid wasting CPU time and reduce lock contention.
298 */ 307 */
299 308static const int trickle_thresh = (INPUT_POOL_WORDS * 28) << ENTROPY_SHIFT;
300static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28;
301 309
302static DEFINE_PER_CPU(int, trickle_count); 310static DEFINE_PER_CPU(int, trickle_count);
303 311
@@ -311,8 +319,8 @@ static DEFINE_PER_CPU(int, trickle_count);
311 */ 319 */
312 320
313static struct poolinfo { 321static struct poolinfo {
314 int poolbitshift, poolwords, poolbytes, poolbits; 322 int poolbitshift, poolwords, poolbytes, poolbits, poolfracbits;
315#define S(x) ilog2(x)+5, (x), (x)*4, (x)*32 323#define S(x) ilog2(x)+5, (x), (x)*4, (x)*32, (x) << (ENTROPY_SHIFT+5)
316 int tap1, tap2, tap3, tap4, tap5; 324 int tap1, tap2, tap3, tap4, tap5;
317} poolinfo_table[] = { 325} poolinfo_table[] = {
318 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */ 326 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
@@ -581,7 +589,9 @@ static void fast_mix(struct fast_pool *f, const void *in, int nbytes)
581} 589}
582 590
583/* 591/*
584 * Credit (or debit) the entropy store with n bits of entropy 592 * Credit (or debit) the entropy store with n bits of entropy.
593 * Use credit_entropy_bits_safe() if the value comes from userspace
594 * or otherwise should be checked for extreme values.
585 */ 595 */
586static void credit_entropy_bits(struct entropy_store *r, int nbits) 596static void credit_entropy_bits(struct entropy_store *r, int nbits)
587{ 597{
@@ -593,13 +603,13 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits)
593 DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); 603 DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name);
594retry: 604retry:
595 entropy_count = orig = ACCESS_ONCE(r->entropy_count); 605 entropy_count = orig = ACCESS_ONCE(r->entropy_count);
596 entropy_count += nbits; 606 entropy_count += nbits << ENTROPY_SHIFT;
597 607
598 if (entropy_count < 0) { 608 if (entropy_count < 0) {
599 DEBUG_ENT("negative entropy/overflow\n"); 609 DEBUG_ENT("negative entropy/overflow\n");
600 entropy_count = 0; 610 entropy_count = 0;
601 } else if (entropy_count > r->poolinfo->poolbits) 611 } else if (entropy_count > r->poolinfo->poolfracbits)
602 entropy_count = r->poolinfo->poolbits; 612 entropy_count = r->poolinfo->poolfracbits;
603 if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) 613 if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
604 goto retry; 614 goto retry;
605 615
@@ -609,16 +619,29 @@ retry:
609 r->initialized = 1; 619 r->initialized = 1;
610 } 620 }
611 621
612 trace_credit_entropy_bits(r->name, nbits, entropy_count, 622 trace_credit_entropy_bits(r->name, nbits,
623 entropy_count >> ENTROPY_SHIFT,
613 r->entropy_total, _RET_IP_); 624 r->entropy_total, _RET_IP_);
614 625
615 /* should we wake readers? */ 626 /* should we wake readers? */
616 if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { 627 if (r == &input_pool &&
628 (entropy_count >> ENTROPY_SHIFT) >= random_read_wakeup_thresh) {
617 wake_up_interruptible(&random_read_wait); 629 wake_up_interruptible(&random_read_wait);
618 kill_fasync(&fasync, SIGIO, POLL_IN); 630 kill_fasync(&fasync, SIGIO, POLL_IN);
619 } 631 }
620} 632}
621 633
634static void credit_entropy_bits_safe(struct entropy_store *r, int nbits)
635{
636 const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1));
637
638 /* Cap the value to avoid overflows */
639 nbits = min(nbits, nbits_max);
640 nbits = max(nbits, -nbits_max);
641
642 credit_entropy_bits(r, nbits);
643}
644
622/********************************************************************* 645/*********************************************************************
623 * 646 *
624 * Entropy input management 647 * Entropy input management
@@ -674,7 +697,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
674 697
675 preempt_disable(); 698 preempt_disable();
676 /* if over the trickle threshold, use only 1 in 4096 samples */ 699 /* if over the trickle threshold, use only 1 in 4096 samples */
677 if (input_pool.entropy_count > trickle_thresh && 700 if (ENTROPY_BITS(&input_pool) > trickle_thresh &&
678 ((__this_cpu_inc_return(trickle_count) - 1) & 0xfff)) 701 ((__this_cpu_inc_return(trickle_count) - 1) & 0xfff))
679 goto out; 702 goto out;
680 703
@@ -813,8 +836,9 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
813{ 836{
814 __u32 tmp[OUTPUT_POOL_WORDS]; 837 __u32 tmp[OUTPUT_POOL_WORDS];
815 838
816 if (r->pull && r->entropy_count < nbytes * 8 && 839 if (r->pull &&
817 r->entropy_count < r->poolinfo->poolbits) { 840 r->entropy_count < (nbytes << (ENTROPY_SHIFT + 3)) &&
841 r->entropy_count < r->poolinfo->poolfracbits) {
818 /* If we're limited, always leave two wakeup worth's BITS */ 842 /* If we're limited, always leave two wakeup worth's BITS */
819 int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; 843 int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4;
820 int bytes = nbytes; 844 int bytes = nbytes;
@@ -826,7 +850,8 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
826 850
827 DEBUG_ENT("going to reseed %s with %d bits " 851 DEBUG_ENT("going to reseed %s with %d bits "
828 "(%zu of %d requested)\n", 852 "(%zu of %d requested)\n",
829 r->name, bytes * 8, nbytes * 8, r->entropy_count); 853 r->name, bytes * 8, nbytes * 8,
854 r->entropy_count >> ENTROPY_SHIFT);
830 855
831 bytes = extract_entropy(r->pull, tmp, bytes, 856 bytes = extract_entropy(r->pull, tmp, bytes,
832 random_read_wakeup_thresh / 8, rsvd); 857 random_read_wakeup_thresh / 8, rsvd);
@@ -852,41 +877,44 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
852{ 877{
853 unsigned long flags; 878 unsigned long flags;
854 int wakeup_write = 0; 879 int wakeup_write = 0;
880 int have_bytes;
881 int entropy_count, orig;
882 size_t ibytes;
855 883
856 /* Hold lock while accounting */ 884 /* Hold lock while accounting */
857 spin_lock_irqsave(&r->lock, flags); 885 spin_lock_irqsave(&r->lock, flags);
858 886
859 BUG_ON(r->entropy_count > r->poolinfo->poolbits); 887 BUG_ON(r->entropy_count > r->poolinfo->poolfracbits);
860 DEBUG_ENT("trying to extract %zu bits from %s\n", 888 DEBUG_ENT("trying to extract %zu bits from %s\n",
861 nbytes * 8, r->name); 889 nbytes * 8, r->name);
862 890
863 /* Can we pull enough? */ 891 /* Can we pull enough? */
864 if (r->entropy_count / 8 < min + reserved) {
865 nbytes = 0;
866 } else {
867 int entropy_count, orig;
868retry: 892retry:
869 entropy_count = orig = ACCESS_ONCE(r->entropy_count); 893 entropy_count = orig = ACCESS_ONCE(r->entropy_count);
894 have_bytes = entropy_count >> (ENTROPY_SHIFT + 3);
895 ibytes = nbytes;
896 if (have_bytes < min + reserved) {
897 ibytes = 0;
898 } else {
870 /* If limited, never pull more than available */ 899 /* If limited, never pull more than available */
871 if (r->limit && nbytes + reserved >= entropy_count / 8) 900 if (r->limit && ibytes + reserved >= have_bytes)
872 nbytes = entropy_count/8 - reserved; 901 ibytes = have_bytes - reserved;
873 902
874 if (entropy_count / 8 >= nbytes + reserved) { 903 if (have_bytes >= ibytes + reserved)
875 entropy_count -= nbytes*8; 904 entropy_count -= ibytes << (ENTROPY_SHIFT + 3);
876 if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) 905 else
877 goto retry; 906 entropy_count = reserved << (ENTROPY_SHIFT + 3);
878 } else {
879 entropy_count = reserved;
880 if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
881 goto retry;
882 }
883 907
884 if (entropy_count < random_write_wakeup_thresh) 908 if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
909 goto retry;
910
911 if ((r->entropy_count >> ENTROPY_SHIFT)
912 < random_write_wakeup_thresh)
885 wakeup_write = 1; 913 wakeup_write = 1;
886 } 914 }
887 915
888 DEBUG_ENT("debiting %zu entropy credits from %s%s\n", 916 DEBUG_ENT("debiting %zu entropy credits from %s%s\n",
889 nbytes * 8, r->name, r->limit ? "" : " (unlimited)"); 917 ibytes * 8, r->name, r->limit ? "" : " (unlimited)");
890 918
891 spin_unlock_irqrestore(&r->lock, flags); 919 spin_unlock_irqrestore(&r->lock, flags);
892 920
@@ -895,7 +923,7 @@ retry:
895 kill_fasync(&fasync, SIGIO, POLL_OUT); 923 kill_fasync(&fasync, SIGIO, POLL_OUT);
896 } 924 }
897 925
898 return nbytes; 926 return ibytes;
899} 927}
900 928
901static void extract_buf(struct entropy_store *r, __u8 *out) 929static void extract_buf(struct entropy_store *r, __u8 *out)
@@ -973,7 +1001,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
973 r->last_data_init = true; 1001 r->last_data_init = true;
974 spin_unlock_irqrestore(&r->lock, flags); 1002 spin_unlock_irqrestore(&r->lock, flags);
975 trace_extract_entropy(r->name, EXTRACT_SIZE, 1003 trace_extract_entropy(r->name, EXTRACT_SIZE,
976 r->entropy_count, _RET_IP_); 1004 ENTROPY_BITS(r), _RET_IP_);
977 xfer_secondary_pool(r, EXTRACT_SIZE); 1005 xfer_secondary_pool(r, EXTRACT_SIZE);
978 extract_buf(r, tmp); 1006 extract_buf(r, tmp);
979 spin_lock_irqsave(&r->lock, flags); 1007 spin_lock_irqsave(&r->lock, flags);
@@ -982,7 +1010,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
982 spin_unlock_irqrestore(&r->lock, flags); 1010 spin_unlock_irqrestore(&r->lock, flags);
983 } 1011 }
984 1012
985 trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); 1013 trace_extract_entropy(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
986 xfer_secondary_pool(r, nbytes); 1014 xfer_secondary_pool(r, nbytes);
987 nbytes = account(r, nbytes, min, reserved); 1015 nbytes = account(r, nbytes, min, reserved);
988 1016
@@ -1015,7 +1043,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
1015 ssize_t ret = 0, i; 1043 ssize_t ret = 0, i;
1016 __u8 tmp[EXTRACT_SIZE]; 1044 __u8 tmp[EXTRACT_SIZE];
1017 1045
1018 trace_extract_entropy_user(r->name, nbytes, r->entropy_count, _RET_IP_); 1046 trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
1019 xfer_secondary_pool(r, nbytes); 1047 xfer_secondary_pool(r, nbytes);
1020 nbytes = account(r, nbytes, 0, 0); 1048 nbytes = account(r, nbytes, 0, 0);
1021 1049
@@ -1187,8 +1215,8 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
1187 DEBUG_ENT("sleeping?\n"); 1215 DEBUG_ENT("sleeping?\n");
1188 1216
1189 wait_event_interruptible(random_read_wait, 1217 wait_event_interruptible(random_read_wait,
1190 input_pool.entropy_count >= 1218 ENTROPY_BITS(&input_pool) >=
1191 random_read_wakeup_thresh); 1219 random_read_wakeup_thresh);
1192 1220
1193 DEBUG_ENT("awake\n"); 1221 DEBUG_ENT("awake\n");
1194 1222
@@ -1224,9 +1252,9 @@ random_poll(struct file *file, poll_table * wait)
1224 poll_wait(file, &random_read_wait, wait); 1252 poll_wait(file, &random_read_wait, wait);
1225 poll_wait(file, &random_write_wait, wait); 1253 poll_wait(file, &random_write_wait, wait);
1226 mask = 0; 1254 mask = 0;
1227 if (input_pool.entropy_count >= random_read_wakeup_thresh) 1255 if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_thresh)
1228 mask |= POLLIN | POLLRDNORM; 1256 mask |= POLLIN | POLLRDNORM;
1229 if (input_pool.entropy_count < random_write_wakeup_thresh) 1257 if (ENTROPY_BITS(&input_pool) < random_write_wakeup_thresh)
1230 mask |= POLLOUT | POLLWRNORM; 1258 mask |= POLLOUT | POLLWRNORM;
1231 return mask; 1259 return mask;
1232} 1260}
@@ -1277,7 +1305,8 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
1277 switch (cmd) { 1305 switch (cmd) {
1278 case RNDGETENTCNT: 1306 case RNDGETENTCNT:
1279 /* inherently racy, no point locking */ 1307 /* inherently racy, no point locking */
1280 if (put_user(input_pool.entropy_count, p)) 1308 ent_count = ENTROPY_BITS(&input_pool);
1309 if (put_user(ent_count, p))
1281 return -EFAULT; 1310 return -EFAULT;
1282 return 0; 1311 return 0;
1283 case RNDADDTOENTCNT: 1312 case RNDADDTOENTCNT:
@@ -1285,7 +1314,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
1285 return -EPERM; 1314 return -EPERM;
1286 if (get_user(ent_count, p)) 1315 if (get_user(ent_count, p))
1287 return -EFAULT; 1316 return -EFAULT;
1288 credit_entropy_bits(&input_pool, ent_count); 1317 credit_entropy_bits_safe(&input_pool, ent_count);
1289 return 0; 1318 return 0;
1290 case RNDADDENTROPY: 1319 case RNDADDENTROPY:
1291 if (!capable(CAP_SYS_ADMIN)) 1320 if (!capable(CAP_SYS_ADMIN))
@@ -1300,7 +1329,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
1300 size); 1329 size);
1301 if (retval < 0) 1330 if (retval < 0)
1302 return retval; 1331 return retval;
1303 credit_entropy_bits(&input_pool, ent_count); 1332 credit_entropy_bits_safe(&input_pool, ent_count);
1304 return 0; 1333 return 0;
1305 case RNDZAPENTCNT: 1334 case RNDZAPENTCNT:
1306 case RNDCLEARPOOL: 1335 case RNDCLEARPOOL:
@@ -1407,6 +1436,23 @@ static int proc_do_uuid(struct ctl_table *table, int write,
1407 return proc_dostring(&fake_table, write, buffer, lenp, ppos); 1436 return proc_dostring(&fake_table, write, buffer, lenp, ppos);
1408} 1437}
1409 1438
1439/*
1440 * Return entropy available scaled to integral bits
1441 */
1442static int proc_do_entropy(ctl_table *table, int write,
1443 void __user *buffer, size_t *lenp, loff_t *ppos)
1444{
1445 ctl_table fake_table;
1446 int entropy_count;
1447
1448 entropy_count = *(int *)table->data >> ENTROPY_SHIFT;
1449
1450 fake_table.data = &entropy_count;
1451 fake_table.maxlen = sizeof(entropy_count);
1452
1453 return proc_dointvec(&fake_table, write, buffer, lenp, ppos);
1454}
1455
1410static int sysctl_poolsize = INPUT_POOL_WORDS * 32; 1456static int sysctl_poolsize = INPUT_POOL_WORDS * 32;
1411extern struct ctl_table random_table[]; 1457extern struct ctl_table random_table[];
1412struct ctl_table random_table[] = { 1458struct ctl_table random_table[] = {
@@ -1421,7 +1467,7 @@ struct ctl_table random_table[] = {
1421 .procname = "entropy_avail", 1467 .procname = "entropy_avail",
1422 .maxlen = sizeof(int), 1468 .maxlen = sizeof(int),
1423 .mode = 0444, 1469 .mode = 0444,
1424 .proc_handler = proc_dointvec, 1470 .proc_handler = proc_do_entropy,
1425 .data = &input_pool.entropy_count, 1471 .data = &input_pool.entropy_count,
1426 }, 1472 },
1427 { 1473 {