random: replace non-blocking pool with a Chacha20-based CRNG

The CRNG is faster, and we don't pretend to track entropy usage in the
CRNG any more.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>

+357 -164
-61
crypto/chacha20_generic.c
··· 15 #include <linux/module.h> 16 #include <crypto/chacha20.h> 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) 24 { 25 return le32_to_cpup(p); 26 - } 27 - 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,
··· 15 #include <linux/module.h> 16 #include <crypto/chacha20.h> 17 18 static inline u32 le32_to_cpuvp(const void *p) 19 { 20 return le32_to_cpup(p); 21 } 22 23 static void chacha20_docrypt(u32 *state, u8 *dst, const u8 *src,
+276 -102
drivers/char/random.c
··· 261 #include <linux/syscalls.h> 262 #include <linux/completion.h> 263 #include <linux/uuid.h> 264 265 #include <asm/processor.h> 266 #include <asm/uaccess.h> ··· 414 static DEFINE_SPINLOCK(random_ready_list_lock); 415 static LIST_HEAD(random_ready_list); 416 417 /********************************************************************** 418 * 419 * OS independent entropy store. Here are the functions which handle ··· 468 __u8 last_data[EXTRACT_SIZE]; 469 }; 470 471 static void push_to_pool(struct work_struct *work); 472 static __u32 input_pool_data[INPUT_POOL_WORDS]; 473 static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; 474 - static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS]; 475 476 static struct entropy_store input_pool = { 477 .poolinfo = &poolinfo_table[0], ··· 494 .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock), 495 .pool = blocking_pool_data, 496 .push_work = __WORK_INITIALIZER(blocking_pool.push_work, 497 - push_to_pool), 498 - }; 499 - 500 - static struct entropy_store nonblocking_pool = { 501 - .poolinfo = &poolinfo_table[1], 502 - .name = "nonblocking", 503 - .pull = &input_pool, 504 - .lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock), 505 - .pool = nonblocking_pool_data, 506 - .push_work = __WORK_INITIALIZER(nonblocking_pool.push_work, 507 push_to_pool), 508 }; 509 ··· 699 if (!r->initialized && r->entropy_total > 128) { 700 r->initialized = 1; 701 r->entropy_total = 0; 702 - if (r == &nonblocking_pool) { 703 - prandom_reseed_late(); 704 - process_random_ready_list(); 705 - wake_up_all(&urandom_init_wait); 706 - pr_notice("random: %s pool is initialized\n", r->name); 707 - } 708 } 709 710 trace_credit_entropy_bits(r->name, nbits, ··· 708 if (r == &input_pool) { 709 int entropy_bits = entropy_count >> ENTROPY_SHIFT; 710 711 /* should we wake readers? */ 712 if (entropy_bits >= random_read_wakeup_bits) { 713 wake_up_interruptible(&random_read_wait); 714 kill_fasync(&fasync, SIGIO, POLL_IN); 715 } 716 /* If the input pool is getting full, send some 717 - * entropy to the two output pools, flipping back and 718 - * forth between them, until the output pools are 75% 719 - * full. 720 */ 721 if (entropy_bits > random_write_wakeup_bits && 722 r->initialized && 723 r->entropy_total >= 2*random_read_wakeup_bits) { 724 - static struct entropy_store *last = &blocking_pool; 725 struct entropy_store *other = &blocking_pool; 726 727 - if (last == &blocking_pool) 728 - other = &nonblocking_pool; 729 if (other->entropy_count <= 730 - 3 * other->poolinfo->poolfracbits / 4) 731 - last = other; 732 - if (last->entropy_count <= 733 - 3 * last->poolinfo->poolfracbits / 4) { 734 - schedule_work(&last->push_work); 735 r->entropy_total = 0; 736 } 737 } ··· 748 749 /********************************************************************* 750 * 751 * Entropy input management 752 * 753 *********************************************************************/ ··· 908 #define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, }; 909 910 /* 911 - * Add device- or boot-specific data to the input and nonblocking 912 - * pools to help initialize them to unique values. 913 * 914 - * None of this adds any entropy, it is meant to avoid the 915 - * problem of the nonblocking pool having similar initial state 916 - * across largely identical devices. 917 */ 918 void add_device_randomness(const void *buf, unsigned int size) 919 { ··· 925 _mix_pool_bytes(&input_pool, buf, size); 926 _mix_pool_bytes(&input_pool, &time, sizeof(time)); 927 spin_unlock_irqrestore(&input_pool.lock, flags); 928 - 929 - spin_lock_irqsave(&nonblocking_pool.lock, flags); 930 - _mix_pool_bytes(&nonblocking_pool, buf, size); 931 - _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time)); 932 - spin_unlock_irqrestore(&nonblocking_pool.lock, flags); 933 } 934 EXPORT_SYMBOL(add_device_randomness); 935 ··· 955 sample.jiffies = jiffies; 956 sample.cycles = random_get_entropy(); 957 sample.num = num; 958 - r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; 959 mix_pool_bytes(r, &sample, sizeof(sample)); 960 961 /* ··· 1071 fast_mix(fast_pool); 1072 add_interrupt_bench(cycles); 1073 1074 if ((fast_pool->count < 64) && 1075 !time_after(now, fast_pool->last + HZ)) 1076 return; 1077 1078 - r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; 1079 if (!spin_trylock(&r->lock)) 1080 return; 1081 ··· 1128 * Entropy extraction routines 1129 * 1130 *********************************************************************/ 1131 - 1132 - static ssize_t extract_entropy(struct entropy_store *r, void *buf, 1133 - size_t nbytes, int min, int rsvd); 1134 1135 /* 1136 * This utility inline function is responsible for transferring entropy ··· 1303 memzero_explicit(&hash, sizeof(hash)); 1304 } 1305 1306 /* 1307 * This function extracts randomness from the "entropy pool", and 1308 * returns it in a buffer. ··· 1345 static ssize_t extract_entropy(struct entropy_store *r, void *buf, 1346 size_t nbytes, int min, int reserved) 1347 { 1348 - ssize_t ret = 0, i; 1349 __u8 tmp[EXTRACT_SIZE]; 1350 unsigned long flags; 1351 ··· 1368 xfer_secondary_pool(r, nbytes); 1369 nbytes = account(r, nbytes, min, reserved); 1370 1371 - while (nbytes) { 1372 - extract_buf(r, tmp); 1373 - 1374 - if (fips_enabled) { 1375 - spin_lock_irqsave(&r->lock, flags); 1376 - if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) 1377 - panic("Hardware RNG duplicated output!\n"); 1378 - memcpy(r->last_data, tmp, EXTRACT_SIZE); 1379 - spin_unlock_irqrestore(&r->lock, flags); 1380 - } 1381 - i = min_t(int, nbytes, EXTRACT_SIZE); 1382 - memcpy(buf, tmp, i); 1383 - nbytes -= i; 1384 - buf += i; 1385 - ret += i; 1386 - } 1387 - 1388 - /* Wipe data just returned from memory */ 1389 - memzero_explicit(tmp, sizeof(tmp)); 1390 - 1391 - return ret; 1392 } 1393 1394 /* ··· 1423 */ 1424 void get_random_bytes(void *buf, int nbytes) 1425 { 1426 #if DEBUG_RANDOM_BOOT > 0 1427 - if (unlikely(nonblocking_pool.initialized == 0)) 1428 printk(KERN_NOTICE "random: %pF get_random_bytes called " 1429 - "with %d bits of entropy available\n", 1430 - (void *) _RET_IP_, 1431 - nonblocking_pool.entropy_total); 1432 #endif 1433 trace_get_random_bytes(nbytes, _RET_IP_); 1434 - extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); 1435 } 1436 EXPORT_SYMBOL(get_random_bytes); 1437 ··· 1460 unsigned long flags; 1461 int err = -EALREADY; 1462 1463 - if (likely(nonblocking_pool.initialized)) 1464 return err; 1465 1466 owner = rdy->owner; ··· 1468 return -ENOENT; 1469 1470 spin_lock_irqsave(&random_ready_list_lock, flags); 1471 - if (nonblocking_pool.initialized) 1472 goto out; 1473 1474 owner = NULL; ··· 1532 } 1533 1534 if (nbytes) 1535 - extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); 1536 } 1537 EXPORT_SYMBOL(get_random_bytes_arch); 1538 ··· 1577 { 1578 init_std_data(&input_pool); 1579 init_std_data(&blocking_pool); 1580 - init_std_data(&nonblocking_pool); 1581 return 0; 1582 } 1583 early_initcall(rand_initialize); ··· 1639 static ssize_t 1640 urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) 1641 { 1642 static int maxwarn = 10; 1643 int ret; 1644 1645 - if (unlikely(nonblocking_pool.initialized == 0) && 1646 - maxwarn > 0) { 1647 maxwarn--; 1648 printk(KERN_NOTICE "random: %s: uninitialized urandom read " 1649 - "(%zd bytes read, %d bits of entropy available)\n", 1650 - current->comm, nbytes, nonblocking_pool.entropy_total); 1651 } 1652 - 1653 nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3)); 1654 - ret = extract_entropy_user(&nonblocking_pool, buf, nbytes); 1655 - 1656 - trace_urandom_read(8 * nbytes, ENTROPY_BITS(&nonblocking_pool), 1657 - ENTROPY_BITS(&input_pool)); 1658 return ret; 1659 } 1660 ··· 1700 { 1701 size_t ret; 1702 1703 - ret = write_pool(&blocking_pool, buffer, count); 1704 - if (ret) 1705 - return ret; 1706 - ret = write_pool(&nonblocking_pool, buffer, count); 1707 if (ret) 1708 return ret; 1709 ··· 1751 if (!capable(CAP_SYS_ADMIN)) 1752 return -EPERM; 1753 input_pool.entropy_count = 0; 1754 - nonblocking_pool.entropy_count = 0; 1755 blocking_pool.entropy_count = 0; 1756 return 0; 1757 default: ··· 1792 if (flags & GRND_RANDOM) 1793 return _random_read(flags & GRND_NONBLOCK, buf, count); 1794 1795 - if (unlikely(nonblocking_pool.initialized == 0)) { 1796 if (flags & GRND_NONBLOCK) 1797 return -EAGAIN; 1798 - wait_event_interruptible(urandom_init_wait, 1799 - nonblocking_pool.initialized); 1800 if (signal_pending(current)) 1801 return -ERESTARTSYS; 1802 } ··· 2031 { 2032 struct entropy_store *poolp = &input_pool; 2033 2034 - if (unlikely(nonblocking_pool.initialized == 0)) 2035 - poolp = &nonblocking_pool; 2036 - else { 2037 - /* Suspend writing if we're above the trickle 2038 - * threshold. We'll be woken up again once below 2039 - * random_write_wakeup_thresh, or when the calling 2040 - * thread is about to terminate. 2041 - */ 2042 - wait_event_interruptible(random_write_wait, 2043 - kthread_should_stop() || 2044 - ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits); 2045 } 2046 mix_pool_bytes(poolp, buffer, count); 2047 credit_entropy_bits(poolp, entropy); 2048 }
··· 261 #include <linux/syscalls.h> 262 #include <linux/completion.h> 263 #include <linux/uuid.h> 264 + #include <crypto/chacha20.h> 265 266 #include <asm/processor.h> 267 #include <asm/uaccess.h> ··· 413 static DEFINE_SPINLOCK(random_ready_list_lock); 414 static LIST_HEAD(random_ready_list); 415 416 + struct crng_state { 417 + __u32 state[16]; 418 + unsigned long init_time; 419 + spinlock_t lock; 420 + }; 421 + 422 + struct crng_state primary_crng = { 423 + .lock = __SPIN_LOCK_UNLOCKED(primary_crng.lock), 424 + }; 425 + 426 + /* 427 + * crng_init = 0 --> Uninitialized 428 + * 1 --> Initialized 429 + * 2 --> Initialized from input_pool 430 + * 431 + * crng_init is protected by primary_crng->lock, and only increases 432 + * its value (from 0->1->2). 433 + */ 434 + static int crng_init = 0; 435 + #define crng_ready() (likely(crng_init > 0)) 436 + static int crng_init_cnt = 0; 437 + #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) 438 + static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE]); 439 + static void process_random_ready_list(void); 440 + 441 /********************************************************************** 442 * 443 * OS independent entropy store. Here are the functions which handle ··· 442 __u8 last_data[EXTRACT_SIZE]; 443 }; 444 445 + static ssize_t extract_entropy(struct entropy_store *r, void *buf, 446 + size_t nbytes, int min, int rsvd); 447 + static ssize_t _extract_entropy(struct entropy_store *r, void *buf, 448 + size_t nbytes, int fips); 449 + 450 + static void crng_reseed(struct crng_state *crng, struct entropy_store *r); 451 static void push_to_pool(struct work_struct *work); 452 static __u32 input_pool_data[INPUT_POOL_WORDS]; 453 static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; 454 455 static struct entropy_store input_pool = { 456 .poolinfo = &poolinfo_table[0], ··· 463 .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock), 464 .pool = blocking_pool_data, 465 .push_work = __WORK_INITIALIZER(blocking_pool.push_work, 466 push_to_pool), 467 }; 468 ··· 678 if (!r->initialized && r->entropy_total > 128) { 679 r->initialized = 1; 680 r->entropy_total = 0; 681 } 682 683 trace_credit_entropy_bits(r->name, nbits, ··· 693 if (r == &input_pool) { 694 int entropy_bits = entropy_count >> ENTROPY_SHIFT; 695 696 + if (crng_init < 2 && entropy_bits >= 128) { 697 + crng_reseed(&primary_crng, r); 698 + entropy_bits = r->entropy_count >> ENTROPY_SHIFT; 699 + } 700 + 701 /* should we wake readers? */ 702 if (entropy_bits >= random_read_wakeup_bits) { 703 wake_up_interruptible(&random_read_wait); 704 kill_fasync(&fasync, SIGIO, POLL_IN); 705 } 706 /* If the input pool is getting full, send some 707 + * entropy to the blocking pool until it is 75% full. 708 */ 709 if (entropy_bits > random_write_wakeup_bits && 710 r->initialized && 711 r->entropy_total >= 2*random_read_wakeup_bits) { 712 struct entropy_store *other = &blocking_pool; 713 714 if (other->entropy_count <= 715 + 3 * other->poolinfo->poolfracbits / 4) { 716 + schedule_work(&other->push_work); 717 r->entropy_total = 0; 718 } 719 } ··· 736 737 /********************************************************************* 738 * 739 + * CRNG using CHACHA20 740 + * 741 + *********************************************************************/ 742 + 743 + #define CRNG_RESEED_INTERVAL (300*HZ) 744 + 745 + static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); 746 + 747 + static void crng_initialize(struct crng_state *crng) 748 + { 749 + int i; 750 + unsigned long rv; 751 + 752 + memcpy(&crng->state[0], "expand 32-byte k", 16); 753 + if (crng == &primary_crng) 754 + _extract_entropy(&input_pool, &crng->state[4], 755 + sizeof(__u32) * 12, 0); 756 + else 757 + get_random_bytes(&crng->state[4], sizeof(__u32) * 12); 758 + for (i = 4; i < 16; i++) { 759 + if (!arch_get_random_seed_long(&rv) && 760 + !arch_get_random_long(&rv)) 761 + rv = random_get_entropy(); 762 + crng->state[i] ^= rv; 763 + } 764 + crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; 765 + } 766 + 767 + static int crng_fast_load(const char *cp, size_t len) 768 + { 769 + unsigned long flags; 770 + char *p; 771 + 772 + if (!spin_trylock_irqsave(&primary_crng.lock, flags)) 773 + return 0; 774 + if (crng_ready()) { 775 + spin_unlock_irqrestore(&primary_crng.lock, flags); 776 + return 0; 777 + } 778 + p = (unsigned char *) &primary_crng.state[4]; 779 + while (len > 0 && crng_init_cnt < CRNG_INIT_CNT_THRESH) { 780 + p[crng_init_cnt % CHACHA20_KEY_SIZE] ^= *cp; 781 + cp++; crng_init_cnt++; len--; 782 + } 783 + if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { 784 + crng_init = 1; 785 + wake_up_interruptible(&crng_init_wait); 786 + pr_notice("random: fast init done\n"); 787 + } 788 + spin_unlock_irqrestore(&primary_crng.lock, flags); 789 + return 1; 790 + } 791 + 792 + static void crng_reseed(struct crng_state *crng, struct entropy_store *r) 793 + { 794 + unsigned long flags; 795 + int i, num; 796 + union { 797 + __u8 block[CHACHA20_BLOCK_SIZE]; 798 + __u32 key[8]; 799 + } buf; 800 + 801 + if (r) { 802 + num = extract_entropy(r, &buf, 32, 16, 0); 803 + if (num == 0) 804 + return; 805 + } else 806 + extract_crng(buf.block); 807 + spin_lock_irqsave(&primary_crng.lock, flags); 808 + for (i = 0; i < 8; i++) { 809 + unsigned long rv; 810 + if (!arch_get_random_seed_long(&rv) && 811 + !arch_get_random_long(&rv)) 812 + rv = random_get_entropy(); 813 + crng->state[i+4] ^= buf.key[i] ^ rv; 814 + } 815 + memzero_explicit(&buf, sizeof(buf)); 816 + crng->init_time = jiffies; 817 + if (crng == &primary_crng && crng_init < 2) { 818 + crng_init = 2; 819 + process_random_ready_list(); 820 + wake_up_interruptible(&crng_init_wait); 821 + pr_notice("random: crng init done\n"); 822 + } 823 + spin_unlock_irqrestore(&primary_crng.lock, flags); 824 + } 825 + 826 + static inline void crng_wait_ready(void) 827 + { 828 + wait_event_interruptible(crng_init_wait, crng_ready()); 829 + } 830 + 831 + static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE]) 832 + { 833 + unsigned long v, flags; 834 + struct crng_state *crng = &primary_crng; 835 + 836 + if (crng_init > 1 && 837 + time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) 838 + crng_reseed(crng, &input_pool); 839 + spin_lock_irqsave(&crng->lock, flags); 840 + if (arch_get_random_long(&v)) 841 + crng->state[14] ^= v; 842 + chacha20_block(&crng->state[0], out); 843 + if (crng->state[12] == 0) 844 + crng->state[13]++; 845 + spin_unlock_irqrestore(&crng->lock, flags); 846 + } 847 + 848 + static ssize_t extract_crng_user(void __user *buf, size_t nbytes) 849 + { 850 + ssize_t ret = 0, i; 851 + __u8 tmp[CHACHA20_BLOCK_SIZE]; 852 + int large_request = (nbytes > 256); 853 + 854 + while (nbytes) { 855 + if (large_request && need_resched()) { 856 + if (signal_pending(current)) { 857 + if (ret == 0) 858 + ret = -ERESTARTSYS; 859 + break; 860 + } 861 + schedule(); 862 + } 863 + 864 + extract_crng(tmp); 865 + i = min_t(int, nbytes, CHACHA20_BLOCK_SIZE); 866 + if (copy_to_user(buf, tmp, i)) { 867 + ret = -EFAULT; 868 + break; 869 + } 870 + 871 + nbytes -= i; 872 + buf += i; 873 + ret += i; 874 + } 875 + 876 + /* Wipe data just written to memory */ 877 + memzero_explicit(tmp, sizeof(tmp)); 878 + 879 + return ret; 880 + } 881 + 882 + 883 + /********************************************************************* 884 + * 885 * Entropy input management 886 * 887 *********************************************************************/ ··· 750 #define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, }; 751 752 /* 753 + * Add device- or boot-specific data to the input pool to help 754 + * initialize it. 755 * 756 + * None of this adds any entropy; it is meant to avoid the problem of 757 + * the entropy pool having similar initial state across largely 758 + * identical devices. 759 */ 760 void add_device_randomness(const void *buf, unsigned int size) 761 { ··· 767 _mix_pool_bytes(&input_pool, buf, size); 768 _mix_pool_bytes(&input_pool, &time, sizeof(time)); 769 spin_unlock_irqrestore(&input_pool.lock, flags); 770 } 771 EXPORT_SYMBOL(add_device_randomness); 772 ··· 802 sample.jiffies = jiffies; 803 sample.cycles = random_get_entropy(); 804 sample.num = num; 805 + r = &input_pool; 806 mix_pool_bytes(r, &sample, sizeof(sample)); 807 808 /* ··· 918 fast_mix(fast_pool); 919 add_interrupt_bench(cycles); 920 921 + if (!crng_ready()) { 922 + if ((fast_pool->count >= 64) && 923 + crng_fast_load((char *) fast_pool->pool, 924 + sizeof(fast_pool->pool))) { 925 + fast_pool->count = 0; 926 + fast_pool->last = now; 927 + } 928 + return; 929 + } 930 + 931 if ((fast_pool->count < 64) && 932 !time_after(now, fast_pool->last + HZ)) 933 return; 934 935 + r = &input_pool; 936 if (!spin_trylock(&r->lock)) 937 return; 938 ··· 965 * Entropy extraction routines 966 * 967 *********************************************************************/ 968 969 /* 970 * This utility inline function is responsible for transferring entropy ··· 1143 memzero_explicit(&hash, sizeof(hash)); 1144 } 1145 1146 + static ssize_t _extract_entropy(struct entropy_store *r, void *buf, 1147 + size_t nbytes, int fips) 1148 + { 1149 + ssize_t ret = 0, i; 1150 + __u8 tmp[EXTRACT_SIZE]; 1151 + unsigned long flags; 1152 + 1153 + while (nbytes) { 1154 + extract_buf(r, tmp); 1155 + 1156 + if (fips) { 1157 + spin_lock_irqsave(&r->lock, flags); 1158 + if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) 1159 + panic("Hardware RNG duplicated output!\n"); 1160 + memcpy(r->last_data, tmp, EXTRACT_SIZE); 1161 + spin_unlock_irqrestore(&r->lock, flags); 1162 + } 1163 + i = min_t(int, nbytes, EXTRACT_SIZE); 1164 + memcpy(buf, tmp, i); 1165 + nbytes -= i; 1166 + buf += i; 1167 + ret += i; 1168 + } 1169 + 1170 + /* Wipe data just returned from memory */ 1171 + memzero_explicit(tmp, sizeof(tmp)); 1172 + 1173 + return ret; 1174 + } 1175 + 1176 /* 1177 * This function extracts randomness from the "entropy pool", and 1178 * returns it in a buffer. ··· 1155 static ssize_t extract_entropy(struct entropy_store *r, void *buf, 1156 size_t nbytes, int min, int reserved) 1157 { 1158 __u8 tmp[EXTRACT_SIZE]; 1159 unsigned long flags; 1160 ··· 1179 xfer_secondary_pool(r, nbytes); 1180 nbytes = account(r, nbytes, min, reserved); 1181 1182 + return _extract_entropy(r, buf, nbytes, fips_enabled); 1183 } 1184 1185 /* ··· 1254 */ 1255 void get_random_bytes(void *buf, int nbytes) 1256 { 1257 + __u8 tmp[CHACHA20_BLOCK_SIZE]; 1258 + 1259 #if DEBUG_RANDOM_BOOT > 0 1260 + if (!crng_ready()) 1261 printk(KERN_NOTICE "random: %pF get_random_bytes called " 1262 + "with crng_init = %d\n", (void *) _RET_IP_, crng_init); 1263 #endif 1264 trace_get_random_bytes(nbytes, _RET_IP_); 1265 + 1266 + while (nbytes >= CHACHA20_BLOCK_SIZE) { 1267 + extract_crng(buf); 1268 + buf += CHACHA20_BLOCK_SIZE; 1269 + nbytes -= CHACHA20_BLOCK_SIZE; 1270 + } 1271 + 1272 + if (nbytes > 0) { 1273 + extract_crng(tmp); 1274 + memcpy(buf, tmp, nbytes); 1275 + memzero_explicit(tmp, nbytes); 1276 + } 1277 } 1278 EXPORT_SYMBOL(get_random_bytes); 1279 ··· 1280 unsigned long flags; 1281 int err = -EALREADY; 1282 1283 + if (crng_ready()) 1284 return err; 1285 1286 owner = rdy->owner; ··· 1288 return -ENOENT; 1289 1290 spin_lock_irqsave(&random_ready_list_lock, flags); 1291 + if (crng_ready()) 1292 goto out; 1293 1294 owner = NULL; ··· 1352 } 1353 1354 if (nbytes) 1355 + get_random_bytes(p, nbytes); 1356 } 1357 EXPORT_SYMBOL(get_random_bytes_arch); 1358 ··· 1397 { 1398 init_std_data(&input_pool); 1399 init_std_data(&blocking_pool); 1400 + crng_initialize(&primary_crng); 1401 return 0; 1402 } 1403 early_initcall(rand_initialize); ··· 1459 static ssize_t 1460 urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) 1461 { 1462 + unsigned long flags; 1463 static int maxwarn = 10; 1464 int ret; 1465 1466 + if (!crng_ready() && maxwarn > 0) { 1467 maxwarn--; 1468 printk(KERN_NOTICE "random: %s: uninitialized urandom read " 1469 + "(%zd bytes read)\n", 1470 + current->comm, nbytes); 1471 + spin_lock_irqsave(&primary_crng.lock, flags); 1472 + crng_init_cnt = 0; 1473 + spin_unlock_irqrestore(&primary_crng.lock, flags); 1474 } 1475 nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3)); 1476 + ret = extract_crng_user(buf, nbytes); 1477 + trace_urandom_read(8 * nbytes, 0, ENTROPY_BITS(&input_pool)); 1478 return ret; 1479 } 1480 ··· 1520 { 1521 size_t ret; 1522 1523 + ret = write_pool(&input_pool, buffer, count); 1524 if (ret) 1525 return ret; 1526 ··· 1574 if (!capable(CAP_SYS_ADMIN)) 1575 return -EPERM; 1576 input_pool.entropy_count = 0; 1577 blocking_pool.entropy_count = 0; 1578 return 0; 1579 default: ··· 1616 if (flags & GRND_RANDOM) 1617 return _random_read(flags & GRND_NONBLOCK, buf, count); 1618 1619 + if (!crng_ready()) { 1620 if (flags & GRND_NONBLOCK) 1621 return -EAGAIN; 1622 + crng_wait_ready(); 1623 if (signal_pending(current)) 1624 return -ERESTARTSYS; 1625 } ··· 1856 { 1857 struct entropy_store *poolp = &input_pool; 1858 1859 + if (!crng_ready()) { 1860 + crng_fast_load(buffer, count); 1861 + return; 1862 } 1863 + 1864 + /* Suspend writing if we're above the trickle threshold. 1865 + * We'll be woken up again once below random_write_wakeup_thresh, 1866 + * or when the calling thread is about to terminate. 1867 + */ 1868 + wait_event_interruptible(random_write_wait, kthread_should_stop() || 1869 + ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits); 1870 mix_pool_bytes(poolp, buffer, count); 1871 credit_entropy_bits(poolp, entropy); 1872 }
+1
include/crypto/chacha20.h
··· 16 u32 key[8]; 17 }; 18 19 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 unsigned int keysize);
··· 16 u32 key[8]; 17 }; 18 19 + void chacha20_block(u32 *state, void *stream); 20 void crypto_chacha20_init(u32 *state, struct chacha20_ctx *ctx, u8 *iv); 21 int crypto_chacha20_setkey(struct crypto_tfm *tfm, const u8 *key, 22 unsigned int keysize);
+1 -1
lib/Makefile
··· 22 lib-y := ctype.o string.o vsprintf.o cmdline.o \ 23 rbtree.o radix-tree.o dump_stack.o timerqueue.o\ 24 idr.o int_sqrt.o extable.o \ 25 - sha1.o md5.o irq_regs.o argv_split.o \ 26 flex_proportions.o ratelimit.o show_mem.o \ 27 is_single_threaded.o plist.o decompress.o kobject_uevent.o \ 28 earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o
··· 22 lib-y := ctype.o string.o vsprintf.o cmdline.o \ 23 rbtree.o radix-tree.o dump_stack.o timerqueue.o\ 24 idr.o int_sqrt.o extable.o \ 25 + sha1.o chacha20.o md5.o irq_regs.o argv_split.o \ 26 flex_proportions.o ratelimit.o show_mem.o \ 27 is_single_threaded.o plist.o decompress.o kobject_uevent.o \ 28 earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o
+79
lib/chacha20.c
···
··· 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);