[OPW,kernel,RFC] drivers: char: Make random number generator infrastructure optional
diff mbox

Message ID 1414569535-17324-1-git-send-email-catalina.mocanu@gmail.com
State New, archived
Headers show

Commit Message

Catalina Mocanu Oct. 29, 2014, 7:58 a.m. UTC
This patch introduces a new expert config RANDOM to compile out
the entire random generator infrastructure in order to save space
on embedded devices. This new config makes /dev/random and /dev/urandom
optional.

If config RANDOM is set to n, then drivers/char/random.c and
lib/random32.c are compiled out and the function definitions from
include/kernel/random.h are replaced by no-ops.

Some functions declared in drivers/char/random.c (add_disk_randomness
and rand_initialize disk) are related to block devices and their
definition from include/linux/genhd.h was also replaced with no-ops
when CONFIG_RANDOM is n.

Also, syscall getrandom is made optional since it depends on the
random number generator infrastructure.

This patch is still work in progress and I have some questions:

*Should config HW_RANDOM depend on config RANDOM? or should HW_RANDOM
select config RANDOM when needed? There is a function in random.c,
add_hwgenerator_randomness, that is used to feed the random entropy pool
with randomness from hardware noise. Besides that, I am not sure how
these two (config HW_RANDOM and config RANDOM) are linked.

*From my investigation, it seems that config HW_RANDOM is selected by
drivers that use it (crypto or s390). Should this be the case for
RANDOM? Should I check all the code that calls functions defined in
include/linux/random.h, include/linux/genhd.h and select RANDOM for
those cases?
For modules that only give randomness input to the entropy pool by calling
functions like add_device_randomness, add_input_randomness etc, I think
there is no need to select CONFIG_RANDOM since these devices with work fine
with stub functions.
On the other hand, for devices/modules that require random return value to
function properly (such as cryptographic libs) I consider that RANDOM
should be automatically selected by them.

Any suggestions are welcomed.

Signed-off-by: Catalina Mocanu <catalina.mocanu@gmail.com>
---
 drivers/char/Makefile     |    3 ++-
 drivers/char/mem.c        |    2 ++
 include/linux/genhd.h     |    5 +++++
 include/linux/hw_random.h |    6 ++++++
 include/linux/random.h    |   44 ++++++++++++++++++++++++++++++++++++++++++++
 init/Kconfig              |    6 ++++++
 kernel/sys_ni.c           |    2 ++
 kernel/sysctl.c           |    4 ++++
 lib/Makefile              |    3 ++-
 9 files changed, 73 insertions(+), 2 deletions(-)

Comments

Josh Triplett Oct. 29, 2014, 4:35 p.m. UTC | #1
On Wed, Oct 29, 2014 at 09:58:55AM +0200, Catalina Mocanu wrote:
> This patch introduces a new expert config RANDOM to compile out
> the entire random generator infrastructure in order to save space
> on embedded devices. This new config makes /dev/random and /dev/urandom
> optional.

Awesome!

> If config RANDOM is set to n, then drivers/char/random.c and
> lib/random32.c are compiled out and the function definitions from
> include/kernel/random.h are replaced by no-ops.

See below regarding the no-ops.

> Some functions declared in drivers/char/random.c (add_disk_randomness
> and rand_initialize disk) are related to block devices and their
> definition from include/linux/genhd.h was also replaced with no-ops
> when CONFIG_RANDOM is n.
> 
> Also, syscall getrandom is made optional since it depends on the
> random number generator infrastructure.

Seems sensible.

> This patch is still work in progress and I have some questions:
> 
> *Should config HW_RANDOM depend on config RANDOM? or should HW_RANDOM
> select config RANDOM when needed? There is a function in random.c,
> add_hwgenerator_randomness, that is used to feed the random entropy pool
> with randomness from hardware noise. Besides that, I am not sure how
> these two (config HW_RANDOM and config RANDOM) are linked.

I don't think anything should "depends on RANDOM"; I think you just want
to "select RANDOM" from anything that needs it.

> *From my investigation, it seems that config HW_RANDOM is selected by
> drivers that use it (crypto or s390). Should this be the case for
> RANDOM? Should I check all the code that calls functions defined in
> include/linux/random.h, include/linux/genhd.h and select RANDOM for
> those cases?
> For modules that only give randomness input to the entropy pool by calling
> functions like add_device_randomness, add_input_randomness etc, I think
> there is no need to select CONFIG_RANDOM since these devices with work fine
> with stub functions.
> On the other hand, for devices/modules that require random return value to
> function properly (such as cryptographic libs) I consider that RANDOM
> should be automatically selected by them.

I think you're exactly right.  You should drop all the stubs for
functions that retrieve randomness, and instead have all of their
callers select RANDOM.  However, you should provide no-op stubs for any
functions that *provide* randomness, so that the callers simply do
nothing.

> Any suggestions are welcomed.
> 
> Signed-off-by: Catalina Mocanu <catalina.mocanu@gmail.com>
> ---
>  drivers/char/Makefile     |    3 ++-
>  drivers/char/mem.c        |    2 ++
>  include/linux/genhd.h     |    5 +++++
>  include/linux/hw_random.h |    6 ++++++
>  include/linux/random.h    |   44 ++++++++++++++++++++++++++++++++++++++++++++
>  init/Kconfig              |    6 ++++++
>  kernel/sys_ni.c           |    2 ++
>  kernel/sysctl.c           |    4 ++++
>  lib/Makefile              |    3 ++-
>  9 files changed, 73 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/char/Makefile b/drivers/char/Makefile
> index d06cde26..6f47417 100644
> --- a/drivers/char/Makefile
> +++ b/drivers/char/Makefile
> @@ -2,7 +2,8 @@
>  # Makefile for the kernel character device drivers.
>  #
>  
> -obj-y				+= mem.o random.o
> +obj-y				+= mem.o
> +obj-$(CONFIG_RANDOM)		+= random.o
>  obj-$(CONFIG_TTY_PRINTK)	+= ttyprintk.o
>  obj-y				+= misc.o
>  obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o
> diff --git a/drivers/char/mem.c b/drivers/char/mem.c
> index 524b707..58ea195 100644
> --- a/drivers/char/mem.c
> +++ b/drivers/char/mem.c
> @@ -792,8 +792,10 @@ static const struct memdev {
>  #endif
>  	 [5] = { "zero", 0666, &zero_fops, &zero_bdi },
>  	 [7] = { "full", 0666, &full_fops, NULL },
> +#ifdef CONFIG_RANDOM
>  	 [8] = { "random", 0666, &random_fops, NULL },
>  	 [9] = { "urandom", 0666, &urandom_fops, NULL },
> +#endif
>  #ifdef CONFIG_PRINTK
>  	[11] = { "kmsg", 0644, &kmsg_fops, NULL },
>  #endif
> diff --git a/include/linux/genhd.h b/include/linux/genhd.h
> index ec274e0..27c49c7 100644
> --- a/include/linux/genhd.h
> +++ b/include/linux/genhd.h
> @@ -434,9 +434,14 @@ extern void disk_unblock_events(struct gendisk *disk);
>  extern void disk_flush_events(struct gendisk *disk, unsigned int mask);
>  extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask);
>  
> +#if CONFIG_RANDOM
>  /* drivers/char/random.c */
>  extern void add_disk_randomness(struct gendisk *disk);
>  extern void rand_initialize_disk(struct gendisk *disk);
> +#else
> +static inline void add_disk_randomness(struct gendisk *disk) {}
> +static inline void rand_initialize_disk(struct gendisk *disk) {}
> +#endif
>  
>  static inline sector_t get_start_sect(struct block_device *bdev)
>  {
> diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
> index 914bb08..bff3bb9 100644
> --- a/include/linux/hw_random.h
> +++ b/include/linux/hw_random.h
> @@ -50,7 +50,13 @@ struct hwrng {
>  extern int hwrng_register(struct hwrng *rng);
>  /** Unregister a Hardware Random Number Generator driver. */
>  extern void hwrng_unregister(struct hwrng *rng);
> +
> +#if CONFIG_RANDOM
>  /** Feed random bits into the pool. */
>  extern void add_hwgenerator_randomness(const char *buffer, size_t count, size_t entropy);
> +#else
> +static inline void
> +add_hwgenerator_randomness(const char *buffer, size_t count, size_t entropy) {}
> +#endif /* CONFIG_RANDOM */
>  
>  #endif /* LINUX_HWRANDOM_H_ */
> diff --git a/include/linux/random.h b/include/linux/random.h
> index b05856e..b104e47 100644
> --- a/include/linux/random.h
> +++ b/include/linux/random.h
> @@ -8,6 +8,7 @@
>  
>  #include <uapi/linux/random.h>
>  
> +#ifdef CONFIG_RANDOM
>  extern void add_device_randomness(const void *, unsigned int);
>  extern void add_input_randomness(unsigned int type, unsigned int code,
>  				 unsigned int value);
> @@ -36,7 +37,50 @@ struct rnd_state {
>  
>  u32 prandom_u32_state(struct rnd_state *state);
>  void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes);
> +#else
> +static inline void add_device_randomness(const void *buf, unsigned int size) {}
> +static inline void add_input_randomness(unsigned int type, unsigned int code,
> +					unsigned int value) {}
> +static inline void add_interrupt_randomness(int irq, int irq_flags) {}
> +
> +static inline void get_random_bytes(void *buf, int nbytes) {}
> +static inline void get_random_bytes_arch(void *buf, int nbytes) {}
> +static inline void generate_random_uuid(unsigned char uuid_out[16]) {}
> +static inline int random_int_secret_init(void)
> +{
> +	return 0;
> +}
> +
> +static inline unsigned int get_random_int(void)
> +{
> +	return 42;
> +}
> +static inline
> +unsigned long randomize_range(unsigned long start, unsigned long end,
> +			      unsigned long len)
> +{
> +	return 0;
> +}
>  
> +static inline u32 prandom_u32(void)
> +{
> +	return 0;
> +}
> +static inline void prandom_bytes(void *buf, size_t nbytes) {}
> +static inline void prandom_seed(u32 seed) {}
> +static inline void prandom_reseed_late(void) {}
> +
> +struct rnd_state {
> +	__u32 s1, s2, s3, s4;
> +};
> +
> +static inline u32 prandom_u32_state(struct rnd_state *state)
> +{
> +	return 0;
> +}
> +static inline void prandom_bytes_state(struct rnd_state *state, void *buf,
> +				       size_t nbytes) {}
> +#endif /* CONFIG_RANDOM*/
>  /**
>   * prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro)
>   * @ep_ro: right open interval endpoint
> diff --git a/init/Kconfig b/init/Kconfig
> index 3ee28ae..866e9877 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1559,6 +1559,12 @@ config PCI_QUIRKS
>  	  bugs/quirks. Disable this only if your target machine is
>  	  unaffected by PCI quirks.
>  
> +config RANDOM
> +	bool "Enable random number generator infrastructure" if EXPERT
> +	default y
> +	help
> +	  TODO
> +
>  config EMBEDDED
>  	bool "Embedded system"
>  	option allnoconfig_y
> diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
> index 02aa418..e55d31c 100644
> --- a/kernel/sys_ni.c
> +++ b/kernel/sys_ni.c
> @@ -224,3 +224,5 @@ cond_syscall(sys_seccomp);
>  
>  /* access BPF programs and maps */
>  cond_syscall(sys_bpf);
> +
> +cond_syscall(sys_getrandom);
> diff --git a/kernel/sysctl.c b/kernel/sysctl.c
> index 4aada6d..a295cca 100644
> --- a/kernel/sysctl.c
> +++ b/kernel/sysctl.c
> @@ -220,7 +220,9 @@ static struct ctl_table vm_table[];
>  static struct ctl_table fs_table[];
>  static struct ctl_table debug_table[];
>  static struct ctl_table dev_table[];
> +#ifdef CONFIG_RANDOM
>  extern struct ctl_table random_table[];
> +#endif
>  #ifdef CONFIG_EPOLL
>  extern struct ctl_table epoll_table[];
>  #endif
> @@ -706,11 +708,13 @@ static struct ctl_table kern_table[] = {
>  		.mode		= 0644,
>  		.proc_handler	= proc_dointvec,
>  	},
> +#if CONFIG_RANDOM
>  	{
>  		.procname	= "random",
>  		.mode		= 0555,
>  		.child		= random_table,
>  	},
> +#endif
>  	{
>  		.procname	= "usermodehelper",
>  		.mode		= 0555,
> diff --git a/lib/Makefile b/lib/Makefile
> index 7512dc9..63b207e 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -22,11 +22,12 @@ lib-$(CONFIG_SMP) += cpumask.o
>  lib-y	+= kobject.o klist.o
>  obj-y	+= lockref.o
>  
> -obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
> +obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o\
>  	 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
>  	 gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
>  	 bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
>  	 percpu-refcount.o percpu_ida.o hash.o rhashtable.o
> +obj-$(CONFIG_RANDOM) += random32.o
>  obj-y += string_helpers.o
>  obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
>  obj-y += kstrtox.o
> -- 
> 1.7.10.4
> 
> -- 
> You received this message because you are subscribed to the Google Groups "opw-kernel" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to opw-kernel+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Catalina Mocanu Oct. 30, 2014, 9:42 p.m. UTC | #2
On Wed, Oct 29, 2014 at 6:35 PM, Josh Triplett <josh@joshtriplett.org>
wrote:

> On Wed, Oct 29, 2014 at 09:58:55AM +0200, Catalina Mocanu wrote:
> > This patch introduces a new expert config RANDOM to compile out
> > the entire random generator infrastructure in order to save space
> > on embedded devices. This new config makes /dev/random and /dev/urandom
> > optional.
>
> Awesome!
>
> > If config RANDOM is set to n, then drivers/char/random.c and
> > lib/random32.c are compiled out and the function definitions from
> > include/kernel/random.h are replaced by no-ops.
>
> See below regarding the no-ops.
>
> > Some functions declared in drivers/char/random.c (add_disk_randomness
> > and rand_initialize disk) are related to block devices and their
> > definition from include/linux/genhd.h was also replaced with no-ops
> > when CONFIG_RANDOM is n.
> >
> > Also, syscall getrandom is made optional since it depends on the
> > random number generator infrastructure.
>
> Seems sensible.
>
> > This patch is still work in progress and I have some questions:
> >
> > *Should config HW_RANDOM depend on config RANDOM? or should HW_RANDOM
> > select config RANDOM when needed? There is a function in random.c,
> > add_hwgenerator_randomness, that is used to feed the random entropy pool
> > with randomness from hardware noise. Besides that, I am not sure how
> > these two (config HW_RANDOM and config RANDOM) are linked.
>
> I don't think anything should "depends on RANDOM"; I think you just want
> to "select RANDOM" from anything that needs it.
>
> > *From my investigation, it seems that config HW_RANDOM is selected by
> > drivers that use it (crypto or s390). Should this be the case for
> > RANDOM? Should I check all the code that calls functions defined in
> > include/linux/random.h, include/linux/genhd.h and select RANDOM for
> > those cases?
> > For modules that only give randomness input to the entropy pool by
> calling
> > functions like add_device_randomness, add_input_randomness etc, I think
> > there is no need to select CONFIG_RANDOM since these devices with work
> fine
> > with stub functions.
> > On the other hand, for devices/modules that require random return value
> to
> > function properly (such as cryptographic libs) I consider that RANDOM
> > should be automatically selected by them.
>
> I think you're exactly right.  You should drop all the stubs for
> functions that retrieve randomness, and instead have all of their
> callers select RANDOM.  However, you should provide no-op stubs for any
> functions that *provide* randomness, so that the callers simply do
> nothing.
>
>
Hi Josh,

I've dropped the stubs for functions that retrieve randomness and I've
started
adding "select RANDOM" to callers of these functions.

I have some new questions:)

1. If config B depends on config A and both of them need random functions,
which is the best approach: add "select RANDOM" to both configs or add
"select RANDOM" only to config A, since anyway config B will not be
available
without config A?

2. Running grep for "get_random_bytes" shows more than 150 calls of the
function.
This means many Kconfig files need to be modified. Should all these changed
Kconfig files go in a single patch along with the files that add the new
config and
compile out random.c or could I divide them into several patches based on
subsystem(drivers, fs, net,..)? I think that a single patch would be really
hard to
review.

Thanks,
Catalina



> > Any suggestions are welcomed.
> >
> > Signed-off-by: Catalina Mocanu <catalina.mocanu@gmail.com>
> > ---
> >  drivers/char/Makefile     |    3 ++-
> >  drivers/char/mem.c        |    2 ++
> >  include/linux/genhd.h     |    5 +++++
> >  include/linux/hw_random.h |    6 ++++++
> >  include/linux/random.h    |   44
> ++++++++++++++++++++++++++++++++++++++++++++
> >  init/Kconfig              |    6 ++++++
> >  kernel/sys_ni.c           |    2 ++
> >  kernel/sysctl.c           |    4 ++++
> >  lib/Makefile              |    3 ++-
> >  9 files changed, 73 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/char/Makefile b/drivers/char/Makefile
> > index d06cde26..6f47417 100644
> > --- a/drivers/char/Makefile
> > +++ b/drivers/char/Makefile
> > @@ -2,7 +2,8 @@
> >  # Makefile for the kernel character device drivers.
> >  #
> >
> > -obj-y                                += mem.o random.o
> > +obj-y                                += mem.o
> > +obj-$(CONFIG_RANDOM)         += random.o
> >  obj-$(CONFIG_TTY_PRINTK)     += ttyprintk.o
> >  obj-y                                += misc.o
> >  obj-$(CONFIG_ATARI_DSP56K)   += dsp56k.o
> > diff --git a/drivers/char/mem.c b/drivers/char/mem.c
> > index 524b707..58ea195 100644
> > --- a/drivers/char/mem.c
> > +++ b/drivers/char/mem.c
> > @@ -792,8 +792,10 @@ static const struct memdev {
> >  #endif
> >        [5] = { "zero", 0666, &zero_fops, &zero_bdi },
> >        [7] = { "full", 0666, &full_fops, NULL },
> > +#ifdef CONFIG_RANDOM
> >        [8] = { "random", 0666, &random_fops, NULL },
> >        [9] = { "urandom", 0666, &urandom_fops, NULL },
> > +#endif
> >  #ifdef CONFIG_PRINTK
> >       [11] = { "kmsg", 0644, &kmsg_fops, NULL },
> >  #endif
> > diff --git a/include/linux/genhd.h b/include/linux/genhd.h
> > index ec274e0..27c49c7 100644
> > --- a/include/linux/genhd.h
> > +++ b/include/linux/genhd.h
> > @@ -434,9 +434,14 @@ extern void disk_unblock_events(struct gendisk
> *disk);
> >  extern void disk_flush_events(struct gendisk *disk, unsigned int mask);
> >  extern unsigned int disk_clear_events(struct gendisk *disk, unsigned
> int mask);
> >
> > +#if CONFIG_RANDOM
> >  /* drivers/char/random.c */
> >  extern void add_disk_randomness(struct gendisk *disk);
> >  extern void rand_initialize_disk(struct gendisk *disk);
> > +#else
> > +static inline void add_disk_randomness(struct gendisk *disk) {}
> > +static inline void rand_initialize_disk(struct gendisk *disk) {}
> > +#endif
> >
> >  static inline sector_t get_start_sect(struct block_device *bdev)
> >  {
> > diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
> > index 914bb08..bff3bb9 100644
> > --- a/include/linux/hw_random.h
> > +++ b/include/linux/hw_random.h
> > @@ -50,7 +50,13 @@ struct hwrng {
> >  extern int hwrng_register(struct hwrng *rng);
> >  /** Unregister a Hardware Random Number Generator driver. */
> >  extern void hwrng_unregister(struct hwrng *rng);
> > +
> > +#if CONFIG_RANDOM
> >  /** Feed random bits into the pool. */
> >  extern void add_hwgenerator_randomness(const char *buffer, size_t
> count, size_t entropy);
> > +#else
> > +static inline void
> > +add_hwgenerator_randomness(const char *buffer, size_t count, size_t
> entropy) {}
> > +#endif /* CONFIG_RANDOM */
> >
> >  #endif /* LINUX_HWRANDOM_H_ */
> > diff --git a/include/linux/random.h b/include/linux/random.h
> > index b05856e..b104e47 100644
> > --- a/include/linux/random.h
> > +++ b/include/linux/random.h
> > @@ -8,6 +8,7 @@
> >
> >  #include <uapi/linux/random.h>
> >
> > +#ifdef CONFIG_RANDOM
> >  extern void add_device_randomness(const void *, unsigned int);
> >  extern void add_input_randomness(unsigned int type, unsigned int code,
> >                                unsigned int value);
> > @@ -36,7 +37,50 @@ struct rnd_state {
> >
> >  u32 prandom_u32_state(struct rnd_state *state);
> >  void prandom_bytes_state(struct rnd_state *state, void *buf, size_t
> nbytes);
> > +#else
> > +static inline void add_device_randomness(const void *buf, unsigned int
> size) {}
> > +static inline void add_input_randomness(unsigned int type, unsigned int
> code,
> > +                                     unsigned int value) {}
> > +static inline void add_interrupt_randomness(int irq, int irq_flags) {}
> > +
> > +static inline void get_random_bytes(void *buf, int nbytes) {}
> > +static inline void get_random_bytes_arch(void *buf, int nbytes) {}
> > +static inline void generate_random_uuid(unsigned char uuid_out[16]) {}
> > +static inline int random_int_secret_init(void)
> > +{
> > +     return 0;
> > +}
> > +
> > +static inline unsigned int get_random_int(void)
> > +{
> > +     return 42;
> > +}
> > +static inline
> > +unsigned long randomize_range(unsigned long start, unsigned long end,
> > +                           unsigned long len)
> > +{
> > +     return 0;
> > +}
> >
> > +static inline u32 prandom_u32(void)
> > +{
> > +     return 0;
> > +}
> > +static inline void prandom_bytes(void *buf, size_t nbytes) {}
> > +static inline void prandom_seed(u32 seed) {}
> > +static inline void prandom_reseed_late(void) {}
> > +
> > +struct rnd_state {
> > +     __u32 s1, s2, s3, s4;
> > +};
> > +
> > +static inline u32 prandom_u32_state(struct rnd_state *state)
> > +{
> > +     return 0;
> > +}
> > +static inline void prandom_bytes_state(struct rnd_state *state, void
> *buf,
> > +                                    size_t nbytes) {}
> > +#endif /* CONFIG_RANDOM*/
> >  /**
> >   * prandom_u32_max - returns a pseudo-random number in interval [0,
> ep_ro)
> >   * @ep_ro: right open interval endpoint
> > diff --git a/init/Kconfig b/init/Kconfig
> > index 3ee28ae..866e9877 100644
> > --- a/init/Kconfig
> > +++ b/init/Kconfig
> > @@ -1559,6 +1559,12 @@ config PCI_QUIRKS
> >         bugs/quirks. Disable this only if your target machine is
> >         unaffected by PCI quirks.
> >
> > +config RANDOM
> > +     bool "Enable random number generator infrastructure" if EXPERT
> > +     default y
> > +     help
> > +       TODO
> > +
> >  config EMBEDDED
> >       bool "Embedded system"
> >       option allnoconfig_y
> > diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
> > index 02aa418..e55d31c 100644
> > --- a/kernel/sys_ni.c
> > +++ b/kernel/sys_ni.c
> > @@ -224,3 +224,5 @@ cond_syscall(sys_seccomp);
> >
> >  /* access BPF programs and maps */
> >  cond_syscall(sys_bpf);
> > +
> > +cond_syscall(sys_getrandom);
> > diff --git a/kernel/sysctl.c b/kernel/sysctl.c
> > index 4aada6d..a295cca 100644
> > --- a/kernel/sysctl.c
> > +++ b/kernel/sysctl.c
> > @@ -220,7 +220,9 @@ static struct ctl_table vm_table[];
> >  static struct ctl_table fs_table[];
> >  static struct ctl_table debug_table[];
> >  static struct ctl_table dev_table[];
> > +#ifdef CONFIG_RANDOM
> >  extern struct ctl_table random_table[];
> > +#endif
> >  #ifdef CONFIG_EPOLL
> >  extern struct ctl_table epoll_table[];
> >  #endif
> > @@ -706,11 +708,13 @@ static struct ctl_table kern_table[] = {
> >               .mode           = 0644,
> >               .proc_handler   = proc_dointvec,
> >       },
> > +#if CONFIG_RANDOM
> >       {
> >               .procname       = "random",
> >               .mode           = 0555,
> >               .child          = random_table,
> >       },
> > +#endif
> >       {
> >               .procname       = "usermodehelper",
> >               .mode           = 0555,
> > diff --git a/lib/Makefile b/lib/Makefile
> > index 7512dc9..63b207e 100644
> > --- a/lib/Makefile
> > +++ b/lib/Makefile
> > @@ -22,11 +22,12 @@ lib-$(CONFIG_SMP) += cpumask.o
> >  lib-y        += kobject.o klist.o
> >  obj-y        += lockref.o
> >
> > -obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o
> random32.o \
> > +obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o\
> >        bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
> >        gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
> >        bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o
> kfifo.o \
> >        percpu-refcount.o percpu_ida.o hash.o rhashtable.o
> > +obj-$(CONFIG_RANDOM) += random32.o
> >  obj-y += string_helpers.o
> >  obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
> >  obj-y += kstrtox.o
> > --
> > 1.7.10.4
> >
> > --
> > You received this message because you are subscribed to the Google
> Groups "opw-kernel" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> an email to opw-kernel+unsubscribe@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
>
Josh Triplett Oct. 30, 2014, 10:32 p.m. UTC | #3
On Thu, Oct 30, 2014 at 11:42:34PM +0200, Catalina Mocanu wrote:
> On Wed, Oct 29, 2014 at 6:35 PM, Josh Triplett <josh@joshtriplett.org>
> wrote:
> 
> > On Wed, Oct 29, 2014 at 09:58:55AM +0200, Catalina Mocanu wrote:
> > > This patch introduces a new expert config RANDOM to compile out
> > > the entire random generator infrastructure in order to save space
> > > on embedded devices. This new config makes /dev/random and /dev/urandom
> > > optional.
> >
> > Awesome!
> >
> > > If config RANDOM is set to n, then drivers/char/random.c and
> > > lib/random32.c are compiled out and the function definitions from
> > > include/kernel/random.h are replaced by no-ops.
> >
> > See below regarding the no-ops.
> >
> > > Some functions declared in drivers/char/random.c (add_disk_randomness
> > > and rand_initialize disk) are related to block devices and their
> > > definition from include/linux/genhd.h was also replaced with no-ops
> > > when CONFIG_RANDOM is n.
> > >
> > > Also, syscall getrandom is made optional since it depends on the
> > > random number generator infrastructure.
> >
> > Seems sensible.
> >
> > > This patch is still work in progress and I have some questions:
> > >
> > > *Should config HW_RANDOM depend on config RANDOM? or should HW_RANDOM
> > > select config RANDOM when needed? There is a function in random.c,
> > > add_hwgenerator_randomness, that is used to feed the random entropy pool
> > > with randomness from hardware noise. Besides that, I am not sure how
> > > these two (config HW_RANDOM and config RANDOM) are linked.
> >
> > I don't think anything should "depends on RANDOM"; I think you just want
> > to "select RANDOM" from anything that needs it.
> >
> > > *From my investigation, it seems that config HW_RANDOM is selected by
> > > drivers that use it (crypto or s390). Should this be the case for
> > > RANDOM? Should I check all the code that calls functions defined in
> > > include/linux/random.h, include/linux/genhd.h and select RANDOM for
> > > those cases?
> > > For modules that only give randomness input to the entropy pool by
> > calling
> > > functions like add_device_randomness, add_input_randomness etc, I think
> > > there is no need to select CONFIG_RANDOM since these devices with work
> > fine
> > > with stub functions.
> > > On the other hand, for devices/modules that require random return value
> > to
> > > function properly (such as cryptographic libs) I consider that RANDOM
> > > should be automatically selected by them.
> >
> > I think you're exactly right.  You should drop all the stubs for
> > functions that retrieve randomness, and instead have all of their
> > callers select RANDOM.  However, you should provide no-op stubs for any
> > functions that *provide* randomness, so that the callers simply do
> > nothing.
> >
> >
> Hi Josh,
> 
> I've dropped the stubs for functions that retrieve randomness and I've
> started
> adding "select RANDOM" to callers of these functions.
> 
> I have some new questions:)
> 
> 1. If config B depends on config A and both of them need random functions,
> which is the best approach: add "select RANDOM" to both configs or add
> "select RANDOM" only to config A, since anyway config B will not be
> available
> without config A?

Depends on the configs, but generally I'd add it just to config A if A
is a subsystem that B depends on and A inherently needs the randomness.
If B depends on A only incidentally (e.g. a dependency on a random
bit of common kernel functionality, rather than a subsystem B needs),
I'd add it to B as well.

> 2. Running grep for "get_random_bytes" shows more than 150 calls of the
> function.
> This means many Kconfig files need to be modified. Should all these changed
> Kconfig files go in a single patch along with the files that add the new
> config and
> compile out random.c or could I divide them into several patches based on
> subsystem(drivers, fs, net,..)? I think that a single patch would be really
> hard to
> review.

Ouch. :(

Looking over that list, I see a few fairly crucial things depending on
it, such as ELF binary support.  Unless those can be reworked first to
make that dependency optional (e.g. a config option to remove the random
seed provided to userspace), I don't think it'll make sense to introduce
a config option here.  While I think this space seems worth saving, it
does seem difficult to justify based on the number of changes required,
and I think we may need to defer this one for a while.

This is one of the possible outcomes that made me put this one on the
"larger projects" list to begin with.  Randomness may be one of those
library bits that will have to wait for LTO to remove. :(

- Josh Triplett
Arnd Bergmann Oct. 31, 2014, 7:31 p.m. UTC | #4
On Thursday 30 October 2014 15:32:16 josh@joshtriplett.org wrote:
> 
> > 2. Running grep for "get_random_bytes" shows more than 150 calls of the
> > function.
> > This means many Kconfig files need to be modified. Should all these changed
> > Kconfig files go in a single patch along with the files that add the new
> > config and
> > compile out random.c or could I divide them into several patches based on
> > subsystem(drivers, fs, net,..)? I think that a single patch would be really
> > hard to
> > review.
> 
> Ouch. 
> 
> Looking over that list, I see a few fairly crucial things depending on
> it, such as ELF binary support.  Unless those can be reworked first to
> make that dependency optional (e.g. a config option to remove the random
> seed provided to userspace), I don't think it'll make sense to introduce
> a config option here.  While I think this space seems worth saving, it
> does seem difficult to justify based on the number of changes required,
> and I think we may need to defer this one for a while.
> 
> This is one of the possible outcomes that made me put this one on the
> "larger projects" list to begin with.  Randomness may be one of those
> library bits that will have to wait for LTO to remove. 

You could put a really simple get_random_bytes function in place,
using an LFSR or something like http://dilbert.com/strips/comic/2001-10-25/

If you know that you are building for a system that has close to zero
entropy sources, it won't make much of a difference.

	Arnd
Josh Triplett Oct. 31, 2014, 8:06 p.m. UTC | #5
On Fri, Oct 31, 2014 at 08:31:23PM +0100, Arnd Bergmann wrote:
> On Thursday 30 October 2014 15:32:16 josh@joshtriplett.org wrote:
> > 
> > > 2. Running grep for "get_random_bytes" shows more than 150 calls of the
> > > function.
> > > This means many Kconfig files need to be modified. Should all these changed
> > > Kconfig files go in a single patch along with the files that add the new
> > > config and
> > > compile out random.c or could I divide them into several patches based on
> > > subsystem(drivers, fs, net,..)? I think that a single patch would be really
> > > hard to
> > > review.
> > 
> > Ouch. 
> > 
> > Looking over that list, I see a few fairly crucial things depending on
> > it, such as ELF binary support.  Unless those can be reworked first to
> > make that dependency optional (e.g. a config option to remove the random
> > seed provided to userspace), I don't think it'll make sense to introduce
> > a config option here.  While I think this space seems worth saving, it
> > does seem difficult to justify based on the number of changes required,
> > and I think we may need to defer this one for a while.
> > 
> > This is one of the possible outcomes that made me put this one on the
> > "larger projects" list to begin with.  Randomness may be one of those
> > library bits that will have to wait for LTO to remove. 
> 
> You could put a really simple get_random_bytes function in place,
> using an LFSR or something like http://dilbert.com/strips/comic/2001-10-25/
> 
> If you know that you are building for a system that has close to zero
> entropy sources, it won't make much of a difference.

Better yet, if you know you're building for a system with a hardware
random number generator, replace the entire random infrastructure with a
one-liner function that just uses the hardware RNG; if you don't trust
your hardware, you're doomed anyway.  I'd love to see a config option to
replace the entire random infrastructure with rdrand.

- Josh Triplett
Arnd Bergmann Oct. 31, 2014, 8:57 p.m. UTC | #6
On Friday 31 October 2014 13:06:38 josh@joshtriplett.org wrote:
> On Fri, Oct 31, 2014 at 08:31:23PM +0100, Arnd Bergmann wrote:
> > On Thursday 30 October 2014 15:32:16 josh@joshtriplett.org wrote:
> >
> > If you know that you are building for a system that has close to zero
> > entropy sources, it won't make much of a difference.
> 
> Better yet, if you know you're building for a system with a hardware
> random number generator, replace the entire random infrastructure with a
> one-liner function that just uses the hardware RNG; if you don't trust
> your hardware, you're doomed anyway.  I'd love to see a config option to
> replace the entire random infrastructure with rdrand.

I don't think it works that way. If you don't trust the hardware RNG, you
have to mix in some other source of entropy. This is a completely
reasonable approach to the problem. 

Doing this for size optimization makes sense though, especially if rdrand
is the only source of entropy you have. We already have the GET_RANDOM
macro for rdrand, so get_random_bytes could use that if it's defined,
or fall back to an LFSR otherwise, but *only* when building with
CONFIG_EXPERT and with the warning that this is less reliable than the
default, much less so with the LFSR fallback.

	Arnd

Patch
diff mbox

diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index d06cde26..6f47417 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -2,7 +2,8 @@ 
 # Makefile for the kernel character device drivers.
 #
 
-obj-y				+= mem.o random.o
+obj-y				+= mem.o
+obj-$(CONFIG_RANDOM)		+= random.o
 obj-$(CONFIG_TTY_PRINTK)	+= ttyprintk.o
 obj-y				+= misc.o
 obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 524b707..58ea195 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -792,8 +792,10 @@  static const struct memdev {
 #endif
 	 [5] = { "zero", 0666, &zero_fops, &zero_bdi },
 	 [7] = { "full", 0666, &full_fops, NULL },
+#ifdef CONFIG_RANDOM
 	 [8] = { "random", 0666, &random_fops, NULL },
 	 [9] = { "urandom", 0666, &urandom_fops, NULL },
+#endif
 #ifdef CONFIG_PRINTK
 	[11] = { "kmsg", 0644, &kmsg_fops, NULL },
 #endif
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index ec274e0..27c49c7 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -434,9 +434,14 @@  extern void disk_unblock_events(struct gendisk *disk);
 extern void disk_flush_events(struct gendisk *disk, unsigned int mask);
 extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask);
 
+#if CONFIG_RANDOM
 /* drivers/char/random.c */
 extern void add_disk_randomness(struct gendisk *disk);
 extern void rand_initialize_disk(struct gendisk *disk);
+#else
+static inline void add_disk_randomness(struct gendisk *disk) {}
+static inline void rand_initialize_disk(struct gendisk *disk) {}
+#endif
 
 static inline sector_t get_start_sect(struct block_device *bdev)
 {
diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
index 914bb08..bff3bb9 100644
--- a/include/linux/hw_random.h
+++ b/include/linux/hw_random.h
@@ -50,7 +50,13 @@  struct hwrng {
 extern int hwrng_register(struct hwrng *rng);
 /** Unregister a Hardware Random Number Generator driver. */
 extern void hwrng_unregister(struct hwrng *rng);
+
+#if CONFIG_RANDOM
 /** Feed random bits into the pool. */
 extern void add_hwgenerator_randomness(const char *buffer, size_t count, size_t entropy);
+#else
+static inline void
+add_hwgenerator_randomness(const char *buffer, size_t count, size_t entropy) {}
+#endif /* CONFIG_RANDOM */
 
 #endif /* LINUX_HWRANDOM_H_ */
diff --git a/include/linux/random.h b/include/linux/random.h
index b05856e..b104e47 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -8,6 +8,7 @@ 
 
 #include <uapi/linux/random.h>
 
+#ifdef CONFIG_RANDOM
 extern void add_device_randomness(const void *, unsigned int);
 extern void add_input_randomness(unsigned int type, unsigned int code,
 				 unsigned int value);
@@ -36,7 +37,50 @@  struct rnd_state {
 
 u32 prandom_u32_state(struct rnd_state *state);
 void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes);
+#else
+static inline void add_device_randomness(const void *buf, unsigned int size) {}
+static inline void add_input_randomness(unsigned int type, unsigned int code,
+					unsigned int value) {}
+static inline void add_interrupt_randomness(int irq, int irq_flags) {}
+
+static inline void get_random_bytes(void *buf, int nbytes) {}
+static inline void get_random_bytes_arch(void *buf, int nbytes) {}
+static inline void generate_random_uuid(unsigned char uuid_out[16]) {}
+static inline int random_int_secret_init(void)
+{
+	return 0;
+}
+
+static inline unsigned int get_random_int(void)
+{
+	return 42;
+}
+static inline
+unsigned long randomize_range(unsigned long start, unsigned long end,
+			      unsigned long len)
+{
+	return 0;
+}
 
+static inline u32 prandom_u32(void)
+{
+	return 0;
+}
+static inline void prandom_bytes(void *buf, size_t nbytes) {}
+static inline void prandom_seed(u32 seed) {}
+static inline void prandom_reseed_late(void) {}
+
+struct rnd_state {
+	__u32 s1, s2, s3, s4;
+};
+
+static inline u32 prandom_u32_state(struct rnd_state *state)
+{
+	return 0;
+}
+static inline void prandom_bytes_state(struct rnd_state *state, void *buf,
+				       size_t nbytes) {}
+#endif /* CONFIG_RANDOM*/
 /**
  * prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro)
  * @ep_ro: right open interval endpoint
diff --git a/init/Kconfig b/init/Kconfig
index 3ee28ae..866e9877 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1559,6 +1559,12 @@  config PCI_QUIRKS
 	  bugs/quirks. Disable this only if your target machine is
 	  unaffected by PCI quirks.
 
+config RANDOM
+	bool "Enable random number generator infrastructure" if EXPERT
+	default y
+	help
+	  TODO
+
 config EMBEDDED
 	bool "Embedded system"
 	option allnoconfig_y
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 02aa418..e55d31c 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -224,3 +224,5 @@  cond_syscall(sys_seccomp);
 
 /* access BPF programs and maps */
 cond_syscall(sys_bpf);
+
+cond_syscall(sys_getrandom);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 4aada6d..a295cca 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -220,7 +220,9 @@  static struct ctl_table vm_table[];
 static struct ctl_table fs_table[];
 static struct ctl_table debug_table[];
 static struct ctl_table dev_table[];
+#ifdef CONFIG_RANDOM
 extern struct ctl_table random_table[];
+#endif
 #ifdef CONFIG_EPOLL
 extern struct ctl_table epoll_table[];
 #endif
@@ -706,11 +708,13 @@  static struct ctl_table kern_table[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
 	},
+#if CONFIG_RANDOM
 	{
 		.procname	= "random",
 		.mode		= 0555,
 		.child		= random_table,
 	},
+#endif
 	{
 		.procname	= "usermodehelper",
 		.mode		= 0555,
diff --git a/lib/Makefile b/lib/Makefile
index 7512dc9..63b207e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -22,11 +22,12 @@  lib-$(CONFIG_SMP) += cpumask.o
 lib-y	+= kobject.o klist.o
 obj-y	+= lockref.o
 
-obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
+obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o\
 	 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
 	 gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
 	 bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
 	 percpu-refcount.o percpu_ida.o hash.o rhashtable.o
+obj-$(CONFIG_RANDOM) += random32.o
 obj-y += string_helpers.o
 obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
 obj-y += kstrtox.o