linux-crypto.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] random: mix in timestamps and reseed on system restore
@ 2022-05-01 12:38 Jason A. Donenfeld
  2022-05-13  6:25 ` Dominik Brodowski
  0 siblings, 1 reply; 3+ messages in thread
From: Jason A. Donenfeld @ 2022-05-01 12:38 UTC (permalink / raw)
  To: linux-kernel, linux-crypto; +Cc: Jason A. Donenfeld, Theodore Ts'o

Since the RNG loses freshness system suspend/hibernation, when we
resume, immediately reseed using whatever data we can, which for this
particular case is the various timestamps regarding system suspend time,
in addition to more generally the RDSEED/RDRAND/RDTSC values that happen
whenever the crng reseeds.

On systems that suspend and resume automatically all the time -- such as
Android -- we skip the reseeding on suspend resumption, since that could
wind up being far too busy. This is the same trade-off made in
WireGuard.

In addition to reseeding upon resumption always mix into the pool these
various stamps on every power notification event.

Cc: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/char/random.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0935a140795e..48eac27214ea 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -53,6 +53,7 @@
 #include <linux/completion.h>
 #include <linux/uuid.h>
 #include <linux/uaccess.h>
+#include <linux/suspend.h>
 #include <crypto/chacha.h>
 #include <crypto/blake2s.h>
 #include <asm/processor.h>
@@ -966,6 +967,37 @@ static int __init parse_trust_bootloader(char *arg)
 early_param("random.trust_cpu", parse_trust_cpu);
 early_param("random.trust_bootloader", parse_trust_bootloader);
 
+static int random_pm_notification(struct notifier_block *nb, unsigned long action, void *data)
+{
+	unsigned long flags, entropy = random_get_entropy();
+
+	/*
+	 * Encode a representation of how long the system has been suspended,
+	 * in a way that is distinct from prior system suspends.
+	 */
+	ktime_t stamps[] = {
+		ktime_get(),
+		ktime_get_boottime(),
+		ktime_get_real()
+	};
+
+	spin_lock_irqsave(&input_pool.lock, flags);
+	_mix_pool_bytes(&action, sizeof(action));
+	_mix_pool_bytes(stamps, sizeof(stamps));
+	_mix_pool_bytes(&entropy, sizeof(entropy));
+	spin_unlock_irqrestore(&input_pool.lock, flags);
+
+	if (action == PM_RESTORE_PREPARE ||
+	    (action == PM_POST_SUSPEND &&
+	     !IS_ENABLED(CONFIG_PM_AUTOSLEEP) && !IS_ENABLED(CONFIG_ANDROID))) {
+		crng_reseed(true);
+		pr_notice("crng reseeded on system resumption\n");
+	}
+	return 0;
+}
+
+static struct notifier_block pm_notifier = { .notifier_call = random_pm_notification };
+
 /*
  * The first collection of entropy occurs at system boot while interrupts
  * are still turned off. Here we push in RDSEED, a timestamp, and utsname().
@@ -1009,6 +1041,8 @@ int __init rand_initialize(void)
 		unseeded_warning.interval = 0;
 	}
 
+	WARN_ON(register_pm_notifier(&pm_notifier));
+
 	WARN(!random_get_entropy(), "Missing cycle counter and fallback timer; RNG "
 				    "entropy collection will consequently suffer.");
 	return 0;
-- 
2.35.1


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

* Re: [PATCH] random: mix in timestamps and reseed on system restore
  2022-05-01 12:38 [PATCH] random: mix in timestamps and reseed on system restore Jason A. Donenfeld
@ 2022-05-13  6:25 ` Dominik Brodowski
  2022-05-13 10:10   ` Jason A. Donenfeld
  0 siblings, 1 reply; 3+ messages in thread
From: Dominik Brodowski @ 2022-05-13  6:25 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: linux-kernel, linux-crypto, Theodore Ts'o

Am Sun, May 01, 2022 at 02:38:49PM +0200 schrieb Jason A. Donenfeld:
> Since the RNG loses freshness system suspend/hibernation, when we
> resume, immediately reseed using whatever data we can, which for this
> particular case is the various timestamps regarding system suspend time,
> in addition to more generally the RDSEED/RDRAND/RDTSC values that happen
> whenever the crng reseeds.
> 
> On systems that suspend and resume automatically all the time -- such as
> Android -- we skip the reseeding on suspend resumption, since that could
> wind up being far too busy. This is the same trade-off made in
> WireGuard.
> 
> In addition to reseeding upon resumption always mix into the pool these
> various stamps on every power notification event.
> 
> Cc: Theodore Ts'o <tytso@mit.edu>
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>  drivers/char/random.c | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/drivers/char/random.c b/drivers/char/random.c
> index 0935a140795e..48eac27214ea 100644
> --- a/drivers/char/random.c
> +++ b/drivers/char/random.c
> @@ -53,6 +53,7 @@
>  #include <linux/completion.h>
>  #include <linux/uuid.h>
>  #include <linux/uaccess.h>
> +#include <linux/suspend.h>
>  #include <crypto/chacha.h>
>  #include <crypto/blake2s.h>
>  #include <asm/processor.h>
> @@ -966,6 +967,37 @@ static int __init parse_trust_bootloader(char *arg)
>  early_param("random.trust_cpu", parse_trust_cpu);
>  early_param("random.trust_bootloader", parse_trust_bootloader);
>  
> +static int random_pm_notification(struct notifier_block *nb, unsigned long action, void *data)
> +{
> +	unsigned long flags, entropy = random_get_entropy();
> +
> +	/*
> +	 * Encode a representation of how long the system has been suspended,
> +	 * in a way that is distinct from prior system suspends.
> +	 */
> +	ktime_t stamps[] = {
> +		ktime_get(),
> +		ktime_get_boottime(),
> +		ktime_get_real()
> +	};
> +
> +	spin_lock_irqsave(&input_pool.lock, flags);
> +	_mix_pool_bytes(&action, sizeof(action));
> +	_mix_pool_bytes(stamps, sizeof(stamps));
> +	_mix_pool_bytes(&entropy, sizeof(entropy));
> +	spin_unlock_irqrestore(&input_pool.lock, flags);
> +
> +	if (action == PM_RESTORE_PREPARE ||
> +	    (action == PM_POST_SUSPEND &&
> +	     !IS_ENABLED(CONFIG_PM_AUTOSLEEP) && !IS_ENABLED(CONFIG_ANDROID))) {
> +		crng_reseed(true);
> +		pr_notice("crng reseeded on system resumption\n");
> +	}
> +	return 0;
> +}

Should this also wake up any thread waiting in add_hwgenerator_randomness()
/ "use" the input already in store there?

Thanks,
	Dominik

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

* Re: [PATCH] random: mix in timestamps and reseed on system restore
  2022-05-13  6:25 ` Dominik Brodowski
@ 2022-05-13 10:10   ` Jason A. Donenfeld
  0 siblings, 0 replies; 3+ messages in thread
From: Jason A. Donenfeld @ 2022-05-13 10:10 UTC (permalink / raw)
  To: Dominik Brodowski; +Cc: linux-kernel, linux-crypto, Theodore Ts'o

Hi Dominik,

On Fri, May 13, 2022 at 08:25:12AM +0200, Dominik Brodowski wrote:
> Am Sun, May 01, 2022 at 02:38:49PM +0200 schrieb Jason A. Donenfeld:
> > Since the RNG loses freshness system suspend/hibernation, when we
> > resume, immediately reseed using whatever data we can, which for this
> > particular case is the various timestamps regarding system suspend time,
> > in addition to more generally the RDSEED/RDRAND/RDTSC values that happen
> > whenever the crng reseeds.
> > 
> > On systems that suspend and resume automatically all the time -- such as
> > Android -- we skip the reseeding on suspend resumption, since that could
> > wind up being far too busy. This is the same trade-off made in
> > WireGuard.
> > 
> > In addition to reseeding upon resumption always mix into the pool these
> > various stamps on every power notification event.
> > 
> > Cc: Theodore Ts'o <tytso@mit.edu>
> > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> > ---
> >  drivers/char/random.c | 34 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 34 insertions(+)
> > 
> > diff --git a/drivers/char/random.c b/drivers/char/random.c
> > index 0935a140795e..48eac27214ea 100644
> > --- a/drivers/char/random.c
> > +++ b/drivers/char/random.c
> > @@ -53,6 +53,7 @@
> >  #include <linux/completion.h>
> >  #include <linux/uuid.h>
> >  #include <linux/uaccess.h>
> > +#include <linux/suspend.h>
> >  #include <crypto/chacha.h>
> >  #include <crypto/blake2s.h>
> >  #include <asm/processor.h>
> > @@ -966,6 +967,37 @@ static int __init parse_trust_bootloader(char *arg)
> >  early_param("random.trust_cpu", parse_trust_cpu);
> >  early_param("random.trust_bootloader", parse_trust_bootloader);
> >  
> > +static int random_pm_notification(struct notifier_block *nb, unsigned long action, void *data)
> > +{
> > +	unsigned long flags, entropy = random_get_entropy();
> > +
> > +	/*
> > +	 * Encode a representation of how long the system has been suspended,
> > +	 * in a way that is distinct from prior system suspends.
> > +	 */
> > +	ktime_t stamps[] = {
> > +		ktime_get(),
> > +		ktime_get_boottime(),
> > +		ktime_get_real()
> > +	};
> > +
> > +	spin_lock_irqsave(&input_pool.lock, flags);
> > +	_mix_pool_bytes(&action, sizeof(action));
> > +	_mix_pool_bytes(stamps, sizeof(stamps));
> > +	_mix_pool_bytes(&entropy, sizeof(entropy));
> > +	spin_unlock_irqrestore(&input_pool.lock, flags);
> > +
> > +	if (action == PM_RESTORE_PREPARE ||
> > +	    (action == PM_POST_SUSPEND &&
> > +	     !IS_ENABLED(CONFIG_PM_AUTOSLEEP) && !IS_ENABLED(CONFIG_ANDROID))) {
> > +		crng_reseed(true);
> > +		pr_notice("crng reseeded on system resumption\n");
> > +	}
> > +	return 0;
> > +}
> 
> Should this also wake up any thread waiting in add_hwgenerator_randomness()
> / "use" the input already in store there?

That would be a nice enhancement I think. Feel free to submit a patch.
Maybe more generally, the add_hwgenerator_randomness() thing should wake
up not based on a timer but just everytime crng_reseed() is called by
something? There are a lot of ways to skin that cat, and hopefully we'll
be able to really revamp the way hwrandomness is used in the future,
both here and other concerns you've brought up like 0 crediting.

Jason

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

end of thread, other threads:[~2022-05-13 10:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-01 12:38 [PATCH] random: mix in timestamps and reseed on system restore Jason A. Donenfeld
2022-05-13  6:25 ` Dominik Brodowski
2022-05-13 10:10   ` Jason A. Donenfeld

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).