aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 03:40:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 03:40:34 -0500
commit42a2d923cc349583ebf6fdd52a7d35e1c2f7e6bd (patch)
tree2b2b0c03b5389c1301800119333967efafd994ca /lib
parent5cbb3d216e2041700231bcfc383ee5f8b7fc8b74 (diff)
parent75ecab1df14d90e86cebef9ec5c76befde46e65f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) The addition of nftables. No longer will we need protocol aware firewall filtering modules, it can all live in userspace. At the core of nftables is a, for lack of a better term, virtual machine that executes byte codes to inspect packet or metadata (arriving interface index, etc.) and make verdict decisions. Besides support for loading packet contents and comparing them, the interpreter supports lookups in various datastructures as fundamental operations. For example sets are supports, and therefore one could create a set of whitelist IP address entries which have ACCEPT verdicts attached to them, and use the appropriate byte codes to do such lookups. Since the interpreted code is composed in userspace, userspace can do things like optimize things before giving it to the kernel. Another major improvement is the capability of atomically updating portions of the ruleset. In the existing netfilter implementation, one has to update the entire rule set in order to make a change and this is very expensive. Userspace tools exist to create nftables rules using existing netfilter rule sets, but both kernel implementations will need to co-exist for quite some time as we transition from the old to the new stuff. Kudos to Patrick McHardy, Pablo Neira Ayuso, and others who have worked so hard on this. 2) Daniel Borkmann and Hannes Frederic Sowa made several improvements to our pseudo-random number generator, mostly used for things like UDP port randomization and netfitler, amongst other things. In particular the taus88 generater is updated to taus113, and test cases are added. 3) Support 64-bit rates in HTB and TBF schedulers, from Eric Dumazet and Yang Yingliang. 4) Add support for new 577xx tigon3 chips to tg3 driver, from Nithin Sujir. 5) Fix two fatal flaws in TCP dynamic right sizing, from Eric Dumazet, Neal Cardwell, and Yuchung Cheng. 6) Allow IP_TOS and IP_TTL to be specified in sendmsg() ancillary control message data, much like other socket option attributes. From Francesco Fusco. 7) Allow applications to specify a cap on the rate computed automatically by the kernel for pacing flows, via a new SO_MAX_PACING_RATE socket option. From Eric Dumazet. 8) Make the initial autotuned send buffer sizing in TCP more closely reflect actual needs, from Eric Dumazet. 9) Currently early socket demux only happens for TCP sockets, but we can do it for connected UDP sockets too. Implementation from Shawn Bohrer. 10) Refactor inet socket demux with the goal of improving hash demux performance for listening sockets. With the main goals being able to use RCU lookups on even request sockets, and eliminating the listening lock contention. From Eric Dumazet. 11) The bonding layer has many demuxes in it's fast path, and an RCU conversion was started back in 3.11, several changes here extend the RCU usage to even more locations. From Ding Tianhong and Wang Yufen, based upon suggestions by Nikolay Aleksandrov and Veaceslav Falico. 12) Allow stackability of segmentation offloads to, in particular, allow segmentation offloading over tunnels. From Eric Dumazet. 13) Significantly improve the handling of secret keys we input into the various hash functions in the inet hashtables, TCP fast open, as well as syncookies. From Hannes Frederic Sowa. The key fundamental operation is "net_get_random_once()" which uses static keys. Hannes even extended this to ipv4/ipv6 fragmentation handling and our generic flow dissector. 14) The generic driver layer takes care now to set the driver data to NULL on device removal, so it's no longer necessary for drivers to explicitly set it to NULL any more. Many drivers have been cleaned up in this way, from Jingoo Han. 15) Add a BPF based packet scheduler classifier, from Daniel Borkmann. 16) Improve CRC32 interfaces and generic SKB checksum iterators so that SCTP's checksumming can more cleanly be handled. Also from Daniel Borkmann. 17) Add a new PMTU discovery mode, IP_PMTUDISC_INTERFACE, which forces using the interface MTU value. This helps avoid PMTU attacks, particularly on DNS servers. From Hannes Frederic Sowa. 18) Use generic XPS for transmit queue steering rather than internal (re-)implementation in virtio-net. From Jason Wang. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1622 commits) random32: add test cases for taus113 implementation random32: upgrade taus88 generator to taus113 from errata paper random32: move rnd_state to linux/random.h random32: add prandom_reseed_late() and call when nonblocking pool becomes initialized random32: add periodic reseeding random32: fix off-by-one in seeding requirement PHY: Add RTL8201CP phy_driver to realtek xtsonic: add missing platform_set_drvdata() in xtsonic_probe() macmace: add missing platform_set_drvdata() in mace_probe() ethernet/arc/arc_emac: add missing platform_set_drvdata() in arc_emac_probe() ipv6: protect for_each_sk_fl_rcu in mem_check with rcu_read_lock_bh vlan: Implement vlan_dev_get_egress_qos_mask as an inline. ixgbe: add warning when max_vfs is out of range. igb: Update link modes display in ethtool netfilter: push reasm skb through instead of original frag skbs ip6_output: fragment outgoing reassembled skb properly MAINTAINERS: mv643xx_eth: take over maintainership from Lennart net_sched: tbf: support of 64bit rates ixgbe: deleting dfwd stations out of order can cause null ptr deref ixgbe: fix build err, num_rx_queues is only available with CONFIG_RPS ...
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig7
-rw-r--r--lib/crc32.c456
-rw-r--r--lib/random32.c307
3 files changed, 536 insertions, 234 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index b3c8be0da17f..75485e163ca3 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -189,6 +189,13 @@ config AUDIT_GENERIC
189 depends on AUDIT && !AUDIT_ARCH 189 depends on AUDIT && !AUDIT_ARCH
190 default y 190 default y
191 191
192config RANDOM32_SELFTEST
193 bool "PRNG perform self test on init"
194 default n
195 help
196 This option enables the 32 bit PRNG library functions to perform a
197 self test on initialization.
198
192# 199#
193# compression support is select'ed if needed 200# compression support is select'ed if needed
194# 201#
diff --git a/lib/crc32.c b/lib/crc32.c
index 410093dbe51c..70f00ca5ef1e 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -29,6 +29,7 @@
29#include <linux/crc32.h> 29#include <linux/crc32.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/sched.h>
32#include "crc32defs.h" 33#include "crc32defs.h"
33 34
34#if CRC_LE_BITS > 8 35#if CRC_LE_BITS > 8
@@ -49,6 +50,30 @@ MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>");
49MODULE_DESCRIPTION("Various CRC32 calculations"); 50MODULE_DESCRIPTION("Various CRC32 calculations");
50MODULE_LICENSE("GPL"); 51MODULE_LICENSE("GPL");
51 52
53#define GF2_DIM 32
54
55static u32 gf2_matrix_times(u32 *mat, u32 vec)
56{
57 u32 sum = 0;
58
59 while (vec) {
60 if (vec & 1)
61 sum ^= *mat;
62 vec >>= 1;
63 mat++;
64 }
65
66 return sum;
67}
68
69static void gf2_matrix_square(u32 *square, u32 *mat)
70{
71 int i;
72
73 for (i = 0; i < GF2_DIM; i++)
74 square[i] = gf2_matrix_times(mat, mat[i]);
75}
76
52#if CRC_LE_BITS > 8 || CRC_BE_BITS > 8 77#if CRC_LE_BITS > 8 || CRC_BE_BITS > 8
53 78
54/* implements slicing-by-4 or slicing-by-8 algorithm */ 79/* implements slicing-by-4 or slicing-by-8 algorithm */
@@ -130,6 +155,52 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
130} 155}
131#endif 156#endif
132 157
158/* For conditions of distribution and use, see copyright notice in zlib.h */
159static u32 crc32_generic_combine(u32 crc1, u32 crc2, size_t len2,
160 u32 polynomial)
161{
162 u32 even[GF2_DIM]; /* Even-power-of-two zeros operator */
163 u32 odd[GF2_DIM]; /* Odd-power-of-two zeros operator */
164 u32 row;
165 int i;
166
167 if (len2 <= 0)
168 return crc1;
169
170 /* Put operator for one zero bit in odd */
171 odd[0] = polynomial;
172 row = 1;
173 for (i = 1; i < GF2_DIM; i++) {
174 odd[i] = row;
175 row <<= 1;
176 }
177
178 gf2_matrix_square(even, odd); /* Put operator for two zero bits in even */
179 gf2_matrix_square(odd, even); /* Put operator for four zero bits in odd */
180
181 /* Apply len2 zeros to crc1 (first square will put the operator for one
182 * zero byte, eight zero bits, in even).
183 */
184 do {
185 /* Apply zeros operator for this bit of len2 */
186 gf2_matrix_square(even, odd);
187 if (len2 & 1)
188 crc1 = gf2_matrix_times(even, crc1);
189 len2 >>= 1;
190 /* If no more bits set, then done */
191 if (len2 == 0)
192 break;
193 /* Another iteration of the loop with odd and even swapped */
194 gf2_matrix_square(odd, even);
195 if (len2 & 1)
196 crc1 = gf2_matrix_times(odd, crc1);
197 len2 >>= 1;
198 } while (len2 != 0);
199
200 crc1 ^= crc2;
201 return crc1;
202}
203
133/** 204/**
134 * crc32_le_generic() - Calculate bitwise little-endian Ethernet AUTODIN II 205 * crc32_le_generic() - Calculate bitwise little-endian Ethernet AUTODIN II
135 * CRC32/CRC32C 206 * CRC32/CRC32C
@@ -200,8 +271,19 @@ u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
200 (const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE); 271 (const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE);
201} 272}
202#endif 273#endif
274u32 __pure crc32_le_combine(u32 crc1, u32 crc2, size_t len2)
275{
276 return crc32_generic_combine(crc1, crc2, len2, CRCPOLY_LE);
277}
278
279u32 __pure __crc32c_le_combine(u32 crc1, u32 crc2, size_t len2)
280{
281 return crc32_generic_combine(crc1, crc2, len2, CRC32C_POLY_LE);
282}
203EXPORT_SYMBOL(crc32_le); 283EXPORT_SYMBOL(crc32_le);
284EXPORT_SYMBOL(crc32_le_combine);
204EXPORT_SYMBOL(__crc32c_le); 285EXPORT_SYMBOL(__crc32c_le);
286EXPORT_SYMBOL(__crc32c_le_combine);
205 287
206/** 288/**
207 * crc32_be_generic() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32 289 * crc32_be_generic() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
@@ -795,206 +877,106 @@ static struct crc_test {
795 u32 crc32c_le; /* expected crc32c_le result */ 877 u32 crc32c_le; /* expected crc32c_le result */
796} test[] = 878} test[] =
797{ 879{
798 {0x674bf11d, 0x00000038, 0x00000542, 0x0af6d466, 0xd8b6e4c1, 880 {0x674bf11d, 0x00000038, 0x00000542, 0x0af6d466, 0xd8b6e4c1, 0xf6e93d6c},
799 0xf6e93d6c}, 881 {0x35c672c6, 0x0000003a, 0x000001aa, 0xc6d3dfba, 0x28aaf3ad, 0x0fe92aca},
800 {0x35c672c6, 0x0000003a, 0x000001aa, 0xc6d3dfba, 0x28aaf3ad, 882 {0x496da28e, 0x00000039, 0x000005af, 0xd933660f, 0x5d57e81f, 0x52e1ebb8},
801 0x0fe92aca}, 883 {0x09a9b90e, 0x00000027, 0x000001f8, 0xb45fe007, 0xf45fca9a, 0x0798af9a},
802 {0x496da28e, 0x00000039, 0x000005af, 0xd933660f, 0x5d57e81f, 884 {0xdc97e5a9, 0x00000025, 0x000003b6, 0xf81a3562, 0xe0126ba2, 0x18eb3152},
803 0x52e1ebb8}, 885 {0x47c58900, 0x0000000a, 0x000000b9, 0x8e58eccf, 0xf3afc793, 0xd00d08c7},
804 {0x09a9b90e, 0x00000027, 0x000001f8, 0xb45fe007, 0xf45fca9a, 886 {0x292561e8, 0x0000000c, 0x00000403, 0xa2ba8aaf, 0x0b797aed, 0x8ba966bc},
805 0x0798af9a}, 887 {0x415037f6, 0x00000003, 0x00000676, 0xa17d52e8, 0x7f0fdf35, 0x11d694a2},
806 {0xdc97e5a9, 0x00000025, 0x000003b6, 0xf81a3562, 0xe0126ba2, 888 {0x3466e707, 0x00000026, 0x00000042, 0x258319be, 0x75c484a2, 0x6ab3208d},
807 0x18eb3152}, 889 {0xafd1281b, 0x00000023, 0x000002ee, 0x4428eaf8, 0x06c7ad10, 0xba4603c5},
808 {0x47c58900, 0x0000000a, 0x000000b9, 0x8e58eccf, 0xf3afc793, 890 {0xd3857b18, 0x00000028, 0x000004a2, 0x5c430821, 0xb062b7cb, 0xe6071c6f},
809 0xd00d08c7}, 891 {0x1d825a8f, 0x0000002b, 0x0000050b, 0xd2c45f0c, 0xd68634e0, 0x179ec30a},
810 {0x292561e8, 0x0000000c, 0x00000403, 0xa2ba8aaf, 0x0b797aed, 892 {0x5033e3bc, 0x0000000b, 0x00000078, 0xa3ea4113, 0xac6d31fb, 0x0903beb8},
811 0x8ba966bc}, 893 {0x94f1fb5e, 0x0000000f, 0x000003a2, 0xfbfc50b1, 0x3cfe50ed, 0x6a7cb4fa},
812 {0x415037f6, 0x00000003, 0x00000676, 0xa17d52e8, 0x7f0fdf35, 894 {0xc9a0fe14, 0x00000009, 0x00000473, 0x5fb61894, 0x87070591, 0xdb535801},
813 0x11d694a2}, 895 {0x88a034b1, 0x0000001c, 0x000005ad, 0xc1b16053, 0x46f95c67, 0x92bed597},
814 {0x3466e707, 0x00000026, 0x00000042, 0x258319be, 0x75c484a2, 896 {0xf0f72239, 0x00000020, 0x0000026d, 0xa6fa58f3, 0xf8c2c1dd, 0x192a3f1b},
815 0x6ab3208d}, 897 {0xcc20a5e3, 0x0000003b, 0x0000067a, 0x7740185a, 0x308b979a, 0xccbaec1a},
816 {0xafd1281b, 0x00000023, 0x000002ee, 0x4428eaf8, 0x06c7ad10, 898 {0xce589c95, 0x0000002b, 0x00000641, 0xd055e987, 0x40aae25b, 0x7eabae4d},
817 0xba4603c5}, 899 {0x78edc885, 0x00000035, 0x000005be, 0xa39cb14b, 0x035b0d1f, 0x28c72982},
818 {0xd3857b18, 0x00000028, 0x000004a2, 0x5c430821, 0xb062b7cb, 900 {0x9d40a377, 0x0000003b, 0x00000038, 0x1f47ccd2, 0x197fbc9d, 0xc3cd4d18},
819 0xe6071c6f}, 901 {0x703d0e01, 0x0000003c, 0x000006f1, 0x88735e7c, 0xfed57c5a, 0xbca8f0e7},
820 {0x1d825a8f, 0x0000002b, 0x0000050b, 0xd2c45f0c, 0xd68634e0, 902 {0x776bf505, 0x0000000f, 0x000005b2, 0x5cc4fc01, 0xf32efb97, 0x713f60b3},
821 0x179ec30a}, 903 {0x4a3e7854, 0x00000027, 0x000004b8, 0x8d923c82, 0x0cbfb4a2, 0xebd08fd5},
822 {0x5033e3bc, 0x0000000b, 0x00000078, 0xa3ea4113, 0xac6d31fb, 904 {0x209172dd, 0x0000003b, 0x00000356, 0xb89e9c2b, 0xd7868138, 0x64406c59},
823 0x0903beb8}, 905 {0x3ba4cc5b, 0x0000002f, 0x00000203, 0xe51601a9, 0x5b2a1032, 0x7421890e},
824 {0x94f1fb5e, 0x0000000f, 0x000003a2, 0xfbfc50b1, 0x3cfe50ed, 906 {0xfc62f297, 0x00000000, 0x00000079, 0x71a8e1a2, 0x5d88685f, 0xe9347603},
825 0x6a7cb4fa}, 907 {0x64280b8b, 0x00000016, 0x000007ab, 0x0fa7a30c, 0xda3a455f, 0x1bef9060},
826 {0xc9a0fe14, 0x00000009, 0x00000473, 0x5fb61894, 0x87070591, 908 {0x97dd724b, 0x00000033, 0x000007ad, 0x5788b2f4, 0xd7326d32, 0x34720072},
827 0xdb535801}, 909 {0x61394b52, 0x00000035, 0x00000571, 0xc66525f1, 0xcabe7fef, 0x48310f59},
828 {0x88a034b1, 0x0000001c, 0x000005ad, 0xc1b16053, 0x46f95c67, 910 {0x29b4faff, 0x00000024, 0x0000006e, 0xca13751e, 0x993648e0, 0x783a4213},
829 0x92bed597}, 911 {0x29bfb1dc, 0x0000000b, 0x00000244, 0x436c43f7, 0x429f7a59, 0x9e8efd41},
830 {0xf0f72239, 0x00000020, 0x0000026d, 0xa6fa58f3, 0xf8c2c1dd, 912 {0x86ae934b, 0x00000035, 0x00000104, 0x0760ec93, 0x9cf7d0f4, 0xfc3d34a5},
831 0x192a3f1b}, 913 {0xc4c1024e, 0x0000002e, 0x000006b1, 0x6516a3ec, 0x19321f9c, 0x17a52ae2},
832 {0xcc20a5e3, 0x0000003b, 0x0000067a, 0x7740185a, 0x308b979a, 914 {0x3287a80a, 0x00000026, 0x00000496, 0x0b257eb1, 0x754ebd51, 0x886d935a},
833 0xccbaec1a}, 915 {0xa4db423e, 0x00000023, 0x0000045d, 0x9b3a66dc, 0x873e9f11, 0xeaaeaeb2},
834 {0xce589c95, 0x0000002b, 0x00000641, 0xd055e987, 0x40aae25b, 916 {0x7a1078df, 0x00000015, 0x0000014a, 0x8c2484c5, 0x6a628659, 0x8e900a4b},
835 0x7eabae4d}, 917 {0x6048bd5b, 0x00000006, 0x0000006a, 0x897e3559, 0xac9961af, 0xd74662b1},
836 {0x78edc885, 0x00000035, 0x000005be, 0xa39cb14b, 0x035b0d1f, 918 {0xd8f9ea20, 0x0000003d, 0x00000277, 0x60eb905b, 0xed2aaf99, 0xd26752ba},
837 0x28c72982}, 919 {0xea5ec3b4, 0x0000002a, 0x000004fe, 0x869965dc, 0x6c1f833b, 0x8b1fcd62},
838 {0x9d40a377, 0x0000003b, 0x00000038, 0x1f47ccd2, 0x197fbc9d, 920 {0x2dfb005d, 0x00000016, 0x00000345, 0x6a3b117e, 0xf05e8521, 0xf54342fe},
839 0xc3cd4d18}, 921 {0x5a214ade, 0x00000020, 0x000005b6, 0x467f70be, 0xcb22ccd3, 0x5b95b988},
840 {0x703d0e01, 0x0000003c, 0x000006f1, 0x88735e7c, 0xfed57c5a, 922 {0xf0ab9cca, 0x00000032, 0x00000515, 0xed223df3, 0x7f3ef01d, 0x2e1176be},
841 0xbca8f0e7}, 923 {0x91b444f9, 0x0000002e, 0x000007f8, 0x84e9a983, 0x5676756f, 0x66120546},
842 {0x776bf505, 0x0000000f, 0x000005b2, 0x5cc4fc01, 0xf32efb97, 924 {0x1b5d2ddb, 0x0000002e, 0x0000012c, 0xba638c4c, 0x3f42047b, 0xf256a5cc},
843 0x713f60b3}, 925 {0xd824d1bb, 0x0000003a, 0x000007b5, 0x6288653b, 0x3a3ebea0, 0x4af1dd69},
844 {0x4a3e7854, 0x00000027, 0x000004b8, 0x8d923c82, 0x0cbfb4a2, 926 {0x0470180c, 0x00000034, 0x000001f0, 0x9d5b80d6, 0x3de08195, 0x56f0a04a},
845 0xebd08fd5}, 927 {0xffaa3a3f, 0x00000036, 0x00000299, 0xf3a82ab8, 0x53e0c13d, 0x74f6b6b2},
846 {0x209172dd, 0x0000003b, 0x00000356, 0xb89e9c2b, 0xd7868138, 928 {0x6406cfeb, 0x00000023, 0x00000600, 0xa920b8e8, 0xe4e2acf4, 0x085951fd},
847 0x64406c59}, 929 {0xb24aaa38, 0x0000003e, 0x000004a1, 0x657cc328, 0x5077b2c3, 0xc65387eb},
848 {0x3ba4cc5b, 0x0000002f, 0x00000203, 0xe51601a9, 0x5b2a1032, 930 {0x58b2ab7c, 0x00000039, 0x000002b4, 0x3a17ee7e, 0x9dcb3643, 0x1ca9257b},
849 0x7421890e}, 931 {0x3db85970, 0x00000006, 0x000002b6, 0x95268b59, 0xb9812c10, 0xfd196d76},
850 {0xfc62f297, 0x00000000, 0x00000079, 0x71a8e1a2, 0x5d88685f, 932 {0x857830c5, 0x00000003, 0x00000590, 0x4ef439d5, 0xf042161d, 0x5ef88339},
851 0xe9347603}, 933 {0xe1fcd978, 0x0000003e, 0x000007d8, 0xae8d8699, 0xce0a1ef5, 0x2c3714d9},
852 {0x64280b8b, 0x00000016, 0x000007ab, 0x0fa7a30c, 0xda3a455f, 934 {0xb982a768, 0x00000016, 0x000006e0, 0x62fad3df, 0x5f8a067b, 0x58576548},
853 0x1bef9060}, 935 {0x1d581ce8, 0x0000001e, 0x0000058b, 0xf0f5da53, 0x26e39eee, 0xfd7c57de},
854 {0x97dd724b, 0x00000033, 0x000007ad, 0x5788b2f4, 0xd7326d32, 936 {0x2456719b, 0x00000025, 0x00000503, 0x4296ac64, 0xd50e4c14, 0xd5fedd59},
855 0x34720072}, 937 {0xfae6d8f2, 0x00000000, 0x0000055d, 0x057fdf2e, 0x2a31391a, 0x1cc3b17b},
856 {0x61394b52, 0x00000035, 0x00000571, 0xc66525f1, 0xcabe7fef, 938 {0xcba828e3, 0x00000039, 0x000002ce, 0xe3f22351, 0x8f00877b, 0x270eed73},
857 0x48310f59}, 939 {0x13d25952, 0x0000000a, 0x0000072d, 0x76d4b4cc, 0x5eb67ec3, 0x91ecbb11},
858 {0x29b4faff, 0x00000024, 0x0000006e, 0xca13751e, 0x993648e0, 940 {0x0342be3f, 0x00000015, 0x00000599, 0xec75d9f1, 0x9d4d2826, 0x05ed8d0c},
859 0x783a4213}, 941 {0xeaa344e0, 0x00000014, 0x000004d8, 0x72a4c981, 0x2064ea06, 0x0b09ad5b},
860 {0x29bfb1dc, 0x0000000b, 0x00000244, 0x436c43f7, 0x429f7a59, 942 {0xbbb52021, 0x0000003b, 0x00000272, 0x04af99fc, 0xaf042d35, 0xf8d511fb},
861 0x9e8efd41}, 943 {0xb66384dc, 0x0000001d, 0x000007fc, 0xd7629116, 0x782bd801, 0x5ad832cc},
862 {0x86ae934b, 0x00000035, 0x00000104, 0x0760ec93, 0x9cf7d0f4, 944 {0x616c01b6, 0x00000022, 0x000002c8, 0x5b1dab30, 0x783ce7d2, 0x1214d196},
863 0xfc3d34a5}, 945 {0xce2bdaad, 0x00000016, 0x0000062a, 0x932535c8, 0x3f02926d, 0x5747218a},
864 {0xc4c1024e, 0x0000002e, 0x000006b1, 0x6516a3ec, 0x19321f9c, 946 {0x00fe84d7, 0x00000005, 0x00000205, 0x850e50aa, 0x753d649c, 0xde8f14de},
865 0x17a52ae2}, 947 {0xbebdcb4c, 0x00000006, 0x0000055d, 0xbeaa37a2, 0x2d8c9eba, 0x3563b7b9},
866 {0x3287a80a, 0x00000026, 0x00000496, 0x0b257eb1, 0x754ebd51, 948 {0xd8b1a02a, 0x00000010, 0x00000387, 0x5017d2fc, 0x503541a5, 0x071475d0},
867 0x886d935a}, 949 {0x3b96cad2, 0x00000036, 0x00000347, 0x1d2372ae, 0x926cd90b, 0x54c79d60},
868 {0xa4db423e, 0x00000023, 0x0000045d, 0x9b3a66dc, 0x873e9f11, 950 {0xc94c1ed7, 0x00000005, 0x0000038b, 0x9e9fdb22, 0x144a9178, 0x4c53eee6},
869 0xeaaeaeb2}, 951 {0x1aad454e, 0x00000025, 0x000002b2, 0xc3f6315c, 0x5c7a35b3, 0x10137a3c},
870 {0x7a1078df, 0x00000015, 0x0000014a, 0x8c2484c5, 0x6a628659, 952 {0xa4fec9a6, 0x00000000, 0x000006d6, 0x90be5080, 0xa4107605, 0xaa9d6c73},
871 0x8e900a4b}, 953 {0x1bbe71e2, 0x0000001f, 0x000002fd, 0x4e504c3b, 0x284ccaf1, 0xb63d23e7},
872 {0x6048bd5b, 0x00000006, 0x0000006a, 0x897e3559, 0xac9961af, 954 {0x4201c7e4, 0x00000002, 0x000002b7, 0x7822e3f9, 0x0cc912a9, 0x7f53e9cf},
873 0xd74662b1}, 955 {0x23fddc96, 0x00000003, 0x00000627, 0x8a385125, 0x07767e78, 0x13c1cd83},
874 {0xd8f9ea20, 0x0000003d, 0x00000277, 0x60eb905b, 0xed2aaf99, 956 {0xd82ba25c, 0x00000016, 0x0000063e, 0x98e4148a, 0x283330c9, 0x49ff5867},
875 0xd26752ba}, 957 {0x786f2032, 0x0000002d, 0x0000060f, 0xf201600a, 0xf561bfcd, 0x8467f211},
876 {0xea5ec3b4, 0x0000002a, 0x000004fe, 0x869965dc, 0x6c1f833b, 958 {0xfebe4e1f, 0x0000002a, 0x000004f2, 0x95e51961, 0xfd80dcab, 0x3f9683b2},
877 0x8b1fcd62}, 959 {0x1a6e0a39, 0x00000008, 0x00000672, 0x8af6c2a5, 0x78dd84cb, 0x76a3f874},
878 {0x2dfb005d, 0x00000016, 0x00000345, 0x6a3b117e, 0xf05e8521, 960 {0x56000ab8, 0x0000000e, 0x000000e5, 0x36bacb8f, 0x22ee1f77, 0x863b702f},
879 0xf54342fe}, 961 {0x4717fe0c, 0x00000000, 0x000006ec, 0x8439f342, 0x5c8e03da, 0xdc6c58ff},
880 {0x5a214ade, 0x00000020, 0x000005b6, 0x467f70be, 0xcb22ccd3, 962 {0xd5d5d68e, 0x0000003c, 0x000003a3, 0x46fff083, 0x177d1b39, 0x0622cc95},
881 0x5b95b988}, 963 {0xc25dd6c6, 0x00000024, 0x000006c0, 0x5ceb8eb4, 0x892b0d16, 0xe85605cd},
882 {0xf0ab9cca, 0x00000032, 0x00000515, 0xed223df3, 0x7f3ef01d, 964 {0xe9b11300, 0x00000023, 0x00000683, 0x07a5d59a, 0x6c6a3208, 0x31da5f06},
883 0x2e1176be}, 965 {0x95cd285e, 0x00000001, 0x00000047, 0x7b3a4368, 0x0202c07e, 0xa1f2e784},
884 {0x91b444f9, 0x0000002e, 0x000007f8, 0x84e9a983, 0x5676756f, 966 {0xd9245a25, 0x0000001e, 0x000003a6, 0xd33c1841, 0x1936c0d5, 0xb07cc616},
885 0x66120546}, 967 {0x103279db, 0x00000006, 0x0000039b, 0xca09b8a0, 0x77d62892, 0xbf943b6c},
886 {0x1b5d2ddb, 0x0000002e, 0x0000012c, 0xba638c4c, 0x3f42047b, 968 {0x1cba3172, 0x00000027, 0x000001c8, 0xcb377194, 0xebe682db, 0x2c01af1c},
887 0xf256a5cc}, 969 {0x8f613739, 0x0000000c, 0x000001df, 0xb4b0bc87, 0x7710bd43, 0x0fe5f56d},
888 {0xd824d1bb, 0x0000003a, 0x000007b5, 0x6288653b, 0x3a3ebea0, 970 {0x1c6aa90d, 0x0000001b, 0x0000053c, 0x70559245, 0xda7894ac, 0xf8943b2d},
889 0x4af1dd69}, 971 {0xaabe5b93, 0x0000003d, 0x00000715, 0xcdbf42fa, 0x0c3b99e7, 0xe4d89272},
890 {0x0470180c, 0x00000034, 0x000001f0, 0x9d5b80d6, 0x3de08195, 972 {0xf15dd038, 0x00000006, 0x000006db, 0x6e104aea, 0x8d5967f2, 0x7c2f6bbb},
891 0x56f0a04a}, 973 {0x584dd49c, 0x00000020, 0x000007bc, 0x36b6cfd6, 0xad4e23b2, 0xabbf388b},
892 {0xffaa3a3f, 0x00000036, 0x00000299, 0xf3a82ab8, 0x53e0c13d, 974 {0x5d8c9506, 0x00000020, 0x00000470, 0x4c62378e, 0x31d92640, 0x1dca1f4e},
893 0x74f6b6b2}, 975 {0xb80d17b0, 0x00000032, 0x00000346, 0x22a5bb88, 0x9a7ec89f, 0x5c170e23},
894 {0x6406cfeb, 0x00000023, 0x00000600, 0xa920b8e8, 0xe4e2acf4, 976 {0xdaf0592e, 0x00000023, 0x000007b0, 0x3cab3f99, 0x9b1fdd99, 0xc0e9d672},
895 0x085951fd}, 977 {0x4793cc85, 0x0000000d, 0x00000706, 0xe82e04f6, 0xed3db6b7, 0xc18bdc86},
896 {0xb24aaa38, 0x0000003e, 0x000004a1, 0x657cc328, 0x5077b2c3, 978 {0x82ebf64e, 0x00000009, 0x000007c3, 0x69d590a9, 0x9efa8499, 0xa874fcdd},
897 0xc65387eb}, 979 {0xb18a0319, 0x00000026, 0x000007db, 0x1cf98dcc, 0x8fa9ad6a, 0x9dc0bb48},
898 {0x58b2ab7c, 0x00000039, 0x000002b4, 0x3a17ee7e, 0x9dcb3643,
899 0x1ca9257b},
900 {0x3db85970, 0x00000006, 0x000002b6, 0x95268b59, 0xb9812c10,
901 0xfd196d76},
902 {0x857830c5, 0x00000003, 0x00000590, 0x4ef439d5, 0xf042161d,
903 0x5ef88339},
904 {0xe1fcd978, 0x0000003e, 0x000007d8, 0xae8d8699, 0xce0a1ef5,
905 0x2c3714d9},
906 {0xb982a768, 0x00000016, 0x000006e0, 0x62fad3df, 0x5f8a067b,
907 0x58576548},
908 {0x1d581ce8, 0x0000001e, 0x0000058b, 0xf0f5da53, 0x26e39eee,
909 0xfd7c57de},
910 {0x2456719b, 0x00000025, 0x00000503, 0x4296ac64, 0xd50e4c14,
911 0xd5fedd59},
912 {0xfae6d8f2, 0x00000000, 0x0000055d, 0x057fdf2e, 0x2a31391a,
913 0x1cc3b17b},
914 {0xcba828e3, 0x00000039, 0x000002ce, 0xe3f22351, 0x8f00877b,
915 0x270eed73},
916 {0x13d25952, 0x0000000a, 0x0000072d, 0x76d4b4cc, 0x5eb67ec3,
917 0x91ecbb11},
918 {0x0342be3f, 0x00000015, 0x00000599, 0xec75d9f1, 0x9d4d2826,
919 0x05ed8d0c},
920 {0xeaa344e0, 0x00000014, 0x000004d8, 0x72a4c981, 0x2064ea06,
921 0x0b09ad5b},
922 {0xbbb52021, 0x0000003b, 0x00000272, 0x04af99fc, 0xaf042d35,
923 0xf8d511fb},
924 {0xb66384dc, 0x0000001d, 0x000007fc, 0xd7629116, 0x782bd801,
925 0x5ad832cc},
926 {0x616c01b6, 0x00000022, 0x000002c8, 0x5b1dab30, 0x783ce7d2,
927 0x1214d196},
928 {0xce2bdaad, 0x00000016, 0x0000062a, 0x932535c8, 0x3f02926d,
929 0x5747218a},
930 {0x00fe84d7, 0x00000005, 0x00000205, 0x850e50aa, 0x753d649c,
931 0xde8f14de},
932 {0xbebdcb4c, 0x00000006, 0x0000055d, 0xbeaa37a2, 0x2d8c9eba,
933 0x3563b7b9},
934 {0xd8b1a02a, 0x00000010, 0x00000387, 0x5017d2fc, 0x503541a5,
935 0x071475d0},
936 {0x3b96cad2, 0x00000036, 0x00000347, 0x1d2372ae, 0x926cd90b,
937 0x54c79d60},
938 {0xc94c1ed7, 0x00000005, 0x0000038b, 0x9e9fdb22, 0x144a9178,
939 0x4c53eee6},
940 {0x1aad454e, 0x00000025, 0x000002b2, 0xc3f6315c, 0x5c7a35b3,
941 0x10137a3c},
942 {0xa4fec9a6, 0x00000000, 0x000006d6, 0x90be5080, 0xa4107605,
943 0xaa9d6c73},
944 {0x1bbe71e2, 0x0000001f, 0x000002fd, 0x4e504c3b, 0x284ccaf1,
945 0xb63d23e7},
946 {0x4201c7e4, 0x00000002, 0x000002b7, 0x7822e3f9, 0x0cc912a9,
947 0x7f53e9cf},
948 {0x23fddc96, 0x00000003, 0x00000627, 0x8a385125, 0x07767e78,
949 0x13c1cd83},
950 {0xd82ba25c, 0x00000016, 0x0000063e, 0x98e4148a, 0x283330c9,
951 0x49ff5867},
952 {0x786f2032, 0x0000002d, 0x0000060f, 0xf201600a, 0xf561bfcd,
953 0x8467f211},
954 {0xfebe4e1f, 0x0000002a, 0x000004f2, 0x95e51961, 0xfd80dcab,
955 0x3f9683b2},
956 {0x1a6e0a39, 0x00000008, 0x00000672, 0x8af6c2a5, 0x78dd84cb,
957 0x76a3f874},
958 {0x56000ab8, 0x0000000e, 0x000000e5, 0x36bacb8f, 0x22ee1f77,
959 0x863b702f},
960 {0x4717fe0c, 0x00000000, 0x000006ec, 0x8439f342, 0x5c8e03da,
961 0xdc6c58ff},
962 {0xd5d5d68e, 0x0000003c, 0x000003a3, 0x46fff083, 0x177d1b39,
963 0x0622cc95},
964 {0xc25dd6c6, 0x00000024, 0x000006c0, 0x5ceb8eb4, 0x892b0d16,
965 0xe85605cd},
966 {0xe9b11300, 0x00000023, 0x00000683, 0x07a5d59a, 0x6c6a3208,
967 0x31da5f06},
968 {0x95cd285e, 0x00000001, 0x00000047, 0x7b3a4368, 0x0202c07e,
969 0xa1f2e784},
970 {0xd9245a25, 0x0000001e, 0x000003a6, 0xd33c1841, 0x1936c0d5,
971 0xb07cc616},
972 {0x103279db, 0x00000006, 0x0000039b, 0xca09b8a0, 0x77d62892,
973 0xbf943b6c},
974 {0x1cba3172, 0x00000027, 0x000001c8, 0xcb377194, 0xebe682db,
975 0x2c01af1c},
976 {0x8f613739, 0x0000000c, 0x000001df, 0xb4b0bc87, 0x7710bd43,
977 0x0fe5f56d},
978 {0x1c6aa90d, 0x0000001b, 0x0000053c, 0x70559245, 0xda7894ac,
979 0xf8943b2d},
980 {0xaabe5b93, 0x0000003d, 0x00000715, 0xcdbf42fa, 0x0c3b99e7,
981 0xe4d89272},
982 {0xf15dd038, 0x00000006, 0x000006db, 0x6e104aea, 0x8d5967f2,
983 0x7c2f6bbb},
984 {0x584dd49c, 0x00000020, 0x000007bc, 0x36b6cfd6, 0xad4e23b2,
985 0xabbf388b},
986 {0x5d8c9506, 0x00000020, 0x00000470, 0x4c62378e, 0x31d92640,
987 0x1dca1f4e},
988 {0xb80d17b0, 0x00000032, 0x00000346, 0x22a5bb88, 0x9a7ec89f,
989 0x5c170e23},
990 {0xdaf0592e, 0x00000023, 0x000007b0, 0x3cab3f99, 0x9b1fdd99,
991 0xc0e9d672},
992 {0x4793cc85, 0x0000000d, 0x00000706, 0xe82e04f6, 0xed3db6b7,
993 0xc18bdc86},
994 {0x82ebf64e, 0x00000009, 0x000007c3, 0x69d590a9, 0x9efa8499,
995 0xa874fcdd},
996 {0xb18a0319, 0x00000026, 0x000007db, 0x1cf98dcc, 0x8fa9ad6a,
997 0x9dc0bb48},
998}; 980};
999 981
1000#include <linux/time.h> 982#include <linux/time.h>
@@ -1050,6 +1032,41 @@ static int __init crc32c_test(void)
1050 return 0; 1032 return 0;
1051} 1033}
1052 1034
1035static int __init crc32c_combine_test(void)
1036{
1037 int i, j;
1038 int errors = 0, runs = 0;
1039
1040 for (i = 0; i < 10; i++) {
1041 u32 crc_full;
1042
1043 crc_full = __crc32c_le(test[i].crc, test_buf + test[i].start,
1044 test[i].length);
1045 for (j = 0; j <= test[i].length; ++j) {
1046 u32 crc1, crc2;
1047 u32 len1 = j, len2 = test[i].length - j;
1048
1049 crc1 = __crc32c_le(test[i].crc, test_buf +
1050 test[i].start, len1);
1051 crc2 = __crc32c_le(0, test_buf + test[i].start +
1052 len1, len2);
1053
1054 if (!(crc_full == __crc32c_le_combine(crc1, crc2, len2) &&
1055 crc_full == test[i].crc32c_le))
1056 errors++;
1057 runs++;
1058 cond_resched();
1059 }
1060 }
1061
1062 if (errors)
1063 pr_warn("crc32c_combine: %d/%d self tests failed\n", errors, runs);
1064 else
1065 pr_info("crc32c_combine: %d self tests passed\n", runs);
1066
1067 return 0;
1068}
1069
1053static int __init crc32_test(void) 1070static int __init crc32_test(void)
1054{ 1071{
1055 int i; 1072 int i;
@@ -1109,10 +1126,49 @@ static int __init crc32_test(void)
1109 return 0; 1126 return 0;
1110} 1127}
1111 1128
1129static int __init crc32_combine_test(void)
1130{
1131 int i, j;
1132 int errors = 0, runs = 0;
1133
1134 for (i = 0; i < 10; i++) {
1135 u32 crc_full;
1136
1137 crc_full = crc32_le(test[i].crc, test_buf + test[i].start,
1138 test[i].length);
1139 for (j = 0; j <= test[i].length; ++j) {
1140 u32 crc1, crc2;
1141 u32 len1 = j, len2 = test[i].length - j;
1142
1143 crc1 = crc32_le(test[i].crc, test_buf +
1144 test[i].start, len1);
1145 crc2 = crc32_le(0, test_buf + test[i].start +
1146 len1, len2);
1147
1148 if (!(crc_full == crc32_le_combine(crc1, crc2, len2) &&
1149 crc_full == test[i].crc_le))
1150 errors++;
1151 runs++;
1152 cond_resched();
1153 }
1154 }
1155
1156 if (errors)
1157 pr_warn("crc32_combine: %d/%d self tests failed\n", errors, runs);
1158 else
1159 pr_info("crc32_combine: %d self tests passed\n", runs);
1160
1161 return 0;
1162}
1163
1112static int __init crc32test_init(void) 1164static int __init crc32test_init(void)
1113{ 1165{
1114 crc32_test(); 1166 crc32_test();
1115 crc32c_test(); 1167 crc32c_test();
1168
1169 crc32_combine_test();
1170 crc32c_combine_test();
1171
1116 return 0; 1172 return 0;
1117} 1173}
1118 1174
diff --git a/lib/random32.c b/lib/random32.c
index 52280d5526be..82da4f4c3489 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -2,19 +2,19 @@
2 This is a maximally equidistributed combined Tausworthe generator 2 This is a maximally equidistributed combined Tausworthe generator
3 based on code from GNU Scientific Library 1.5 (30 Jun 2004) 3 based on code from GNU Scientific Library 1.5 (30 Jun 2004)
4 4
5 x_n = (s1_n ^ s2_n ^ s3_n) 5 lfsr113 version:
6 6
7 s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19)) 7 x_n = (s1_n ^ s2_n ^ s3_n ^ s4_n)
8 s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25))
9 s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11))
10 8
11 The period of this generator is about 2^88. 9 s1_{n+1} = (((s1_n & 4294967294) << 18) ^ (((s1_n << 6) ^ s1_n) >> 13))
10 s2_{n+1} = (((s2_n & 4294967288) << 2) ^ (((s2_n << 2) ^ s2_n) >> 27))
11 s3_{n+1} = (((s3_n & 4294967280) << 7) ^ (((s3_n << 13) ^ s3_n) >> 21))
12 s4_{n+1} = (((s4_n & 4294967168) << 13) ^ (((s4_n << 3) ^ s4_n) >> 12))
12 13
13 From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe 14 The period of this generator is about 2^113 (see erratum paper).
14 Generators", Mathematics of Computation, 65, 213 (1996), 203--213.
15
16 This is available on the net from L'Ecuyer's home page,
17 15
16 From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
17 Generators", Mathematics of Computation, 65, 213 (1996), 203--213:
18 http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps 18 http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
19 ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps 19 ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps
20 20
@@ -29,7 +29,7 @@
29 that paper.) 29 that paper.)
30 30
31 This affects the seeding procedure by imposing the requirement 31 This affects the seeding procedure by imposing the requirement
32 s1 > 1, s2 > 7, s3 > 15. 32 s1 > 1, s2 > 7, s3 > 15, s4 > 127.
33 33
34*/ 34*/
35 35
@@ -38,6 +38,11 @@
38#include <linux/export.h> 38#include <linux/export.h>
39#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40#include <linux/random.h> 40#include <linux/random.h>
41#include <linux/sched.h>
42
43#ifdef CONFIG_RANDOM32_SELFTEST
44static void __init prandom_state_selftest(void);
45#endif
41 46
42static DEFINE_PER_CPU(struct rnd_state, net_rand_state); 47static DEFINE_PER_CPU(struct rnd_state, net_rand_state);
43 48
@@ -52,11 +57,12 @@ u32 prandom_u32_state(struct rnd_state *state)
52{ 57{
53#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b) 58#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
54 59
55 state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12); 60 state->s1 = TAUSWORTHE(state->s1, 6U, 13U, 4294967294U, 18U);
56 state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4); 61 state->s2 = TAUSWORTHE(state->s2, 2U, 27U, 4294967288U, 2U);
57 state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17); 62 state->s3 = TAUSWORTHE(state->s3, 13U, 21U, 4294967280U, 7U);
63 state->s4 = TAUSWORTHE(state->s4, 3U, 12U, 4294967168U, 13U);
58 64
59 return (state->s1 ^ state->s2 ^ state->s3); 65 return (state->s1 ^ state->s2 ^ state->s3 ^ state->s4);
60} 66}
61EXPORT_SYMBOL(prandom_u32_state); 67EXPORT_SYMBOL(prandom_u32_state);
62 68
@@ -126,6 +132,38 @@ void prandom_bytes(void *buf, int bytes)
126} 132}
127EXPORT_SYMBOL(prandom_bytes); 133EXPORT_SYMBOL(prandom_bytes);
128 134
135static void prandom_warmup(struct rnd_state *state)
136{
137 /* Calling RNG ten times to satify recurrence condition */
138 prandom_u32_state(state);
139 prandom_u32_state(state);
140 prandom_u32_state(state);
141 prandom_u32_state(state);
142 prandom_u32_state(state);
143 prandom_u32_state(state);
144 prandom_u32_state(state);
145 prandom_u32_state(state);
146 prandom_u32_state(state);
147 prandom_u32_state(state);
148}
149
150static void prandom_seed_very_weak(struct rnd_state *state, u32 seed)
151{
152 /* Note: This sort of seeding is ONLY used in test cases and
153 * during boot at the time from core_initcall until late_initcall
154 * as we don't have a stronger entropy source available yet.
155 * After late_initcall, we reseed entire state, we have to (!),
156 * otherwise an attacker just needs to search 32 bit space to
157 * probe for our internal 128 bit state if he knows a couple
158 * of prandom32 outputs!
159 */
160#define LCG(x) ((x) * 69069U) /* super-duper LCG */
161 state->s1 = __seed(LCG(seed), 2U);
162 state->s2 = __seed(LCG(state->s1), 8U);
163 state->s3 = __seed(LCG(state->s2), 16U);
164 state->s4 = __seed(LCG(state->s3), 128U);
165}
166
129/** 167/**
130 * prandom_seed - add entropy to pseudo random number generator 168 * prandom_seed - add entropy to pseudo random number generator
131 * @seed: seed value 169 * @seed: seed value
@@ -141,7 +179,9 @@ void prandom_seed(u32 entropy)
141 */ 179 */
142 for_each_possible_cpu (i) { 180 for_each_possible_cpu (i) {
143 struct rnd_state *state = &per_cpu(net_rand_state, i); 181 struct rnd_state *state = &per_cpu(net_rand_state, i);
144 state->s1 = __seed(state->s1 ^ entropy, 1); 182
183 state->s1 = __seed(state->s1 ^ entropy, 2U);
184 prandom_warmup(state);
145 } 185 }
146} 186}
147EXPORT_SYMBOL(prandom_seed); 187EXPORT_SYMBOL(prandom_seed);
@@ -154,46 +194,245 @@ static int __init prandom_init(void)
154{ 194{
155 int i; 195 int i;
156 196
197#ifdef CONFIG_RANDOM32_SELFTEST
198 prandom_state_selftest();
199#endif
200
157 for_each_possible_cpu(i) { 201 for_each_possible_cpu(i) {
158 struct rnd_state *state = &per_cpu(net_rand_state,i); 202 struct rnd_state *state = &per_cpu(net_rand_state,i);
159 203
160#define LCG(x) ((x) * 69069) /* super-duper LCG */ 204 prandom_seed_very_weak(state, (i + jiffies) ^ random_get_entropy());
161 state->s1 = __seed(LCG(i + jiffies), 1); 205 prandom_warmup(state);
162 state->s2 = __seed(LCG(state->s1), 7);
163 state->s3 = __seed(LCG(state->s2), 15);
164
165 /* "warm it up" */
166 prandom_u32_state(state);
167 prandom_u32_state(state);
168 prandom_u32_state(state);
169 prandom_u32_state(state);
170 prandom_u32_state(state);
171 prandom_u32_state(state);
172 } 206 }
173 return 0; 207 return 0;
174} 208}
175core_initcall(prandom_init); 209core_initcall(prandom_init);
176 210
211static void __prandom_timer(unsigned long dontcare);
212static DEFINE_TIMER(seed_timer, __prandom_timer, 0, 0);
213
214static void __prandom_timer(unsigned long dontcare)
215{
216 u32 entropy;
217
218 get_random_bytes(&entropy, sizeof(entropy));
219 prandom_seed(entropy);
220 /* reseed every ~60 seconds, in [40 .. 80) interval with slack */
221 seed_timer.expires = jiffies + (40 * HZ + (prandom_u32() % (40 * HZ)));
222 add_timer(&seed_timer);
223}
224
225static void prandom_start_seed_timer(void)
226{
227 set_timer_slack(&seed_timer, HZ);
228 seed_timer.expires = jiffies + 40 * HZ;
229 add_timer(&seed_timer);
230}
231
177/* 232/*
178 * Generate better values after random number generator 233 * Generate better values after random number generator
179 * is fully initialized. 234 * is fully initialized.
180 */ 235 */
181static int __init prandom_reseed(void) 236static void __prandom_reseed(bool late)
182{ 237{
183 int i; 238 int i;
239 unsigned long flags;
240 static bool latch = false;
241 static DEFINE_SPINLOCK(lock);
242
243 /* only allow initial seeding (late == false) once */
244 spin_lock_irqsave(&lock, flags);
245 if (latch && !late)
246 goto out;
247 latch = true;
184 248
185 for_each_possible_cpu(i) { 249 for_each_possible_cpu(i) {
186 struct rnd_state *state = &per_cpu(net_rand_state,i); 250 struct rnd_state *state = &per_cpu(net_rand_state,i);
187 u32 seeds[3]; 251 u32 seeds[4];
188 252
189 get_random_bytes(&seeds, sizeof(seeds)); 253 get_random_bytes(&seeds, sizeof(seeds));
190 state->s1 = __seed(seeds[0], 1); 254 state->s1 = __seed(seeds[0], 2U);
191 state->s2 = __seed(seeds[1], 7); 255 state->s2 = __seed(seeds[1], 8U);
192 state->s3 = __seed(seeds[2], 15); 256 state->s3 = __seed(seeds[2], 16U);
257 state->s4 = __seed(seeds[3], 128U);
193 258
194 /* mix it in */ 259 prandom_warmup(state);
195 prandom_u32_state(state);
196 } 260 }
261out:
262 spin_unlock_irqrestore(&lock, flags);
263}
264
265void prandom_reseed_late(void)
266{
267 __prandom_reseed(true);
268}
269
270static int __init prandom_reseed(void)
271{
272 __prandom_reseed(false);
273 prandom_start_seed_timer();
197 return 0; 274 return 0;
198} 275}
199late_initcall(prandom_reseed); 276late_initcall(prandom_reseed);
277
278#ifdef CONFIG_RANDOM32_SELFTEST
279static struct prandom_test1 {
280 u32 seed;
281 u32 result;
282} test1[] = {
283 { 1U, 3484351685U },
284 { 2U, 2623130059U },
285 { 3U, 3125133893U },
286 { 4U, 984847254U },
287};
288
289static struct prandom_test2 {
290 u32 seed;
291 u32 iteration;
292 u32 result;
293} test2[] = {
294 /* Test cases against taus113 from GSL library. */
295 { 931557656U, 959U, 2975593782U },
296 { 1339693295U, 876U, 3887776532U },
297 { 1545556285U, 961U, 1615538833U },
298 { 601730776U, 723U, 1776162651U },
299 { 1027516047U, 687U, 511983079U },
300 { 416526298U, 700U, 916156552U },
301 { 1395522032U, 652U, 2222063676U },
302 { 366221443U, 617U, 2992857763U },
303 { 1539836965U, 714U, 3783265725U },
304 { 556206671U, 994U, 799626459U },
305 { 684907218U, 799U, 367789491U },
306 { 2121230701U, 931U, 2115467001U },
307 { 1668516451U, 644U, 3620590685U },
308 { 768046066U, 883U, 2034077390U },
309 { 1989159136U, 833U, 1195767305U },
310 { 536585145U, 996U, 3577259204U },
311 { 1008129373U, 642U, 1478080776U },
312 { 1740775604U, 939U, 1264980372U },
313 { 1967883163U, 508U, 10734624U },
314 { 1923019697U, 730U, 3821419629U },
315 { 442079932U, 560U, 3440032343U },
316 { 1961302714U, 845U, 841962572U },
317 { 2030205964U, 962U, 1325144227U },
318 { 1160407529U, 507U, 240940858U },
319 { 635482502U, 779U, 4200489746U },
320 { 1252788931U, 699U, 867195434U },
321 { 1961817131U, 719U, 668237657U },
322 { 1071468216U, 983U, 917876630U },
323 { 1281848367U, 932U, 1003100039U },
324 { 582537119U, 780U, 1127273778U },
325 { 1973672777U, 853U, 1071368872U },
326 { 1896756996U, 762U, 1127851055U },
327 { 847917054U, 500U, 1717499075U },
328 { 1240520510U, 951U, 2849576657U },
329 { 1685071682U, 567U, 1961810396U },
330 { 1516232129U, 557U, 3173877U },
331 { 1208118903U, 612U, 1613145022U },
332 { 1817269927U, 693U, 4279122573U },
333 { 1510091701U, 717U, 638191229U },
334 { 365916850U, 807U, 600424314U },
335 { 399324359U, 702U, 1803598116U },
336 { 1318480274U, 779U, 2074237022U },
337 { 697758115U, 840U, 1483639402U },
338 { 1696507773U, 840U, 577415447U },
339 { 2081979121U, 981U, 3041486449U },
340 { 955646687U, 742U, 3846494357U },
341 { 1250683506U, 749U, 836419859U },
342 { 595003102U, 534U, 366794109U },
343 { 47485338U, 558U, 3521120834U },
344 { 619433479U, 610U, 3991783875U },
345 { 704096520U, 518U, 4139493852U },
346 { 1712224984U, 606U, 2393312003U },
347 { 1318233152U, 922U, 3880361134U },
348 { 855572992U, 761U, 1472974787U },
349 { 64721421U, 703U, 683860550U },
350 { 678931758U, 840U, 380616043U },
351 { 692711973U, 778U, 1382361947U },
352 { 677703619U, 530U, 2826914161U },
353 { 92393223U, 586U, 1522128471U },
354 { 1222592920U, 743U, 3466726667U },
355 { 358288986U, 695U, 1091956998U },
356 { 1935056945U, 958U, 514864477U },
357 { 735675993U, 990U, 1294239989U },
358 { 1560089402U, 897U, 2238551287U },
359 { 70616361U, 829U, 22483098U },
360 { 368234700U, 731U, 2913875084U },
361 { 20221190U, 879U, 1564152970U },
362 { 539444654U, 682U, 1835141259U },
363 { 1314987297U, 840U, 1801114136U },
364 { 2019295544U, 645U, 3286438930U },
365 { 469023838U, 716U, 1637918202U },
366 { 1843754496U, 653U, 2562092152U },
367 { 400672036U, 809U, 4264212785U },
368 { 404722249U, 965U, 2704116999U },
369 { 600702209U, 758U, 584979986U },
370 { 519953954U, 667U, 2574436237U },
371 { 1658071126U, 694U, 2214569490U },
372 { 420480037U, 749U, 3430010866U },
373 { 690103647U, 969U, 3700758083U },
374 { 1029424799U, 937U, 3787746841U },
375 { 2012608669U, 506U, 3362628973U },
376 { 1535432887U, 998U, 42610943U },
377 { 1330635533U, 857U, 3040806504U },
378 { 1223800550U, 539U, 3954229517U },
379 { 1322411537U, 680U, 3223250324U },
380 { 1877847898U, 945U, 2915147143U },
381 { 1646356099U, 874U, 965988280U },
382 { 805687536U, 744U, 4032277920U },
383 { 1948093210U, 633U, 1346597684U },
384 { 392609744U, 783U, 1636083295U },
385 { 690241304U, 770U, 1201031298U },
386 { 1360302965U, 696U, 1665394461U },
387 { 1220090946U, 780U, 1316922812U },
388 { 447092251U, 500U, 3438743375U },
389 { 1613868791U, 592U, 828546883U },
390 { 523430951U, 548U, 2552392304U },
391 { 726692899U, 810U, 1656872867U },
392 { 1364340021U, 836U, 3710513486U },
393 { 1986257729U, 931U, 935013962U },
394 { 407983964U, 921U, 728767059U },
395};
396
397static void __init prandom_state_selftest(void)
398{
399 int i, j, errors = 0, runs = 0;
400 bool error = false;
401
402 for (i = 0; i < ARRAY_SIZE(test1); i++) {
403 struct rnd_state state;
404
405 prandom_seed_very_weak(&state, test1[i].seed);
406 prandom_warmup(&state);
407
408 if (test1[i].result != prandom_u32_state(&state))
409 error = true;
410 }
411
412 if (error)
413 pr_warn("prandom: seed boundary self test failed\n");
414 else
415 pr_info("prandom: seed boundary self test passed\n");
416
417 for (i = 0; i < ARRAY_SIZE(test2); i++) {
418 struct rnd_state state;
419
420 prandom_seed_very_weak(&state, test2[i].seed);
421 prandom_warmup(&state);
422
423 for (j = 0; j < test2[i].iteration - 1; j++)
424 prandom_u32_state(&state);
425
426 if (test2[i].result != prandom_u32_state(&state))
427 errors++;
428
429 runs++;
430 cond_resched();
431 }
432
433 if (errors)
434 pr_warn("prandom: %d/%d self tests failed\n", errors, runs);
435 else
436 pr_info("prandom: %d self tests passed\n", runs);
437}
438#endif