aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-11-11 14:33:06 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-11 14:33:06 -0500
commit75ecab1df14d90e86cebef9ec5c76befde46e65f (patch)
treeaa0aee61cf99280eaa533956438c9daec3a2afc7
parent129596674c00352cbbb1efaf36db50726fd374ef (diff)
parenta6a9c0f1bf5a9a5faa605773ea75e0b93c3ab108 (diff)
Merge branch 'prandom'
prandom fixes/improvements ==================== It would be great if you could still consider this series that fixes and improves prandom for 3.13. We have sent it to netdev as prandom() originally came from net/core/utils.c and networking is its main user. For a detailled description, please see individual patches. For patch 3 in this series, there will be a minor merge conflict with the random tree that is for 3.13. See below how to resolve it. ==== Hannes says: on merge with the random tree I would suggest to resolve the conflict in drivers/char/random.c like this: if (r->entropy_total > 128) { r->initialized = 1; r->entropy_total = 0; if (r == &nonblocking_pool) { prandom_reseed_late(); pr_notice("random: %s pool is initialized\n", r->name); } } So it won't generate a warning if DEBUG_RANDOM_BOOT gets activated. ==== Patch 1 should probably also go to -stable. Set tested on 32 and 64 bit machines. Thanks a lot! Ref. original discussion: http://patchwork.ozlabs.org/patch/289951/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/char/random.c5
-rw-r--r--include/linux/random.h14
-rw-r--r--include/uapi/linux/random.h7
-rw-r--r--lib/Kconfig7
-rw-r--r--lib/random32.c307
5 files changed, 294 insertions, 46 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7a744d391756..4fe5609eeb72 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -603,8 +603,11 @@ retry:
603 603
604 if (!r->initialized && nbits > 0) { 604 if (!r->initialized && nbits > 0) {
605 r->entropy_total += nbits; 605 r->entropy_total += nbits;
606 if (r->entropy_total > 128) 606 if (r->entropy_total > 128) {
607 r->initialized = 1; 607 r->initialized = 1;
608 if (r == &nonblocking_pool)
609 prandom_reseed_late();
610 }
608 } 611 }
609 612
610 trace_credit_entropy_bits(r->name, nbits, entropy_count, 613 trace_credit_entropy_bits(r->name, nbits, entropy_count,
diff --git a/include/linux/random.h b/include/linux/random.h
index 6312dd9ba449..4002b3df4c85 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -29,8 +29,13 @@ unsigned long randomize_range(unsigned long start, unsigned long end, unsigned l
29u32 prandom_u32(void); 29u32 prandom_u32(void);
30void prandom_bytes(void *buf, int nbytes); 30void prandom_bytes(void *buf, int nbytes);
31void prandom_seed(u32 seed); 31void prandom_seed(u32 seed);
32void prandom_reseed_late(void);
32 33
33u32 prandom_u32_state(struct rnd_state *); 34struct rnd_state {
35 __u32 s1, s2, s3, s4;
36};
37
38u32 prandom_u32_state(struct rnd_state *state);
34void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes); 39void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes);
35 40
36/* 41/*
@@ -50,9 +55,10 @@ static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
50{ 55{
51 u32 i = (seed >> 32) ^ (seed << 10) ^ seed; 56 u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
52 57
53 state->s1 = __seed(i, 1); 58 state->s1 = __seed(i, 2U);
54 state->s2 = __seed(i, 7); 59 state->s2 = __seed(i, 8U);
55 state->s3 = __seed(i, 15); 60 state->s3 = __seed(i, 16U);
61 state->s4 = __seed(i, 128U);
56} 62}
57 63
58#ifdef CONFIG_ARCH_RANDOM 64#ifdef CONFIG_ARCH_RANDOM
diff --git a/include/uapi/linux/random.h b/include/uapi/linux/random.h
index 7471b5b3b8ba..fff3528a078f 100644
--- a/include/uapi/linux/random.h
+++ b/include/uapi/linux/random.h
@@ -40,11 +40,4 @@ struct rand_pool_info {
40 __u32 buf[0]; 40 __u32 buf[0];
41}; 41};
42 42
43struct rnd_state {
44 __u32 s1, s2, s3;
45};
46
47/* Exported functions */
48
49
50#endif /* _UAPI_LINUX_RANDOM_H */ 43#endif /* _UAPI_LINUX_RANDOM_H */
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/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!
15