linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Allow hwrng to initialize crng.
@ 2018-09-26  3:24 Louis Collard
  2018-09-26 10:35 ` Jarkko Sakkinen
  2018-11-17 20:15 ` Michael Niewöhner
  0 siblings, 2 replies; 7+ messages in thread
From: Louis Collard @ 2018-09-26  3:24 UTC (permalink / raw)
  To: linux-integrity
  Cc: Arnd Bergmann, Greg Kroah-Hartman, linux-kernel, Jarkko Sakkinen,
	apronin, Jason Gunthorpe, david.bild

Some systems, for example embedded systems, do not generate
enough entropy on boot through interrupts, and boot may be blocked for
several minutes waiting for a call to getrandom to complete.

Currently, random data is read from a hwrng when it is registered,
and is loaded into primary_crng. This data is treated in the same
way as data that is device-specific but otherwise unchanging, and
so primary_crng cannot become initialized with the data from the
hwrng.

This change causes the data initially read from the hwrng to be
treated the same as subsequent data that is read from the hwrng if
it's quality score is non-zero.

The implications of this are:

The data read from hwrng can cause primary_crng to become
initialized, therefore avoiding problems of getrandom blocking
on boot.

Calls to getrandom (with GRND_RANDOM) may be using entropy
exclusively (or in practise, almost exclusively) from the hwrng.

Regarding the latter point; this behavior is the same as if a
user specified a quality score of 1 (bit of entropy per 1024 bits)
so hopefully this is not too scary a change to make.

This change is the result of the discussion here:
https://patchwork.kernel.org/patch/10453893/

Signed-off-by: Louis Collard <louiscollard@chromium.org>
---
 drivers/char/hw_random/core.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index aaf9e5afaad4..47f358aa0c3d 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <crypto/chacha20.h>
 
 #define RNG_MODULE_NAME		"hw_random"
 
@@ -64,13 +65,17 @@ static size_t rng_buffer_size(void)
 static void add_early_randomness(struct hwrng *rng)
 {
 	int bytes_read;
-	size_t size = min_t(size_t, 16, rng_buffer_size());
+	/* Read enough to initialize crng. */
+	size_t size = 2*CHACHA20_KEY_SIZE;
 
 	mutex_lock(&reading_mutex);
 	bytes_read = rng_get_data(rng, rng_buffer, size, 1);
 	mutex_unlock(&reading_mutex);
 	if (bytes_read > 0)
-		add_device_randomness(rng_buffer, bytes_read);
+		/* Allow crng to become initialized, but do not add
+		 * entropy to the pool.
+		 */
+		add_hwgenerator_randomness(rng_buffer, bytes_read, 0);
 }
 
 static inline void cleanup_rng(struct kref *kref)
-- 
2.13.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] Allow hwrng to initialize crng.
  2018-09-26  3:24 [PATCH] Allow hwrng to initialize crng Louis Collard
@ 2018-09-26 10:35 ` Jarkko Sakkinen
  2018-10-05  1:45   ` Louis Collard
  2018-11-17 20:15 ` Michael Niewöhner
  1 sibling, 1 reply; 7+ messages in thread
From: Jarkko Sakkinen @ 2018-09-26 10:35 UTC (permalink / raw)
  To: Louis Collard
  Cc: linux-integrity, Arnd Bergmann, Greg Kroah-Hartman, linux-kernel,
	apronin, Jason Gunthorpe, david.bild

On Wed, Sep 26, 2018 at 11:24:55AM +0800, Louis Collard wrote:
> Some systems, for example embedded systems, do not generate
> enough entropy on boot through interrupts, and boot may be blocked for
> several minutes waiting for a call to getrandom to complete.
> 
> Currently, random data is read from a hwrng when it is registered,
> and is loaded into primary_crng. This data is treated in the same
> way as data that is device-specific but otherwise unchanging, and
> so primary_crng cannot become initialized with the data from the
> hwrng.
> 
> This change causes the data initially read from the hwrng to be
> treated the same as subsequent data that is read from the hwrng if
> it's quality score is non-zero.
> 
> The implications of this are:
> 
> The data read from hwrng can cause primary_crng to become
> initialized, therefore avoiding problems of getrandom blocking
> on boot.
> 
> Calls to getrandom (with GRND_RANDOM) may be using entropy
> exclusively (or in practise, almost exclusively) from the hwrng.
> 
> Regarding the latter point; this behavior is the same as if a
> user specified a quality score of 1 (bit of entropy per 1024 bits)
> so hopefully this is not too scary a change to make.
> 
> This change is the result of the discussion here:
> https://patchwork.kernel.org/patch/10453893/
> 
> Signed-off-by: Louis Collard <louiscollard@chromium.org>

Acked-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>

/Jarkko

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Allow hwrng to initialize crng.
  2018-09-26 10:35 ` Jarkko Sakkinen
@ 2018-10-05  1:45   ` Louis Collard
  0 siblings, 0 replies; 7+ messages in thread
From: Louis Collard @ 2018-10-05  1:45 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-integrity, Arnd Bergmann, Greg Kroah-Hartman, linux-kernel,
	Andrey Pronin, Jason Gunthorpe, David R. Bild,
	PrasannaKumar Muralidharan, Herbert Xu, Michael Buesch,
	Arvind Yadav, Gary R Hook

On Wed, Sep 26, 2018 at 6:35 PM Jarkko Sakkinen
<jarkko.sakkinen@linux.intel.com> wrote:
>
> On Wed, Sep 26, 2018 at 11:24:55AM +0800, Louis Collard wrote:
> > Some systems, for example embedded systems, do not generate
> > enough entropy on boot through interrupts, and boot may be blocked for
> > several minutes waiting for a call to getrandom to complete.
> >
> > Currently, random data is read from a hwrng when it is registered,
> > and is loaded into primary_crng. This data is treated in the same
> > way as data that is device-specific but otherwise unchanging, and
> > so primary_crng cannot become initialized with the data from the
> > hwrng.
> >
> > This change causes the data initially read from the hwrng to be
> > treated the same as subsequent data that is read from the hwrng if
> > it's quality score is non-zero.
> >
> > The implications of this are:
> >
> > The data read from hwrng can cause primary_crng to become
> > initialized, therefore avoiding problems of getrandom blocking
> > on boot.
> >
> > Calls to getrandom (with GRND_RANDOM) may be using entropy
> > exclusively (or in practise, almost exclusively) from the hwrng.
> >
> > Regarding the latter point; this behavior is the same as if a
> > user specified a quality score of 1 (bit of entropy per 1024 bits)
> > so hopefully this is not too scary a change to make.
> >
> > This change is the result of the discussion here:
> > https://patchwork.kernel.org/patch/10453893/
> >
> > Signed-off-by: Louis Collard <louiscollard@chromium.org>
>
> Acked-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
>
> /Jarkko

Thanks!

Adding a few people I think I should have included previously - I'm
new to this process so apologies for any missteps; please let me know
if there is anything else I can / should be doing!

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Allow hwrng to initialize crng.
  2018-09-26  3:24 [PATCH] Allow hwrng to initialize crng Louis Collard
  2018-09-26 10:35 ` Jarkko Sakkinen
@ 2018-11-17 20:15 ` Michael Niewöhner
  2018-12-13  4:50   ` Louis Collard
  1 sibling, 1 reply; 7+ messages in thread
From: Michael Niewöhner @ 2018-11-17 20:15 UTC (permalink / raw)
  To: Louis Collard
  Cc: linux-integrity, Arnd Bergmann, Greg Kroah-Hartman, linux-kernel,
	Jarkko Sakkinen, apronin, Jason Gunthorpe, david.bild

Hi Louis,

On Wed, 2018-09-26 at 11:24 +0800, Louis Collard wrote:
> Some systems, for example embedded systems, do not generate
> enough entropy on boot through interrupts, and boot may be blocked for
> several minutes waiting for a call to getrandom to complete.
> 
> Currently, random data is read from a hwrng when it is registered,
> and is loaded into primary_crng. This data is treated in the same
> way as data that is device-specific but otherwise unchanging, and
> so primary_crng cannot become initialized with the data from the
> hwrng.
> 
> This change causes the data initially read from the hwrng to be
> treated the same as subsequent data that is read from the hwrng if
> it's quality score is non-zero.
> 
> The implications of this are:
> 
> The data read from hwrng can cause primary_crng to become
> initialized, therefore avoiding problems of getrandom blocking
> on boot.
> 
> Calls to getrandom (with GRND_RANDOM) may be using entropy
> exclusively (or in practise, almost exclusively) from the hwrng.
> 
> Regarding the latter point; this behavior is the same as if a
> user specified a quality score of 1 (bit of entropy per 1024 bits)
> so hopefully this is not too scary a change to make.
> 
> This change is the result of the discussion here:
> https://patchwork.kernel.org/patch/10453893/
> 
> Signed-off-by: Louis Collard <louiscollard@chromium.org>
> Acked-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> ---
>  drivers/char/hw_random/core.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
> index aaf9e5afaad4..47f358aa0c3d 100644
> --- a/drivers/char/hw_random/core.c
> +++ b/drivers/char/hw_random/core.c
> @@ -24,6 +24,7 @@
>  #include <linux/sched.h>
>  #include <linux/slab.h>
>  #include <linux/uaccess.h>
> +#include <crypto/chacha20.h>
>  
>  #define RNG_MODULE_NAME		"hw_random"
>  
> @@ -64,13 +65,17 @@ static size_t rng_buffer_size(void)
>  static void add_early_randomness(struct hwrng *rng)
>  {
>  	int bytes_read;
> -	size_t size = min_t(size_t, 16, rng_buffer_size());
> +	/* Read enough to initialize crng. */
> +	size_t size = 2*CHACHA20_KEY_SIZE;
>  
>  	mutex_lock(&reading_mutex);
>  	bytes_read = rng_get_data(rng, rng_buffer, size, 1);
>  	mutex_unlock(&reading_mutex);
>  	if (bytes_read > 0)
> -		add_device_randomness(rng_buffer, bytes_read);
> +		/* Allow crng to become initialized, but do not add
> +		 * entropy to the pool.
> +		 */
> +		add_hwgenerator_randomness(rng_buffer, bytes_read, 0);
>  }
>  
>  static inline void cleanup_rng(struct kref *kref)

I found your patch by chance, searching for a solution for crng init delay on my
headless machine. Unfortunately it hardly makes any difference for me. With the
patch the system hangs for about 80s instead of 120s until the "crng init done"
message.In contrast, doing a `cat /dev/hwrng >/dev/random` or running rngd
initializes the crng instantly.

Isn't that delay the problem this patch tries to fix? Any idea what is wrong
here?

Thanks!

Best regards
Michael



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Allow hwrng to initialize crng.
  2018-11-17 20:15 ` Michael Niewöhner
@ 2018-12-13  4:50   ` Louis Collard
  2018-12-15 17:11     ` Michael Niewöhner
  0 siblings, 1 reply; 7+ messages in thread
From: Louis Collard @ 2018-12-13  4:50 UTC (permalink / raw)
  To: linux
  Cc: linux-integrity, Arnd Bergmann, Greg Kroah-Hartman, linux-kernel,
	Jarkko Sakkinen, Andrey Pronin, Jason Gunthorpe, David R. Bild

On Sun, Nov 18, 2018 at 4:15 AM Michael Niewöhner <linux@mniewoehner.de> wrote:
>
> Hi Louis,
>
> On Wed, 2018-09-26 at 11:24 +0800, Louis Collard wrote:
> > Some systems, for example embedded systems, do not generate
> > enough entropy on boot through interrupts, and boot may be blocked for
> > several minutes waiting for a call to getrandom to complete.
> >
> > Currently, random data is read from a hwrng when it is registered,
> > and is loaded into primary_crng. This data is treated in the same
> > way as data that is device-specific but otherwise unchanging, and
> > so primary_crng cannot become initialized with the data from the
> > hwrng.
> >
> > This change causes the data initially read from the hwrng to be
> > treated the same as subsequent data that is read from the hwrng if
> > it's quality score is non-zero.
> >
> > The implications of this are:
> >
> > The data read from hwrng can cause primary_crng to become
> > initialized, therefore avoiding problems of getrandom blocking
> > on boot.
> >
> > Calls to getrandom (with GRND_RANDOM) may be using entropy
> > exclusively (or in practise, almost exclusively) from the hwrng.
> >
> > Regarding the latter point; this behavior is the same as if a
> > user specified a quality score of 1 (bit of entropy per 1024 bits)
> > so hopefully this is not too scary a change to make.
> >
> > This change is the result of the discussion here:
> > https://patchwork.kernel.org/patch/10453893/
> >
> > Signed-off-by: Louis Collard <louiscollard@chromium.org>
> > Acked-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > ---
> >  drivers/char/hw_random/core.c | 9 +++++++--
> >  1 file changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
> > index aaf9e5afaad4..47f358aa0c3d 100644
> > --- a/drivers/char/hw_random/core.c
> > +++ b/drivers/char/hw_random/core.c
> > @@ -24,6 +24,7 @@
> >  #include <linux/sched.h>
> >  #include <linux/slab.h>
> >  #include <linux/uaccess.h>
> > +#include <crypto/chacha20.h>
> >
> >  #define RNG_MODULE_NAME              "hw_random"
> >
> > @@ -64,13 +65,17 @@ static size_t rng_buffer_size(void)
> >  static void add_early_randomness(struct hwrng *rng)
> >  {
> >       int bytes_read;
> > -     size_t size = min_t(size_t, 16, rng_buffer_size());
> > +     /* Read enough to initialize crng. */
> > +     size_t size = 2*CHACHA20_KEY_SIZE;
> >
> >       mutex_lock(&reading_mutex);
> >       bytes_read = rng_get_data(rng, rng_buffer, size, 1);
> >       mutex_unlock(&reading_mutex);
> >       if (bytes_read > 0)
> > -             add_device_randomness(rng_buffer, bytes_read);
> > +             /* Allow crng to become initialized, but do not add
> > +              * entropy to the pool.
> > +              */
> > +             add_hwgenerator_randomness(rng_buffer, bytes_read, 0);
> >  }
> >
> >  static inline void cleanup_rng(struct kref *kref)
>
> I found your patch by chance, searching for a solution for crng init delay on my
> headless machine. Unfortunately it hardly makes any difference for me. With the
> patch the system hangs for about 80s instead of 120s until the "crng init done"
> message.In contrast, doing a `cat /dev/hwrng >/dev/random` or running rngd
> initializes the crng instantly.
>
> Isn't that delay the problem this patch tries to fix? Any idea what is wrong
> here?
>
> Thanks!
>
> Best regards
> Michael
>
>

Yes that is the problem this is trying to address. My guess would be
rng_get_data() is not returning as much data as requested, so the
delay is reduced but not eliminated. Looking at implementation of
rng_get_data() it appears this could be caused by device support for
read() vs data_read(). I don't have a good feel for whether looping to
retrieve more data here would be acceptable, it is certainly a bigger
change than currently proposed.

Thanks,
Louis

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Allow hwrng to initialize crng.
  2018-12-13  4:50   ` Louis Collard
@ 2018-12-15 17:11     ` Michael Niewöhner
  2018-12-15 18:20       ` Michael Niewöhner
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Niewöhner @ 2018-12-15 17:11 UTC (permalink / raw)
  To: Louis Collard
  Cc: linux-integrity, Arnd Bergmann, Greg Kroah-Hartman, linux-kernel,
	Jarkko Sakkinen, Andrey Pronin, Jason Gunthorpe, David R. Bild

On Thu, 2018-12-13 at 12:50 +0800, Louis Collard wrote:
> On Sun, Nov 18, 2018 at 4:15 AM Michael Niewöhner <linux@mniewoehner.de>
> wrote:
> > 
> > Hi Louis,
> > 
> > On Wed, 2018-09-26 at 11:24 +0800, Louis Collard wrote:
> > > Some systems, for example embedded systems, do not generate
> > > enough entropy on boot through interrupts, and boot may be blocked for
> > > several minutes waiting for a call to getrandom to complete.
> > > 
> > > Currently, random data is read from a hwrng when it is registered,
> > > and is loaded into primary_crng. This data is treated in the same
> > > way as data that is device-specific but otherwise unchanging, and
> > > so primary_crng cannot become initialized with the data from the
> > > hwrng.
> > > 
> > > This change causes the data initially read from the hwrng to be
> > > treated the same as subsequent data that is read from the hwrng if
> > > it's quality score is non-zero.
> > > 
> > > The implications of this are:
> > > 
> > > The data read from hwrng can cause primary_crng to become
> > > initialized, therefore avoiding problems of getrandom blocking
> > > on boot.
> > > 
> > > Calls to getrandom (with GRND_RANDOM) may be using entropy
> > > exclusively (or in practise, almost exclusively) from the hwrng.
> > > 
> > > Regarding the latter point; this behavior is the same as if a
> > > user specified a quality score of 1 (bit of entropy per 1024 bits)
> > > so hopefully this is not too scary a change to make.
> > > 
> > > This change is the result of the discussion here:
> > > https://patchwork.kernel.org/patch/10453893/
> > > 
> > > Signed-off-by: Louis Collard <louiscollard@chromium.org>
> > > Acked-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > > ---
> > >  drivers/char/hw_random/core.c | 9 +++++++--
> > >  1 file changed, 7 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
> > > index aaf9e5afaad4..47f358aa0c3d 100644
> > > --- a/drivers/char/hw_random/core.c
> > > +++ b/drivers/char/hw_random/core.c
> > > @@ -24,6 +24,7 @@
> > >  #include <linux/sched.h>
> > >  #include <linux/slab.h>
> > >  #include <linux/uaccess.h>
> > > +#include <crypto/chacha20.h>
> > > 
> > >  #define RNG_MODULE_NAME              "hw_random"
> > > 
> > > @@ -64,13 +65,17 @@ static size_t rng_buffer_size(void)
> > >  static void add_early_randomness(struct hwrng *rng)
> > >  {
> > >       int bytes_read;
> > > -     size_t size = min_t(size_t, 16, rng_buffer_size());
> > > +     /* Read enough to initialize crng. */
> > > +     size_t size = 2*CHACHA20_KEY_SIZE;
> > > 
> > >       mutex_lock(&reading_mutex);
> > >       bytes_read = rng_get_data(rng, rng_buffer, size, 1);
> > >       mutex_unlock(&reading_mutex);
> > >       if (bytes_read > 0)
> > > -             add_device_randomness(rng_buffer, bytes_read);
> > > +             /* Allow crng to become initialized, but do not add
> > > +              * entropy to the pool.
> > > +              */
> > > +             add_hwgenerator_randomness(rng_buffer, bytes_read, 0);
> > >  }
> > > 
> > >  static inline void cleanup_rng(struct kref *kref)
> > 
> > I found your patch by chance, searching for a solution for crng init delay
> > on my
> > headless machine. Unfortunately it hardly makes any difference for me. With
> > the
> > patch the system hangs for about 80s instead of 120s until the "crng init
> > done"
> > message.In contrast, doing a `cat /dev/hwrng >/dev/random` or running rngd
> > initializes the crng instantly.
> > 
> > Isn't that delay the problem this patch tries to fix? Any idea what is wrong
> > here?
> > 
> > Thanks!
> > 
> > Best regards
> > Michael
> > 
> > 
> 
> Yes that is the problem this is trying to address. My guess would be
> rng_get_data() is not returning as much data as requested, so the
> delay is reduced but not eliminated. Looking at implementation of
> rng_get_data() it appears this could be caused by device support for
> read() vs data_read(). I don't have a good feel for whether looping to
> retrieve more data here would be acceptable, it is certainly a bigger
> change than currently proposed.
> 
> Thanks,
> Louis

Hi Louis,

that is what I thought first, too, but I was able to verify that 64 bytes are
read as expected.

It seems this is exactly what David noticed in your discussion about the quality
module parameter (https://patchwork.kernel.org/patch/10453893/#22130681):

> Interesting.
> 
> add_hwgenereator_randomness() will call crng_fast_load(), regardless
> of entropy estimate/quality, if crng_init is 0.  So initializing
> crng_init from the hwrng, regardless of quality, is already the
> intent.
> 
> But hw_random only calls add_hwgenerator_randomness() if
> current_quality > 0, via the hwrng_fillfn() kthread.
> 
> All that to say, I agree.  add_early_randomness() should (indirectly)
> call crng_fast_load(), like add_hwgenerator_randomness() does.

When I set rng_quality=1024, the crng does get initialized more or less
instantly.


dmesg with default rng_quality=0:

[    0.003831] ACPI: TPM2 0x000000009E0B7F70 000034 (v03 LENOVO TC-
S06   00001260 AMI  00000000)
[    0.161803] random: get_random_bytes called from start_kernel+0x8f/0x50e with
crng_init=0
[    3.590433] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0xFE, rev-id 2)
[    3.644148] random: fast init done
[   85.183006] random: crng init done


dmesg with rng_quality patch:

[    0.003837] ACPI: TPM2 0x000000009E0B7F70 000034 (v03 LENOVO TC-
S06   00001260 AMI  00000000)
[    0.162136] random: get_random_bytes called from start_kernel+0x8f/0x50e with
crng_init=0
[    3.582675] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0xFE, rev-id 2)
[    3.636408] random: fast init done
[    3.650355] random: crng init done


Test patch:

diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index f08949a5f678..59e5a8753ba1 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -214,6 +214,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info
*tpm_info)
        if (itpm || is_itpm(ACPI_COMPANION(dev)))
                phy->priv.flags |= TPM_TIS_ITPM_WORKAROUND;
 
+       priv->rng_quality = 1;
+
        return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg,
                                 ACPI_HANDLE(dev));
 }



Thanks
Michael



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] Allow hwrng to initialize crng.
  2018-12-15 17:11     ` Michael Niewöhner
@ 2018-12-15 18:20       ` Michael Niewöhner
  0 siblings, 0 replies; 7+ messages in thread
From: Michael Niewöhner @ 2018-12-15 18:20 UTC (permalink / raw)
  To: Louis Collard
  Cc: linux-integrity, Arnd Bergmann, Greg Kroah-Hartman, linux-kernel,
	Jarkko Sakkinen, Andrey Pronin, Jason Gunthorpe, David R. Bild

On Sat, 2018-12-15 at 18:11 +0100, Michael Niewöhner wrote:
> On Thu, 2018-12-13 at 12:50 +0800, Louis Collard wrote:
> > On Sun, Nov 18, 2018 at 4:15 AM Michael Niewöhner <linux@mniewoehner.de>
> > wrote:
> > > 
> > > Hi Louis,
> > > 
> > > On Wed, 2018-09-26 at 11:24 +0800, Louis Collard wrote:
> > > > Some systems, for example embedded systems, do not generate
> > > > enough entropy on boot through interrupts, and boot may be blocked for
> > > > several minutes waiting for a call to getrandom to complete.
> > > > 
> > > > Currently, random data is read from a hwrng when it is registered,
> > > > and is loaded into primary_crng. This data is treated in the same
> > > > way as data that is device-specific but otherwise unchanging, and
> > > > so primary_crng cannot become initialized with the data from the
> > > > hwrng.
> > > > 
> > > > This change causes the data initially read from the hwrng to be
> > > > treated the same as subsequent data that is read from the hwrng if
> > > > it's quality score is non-zero.
> > > > 
> > > > The implications of this are:
> > > > 
> > > > The data read from hwrng can cause primary_crng to become
> > > > initialized, therefore avoiding problems of getrandom blocking
> > > > on boot.
> > > > 
> > > > Calls to getrandom (with GRND_RANDOM) may be using entropy
> > > > exclusively (or in practise, almost exclusively) from the hwrng.
> > > > 
> > > > Regarding the latter point; this behavior is the same as if a
> > > > user specified a quality score of 1 (bit of entropy per 1024 bits)
> > > > so hopefully this is not too scary a change to make.
> > > > 
> > > > This change is the result of the discussion here:
> > > > https://patchwork.kernel.org/patch/10453893/
> > > > 
> > > > Signed-off-by: Louis Collard <louiscollard@chromium.org>
> > > > Acked-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > > > ---
> > > >  drivers/char/hw_random/core.c | 9 +++++++--
> > > >  1 file changed, 7 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/char/hw_random/core.c
> > > > b/drivers/char/hw_random/core.c
> > > > index aaf9e5afaad4..47f358aa0c3d 100644
> > > > --- a/drivers/char/hw_random/core.c
> > > > +++ b/drivers/char/hw_random/core.c
> > > > @@ -24,6 +24,7 @@
> > > >  #include <linux/sched.h>
> > > >  #include <linux/slab.h>
> > > >  #include <linux/uaccess.h>
> > > > +#include <crypto/chacha20.h>
> > > > 
> > > >  #define RNG_MODULE_NAME              "hw_random"
> > > > 
> > > > @@ -64,13 +65,17 @@ static size_t rng_buffer_size(void)
> > > >  static void add_early_randomness(struct hwrng *rng)
> > > >  {
> > > >       int bytes_read;
> > > > -     size_t size = min_t(size_t, 16, rng_buffer_size());
> > > > +     /* Read enough to initialize crng. */
> > > > +     size_t size = 2*CHACHA20_KEY_SIZE;
> > > > 
> > > >       mutex_lock(&reading_mutex);
> > > >       bytes_read = rng_get_data(rng, rng_buffer, size, 1);
> > > >       mutex_unlock(&reading_mutex);
> > > >       if (bytes_read > 0)
> > > > -             add_device_randomness(rng_buffer, bytes_read);
> > > > +             /* Allow crng to become initialized, but do not add
> > > > +              * entropy to the pool.
> > > > +              */
> > > > +             add_hwgenerator_randomness(rng_buffer, bytes_read, 0);
> > > >  }
> > > > 
> > > >  static inline void cleanup_rng(struct kref *kref)
> > > 
> > > I found your patch by chance, searching for a solution for crng init delay
> > > on my
> > > headless machine. Unfortunately it hardly makes any difference for me.
> > > With
> > > the
> > > patch the system hangs for about 80s instead of 120s until the "crng init
> > > done"
> > > message.In contrast, doing a `cat /dev/hwrng >/dev/random` or running rngd
> > > initializes the crng instantly.
> > > 
> > > Isn't that delay the problem this patch tries to fix? Any idea what is
> > > wrong
> > > here?
> > > 
> > > Thanks!
> > > 
> > > Best regards
> > > Michael
> > > 
> > > 
> > 
> > Yes that is the problem this is trying to address. My guess would be
> > rng_get_data() is not returning as much data as requested, so the
> > delay is reduced but not eliminated. Looking at implementation of
> > rng_get_data() it appears this could be caused by device support for
> > read() vs data_read(). I don't have a good feel for whether looping to
> > retrieve more data here would be acceptable, it is certainly a bigger
> > change than currently proposed.
> > 
> > Thanks,
> > Louis
> 
> Hi Louis,
> 
> that is what I thought first, too, but I was able to verify that 64 bytes are
> read as expected.
> 
> It seems this is exactly what David noticed in your discussion about the
> quality
> module parameter (https://patchwork.kernel.org/patch/10453893/#22130681):
> 
> > Interesting.
> > 
> > add_hwgenereator_randomness() will call crng_fast_load(), regardless
> > of entropy estimate/quality, if crng_init is 0.  So initializing
> > crng_init from the hwrng, regardless of quality, is already the
> > intent.
> > 
> > But hw_random only calls add_hwgenerator_randomness() if
> > current_quality > 0, via the hwrng_fillfn() kthread.
> > 
> > All that to say, I agree.  add_early_randomness() should (indirectly)
> > call crng_fast_load(), like add_hwgenerator_randomness() does.
> 
> When I set rng_quality=1024, the crng does get initialized more or less
> instantly.
> 
> 
> dmesg with default rng_quality=0:
> 
> [    0.003831] ACPI: TPM2 0x000000009E0B7F70 000034 (v03 LENOVO TC-
> S06   00001260 AMI  00000000)
> [    0.161803] random: get_random_bytes called from start_kernel+0x8f/0x50e
> with
> crng_init=0
> [    3.590433] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0xFE, rev-id 2)
> [    3.644148] random: fast init done
> [   85.183006] random: crng init done
> 
> 
> dmesg with rng_quality patch:
> 
> [    0.003837] ACPI: TPM2 0x000000009E0B7F70 000034 (v03 LENOVO TC-
> S06   00001260 AMI  00000000)
> [    0.162136] random: get_random_bytes called from start_kernel+0x8f/0x50e
> with
> crng_init=0
> [    3.582675] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0xFE, rev-id 2)
> [    3.636408] random: fast init done
> [    3.650355] random: crng init done
> 
> 
> Test patch:
> 
> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> index f08949a5f678..59e5a8753ba1 100644
> --- a/drivers/char/tpm/tpm_tis.c
> +++ b/drivers/char/tpm/tpm_tis.c
> @@ -214,6 +214,8 @@ static int tpm_tis_init(struct device *dev, struct
> tpm_info
> *tpm_info)
>         if (itpm || is_itpm(ACPI_COMPANION(dev)))
>                 phy->priv.flags |= TPM_TIS_ITPM_WORKAROUND;
>  
> +       priv->rng_quality = 1;
> +
>         return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg,
>                                  ACPI_HANDLE(dev));
>  }
> 
> 
> 
> Thanks
> Michael


Hi Louis,

I think I might know what is causing the delay of crng init.

Your patch is working as expected but only for fast init.
add_hwgenerator_randomness calls crng_fast_load which does stage 1
initialization of the crng ("fast init done" -> crng_init=1).

Currently no entropy comes from the TPM at all for 1) the second stage init /
reseed 2) later operation because tpm_tis sets no quality while the default in
tpm-chip is quality=0 and so khwrngd will not be started in hwrng_init.
This is why setting the quality to 1024 instantly leads to setting crng_init=2
and reseeding the crng ("crng init done").

That means the current default value of rng_quality=0 renders the tpm hwrng
completely useless.





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-12-15 18:20 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-26  3:24 [PATCH] Allow hwrng to initialize crng Louis Collard
2018-09-26 10:35 ` Jarkko Sakkinen
2018-10-05  1:45   ` Louis Collard
2018-11-17 20:15 ` Michael Niewöhner
2018-12-13  4:50   ` Louis Collard
2018-12-15 17:11     ` Michael Niewöhner
2018-12-15 18:20       ` Michael Niewöhner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).