18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * This is a maximally equidistributed combined Tausworthe generator 48c2ecf20Sopenharmony_ci * based on code from GNU Scientific Library 1.5 (30 Jun 2004) 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * lfsr113 version: 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * x_n = (s1_n ^ s2_n ^ s3_n ^ s4_n) 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * s1_{n+1} = (((s1_n & 4294967294) << 18) ^ (((s1_n << 6) ^ s1_n) >> 13)) 118c2ecf20Sopenharmony_ci * s2_{n+1} = (((s2_n & 4294967288) << 2) ^ (((s2_n << 2) ^ s2_n) >> 27)) 128c2ecf20Sopenharmony_ci * s3_{n+1} = (((s3_n & 4294967280) << 7) ^ (((s3_n << 13) ^ s3_n) >> 21)) 138c2ecf20Sopenharmony_ci * s4_{n+1} = (((s4_n & 4294967168) << 13) ^ (((s4_n << 3) ^ s4_n) >> 12)) 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * The period of this generator is about 2^113 (see erratum paper). 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe 188c2ecf20Sopenharmony_ci * Generators", Mathematics of Computation, 65, 213 (1996), 203--213: 198c2ecf20Sopenharmony_ci * http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps 208c2ecf20Sopenharmony_ci * ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * There is an erratum in the paper "Tables of Maximally Equidistributed 238c2ecf20Sopenharmony_ci * Combined LFSR Generators", Mathematics of Computation, 68, 225 (1999), 248c2ecf20Sopenharmony_ci * 261--269: http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * ... the k_j most significant bits of z_j must be non-zero, 278c2ecf20Sopenharmony_ci * for each j. (Note: this restriction also applies to the 288c2ecf20Sopenharmony_ci * computer code given in [4], but was mistakenly not mentioned 298c2ecf20Sopenharmony_ci * in that paper.) 308c2ecf20Sopenharmony_ci * 318c2ecf20Sopenharmony_ci * This affects the seeding procedure by imposing the requirement 328c2ecf20Sopenharmony_ci * s1 > 1, s2 > 7, s3 > 15, s4 > 127. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include <linux/types.h> 368c2ecf20Sopenharmony_ci#include <linux/percpu.h> 378c2ecf20Sopenharmony_ci#include <linux/export.h> 388c2ecf20Sopenharmony_ci#include <linux/jiffies.h> 398c2ecf20Sopenharmony_ci#include <linux/random.h> 408c2ecf20Sopenharmony_ci#include <linux/sched.h> 418c2ecf20Sopenharmony_ci#include <linux/bitops.h> 428c2ecf20Sopenharmony_ci#include <linux/slab.h> 438c2ecf20Sopenharmony_ci#include <linux/notifier.h> 448c2ecf20Sopenharmony_ci#include <asm/unaligned.h> 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/** 478c2ecf20Sopenharmony_ci * prandom_u32_state - seeded pseudo-random number generator. 488c2ecf20Sopenharmony_ci * @state: pointer to state structure holding seeded state. 498c2ecf20Sopenharmony_ci * 508c2ecf20Sopenharmony_ci * This is used for pseudo-randomness with no outside seeding. 518c2ecf20Sopenharmony_ci * For more random results, use prandom_u32(). 528c2ecf20Sopenharmony_ci */ 538c2ecf20Sopenharmony_ciu32 prandom_u32_state(struct rnd_state *state) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci#define TAUSWORTHE(s, a, b, c, d) ((s & c) << d) ^ (((s << a) ^ s) >> b) 568c2ecf20Sopenharmony_ci state->s1 = TAUSWORTHE(state->s1, 6U, 13U, 4294967294U, 18U); 578c2ecf20Sopenharmony_ci state->s2 = TAUSWORTHE(state->s2, 2U, 27U, 4294967288U, 2U); 588c2ecf20Sopenharmony_ci state->s3 = TAUSWORTHE(state->s3, 13U, 21U, 4294967280U, 7U); 598c2ecf20Sopenharmony_ci state->s4 = TAUSWORTHE(state->s4, 3U, 12U, 4294967168U, 13U); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci return (state->s1 ^ state->s2 ^ state->s3 ^ state->s4); 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ciEXPORT_SYMBOL(prandom_u32_state); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci/** 668c2ecf20Sopenharmony_ci * prandom_bytes_state - get the requested number of pseudo-random bytes 678c2ecf20Sopenharmony_ci * 688c2ecf20Sopenharmony_ci * @state: pointer to state structure holding seeded state. 698c2ecf20Sopenharmony_ci * @buf: where to copy the pseudo-random bytes to 708c2ecf20Sopenharmony_ci * @bytes: the requested number of bytes 718c2ecf20Sopenharmony_ci * 728c2ecf20Sopenharmony_ci * This is used for pseudo-randomness with no outside seeding. 738c2ecf20Sopenharmony_ci * For more random results, use prandom_bytes(). 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_civoid prandom_bytes_state(struct rnd_state *state, void *buf, size_t bytes) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci u8 *ptr = buf; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci while (bytes >= sizeof(u32)) { 808c2ecf20Sopenharmony_ci put_unaligned(prandom_u32_state(state), (u32 *) ptr); 818c2ecf20Sopenharmony_ci ptr += sizeof(u32); 828c2ecf20Sopenharmony_ci bytes -= sizeof(u32); 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci if (bytes > 0) { 868c2ecf20Sopenharmony_ci u32 rem = prandom_u32_state(state); 878c2ecf20Sopenharmony_ci do { 888c2ecf20Sopenharmony_ci *ptr++ = (u8) rem; 898c2ecf20Sopenharmony_ci bytes--; 908c2ecf20Sopenharmony_ci rem >>= BITS_PER_BYTE; 918c2ecf20Sopenharmony_ci } while (bytes > 0); 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ciEXPORT_SYMBOL(prandom_bytes_state); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistatic void prandom_warmup(struct rnd_state *state) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci /* Calling RNG ten times to satisfy recurrence condition */ 998c2ecf20Sopenharmony_ci prandom_u32_state(state); 1008c2ecf20Sopenharmony_ci prandom_u32_state(state); 1018c2ecf20Sopenharmony_ci prandom_u32_state(state); 1028c2ecf20Sopenharmony_ci prandom_u32_state(state); 1038c2ecf20Sopenharmony_ci prandom_u32_state(state); 1048c2ecf20Sopenharmony_ci prandom_u32_state(state); 1058c2ecf20Sopenharmony_ci prandom_u32_state(state); 1068c2ecf20Sopenharmony_ci prandom_u32_state(state); 1078c2ecf20Sopenharmony_ci prandom_u32_state(state); 1088c2ecf20Sopenharmony_ci prandom_u32_state(state); 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_civoid prandom_seed_full_state(struct rnd_state __percpu *pcpu_state) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci int i; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci for_each_possible_cpu(i) { 1168c2ecf20Sopenharmony_ci struct rnd_state *state = per_cpu_ptr(pcpu_state, i); 1178c2ecf20Sopenharmony_ci u32 seeds[4]; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci get_random_bytes(&seeds, sizeof(seeds)); 1208c2ecf20Sopenharmony_ci state->s1 = __seed(seeds[0], 2U); 1218c2ecf20Sopenharmony_ci state->s2 = __seed(seeds[1], 8U); 1228c2ecf20Sopenharmony_ci state->s3 = __seed(seeds[2], 16U); 1238c2ecf20Sopenharmony_ci state->s4 = __seed(seeds[3], 128U); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci prandom_warmup(state); 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci} 1288c2ecf20Sopenharmony_ciEXPORT_SYMBOL(prandom_seed_full_state); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci#ifdef CONFIG_RANDOM32_SELFTEST 1318c2ecf20Sopenharmony_cistatic struct prandom_test1 { 1328c2ecf20Sopenharmony_ci u32 seed; 1338c2ecf20Sopenharmony_ci u32 result; 1348c2ecf20Sopenharmony_ci} test1[] = { 1358c2ecf20Sopenharmony_ci { 1U, 3484351685U }, 1368c2ecf20Sopenharmony_ci { 2U, 2623130059U }, 1378c2ecf20Sopenharmony_ci { 3U, 3125133893U }, 1388c2ecf20Sopenharmony_ci { 4U, 984847254U }, 1398c2ecf20Sopenharmony_ci}; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistatic struct prandom_test2 { 1428c2ecf20Sopenharmony_ci u32 seed; 1438c2ecf20Sopenharmony_ci u32 iteration; 1448c2ecf20Sopenharmony_ci u32 result; 1458c2ecf20Sopenharmony_ci} test2[] = { 1468c2ecf20Sopenharmony_ci /* Test cases against taus113 from GSL library. */ 1478c2ecf20Sopenharmony_ci { 931557656U, 959U, 2975593782U }, 1488c2ecf20Sopenharmony_ci { 1339693295U, 876U, 3887776532U }, 1498c2ecf20Sopenharmony_ci { 1545556285U, 961U, 1615538833U }, 1508c2ecf20Sopenharmony_ci { 601730776U, 723U, 1776162651U }, 1518c2ecf20Sopenharmony_ci { 1027516047U, 687U, 511983079U }, 1528c2ecf20Sopenharmony_ci { 416526298U, 700U, 916156552U }, 1538c2ecf20Sopenharmony_ci { 1395522032U, 652U, 2222063676U }, 1548c2ecf20Sopenharmony_ci { 366221443U, 617U, 2992857763U }, 1558c2ecf20Sopenharmony_ci { 1539836965U, 714U, 3783265725U }, 1568c2ecf20Sopenharmony_ci { 556206671U, 994U, 799626459U }, 1578c2ecf20Sopenharmony_ci { 684907218U, 799U, 367789491U }, 1588c2ecf20Sopenharmony_ci { 2121230701U, 931U, 2115467001U }, 1598c2ecf20Sopenharmony_ci { 1668516451U, 644U, 3620590685U }, 1608c2ecf20Sopenharmony_ci { 768046066U, 883U, 2034077390U }, 1618c2ecf20Sopenharmony_ci { 1989159136U, 833U, 1195767305U }, 1628c2ecf20Sopenharmony_ci { 536585145U, 996U, 3577259204U }, 1638c2ecf20Sopenharmony_ci { 1008129373U, 642U, 1478080776U }, 1648c2ecf20Sopenharmony_ci { 1740775604U, 939U, 1264980372U }, 1658c2ecf20Sopenharmony_ci { 1967883163U, 508U, 10734624U }, 1668c2ecf20Sopenharmony_ci { 1923019697U, 730U, 3821419629U }, 1678c2ecf20Sopenharmony_ci { 442079932U, 560U, 3440032343U }, 1688c2ecf20Sopenharmony_ci { 1961302714U, 845U, 841962572U }, 1698c2ecf20Sopenharmony_ci { 2030205964U, 962U, 1325144227U }, 1708c2ecf20Sopenharmony_ci { 1160407529U, 507U, 240940858U }, 1718c2ecf20Sopenharmony_ci { 635482502U, 779U, 4200489746U }, 1728c2ecf20Sopenharmony_ci { 1252788931U, 699U, 867195434U }, 1738c2ecf20Sopenharmony_ci { 1961817131U, 719U, 668237657U }, 1748c2ecf20Sopenharmony_ci { 1071468216U, 983U, 917876630U }, 1758c2ecf20Sopenharmony_ci { 1281848367U, 932U, 1003100039U }, 1768c2ecf20Sopenharmony_ci { 582537119U, 780U, 1127273778U }, 1778c2ecf20Sopenharmony_ci { 1973672777U, 853U, 1071368872U }, 1788c2ecf20Sopenharmony_ci { 1896756996U, 762U, 1127851055U }, 1798c2ecf20Sopenharmony_ci { 847917054U, 500U, 1717499075U }, 1808c2ecf20Sopenharmony_ci { 1240520510U, 951U, 2849576657U }, 1818c2ecf20Sopenharmony_ci { 1685071682U, 567U, 1961810396U }, 1828c2ecf20Sopenharmony_ci { 1516232129U, 557U, 3173877U }, 1838c2ecf20Sopenharmony_ci { 1208118903U, 612U, 1613145022U }, 1848c2ecf20Sopenharmony_ci { 1817269927U, 693U, 4279122573U }, 1858c2ecf20Sopenharmony_ci { 1510091701U, 717U, 638191229U }, 1868c2ecf20Sopenharmony_ci { 365916850U, 807U, 600424314U }, 1878c2ecf20Sopenharmony_ci { 399324359U, 702U, 1803598116U }, 1888c2ecf20Sopenharmony_ci { 1318480274U, 779U, 2074237022U }, 1898c2ecf20Sopenharmony_ci { 697758115U, 840U, 1483639402U }, 1908c2ecf20Sopenharmony_ci { 1696507773U, 840U, 577415447U }, 1918c2ecf20Sopenharmony_ci { 2081979121U, 981U, 3041486449U }, 1928c2ecf20Sopenharmony_ci { 955646687U, 742U, 3846494357U }, 1938c2ecf20Sopenharmony_ci { 1250683506U, 749U, 836419859U }, 1948c2ecf20Sopenharmony_ci { 595003102U, 534U, 366794109U }, 1958c2ecf20Sopenharmony_ci { 47485338U, 558U, 3521120834U }, 1968c2ecf20Sopenharmony_ci { 619433479U, 610U, 3991783875U }, 1978c2ecf20Sopenharmony_ci { 704096520U, 518U, 4139493852U }, 1988c2ecf20Sopenharmony_ci { 1712224984U, 606U, 2393312003U }, 1998c2ecf20Sopenharmony_ci { 1318233152U, 922U, 3880361134U }, 2008c2ecf20Sopenharmony_ci { 855572992U, 761U, 1472974787U }, 2018c2ecf20Sopenharmony_ci { 64721421U, 703U, 683860550U }, 2028c2ecf20Sopenharmony_ci { 678931758U, 840U, 380616043U }, 2038c2ecf20Sopenharmony_ci { 692711973U, 778U, 1382361947U }, 2048c2ecf20Sopenharmony_ci { 677703619U, 530U, 2826914161U }, 2058c2ecf20Sopenharmony_ci { 92393223U, 586U, 1522128471U }, 2068c2ecf20Sopenharmony_ci { 1222592920U, 743U, 3466726667U }, 2078c2ecf20Sopenharmony_ci { 358288986U, 695U, 1091956998U }, 2088c2ecf20Sopenharmony_ci { 1935056945U, 958U, 514864477U }, 2098c2ecf20Sopenharmony_ci { 735675993U, 990U, 1294239989U }, 2108c2ecf20Sopenharmony_ci { 1560089402U, 897U, 2238551287U }, 2118c2ecf20Sopenharmony_ci { 70616361U, 829U, 22483098U }, 2128c2ecf20Sopenharmony_ci { 368234700U, 731U, 2913875084U }, 2138c2ecf20Sopenharmony_ci { 20221190U, 879U, 1564152970U }, 2148c2ecf20Sopenharmony_ci { 539444654U, 682U, 1835141259U }, 2158c2ecf20Sopenharmony_ci { 1314987297U, 840U, 1801114136U }, 2168c2ecf20Sopenharmony_ci { 2019295544U, 645U, 3286438930U }, 2178c2ecf20Sopenharmony_ci { 469023838U, 716U, 1637918202U }, 2188c2ecf20Sopenharmony_ci { 1843754496U, 653U, 2562092152U }, 2198c2ecf20Sopenharmony_ci { 400672036U, 809U, 4264212785U }, 2208c2ecf20Sopenharmony_ci { 404722249U, 965U, 2704116999U }, 2218c2ecf20Sopenharmony_ci { 600702209U, 758U, 584979986U }, 2228c2ecf20Sopenharmony_ci { 519953954U, 667U, 2574436237U }, 2238c2ecf20Sopenharmony_ci { 1658071126U, 694U, 2214569490U }, 2248c2ecf20Sopenharmony_ci { 420480037U, 749U, 3430010866U }, 2258c2ecf20Sopenharmony_ci { 690103647U, 969U, 3700758083U }, 2268c2ecf20Sopenharmony_ci { 1029424799U, 937U, 3787746841U }, 2278c2ecf20Sopenharmony_ci { 2012608669U, 506U, 3362628973U }, 2288c2ecf20Sopenharmony_ci { 1535432887U, 998U, 42610943U }, 2298c2ecf20Sopenharmony_ci { 1330635533U, 857U, 3040806504U }, 2308c2ecf20Sopenharmony_ci { 1223800550U, 539U, 3954229517U }, 2318c2ecf20Sopenharmony_ci { 1322411537U, 680U, 3223250324U }, 2328c2ecf20Sopenharmony_ci { 1877847898U, 945U, 2915147143U }, 2338c2ecf20Sopenharmony_ci { 1646356099U, 874U, 965988280U }, 2348c2ecf20Sopenharmony_ci { 805687536U, 744U, 4032277920U }, 2358c2ecf20Sopenharmony_ci { 1948093210U, 633U, 1346597684U }, 2368c2ecf20Sopenharmony_ci { 392609744U, 783U, 1636083295U }, 2378c2ecf20Sopenharmony_ci { 690241304U, 770U, 1201031298U }, 2388c2ecf20Sopenharmony_ci { 1360302965U, 696U, 1665394461U }, 2398c2ecf20Sopenharmony_ci { 1220090946U, 780U, 1316922812U }, 2408c2ecf20Sopenharmony_ci { 447092251U, 500U, 3438743375U }, 2418c2ecf20Sopenharmony_ci { 1613868791U, 592U, 828546883U }, 2428c2ecf20Sopenharmony_ci { 523430951U, 548U, 2552392304U }, 2438c2ecf20Sopenharmony_ci { 726692899U, 810U, 1656872867U }, 2448c2ecf20Sopenharmony_ci { 1364340021U, 836U, 3710513486U }, 2458c2ecf20Sopenharmony_ci { 1986257729U, 931U, 935013962U }, 2468c2ecf20Sopenharmony_ci { 407983964U, 921U, 728767059U }, 2478c2ecf20Sopenharmony_ci}; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic u32 __extract_hwseed(void) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci unsigned int val = 0; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci (void)(arch_get_random_seed_int(&val) || 2548c2ecf20Sopenharmony_ci arch_get_random_int(&val)); 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci return val; 2578c2ecf20Sopenharmony_ci} 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_cistatic void prandom_seed_early(struct rnd_state *state, u32 seed, 2608c2ecf20Sopenharmony_ci bool mix_with_hwseed) 2618c2ecf20Sopenharmony_ci{ 2628c2ecf20Sopenharmony_ci#define LCG(x) ((x) * 69069U) /* super-duper LCG */ 2638c2ecf20Sopenharmony_ci#define HWSEED() (mix_with_hwseed ? __extract_hwseed() : 0) 2648c2ecf20Sopenharmony_ci state->s1 = __seed(HWSEED() ^ LCG(seed), 2U); 2658c2ecf20Sopenharmony_ci state->s2 = __seed(HWSEED() ^ LCG(state->s1), 8U); 2668c2ecf20Sopenharmony_ci state->s3 = __seed(HWSEED() ^ LCG(state->s2), 16U); 2678c2ecf20Sopenharmony_ci state->s4 = __seed(HWSEED() ^ LCG(state->s3), 128U); 2688c2ecf20Sopenharmony_ci} 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic int __init prandom_state_selftest(void) 2718c2ecf20Sopenharmony_ci{ 2728c2ecf20Sopenharmony_ci int i, j, errors = 0, runs = 0; 2738c2ecf20Sopenharmony_ci bool error = false; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(test1); i++) { 2768c2ecf20Sopenharmony_ci struct rnd_state state; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci prandom_seed_early(&state, test1[i].seed, false); 2798c2ecf20Sopenharmony_ci prandom_warmup(&state); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci if (test1[i].result != prandom_u32_state(&state)) 2828c2ecf20Sopenharmony_ci error = true; 2838c2ecf20Sopenharmony_ci } 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci if (error) 2868c2ecf20Sopenharmony_ci pr_warn("prandom: seed boundary self test failed\n"); 2878c2ecf20Sopenharmony_ci else 2888c2ecf20Sopenharmony_ci pr_info("prandom: seed boundary self test passed\n"); 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(test2); i++) { 2918c2ecf20Sopenharmony_ci struct rnd_state state; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci prandom_seed_early(&state, test2[i].seed, false); 2948c2ecf20Sopenharmony_ci prandom_warmup(&state); 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci for (j = 0; j < test2[i].iteration - 1; j++) 2978c2ecf20Sopenharmony_ci prandom_u32_state(&state); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci if (test2[i].result != prandom_u32_state(&state)) 3008c2ecf20Sopenharmony_ci errors++; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci runs++; 3038c2ecf20Sopenharmony_ci cond_resched(); 3048c2ecf20Sopenharmony_ci } 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci if (errors) 3078c2ecf20Sopenharmony_ci pr_warn("prandom: %d/%d self tests failed\n", errors, runs); 3088c2ecf20Sopenharmony_ci else 3098c2ecf20Sopenharmony_ci pr_info("prandom: %d self tests passed\n", runs); 3108c2ecf20Sopenharmony_ci return 0; 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_cicore_initcall(prandom_state_selftest); 3138c2ecf20Sopenharmony_ci#endif 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci/* 3168c2ecf20Sopenharmony_ci * The prandom_u32() implementation is now completely separate from the 3178c2ecf20Sopenharmony_ci * prandom_state() functions, which are retained (for now) for compatibility. 3188c2ecf20Sopenharmony_ci * 3198c2ecf20Sopenharmony_ci * Because of (ab)use in the networking code for choosing random TCP/UDP port 3208c2ecf20Sopenharmony_ci * numbers, which open DoS possibilities if guessable, we want something 3218c2ecf20Sopenharmony_ci * stronger than a standard PRNG. But the performance requirements of 3228c2ecf20Sopenharmony_ci * the network code do not allow robust crypto for this application. 3238c2ecf20Sopenharmony_ci * 3248c2ecf20Sopenharmony_ci * So this is a homebrew Junior Spaceman implementation, based on the 3258c2ecf20Sopenharmony_ci * lowest-latency trustworthy crypto primitive available, SipHash. 3268c2ecf20Sopenharmony_ci * (The authors of SipHash have not been consulted about this abuse of 3278c2ecf20Sopenharmony_ci * their work.) 3288c2ecf20Sopenharmony_ci * 3298c2ecf20Sopenharmony_ci * Standard SipHash-2-4 uses 2n+4 rounds to hash n words of input to 3308c2ecf20Sopenharmony_ci * one word of output. This abbreviated version uses 2 rounds per word 3318c2ecf20Sopenharmony_ci * of output. 3328c2ecf20Sopenharmony_ci */ 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_cistruct siprand_state { 3358c2ecf20Sopenharmony_ci unsigned long v0; 3368c2ecf20Sopenharmony_ci unsigned long v1; 3378c2ecf20Sopenharmony_ci unsigned long v2; 3388c2ecf20Sopenharmony_ci unsigned long v3; 3398c2ecf20Sopenharmony_ci}; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_cistatic DEFINE_PER_CPU(struct siprand_state, net_rand_state) __latent_entropy; 3428c2ecf20Sopenharmony_ciDEFINE_PER_CPU(unsigned long, net_rand_noise); 3438c2ecf20Sopenharmony_ciEXPORT_PER_CPU_SYMBOL(net_rand_noise); 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci/* 3468c2ecf20Sopenharmony_ci * This is the core CPRNG function. As "pseudorandom", this is not used 3478c2ecf20Sopenharmony_ci * for truly valuable things, just intended to be a PITA to guess. 3488c2ecf20Sopenharmony_ci * For maximum speed, we do just two SipHash rounds per word. This is 3498c2ecf20Sopenharmony_ci * the same rate as 4 rounds per 64 bits that SipHash normally uses, 3508c2ecf20Sopenharmony_ci * so hopefully it's reasonably secure. 3518c2ecf20Sopenharmony_ci * 3528c2ecf20Sopenharmony_ci * There are two changes from the official SipHash finalization: 3538c2ecf20Sopenharmony_ci * - We omit some constants XORed with v2 in the SipHash spec as irrelevant; 3548c2ecf20Sopenharmony_ci * they are there only to make the output rounds distinct from the input 3558c2ecf20Sopenharmony_ci * rounds, and this application has no input rounds. 3568c2ecf20Sopenharmony_ci * - Rather than returning v0^v1^v2^v3, return v1+v3. 3578c2ecf20Sopenharmony_ci * If you look at the SipHash round, the last operation on v3 is 3588c2ecf20Sopenharmony_ci * "v3 ^= v0", so "v0 ^ v3" just undoes that, a waste of time. 3598c2ecf20Sopenharmony_ci * Likewise "v1 ^= v2". (The rotate of v2 makes a difference, but 3608c2ecf20Sopenharmony_ci * it still cancels out half of the bits in v2 for no benefit.) 3618c2ecf20Sopenharmony_ci * Second, since the last combining operation was xor, continue the 3628c2ecf20Sopenharmony_ci * pattern of alternating xor/add for a tiny bit of extra non-linearity. 3638c2ecf20Sopenharmony_ci */ 3648c2ecf20Sopenharmony_cistatic inline u32 siprand_u32(struct siprand_state *s) 3658c2ecf20Sopenharmony_ci{ 3668c2ecf20Sopenharmony_ci unsigned long v0 = s->v0, v1 = s->v1, v2 = s->v2, v3 = s->v3; 3678c2ecf20Sopenharmony_ci unsigned long n = raw_cpu_read(net_rand_noise); 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci v3 ^= n; 3708c2ecf20Sopenharmony_ci PRND_SIPROUND(v0, v1, v2, v3); 3718c2ecf20Sopenharmony_ci PRND_SIPROUND(v0, v1, v2, v3); 3728c2ecf20Sopenharmony_ci v0 ^= n; 3738c2ecf20Sopenharmony_ci s->v0 = v0; s->v1 = v1; s->v2 = v2; s->v3 = v3; 3748c2ecf20Sopenharmony_ci return v1 + v3; 3758c2ecf20Sopenharmony_ci} 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci/** 3798c2ecf20Sopenharmony_ci * prandom_u32 - pseudo random number generator 3808c2ecf20Sopenharmony_ci * 3818c2ecf20Sopenharmony_ci * A 32 bit pseudo-random number is generated using a fast 3828c2ecf20Sopenharmony_ci * algorithm suitable for simulation. This algorithm is NOT 3838c2ecf20Sopenharmony_ci * considered safe for cryptographic use. 3848c2ecf20Sopenharmony_ci */ 3858c2ecf20Sopenharmony_ciu32 prandom_u32(void) 3868c2ecf20Sopenharmony_ci{ 3878c2ecf20Sopenharmony_ci struct siprand_state *state = get_cpu_ptr(&net_rand_state); 3888c2ecf20Sopenharmony_ci u32 res = siprand_u32(state); 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci put_cpu_ptr(&net_rand_state); 3918c2ecf20Sopenharmony_ci return res; 3928c2ecf20Sopenharmony_ci} 3938c2ecf20Sopenharmony_ciEXPORT_SYMBOL(prandom_u32); 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci/** 3968c2ecf20Sopenharmony_ci * prandom_bytes - get the requested number of pseudo-random bytes 3978c2ecf20Sopenharmony_ci * @buf: where to copy the pseudo-random bytes to 3988c2ecf20Sopenharmony_ci * @bytes: the requested number of bytes 3998c2ecf20Sopenharmony_ci */ 4008c2ecf20Sopenharmony_civoid prandom_bytes(void *buf, size_t bytes) 4018c2ecf20Sopenharmony_ci{ 4028c2ecf20Sopenharmony_ci struct siprand_state *state = get_cpu_ptr(&net_rand_state); 4038c2ecf20Sopenharmony_ci u8 *ptr = buf; 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci while (bytes >= sizeof(u32)) { 4068c2ecf20Sopenharmony_ci put_unaligned(siprand_u32(state), (u32 *)ptr); 4078c2ecf20Sopenharmony_ci ptr += sizeof(u32); 4088c2ecf20Sopenharmony_ci bytes -= sizeof(u32); 4098c2ecf20Sopenharmony_ci } 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci if (bytes > 0) { 4128c2ecf20Sopenharmony_ci u32 rem = siprand_u32(state); 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci do { 4158c2ecf20Sopenharmony_ci *ptr++ = (u8)rem; 4168c2ecf20Sopenharmony_ci rem >>= BITS_PER_BYTE; 4178c2ecf20Sopenharmony_ci } while (--bytes > 0); 4188c2ecf20Sopenharmony_ci } 4198c2ecf20Sopenharmony_ci put_cpu_ptr(&net_rand_state); 4208c2ecf20Sopenharmony_ci} 4218c2ecf20Sopenharmony_ciEXPORT_SYMBOL(prandom_bytes); 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci/** 4248c2ecf20Sopenharmony_ci * prandom_seed - add entropy to pseudo random number generator 4258c2ecf20Sopenharmony_ci * @entropy: entropy value 4268c2ecf20Sopenharmony_ci * 4278c2ecf20Sopenharmony_ci * Add some additional seed material to the prandom pool. 4288c2ecf20Sopenharmony_ci * The "entropy" is actually our IP address (the only caller is 4298c2ecf20Sopenharmony_ci * the network code), not for unpredictability, but to ensure that 4308c2ecf20Sopenharmony_ci * different machines are initialized differently. 4318c2ecf20Sopenharmony_ci */ 4328c2ecf20Sopenharmony_civoid prandom_seed(u32 entropy) 4338c2ecf20Sopenharmony_ci{ 4348c2ecf20Sopenharmony_ci int i; 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci add_device_randomness(&entropy, sizeof(entropy)); 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci for_each_possible_cpu(i) { 4398c2ecf20Sopenharmony_ci struct siprand_state *state = per_cpu_ptr(&net_rand_state, i); 4408c2ecf20Sopenharmony_ci unsigned long v0 = state->v0, v1 = state->v1; 4418c2ecf20Sopenharmony_ci unsigned long v2 = state->v2, v3 = state->v3; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci do { 4448c2ecf20Sopenharmony_ci v3 ^= entropy; 4458c2ecf20Sopenharmony_ci PRND_SIPROUND(v0, v1, v2, v3); 4468c2ecf20Sopenharmony_ci PRND_SIPROUND(v0, v1, v2, v3); 4478c2ecf20Sopenharmony_ci v0 ^= entropy; 4488c2ecf20Sopenharmony_ci } while (unlikely(!v0 || !v1 || !v2 || !v3)); 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci WRITE_ONCE(state->v0, v0); 4518c2ecf20Sopenharmony_ci WRITE_ONCE(state->v1, v1); 4528c2ecf20Sopenharmony_ci WRITE_ONCE(state->v2, v2); 4538c2ecf20Sopenharmony_ci WRITE_ONCE(state->v3, v3); 4548c2ecf20Sopenharmony_ci } 4558c2ecf20Sopenharmony_ci} 4568c2ecf20Sopenharmony_ciEXPORT_SYMBOL(prandom_seed); 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_ci/* 4598c2ecf20Sopenharmony_ci * Generate some initially weak seeding values to allow 4608c2ecf20Sopenharmony_ci * the prandom_u32() engine to be started. 4618c2ecf20Sopenharmony_ci */ 4628c2ecf20Sopenharmony_cistatic int __init prandom_init_early(void) 4638c2ecf20Sopenharmony_ci{ 4648c2ecf20Sopenharmony_ci int i; 4658c2ecf20Sopenharmony_ci unsigned long v0, v1, v2, v3; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci if (!arch_get_random_long(&v0)) 4688c2ecf20Sopenharmony_ci v0 = jiffies; 4698c2ecf20Sopenharmony_ci if (!arch_get_random_long(&v1)) 4708c2ecf20Sopenharmony_ci v1 = random_get_entropy(); 4718c2ecf20Sopenharmony_ci v2 = v0 ^ PRND_K0; 4728c2ecf20Sopenharmony_ci v3 = v1 ^ PRND_K1; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci for_each_possible_cpu(i) { 4758c2ecf20Sopenharmony_ci struct siprand_state *state; 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci v3 ^= i; 4788c2ecf20Sopenharmony_ci PRND_SIPROUND(v0, v1, v2, v3); 4798c2ecf20Sopenharmony_ci PRND_SIPROUND(v0, v1, v2, v3); 4808c2ecf20Sopenharmony_ci v0 ^= i; 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci state = per_cpu_ptr(&net_rand_state, i); 4838c2ecf20Sopenharmony_ci state->v0 = v0; state->v1 = v1; 4848c2ecf20Sopenharmony_ci state->v2 = v2; state->v3 = v3; 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci return 0; 4888c2ecf20Sopenharmony_ci} 4898c2ecf20Sopenharmony_cicore_initcall(prandom_init_early); 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci/* Stronger reseeding when available, and periodically thereafter. */ 4938c2ecf20Sopenharmony_cistatic void prandom_reseed(struct timer_list *unused); 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_cistatic DEFINE_TIMER(seed_timer, prandom_reseed); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_cistatic void prandom_reseed(struct timer_list *unused) 4988c2ecf20Sopenharmony_ci{ 4998c2ecf20Sopenharmony_ci unsigned long expires; 5008c2ecf20Sopenharmony_ci int i; 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci /* 5038c2ecf20Sopenharmony_ci * Reinitialize each CPU's PRNG with 128 bits of key. 5048c2ecf20Sopenharmony_ci * No locking on the CPUs, but then somewhat random results are, 5058c2ecf20Sopenharmony_ci * well, expected. 5068c2ecf20Sopenharmony_ci */ 5078c2ecf20Sopenharmony_ci for_each_possible_cpu(i) { 5088c2ecf20Sopenharmony_ci struct siprand_state *state; 5098c2ecf20Sopenharmony_ci unsigned long v0 = get_random_long(), v2 = v0 ^ PRND_K0; 5108c2ecf20Sopenharmony_ci unsigned long v1 = get_random_long(), v3 = v1 ^ PRND_K1; 5118c2ecf20Sopenharmony_ci#if BITS_PER_LONG == 32 5128c2ecf20Sopenharmony_ci int j; 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci /* 5158c2ecf20Sopenharmony_ci * On 32-bit machines, hash in two extra words to 5168c2ecf20Sopenharmony_ci * approximate 128-bit key length. Not that the hash 5178c2ecf20Sopenharmony_ci * has that much security, but this prevents a trivial 5188c2ecf20Sopenharmony_ci * 64-bit brute force. 5198c2ecf20Sopenharmony_ci */ 5208c2ecf20Sopenharmony_ci for (j = 0; j < 2; j++) { 5218c2ecf20Sopenharmony_ci unsigned long m = get_random_long(); 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci v3 ^= m; 5248c2ecf20Sopenharmony_ci PRND_SIPROUND(v0, v1, v2, v3); 5258c2ecf20Sopenharmony_ci PRND_SIPROUND(v0, v1, v2, v3); 5268c2ecf20Sopenharmony_ci v0 ^= m; 5278c2ecf20Sopenharmony_ci } 5288c2ecf20Sopenharmony_ci#endif 5298c2ecf20Sopenharmony_ci /* 5308c2ecf20Sopenharmony_ci * Probably impossible in practice, but there is a 5318c2ecf20Sopenharmony_ci * theoretical risk that a race between this reseeding 5328c2ecf20Sopenharmony_ci * and the target CPU writing its state back could 5338c2ecf20Sopenharmony_ci * create the all-zero SipHash fixed point. 5348c2ecf20Sopenharmony_ci * 5358c2ecf20Sopenharmony_ci * To ensure that never happens, ensure the state 5368c2ecf20Sopenharmony_ci * we write contains no zero words. 5378c2ecf20Sopenharmony_ci */ 5388c2ecf20Sopenharmony_ci state = per_cpu_ptr(&net_rand_state, i); 5398c2ecf20Sopenharmony_ci WRITE_ONCE(state->v0, v0 ? v0 : -1ul); 5408c2ecf20Sopenharmony_ci WRITE_ONCE(state->v1, v1 ? v1 : -1ul); 5418c2ecf20Sopenharmony_ci WRITE_ONCE(state->v2, v2 ? v2 : -1ul); 5428c2ecf20Sopenharmony_ci WRITE_ONCE(state->v3, v3 ? v3 : -1ul); 5438c2ecf20Sopenharmony_ci } 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci /* reseed every ~60 seconds, in [40 .. 80) interval with slack */ 5468c2ecf20Sopenharmony_ci expires = round_jiffies(jiffies + 40 * HZ + prandom_u32_max(40 * HZ)); 5478c2ecf20Sopenharmony_ci mod_timer(&seed_timer, expires); 5488c2ecf20Sopenharmony_ci} 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci/* 5518c2ecf20Sopenharmony_ci * The random ready callback can be called from almost any interrupt. 5528c2ecf20Sopenharmony_ci * To avoid worrying about whether it's safe to delay that interrupt 5538c2ecf20Sopenharmony_ci * long enough to seed all CPUs, just schedule an immediate timer event. 5548c2ecf20Sopenharmony_ci */ 5558c2ecf20Sopenharmony_cistatic int prandom_timer_start(struct notifier_block *nb, 5568c2ecf20Sopenharmony_ci unsigned long action, void *data) 5578c2ecf20Sopenharmony_ci{ 5588c2ecf20Sopenharmony_ci mod_timer(&seed_timer, jiffies); 5598c2ecf20Sopenharmony_ci return 0; 5608c2ecf20Sopenharmony_ci} 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci#ifdef CONFIG_RANDOM32_SELFTEST 5638c2ecf20Sopenharmony_ci/* Principle: True 32-bit random numbers will all have 16 differing bits on 5648c2ecf20Sopenharmony_ci * average. For each 32-bit number, there are 601M numbers differing by 16 5658c2ecf20Sopenharmony_ci * bits, and 89% of the numbers differ by at least 12 bits. Note that more 5668c2ecf20Sopenharmony_ci * than 16 differing bits also implies a correlation with inverted bits. Thus 5678c2ecf20Sopenharmony_ci * we take 1024 random numbers and compare each of them to the other ones, 5688c2ecf20Sopenharmony_ci * counting the deviation of correlated bits to 16. Constants report 32, 5698c2ecf20Sopenharmony_ci * counters 32-log2(TEST_SIZE), and pure randoms, around 6 or lower. With the 5708c2ecf20Sopenharmony_ci * u32 total, TEST_SIZE may be as large as 4096 samples. 5718c2ecf20Sopenharmony_ci */ 5728c2ecf20Sopenharmony_ci#define TEST_SIZE 1024 5738c2ecf20Sopenharmony_cistatic int __init prandom32_state_selftest(void) 5748c2ecf20Sopenharmony_ci{ 5758c2ecf20Sopenharmony_ci unsigned int x, y, bits, samples; 5768c2ecf20Sopenharmony_ci u32 xor, flip; 5778c2ecf20Sopenharmony_ci u32 total; 5788c2ecf20Sopenharmony_ci u32 *data; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci data = kmalloc(sizeof(*data) * TEST_SIZE, GFP_KERNEL); 5818c2ecf20Sopenharmony_ci if (!data) 5828c2ecf20Sopenharmony_ci return 0; 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci for (samples = 0; samples < TEST_SIZE; samples++) 5858c2ecf20Sopenharmony_ci data[samples] = prandom_u32(); 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci flip = total = 0; 5888c2ecf20Sopenharmony_ci for (x = 0; x < samples; x++) { 5898c2ecf20Sopenharmony_ci for (y = 0; y < samples; y++) { 5908c2ecf20Sopenharmony_ci if (x == y) 5918c2ecf20Sopenharmony_ci continue; 5928c2ecf20Sopenharmony_ci xor = data[x] ^ data[y]; 5938c2ecf20Sopenharmony_ci flip |= xor; 5948c2ecf20Sopenharmony_ci bits = hweight32(xor); 5958c2ecf20Sopenharmony_ci total += (bits - 16) * (bits - 16); 5968c2ecf20Sopenharmony_ci } 5978c2ecf20Sopenharmony_ci } 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci /* We'll return the average deviation as 2*sqrt(corr/samples), which 6008c2ecf20Sopenharmony_ci * is also sqrt(4*corr/samples) which provides a better resolution. 6018c2ecf20Sopenharmony_ci */ 6028c2ecf20Sopenharmony_ci bits = int_sqrt(total / (samples * (samples - 1)) * 4); 6038c2ecf20Sopenharmony_ci if (bits > 6) 6048c2ecf20Sopenharmony_ci pr_warn("prandom32: self test failed (at least %u bits" 6058c2ecf20Sopenharmony_ci " correlated, fixed_mask=%#x fixed_value=%#x\n", 6068c2ecf20Sopenharmony_ci bits, ~flip, data[0] & ~flip); 6078c2ecf20Sopenharmony_ci else 6088c2ecf20Sopenharmony_ci pr_info("prandom32: self test passed (less than %u bits" 6098c2ecf20Sopenharmony_ci " correlated)\n", 6108c2ecf20Sopenharmony_ci bits+1); 6118c2ecf20Sopenharmony_ci kfree(data); 6128c2ecf20Sopenharmony_ci return 0; 6138c2ecf20Sopenharmony_ci} 6148c2ecf20Sopenharmony_cicore_initcall(prandom32_state_selftest); 6158c2ecf20Sopenharmony_ci#endif /* CONFIG_RANDOM32_SELFTEST */ 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci/* 6188c2ecf20Sopenharmony_ci * Start periodic full reseeding as soon as strong 6198c2ecf20Sopenharmony_ci * random numbers are available. 6208c2ecf20Sopenharmony_ci */ 6218c2ecf20Sopenharmony_cistatic int __init prandom_init_late(void) 6228c2ecf20Sopenharmony_ci{ 6238c2ecf20Sopenharmony_ci static struct notifier_block random_ready = { 6248c2ecf20Sopenharmony_ci .notifier_call = prandom_timer_start 6258c2ecf20Sopenharmony_ci }; 6268c2ecf20Sopenharmony_ci int ret = register_random_ready_notifier(&random_ready); 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci if (ret == -EALREADY) { 6298c2ecf20Sopenharmony_ci prandom_timer_start(&random_ready, 0, NULL); 6308c2ecf20Sopenharmony_ci ret = 0; 6318c2ecf20Sopenharmony_ci } 6328c2ecf20Sopenharmony_ci return ret; 6338c2ecf20Sopenharmony_ci} 6348c2ecf20Sopenharmony_cilate_initcall(prandom_init_late); 635