LCOV - code coverage report
Current view: top level - lib - random32.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 31 90 34.4 %
Date: 2014-02-18 Functions: 5 13 38.5 %
Branches: 2 20 10.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :   This is a maximally equidistributed combined Tausworthe generator
       3                 :            :   based on code from GNU Scientific Library 1.5 (30 Jun 2004)
       4                 :            : 
       5                 :            :   lfsr113 version:
       6                 :            : 
       7                 :            :    x_n = (s1_n ^ s2_n ^ s3_n ^ s4_n)
       8                 :            : 
       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))
      13                 :            : 
      14                 :            :    The period of this generator is about 2^113 (see erratum paper).
      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
      19                 :            :    ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps
      20                 :            : 
      21                 :            :    There is an erratum in the paper "Tables of Maximally
      22                 :            :    Equidistributed Combined LFSR Generators", Mathematics of
      23                 :            :    Computation, 68, 225 (1999), 261--269:
      24                 :            :    http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps
      25                 :            : 
      26                 :            :         ... the k_j most significant bits of z_j must be non-
      27                 :            :         zero, for each j. (Note: this restriction also applies to the
      28                 :            :         computer code given in [4], but was mistakenly not mentioned in
      29                 :            :         that paper.)
      30                 :            : 
      31                 :            :    This affects the seeding procedure by imposing the requirement
      32                 :            :    s1 > 1, s2 > 7, s3 > 15, s4 > 127.
      33                 :            : 
      34                 :            : */
      35                 :            : 
      36                 :            : #include <linux/types.h>
      37                 :            : #include <linux/percpu.h>
      38                 :            : #include <linux/export.h>
      39                 :            : #include <linux/jiffies.h>
      40                 :            : #include <linux/random.h>
      41                 :            : #include <linux/sched.h>
      42                 :            : 
      43                 :            : #ifdef CONFIG_RANDOM32_SELFTEST
      44                 :            : static void __init prandom_state_selftest(void);
      45                 :            : #endif
      46                 :            : 
      47                 :            : static DEFINE_PER_CPU(struct rnd_state, net_rand_state);
      48                 :            : 
      49                 :            : /**
      50                 :            :  *      prandom_u32_state - seeded pseudo-random number generator.
      51                 :            :  *      @state: pointer to state structure holding seeded state.
      52                 :            :  *
      53                 :            :  *      This is used for pseudo-randomness with no outside seeding.
      54                 :            :  *      For more random results, use prandom_u32().
      55                 :            :  */
      56                 :          0 : u32 prandom_u32_state(struct rnd_state *state)
      57                 :            : {
      58                 :            : #define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
      59                 :            : 
      60                 :      73810 :         state->s1 = TAUSWORTHE(state->s1,  6U, 13U, 4294967294U, 18U);
      61                 :      73810 :         state->s2 = TAUSWORTHE(state->s2,  2U, 27U, 4294967288U,  2U);
      62                 :      73810 :         state->s3 = TAUSWORTHE(state->s3, 13U, 21U, 4294967280U,  7U);
      63                 :      73810 :         state->s4 = TAUSWORTHE(state->s4,  3U, 12U, 4294967168U, 13U);
      64                 :            : 
      65                 :      73810 :         return (state->s1 ^ state->s2 ^ state->s3 ^ state->s4);
      66                 :            : }
      67                 :            : EXPORT_SYMBOL(prandom_u32_state);
      68                 :            : 
      69                 :            : /**
      70                 :            :  *      prandom_u32 - pseudo random number generator
      71                 :            :  *
      72                 :            :  *      A 32 bit pseudo-random number is generated using a fast
      73                 :            :  *      algorithm suitable for simulation. This algorithm is NOT
      74                 :            :  *      considered safe for cryptographic use.
      75                 :            :  */
      76                 :          0 : u32 prandom_u32(void)
      77                 :            : {
      78                 :            :         unsigned long r;
      79                 :       1510 :         struct rnd_state *state = &get_cpu_var(net_rand_state);
      80                 :       1510 :         r = prandom_u32_state(state);
      81                 :       1510 :         put_cpu_var(state);
      82                 :         64 :         return r;
      83                 :            : }
      84                 :            : EXPORT_SYMBOL(prandom_u32);
      85                 :            : 
      86                 :            : /*
      87                 :            :  *      prandom_bytes_state - get the requested number of pseudo-random bytes
      88                 :            :  *
      89                 :            :  *      @state: pointer to state structure holding seeded state.
      90                 :            :  *      @buf: where to copy the pseudo-random bytes to
      91                 :            :  *      @bytes: the requested number of bytes
      92                 :            :  *
      93                 :            :  *      This is used for pseudo-randomness with no outside seeding.
      94                 :            :  *      For more random results, use prandom_bytes().
      95                 :            :  */
      96                 :          0 : void prandom_bytes_state(struct rnd_state *state, void *buf, int bytes)
      97                 :            : {
      98                 :            :         unsigned char *p = buf;
      99                 :            :         int i;
     100                 :            : 
     101         [ #  # ]:          0 :         for (i = 0; i < round_down(bytes, sizeof(u32)); i += sizeof(u32)) {
     102                 :          0 :                 u32 random = prandom_u32_state(state);
     103                 :            :                 int j;
     104                 :            : 
     105         [ #  # ]:          0 :                 for (j = 0; j < sizeof(u32); j++) {
     106                 :          0 :                         p[i + j] = random;
     107                 :          0 :                         random >>= BITS_PER_BYTE;
     108                 :            :                 }
     109                 :            :         }
     110         [ #  # ]:          0 :         if (i < bytes) {
     111                 :          0 :                 u32 random = prandom_u32_state(state);
     112                 :            : 
     113         [ #  # ]:          0 :                 for (; i < bytes; i++) {
     114                 :          0 :                         p[i] = random;
     115                 :          0 :                         random >>= BITS_PER_BYTE;
     116                 :            :                 }
     117                 :            :         }
     118                 :          0 : }
     119                 :            : EXPORT_SYMBOL(prandom_bytes_state);
     120                 :            : 
     121                 :            : /**
     122                 :            :  *      prandom_bytes - get the requested number of pseudo-random bytes
     123                 :            :  *      @buf: where to copy the pseudo-random bytes to
     124                 :            :  *      @bytes: the requested number of bytes
     125                 :            :  */
     126                 :          0 : void prandom_bytes(void *buf, int bytes)
     127                 :            : {
     128                 :          0 :         struct rnd_state *state = &get_cpu_var(net_rand_state);
     129                 :            : 
     130                 :          0 :         prandom_bytes_state(state, buf, bytes);
     131                 :          0 :         put_cpu_var(state);
     132                 :          0 : }
     133                 :            : EXPORT_SYMBOL(prandom_bytes);
     134                 :            : 
     135                 :          0 : static void prandom_warmup(struct rnd_state *state)
     136                 :            : {
     137                 :            :         /* Calling RNG ten times to satify recurrence condition */
     138                 :       7230 :         prandom_u32_state(state);
     139                 :       7230 :         prandom_u32_state(state);
     140                 :       7230 :         prandom_u32_state(state);
     141                 :       7230 :         prandom_u32_state(state);
     142                 :       7230 :         prandom_u32_state(state);
     143                 :       7230 :         prandom_u32_state(state);
     144                 :       7230 :         prandom_u32_state(state);
     145                 :       7230 :         prandom_u32_state(state);
     146                 :       7230 :         prandom_u32_state(state);
     147                 :       7230 :         prandom_u32_state(state);
     148                 :       7230 : }
     149                 :            : 
     150                 :          0 : static 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                 :          0 :         state->s1 = __seed(LCG(seed),        2U);
     162                 :          0 :         state->s2 = __seed(LCG(state->s1),   8U);
     163                 :          0 :         state->s3 = __seed(LCG(state->s2),  16U);
     164                 :          0 :         state->s4 = __seed(LCG(state->s3), 128U);
     165                 :          0 : }
     166                 :            : 
     167                 :            : /**
     168                 :            :  *      prandom_seed - add entropy to pseudo random number generator
     169                 :            :  *      @seed: seed value
     170                 :            :  *
     171                 :            :  *      Add some additional seeding to the prandom pool.
     172                 :            :  */
     173                 :          0 : void prandom_seed(u32 entropy)
     174                 :            : {
     175                 :            :         int i;
     176                 :            :         /*
     177                 :            :          * No locking on the CPUs, but then somewhat random results are, well,
     178                 :            :          * expected.
     179                 :            :          */
     180         [ +  + ]:      10122 :         for_each_possible_cpu (i) {
     181                 :       7230 :                 struct rnd_state *state = &per_cpu(net_rand_state, i);
     182                 :            : 
     183                 :      13014 :                 state->s1 = __seed(state->s1 ^ entropy, 2U);
     184                 :       7230 :                 prandom_warmup(state);
     185                 :            :         }
     186                 :       1446 : }
     187                 :            : EXPORT_SYMBOL(prandom_seed);
     188                 :            : 
     189                 :            : /*
     190                 :            :  *      Generate some initially weak seeding values to allow
     191                 :            :  *      to start the prandom_u32() engine.
     192                 :            :  */
     193                 :          0 : static int __init prandom_init(void)
     194                 :            : {
     195                 :            :         int i;
     196                 :            : 
     197                 :            : #ifdef CONFIG_RANDOM32_SELFTEST
     198                 :            :         prandom_state_selftest();
     199                 :            : #endif
     200                 :            : 
     201         [ #  # ]:          0 :         for_each_possible_cpu(i) {
     202                 :          0 :                 struct rnd_state *state = &per_cpu(net_rand_state,i);
     203                 :            : 
     204         [ #  # ]:          0 :                 prandom_seed_very_weak(state, (i + jiffies) ^ random_get_entropy());
     205                 :          0 :                 prandom_warmup(state);
     206                 :            :         }
     207                 :          0 :         return 0;
     208                 :            : }
     209                 :            : core_initcall(prandom_init);
     210                 :            : 
     211                 :            : static void __prandom_timer(unsigned long dontcare);
     212                 :            : static DEFINE_TIMER(seed_timer, __prandom_timer, 0, 0);
     213                 :            : 
     214                 :          0 : static void __prandom_timer(unsigned long dontcare)
     215                 :            : {
     216                 :            :         u32 entropy;
     217                 :            :         unsigned long expires;
     218                 :            : 
     219                 :       1446 :         get_random_bytes(&entropy, sizeof(entropy));
     220                 :       1446 :         prandom_seed(entropy);
     221                 :            : 
     222                 :            :         /* reseed every ~60 seconds, in [40 .. 80) interval with slack */
     223                 :       1446 :         expires = 40 + (prandom_u32() % 40);
     224                 :       1446 :         seed_timer.expires = jiffies + msecs_to_jiffies(expires * MSEC_PER_SEC);
     225                 :            : 
     226                 :       1446 :         add_timer(&seed_timer);
     227                 :       1446 : }
     228                 :            : 
     229                 :          0 : static void __init __prandom_start_seed_timer(void)
     230                 :            : {
     231                 :          0 :         set_timer_slack(&seed_timer, HZ);
     232                 :          0 :         seed_timer.expires = jiffies + msecs_to_jiffies(40 * MSEC_PER_SEC);
     233                 :          0 :         add_timer(&seed_timer);
     234                 :          0 : }
     235                 :            : 
     236                 :            : /*
     237                 :            :  *      Generate better values after random number generator
     238                 :            :  *      is fully initialized.
     239                 :            :  */
     240                 :          0 : static void __prandom_reseed(bool late)
     241                 :            : {
     242                 :            :         int i;
     243                 :            :         unsigned long flags;
     244                 :            :         static bool latch = false;
     245                 :            :         static DEFINE_SPINLOCK(lock);
     246                 :            : 
     247                 :            :         /* only allow initial seeding (late == false) once */
     248                 :          0 :         spin_lock_irqsave(&lock, flags);
     249 [ #  # ][ #  # ]:          0 :         if (latch && !late)
     250                 :            :                 goto out;
     251                 :          0 :         latch = true;
     252                 :            : 
     253         [ #  # ]:          0 :         for_each_possible_cpu(i) {
     254                 :          0 :                 struct rnd_state *state = &per_cpu(net_rand_state,i);
     255                 :            :                 u32 seeds[4];
     256                 :            : 
     257                 :          0 :                 get_random_bytes(&seeds, sizeof(seeds));
     258                 :          0 :                 state->s1 = __seed(seeds[0],   2U);
     259                 :          0 :                 state->s2 = __seed(seeds[1],   8U);
     260                 :          0 :                 state->s3 = __seed(seeds[2],  16U);
     261                 :          0 :                 state->s4 = __seed(seeds[3], 128U);
     262                 :            : 
     263                 :          0 :                 prandom_warmup(state);
     264                 :            :         }
     265                 :            : out:
     266                 :            :         spin_unlock_irqrestore(&lock, flags);
     267                 :          0 : }
     268                 :            : 
     269                 :          0 : void prandom_reseed_late(void)
     270                 :            : {
     271                 :          0 :         __prandom_reseed(true);
     272                 :          0 : }
     273                 :            : 
     274                 :          0 : static int __init prandom_reseed(void)
     275                 :            : {
     276                 :          0 :         __prandom_reseed(false);
     277                 :          0 :         __prandom_start_seed_timer();
     278                 :          0 :         return 0;
     279                 :            : }
     280                 :            : late_initcall(prandom_reseed);
     281                 :            : 
     282                 :            : #ifdef CONFIG_RANDOM32_SELFTEST
     283                 :            : static struct prandom_test1 {
     284                 :            :         u32 seed;
     285                 :            :         u32 result;
     286                 :            : } test1[] = {
     287                 :            :         { 1U, 3484351685U },
     288                 :            :         { 2U, 2623130059U },
     289                 :            :         { 3U, 3125133893U },
     290                 :            :         { 4U,  984847254U },
     291                 :            : };
     292                 :            : 
     293                 :            : static struct prandom_test2 {
     294                 :            :         u32 seed;
     295                 :            :         u32 iteration;
     296                 :            :         u32 result;
     297                 :            : } test2[] = {
     298                 :            :         /* Test cases against taus113 from GSL library. */
     299                 :            :         {  931557656U, 959U, 2975593782U },
     300                 :            :         { 1339693295U, 876U, 3887776532U },
     301                 :            :         { 1545556285U, 961U, 1615538833U },
     302                 :            :         {  601730776U, 723U, 1776162651U },
     303                 :            :         { 1027516047U, 687U,  511983079U },
     304                 :            :         {  416526298U, 700U,  916156552U },
     305                 :            :         { 1395522032U, 652U, 2222063676U },
     306                 :            :         {  366221443U, 617U, 2992857763U },
     307                 :            :         { 1539836965U, 714U, 3783265725U },
     308                 :            :         {  556206671U, 994U,  799626459U },
     309                 :            :         {  684907218U, 799U,  367789491U },
     310                 :            :         { 2121230701U, 931U, 2115467001U },
     311                 :            :         { 1668516451U, 644U, 3620590685U },
     312                 :            :         {  768046066U, 883U, 2034077390U },
     313                 :            :         { 1989159136U, 833U, 1195767305U },
     314                 :            :         {  536585145U, 996U, 3577259204U },
     315                 :            :         { 1008129373U, 642U, 1478080776U },
     316                 :            :         { 1740775604U, 939U, 1264980372U },
     317                 :            :         { 1967883163U, 508U,   10734624U },
     318                 :            :         { 1923019697U, 730U, 3821419629U },
     319                 :            :         {  442079932U, 560U, 3440032343U },
     320                 :            :         { 1961302714U, 845U,  841962572U },
     321                 :            :         { 2030205964U, 962U, 1325144227U },
     322                 :            :         { 1160407529U, 507U,  240940858U },
     323                 :            :         {  635482502U, 779U, 4200489746U },
     324                 :            :         { 1252788931U, 699U,  867195434U },
     325                 :            :         { 1961817131U, 719U,  668237657U },
     326                 :            :         { 1071468216U, 983U,  917876630U },
     327                 :            :         { 1281848367U, 932U, 1003100039U },
     328                 :            :         {  582537119U, 780U, 1127273778U },
     329                 :            :         { 1973672777U, 853U, 1071368872U },
     330                 :            :         { 1896756996U, 762U, 1127851055U },
     331                 :            :         {  847917054U, 500U, 1717499075U },
     332                 :            :         { 1240520510U, 951U, 2849576657U },
     333                 :            :         { 1685071682U, 567U, 1961810396U },
     334                 :            :         { 1516232129U, 557U,    3173877U },
     335                 :            :         { 1208118903U, 612U, 1613145022U },
     336                 :            :         { 1817269927U, 693U, 4279122573U },
     337                 :            :         { 1510091701U, 717U,  638191229U },
     338                 :            :         {  365916850U, 807U,  600424314U },
     339                 :            :         {  399324359U, 702U, 1803598116U },
     340                 :            :         { 1318480274U, 779U, 2074237022U },
     341                 :            :         {  697758115U, 840U, 1483639402U },
     342                 :            :         { 1696507773U, 840U,  577415447U },
     343                 :            :         { 2081979121U, 981U, 3041486449U },
     344                 :            :         {  955646687U, 742U, 3846494357U },
     345                 :            :         { 1250683506U, 749U,  836419859U },
     346                 :            :         {  595003102U, 534U,  366794109U },
     347                 :            :         {   47485338U, 558U, 3521120834U },
     348                 :            :         {  619433479U, 610U, 3991783875U },
     349                 :            :         {  704096520U, 518U, 4139493852U },
     350                 :            :         { 1712224984U, 606U, 2393312003U },
     351                 :            :         { 1318233152U, 922U, 3880361134U },
     352                 :            :         {  855572992U, 761U, 1472974787U },
     353                 :            :         {   64721421U, 703U,  683860550U },
     354                 :            :         {  678931758U, 840U,  380616043U },
     355                 :            :         {  692711973U, 778U, 1382361947U },
     356                 :            :         {  677703619U, 530U, 2826914161U },
     357                 :            :         {   92393223U, 586U, 1522128471U },
     358                 :            :         { 1222592920U, 743U, 3466726667U },
     359                 :            :         {  358288986U, 695U, 1091956998U },
     360                 :            :         { 1935056945U, 958U,  514864477U },
     361                 :            :         {  735675993U, 990U, 1294239989U },
     362                 :            :         { 1560089402U, 897U, 2238551287U },
     363                 :            :         {   70616361U, 829U,   22483098U },
     364                 :            :         {  368234700U, 731U, 2913875084U },
     365                 :            :         {   20221190U, 879U, 1564152970U },
     366                 :            :         {  539444654U, 682U, 1835141259U },
     367                 :            :         { 1314987297U, 840U, 1801114136U },
     368                 :            :         { 2019295544U, 645U, 3286438930U },
     369                 :            :         {  469023838U, 716U, 1637918202U },
     370                 :            :         { 1843754496U, 653U, 2562092152U },
     371                 :            :         {  400672036U, 809U, 4264212785U },
     372                 :            :         {  404722249U, 965U, 2704116999U },
     373                 :            :         {  600702209U, 758U,  584979986U },
     374                 :            :         {  519953954U, 667U, 2574436237U },
     375                 :            :         { 1658071126U, 694U, 2214569490U },
     376                 :            :         {  420480037U, 749U, 3430010866U },
     377                 :            :         {  690103647U, 969U, 3700758083U },
     378                 :            :         { 1029424799U, 937U, 3787746841U },
     379                 :            :         { 2012608669U, 506U, 3362628973U },
     380                 :            :         { 1535432887U, 998U,   42610943U },
     381                 :            :         { 1330635533U, 857U, 3040806504U },
     382                 :            :         { 1223800550U, 539U, 3954229517U },
     383                 :            :         { 1322411537U, 680U, 3223250324U },
     384                 :            :         { 1877847898U, 945U, 2915147143U },
     385                 :            :         { 1646356099U, 874U,  965988280U },
     386                 :            :         {  805687536U, 744U, 4032277920U },
     387                 :            :         { 1948093210U, 633U, 1346597684U },
     388                 :            :         {  392609744U, 783U, 1636083295U },
     389                 :            :         {  690241304U, 770U, 1201031298U },
     390                 :            :         { 1360302965U, 696U, 1665394461U },
     391                 :            :         { 1220090946U, 780U, 1316922812U },
     392                 :            :         {  447092251U, 500U, 3438743375U },
     393                 :            :         { 1613868791U, 592U,  828546883U },
     394                 :            :         {  523430951U, 548U, 2552392304U },
     395                 :            :         {  726692899U, 810U, 1656872867U },
     396                 :            :         { 1364340021U, 836U, 3710513486U },
     397                 :            :         { 1986257729U, 931U,  935013962U },
     398                 :            :         {  407983964U, 921U,  728767059U },
     399                 :            : };
     400                 :            : 
     401                 :            : static void __init prandom_state_selftest(void)
     402                 :            : {
     403                 :            :         int i, j, errors = 0, runs = 0;
     404                 :            :         bool error = false;
     405                 :            : 
     406                 :            :         for (i = 0; i < ARRAY_SIZE(test1); i++) {
     407                 :            :                 struct rnd_state state;
     408                 :            : 
     409                 :            :                 prandom_seed_very_weak(&state, test1[i].seed);
     410                 :            :                 prandom_warmup(&state);
     411                 :            : 
     412                 :            :                 if (test1[i].result != prandom_u32_state(&state))
     413                 :            :                         error = true;
     414                 :            :         }
     415                 :            : 
     416                 :            :         if (error)
     417                 :            :                 pr_warn("prandom: seed boundary self test failed\n");
     418                 :            :         else
     419                 :            :                 pr_info("prandom: seed boundary self test passed\n");
     420                 :            : 
     421                 :            :         for (i = 0; i < ARRAY_SIZE(test2); i++) {
     422                 :            :                 struct rnd_state state;
     423                 :            : 
     424                 :            :                 prandom_seed_very_weak(&state, test2[i].seed);
     425                 :            :                 prandom_warmup(&state);
     426                 :            : 
     427                 :            :                 for (j = 0; j < test2[i].iteration - 1; j++)
     428                 :            :                         prandom_u32_state(&state);
     429                 :            : 
     430                 :            :                 if (test2[i].result != prandom_u32_state(&state))
     431                 :            :                         errors++;
     432                 :            : 
     433                 :            :                 runs++;
     434                 :            :                 cond_resched();
     435                 :            :         }
     436                 :            : 
     437                 :            :         if (errors)
     438                 :            :                 pr_warn("prandom: %d/%d self tests failed\n", errors, runs);
     439                 :            :         else
     440                 :            :                 pr_info("prandom: %d self tests passed\n", runs);
     441                 :            : }
     442                 :            : #endif

Generated by: LCOV version 1.9