linux-imx/include/linux/random.h
Daniel Borkmann 12516ee181 random32: fix off-by-one in seeding requirement
[ Upstream commit 51c37a70aaa3f95773af560e6db3073520513912 ]

For properly initialising the Tausworthe generator [1], we have
a strict seeding requirement, that is, s1 > 1, s2 > 7, s3 > 15.

Commit 697f8d0348 ("random32: seeding improvement") introduced
a __seed() function that imposes boundary checks proposed by the
errata paper [2] to properly ensure above conditions.

However, we're off by one, as the function is implemented as:
"return (x < m) ? x + m : x;", and called with __seed(X, 1),
__seed(X, 7), __seed(X, 15). Thus, an unwanted seed of 1, 7, 15
would be possible, whereas the lower boundary should actually
be of at least 2, 8, 16, just as GSL does. Fix this, as otherwise
an initialization with an unwanted seed could have the effect
that Tausworthe's PRNG properties cannot not be ensured.

Note that this PRNG is *not* used for cryptography in the kernel.

 [1] http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
 [2] http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps

Joint work with Hannes Frederic Sowa.

Fixes: 697f8d0348a6 ("random32: seeding improvement")
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Florian Weimer <fweimer@redhat.com>
Cc: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2014-01-03 04:33:32 +00:00

113 lines
2.5 KiB
C

/*
* include/linux/random.h
*
* Include file for the random number generator.
*/
#ifndef _LINUX_RANDOM_H
#define _LINUX_RANDOM_H
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/irqnr.h>
/* ioctl()'s for the random number generator */
/* Get the entropy count. */
#define RNDGETENTCNT _IOR( 'R', 0x00, int )
/* Add to (or subtract from) the entropy count. (Superuser only.) */
#define RNDADDTOENTCNT _IOW( 'R', 0x01, int )
/* Get the contents of the entropy pool. (Superuser only.) */
#define RNDGETPOOL _IOR( 'R', 0x02, int [2] )
/*
* Write bytes into the entropy pool and add to the entropy count.
* (Superuser only.)
*/
#define RNDADDENTROPY _IOW( 'R', 0x03, int [2] )
/* Clear entropy count to 0. (Superuser only.) */
#define RNDZAPENTCNT _IO( 'R', 0x04 )
/* Clear the entropy pool and associated counters. (Superuser only.) */
#define RNDCLEARPOOL _IO( 'R', 0x06 )
struct rand_pool_info {
int entropy_count;
int buf_size;
__u32 buf[0];
};
struct rnd_state {
__u32 s1, s2, s3;
};
/* Exported functions */
#ifdef __KERNEL__
extern void rand_initialize_irq(int irq);
extern void add_device_randomness(const void *, unsigned int);
extern void add_input_randomness(unsigned int type, unsigned int code,
unsigned int value);
extern void add_interrupt_randomness(int irq, int irq_flags);
extern void get_random_bytes(void *buf, int nbytes);
extern void get_random_bytes_arch(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]);
extern int random_int_secret_init(void);
#ifndef MODULE
extern const struct file_operations random_fops, urandom_fops;
#endif
unsigned int get_random_int(void);
unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len);
u32 random32(void);
void srandom32(u32 seed);
u32 prandom32(struct rnd_state *);
/*
* Handle minimum values for seeds
*/
static inline u32 __seed(u32 x, u32 m)
{
return (x < m) ? x + m : x;
}
/**
* prandom32_seed - set seed for prandom32().
* @state: pointer to state structure to receive the seed.
* @seed: arbitrary 64-bit value to use as a seed.
*/
static inline void prandom32_seed(struct rnd_state *state, u64 seed)
{
u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
state->s1 = __seed(i, 2);
state->s2 = __seed(i, 8);
state->s3 = __seed(i, 16);
}
#ifdef CONFIG_ARCH_RANDOM
# include <asm/archrandom.h>
#else
static inline int arch_get_random_long(unsigned long *v)
{
return 0;
}
static inline int arch_get_random_int(unsigned int *v)
{
return 0;
}
#endif
#endif /* __KERNEL___ */
#endif /* _LINUX_RANDOM_H */