LCOV - code coverage report
Current view: top level - include/linux - prandom.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 6 9 66.7 %
Date: 2021-04-22 12:43:58 Functions: 0 0 -

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : /*
       3             :  * include/linux/prandom.h
       4             :  *
       5             :  * Include file for the fast pseudo-random 32-bit
       6             :  * generation.
       7             :  */
       8             : #ifndef _LINUX_PRANDOM_H
       9             : #define _LINUX_PRANDOM_H
      10             : 
      11             : #include <linux/types.h>
      12             : #include <linux/percpu.h>
      13             : 
      14             : u32 prandom_u32(void);
      15             : void prandom_bytes(void *buf, size_t nbytes);
      16             : void prandom_seed(u32 seed);
      17             : void prandom_reseed_late(void);
      18             : 
      19             : DECLARE_PER_CPU(unsigned long, net_rand_noise);
      20             : 
      21             : #define PRANDOM_ADD_NOISE(a, b, c, d) \
      22             :         prandom_u32_add_noise((unsigned long)(a), (unsigned long)(b), \
      23             :                               (unsigned long)(c), (unsigned long)(d))
      24             : 
      25             : #if BITS_PER_LONG == 64
      26             : /*
      27             :  * The core SipHash round function.  Each line can be executed in
      28             :  * parallel given enough CPU resources.
      29             :  */
      30             : #define PRND_SIPROUND(v0, v1, v2, v3) ( \
      31             :         v0 += v1, v1 = rol64(v1, 13),  v2 += v3, v3 = rol64(v3, 16), \
      32             :         v1 ^= v0, v0 = rol64(v0, 32),  v3 ^= v2,                     \
      33             :         v0 += v3, v3 = rol64(v3, 21),  v2 += v1, v1 = rol64(v1, 17), \
      34             :         v3 ^= v0,                      v1 ^= v2, v2 = rol64(v2, 32)  \
      35             : )
      36             : 
      37             : #define PRND_K0 (0x736f6d6570736575 ^ 0x6c7967656e657261)
      38             : #define PRND_K1 (0x646f72616e646f6d ^ 0x7465646279746573)
      39             : 
      40             : #elif BITS_PER_LONG == 32
      41             : /*
      42             :  * On 32-bit machines, we use HSipHash, a reduced-width version of SipHash.
      43             :  * This is weaker, but 32-bit machines are not used for high-traffic
      44             :  * applications, so there is less output for an attacker to analyze.
      45             :  */
      46             : #define PRND_SIPROUND(v0, v1, v2, v3) ( \
      47             :         v0 += v1, v1 = rol32(v1,  5),  v2 += v3, v3 = rol32(v3,  8), \
      48             :         v1 ^= v0, v0 = rol32(v0, 16),  v3 ^= v2,                     \
      49             :         v0 += v3, v3 = rol32(v3,  7),  v2 += v1, v1 = rol32(v1, 13), \
      50             :         v3 ^= v0,                      v1 ^= v2, v2 = rol32(v2, 16)  \
      51             : )
      52             : #define PRND_K0 0x6c796765
      53             : #define PRND_K1 0x74656462
      54             : 
      55             : #else
      56             : #error Unsupported BITS_PER_LONG
      57             : #endif
      58             : 
      59       28482 : static inline void prandom_u32_add_noise(unsigned long a, unsigned long b,
      60             :                                          unsigned long c, unsigned long d)
      61             : {
      62             :         /*
      63             :          * This is not used cryptographically; it's just
      64             :          * a convenient 4-word hash function. (3 xor, 2 add, 2 rol)
      65             :          */
      66       28482 :         a ^= raw_cpu_read(net_rand_noise);
      67       28482 :         PRND_SIPROUND(a, b, c, d);
      68       28482 :         raw_cpu_write(net_rand_noise, d);
      69           0 : }
      70             : 
      71             : struct rnd_state {
      72             :         __u32 s1, s2, s3, s4;
      73             : };
      74             : 
      75             : u32 prandom_u32_state(struct rnd_state *state);
      76             : void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes);
      77             : void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state);
      78             : 
      79             : #define prandom_init_once(pcpu_state)                   \
      80             :         DO_ONCE(prandom_seed_full_state, (pcpu_state))
      81             : 
      82             : /**
      83             :  * prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro)
      84             :  * @ep_ro: right open interval endpoint
      85             :  *
      86             :  * Returns a pseudo-random number that is in interval [0, ep_ro). Note
      87             :  * that the result depends on PRNG being well distributed in [0, ~0U]
      88             :  * u32 space. Here we use maximally equidistributed combined Tausworthe
      89             :  * generator, that is, prandom_u32(). This is useful when requesting a
      90             :  * random index of an array containing ep_ro elements, for example.
      91             :  *
      92             :  * Returns: pseudo-random number in interval [0, ep_ro)
      93             :  */
      94          29 : static inline u32 prandom_u32_max(u32 ep_ro)
      95             : {
      96          29 :         return (u32)(((u64) prandom_u32() * ep_ro) >> 32);
      97             : }
      98             : 
      99             : /*
     100             :  * Handle minimum values for seeds
     101             :  */
     102           0 : static inline u32 __seed(u32 x, u32 m)
     103             : {
     104           0 :         return (x < m) ? x + m : x;
     105             : }
     106             : 
     107             : /**
     108             :  * prandom_seed_state - set seed for prandom_u32_state().
     109             :  * @state: pointer to state structure to receive the seed.
     110             :  * @seed: arbitrary 64-bit value to use as a seed.
     111             :  */
     112             : static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
     113             : {
     114             :         u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
     115             : 
     116             :         state->s1 = __seed(i,   2U);
     117             :         state->s2 = __seed(i,   8U);
     118             :         state->s3 = __seed(i,  16U);
     119             :         state->s4 = __seed(i, 128U);
     120             :         PRANDOM_ADD_NOISE(state, i, 0, 0);
     121             : }
     122             : 
     123             : /* Pseudo random number generator from numerical recipes. */
     124             : static inline u32 next_pseudo_random32(u32 seed)
     125             : {
     126             :         return seed * 1664525 + 1013904223;
     127             : }
     128             : 
     129             : #endif

Generated by: LCOV version 1.14