0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #include <linux/types.h>
0036 #include <linux/percpu.h>
0037 #include <linux/export.h>
0038 #include <linux/jiffies.h>
0039 #include <linux/random.h>
0040 #include <linux/sched.h>
0041 #include <linux/bitops.h>
0042 #include <linux/slab.h>
0043 #include <asm/unaligned.h>
0044
0045
0046
0047
0048
0049
0050
0051
0052 u32 prandom_u32_state(struct rnd_state *state)
0053 {
0054 #define TAUSWORTHE(s, a, b, c, d) ((s & c) << d) ^ (((s << a) ^ s) >> b)
0055 state->s1 = TAUSWORTHE(state->s1, 6U, 13U, 4294967294U, 18U);
0056 state->s2 = TAUSWORTHE(state->s2, 2U, 27U, 4294967288U, 2U);
0057 state->s3 = TAUSWORTHE(state->s3, 13U, 21U, 4294967280U, 7U);
0058 state->s4 = TAUSWORTHE(state->s4, 3U, 12U, 4294967168U, 13U);
0059
0060 return (state->s1 ^ state->s2 ^ state->s3 ^ state->s4);
0061 }
0062 EXPORT_SYMBOL(prandom_u32_state);
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 void prandom_bytes_state(struct rnd_state *state, void *buf, size_t bytes)
0075 {
0076 u8 *ptr = buf;
0077
0078 while (bytes >= sizeof(u32)) {
0079 put_unaligned(prandom_u32_state(state), (u32 *) ptr);
0080 ptr += sizeof(u32);
0081 bytes -= sizeof(u32);
0082 }
0083
0084 if (bytes > 0) {
0085 u32 rem = prandom_u32_state(state);
0086 do {
0087 *ptr++ = (u8) rem;
0088 bytes--;
0089 rem >>= BITS_PER_BYTE;
0090 } while (bytes > 0);
0091 }
0092 }
0093 EXPORT_SYMBOL(prandom_bytes_state);
0094
0095 static void prandom_warmup(struct rnd_state *state)
0096 {
0097
0098 prandom_u32_state(state);
0099 prandom_u32_state(state);
0100 prandom_u32_state(state);
0101 prandom_u32_state(state);
0102 prandom_u32_state(state);
0103 prandom_u32_state(state);
0104 prandom_u32_state(state);
0105 prandom_u32_state(state);
0106 prandom_u32_state(state);
0107 prandom_u32_state(state);
0108 }
0109
0110 void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state)
0111 {
0112 int i;
0113
0114 for_each_possible_cpu(i) {
0115 struct rnd_state *state = per_cpu_ptr(pcpu_state, i);
0116 u32 seeds[4];
0117
0118 get_random_bytes(&seeds, sizeof(seeds));
0119 state->s1 = __seed(seeds[0], 2U);
0120 state->s2 = __seed(seeds[1], 8U);
0121 state->s3 = __seed(seeds[2], 16U);
0122 state->s4 = __seed(seeds[3], 128U);
0123
0124 prandom_warmup(state);
0125 }
0126 }
0127 EXPORT_SYMBOL(prandom_seed_full_state);
0128
0129 #ifdef CONFIG_RANDOM32_SELFTEST
0130 static struct prandom_test1 {
0131 u32 seed;
0132 u32 result;
0133 } test1[] = {
0134 { 1U, 3484351685U },
0135 { 2U, 2623130059U },
0136 { 3U, 3125133893U },
0137 { 4U, 984847254U },
0138 };
0139
0140 static struct prandom_test2 {
0141 u32 seed;
0142 u32 iteration;
0143 u32 result;
0144 } test2[] = {
0145
0146 { 931557656U, 959U, 2975593782U },
0147 { 1339693295U, 876U, 3887776532U },
0148 { 1545556285U, 961U, 1615538833U },
0149 { 601730776U, 723U, 1776162651U },
0150 { 1027516047U, 687U, 511983079U },
0151 { 416526298U, 700U, 916156552U },
0152 { 1395522032U, 652U, 2222063676U },
0153 { 366221443U, 617U, 2992857763U },
0154 { 1539836965U, 714U, 3783265725U },
0155 { 556206671U, 994U, 799626459U },
0156 { 684907218U, 799U, 367789491U },
0157 { 2121230701U, 931U, 2115467001U },
0158 { 1668516451U, 644U, 3620590685U },
0159 { 768046066U, 883U, 2034077390U },
0160 { 1989159136U, 833U, 1195767305U },
0161 { 536585145U, 996U, 3577259204U },
0162 { 1008129373U, 642U, 1478080776U },
0163 { 1740775604U, 939U, 1264980372U },
0164 { 1967883163U, 508U, 10734624U },
0165 { 1923019697U, 730U, 3821419629U },
0166 { 442079932U, 560U, 3440032343U },
0167 { 1961302714U, 845U, 841962572U },
0168 { 2030205964U, 962U, 1325144227U },
0169 { 1160407529U, 507U, 240940858U },
0170 { 635482502U, 779U, 4200489746U },
0171 { 1252788931U, 699U, 867195434U },
0172 { 1961817131U, 719U, 668237657U },
0173 { 1071468216U, 983U, 917876630U },
0174 { 1281848367U, 932U, 1003100039U },
0175 { 582537119U, 780U, 1127273778U },
0176 { 1973672777U, 853U, 1071368872U },
0177 { 1896756996U, 762U, 1127851055U },
0178 { 847917054U, 500U, 1717499075U },
0179 { 1240520510U, 951U, 2849576657U },
0180 { 1685071682U, 567U, 1961810396U },
0181 { 1516232129U, 557U, 3173877U },
0182 { 1208118903U, 612U, 1613145022U },
0183 { 1817269927U, 693U, 4279122573U },
0184 { 1510091701U, 717U, 638191229U },
0185 { 365916850U, 807U, 600424314U },
0186 { 399324359U, 702U, 1803598116U },
0187 { 1318480274U, 779U, 2074237022U },
0188 { 697758115U, 840U, 1483639402U },
0189 { 1696507773U, 840U, 577415447U },
0190 { 2081979121U, 981U, 3041486449U },
0191 { 955646687U, 742U, 3846494357U },
0192 { 1250683506U, 749U, 836419859U },
0193 { 595003102U, 534U, 366794109U },
0194 { 47485338U, 558U, 3521120834U },
0195 { 619433479U, 610U, 3991783875U },
0196 { 704096520U, 518U, 4139493852U },
0197 { 1712224984U, 606U, 2393312003U },
0198 { 1318233152U, 922U, 3880361134U },
0199 { 855572992U, 761U, 1472974787U },
0200 { 64721421U, 703U, 683860550U },
0201 { 678931758U, 840U, 380616043U },
0202 { 692711973U, 778U, 1382361947U },
0203 { 677703619U, 530U, 2826914161U },
0204 { 92393223U, 586U, 1522128471U },
0205 { 1222592920U, 743U, 3466726667U },
0206 { 358288986U, 695U, 1091956998U },
0207 { 1935056945U, 958U, 514864477U },
0208 { 735675993U, 990U, 1294239989U },
0209 { 1560089402U, 897U, 2238551287U },
0210 { 70616361U, 829U, 22483098U },
0211 { 368234700U, 731U, 2913875084U },
0212 { 20221190U, 879U, 1564152970U },
0213 { 539444654U, 682U, 1835141259U },
0214 { 1314987297U, 840U, 1801114136U },
0215 { 2019295544U, 645U, 3286438930U },
0216 { 469023838U, 716U, 1637918202U },
0217 { 1843754496U, 653U, 2562092152U },
0218 { 400672036U, 809U, 4264212785U },
0219 { 404722249U, 965U, 2704116999U },
0220 { 600702209U, 758U, 584979986U },
0221 { 519953954U, 667U, 2574436237U },
0222 { 1658071126U, 694U, 2214569490U },
0223 { 420480037U, 749U, 3430010866U },
0224 { 690103647U, 969U, 3700758083U },
0225 { 1029424799U, 937U, 3787746841U },
0226 { 2012608669U, 506U, 3362628973U },
0227 { 1535432887U, 998U, 42610943U },
0228 { 1330635533U, 857U, 3040806504U },
0229 { 1223800550U, 539U, 3954229517U },
0230 { 1322411537U, 680U, 3223250324U },
0231 { 1877847898U, 945U, 2915147143U },
0232 { 1646356099U, 874U, 965988280U },
0233 { 805687536U, 744U, 4032277920U },
0234 { 1948093210U, 633U, 1346597684U },
0235 { 392609744U, 783U, 1636083295U },
0236 { 690241304U, 770U, 1201031298U },
0237 { 1360302965U, 696U, 1665394461U },
0238 { 1220090946U, 780U, 1316922812U },
0239 { 447092251U, 500U, 3438743375U },
0240 { 1613868791U, 592U, 828546883U },
0241 { 523430951U, 548U, 2552392304U },
0242 { 726692899U, 810U, 1656872867U },
0243 { 1364340021U, 836U, 3710513486U },
0244 { 1986257729U, 931U, 935013962U },
0245 { 407983964U, 921U, 728767059U },
0246 };
0247
0248 static void prandom_state_selftest_seed(struct rnd_state *state, u32 seed)
0249 {
0250 #define LCG(x) ((x) * 69069U)
0251 state->s1 = __seed(LCG(seed), 2U);
0252 state->s2 = __seed(LCG(state->s1), 8U);
0253 state->s3 = __seed(LCG(state->s2), 16U);
0254 state->s4 = __seed(LCG(state->s3), 128U);
0255 }
0256
0257 static int __init prandom_state_selftest(void)
0258 {
0259 int i, j, errors = 0, runs = 0;
0260 bool error = false;
0261
0262 for (i = 0; i < ARRAY_SIZE(test1); i++) {
0263 struct rnd_state state;
0264
0265 prandom_state_selftest_seed(&state, test1[i].seed);
0266 prandom_warmup(&state);
0267
0268 if (test1[i].result != prandom_u32_state(&state))
0269 error = true;
0270 }
0271
0272 if (error)
0273 pr_warn("prandom: seed boundary self test failed\n");
0274 else
0275 pr_info("prandom: seed boundary self test passed\n");
0276
0277 for (i = 0; i < ARRAY_SIZE(test2); i++) {
0278 struct rnd_state state;
0279
0280 prandom_state_selftest_seed(&state, test2[i].seed);
0281 prandom_warmup(&state);
0282
0283 for (j = 0; j < test2[i].iteration - 1; j++)
0284 prandom_u32_state(&state);
0285
0286 if (test2[i].result != prandom_u32_state(&state))
0287 errors++;
0288
0289 runs++;
0290 cond_resched();
0291 }
0292
0293 if (errors)
0294 pr_warn("prandom: %d/%d self tests failed\n", errors, runs);
0295 else
0296 pr_info("prandom: %d self tests passed\n", runs);
0297 return 0;
0298 }
0299 core_initcall(prandom_state_selftest);
0300 #endif