linux-crypto.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] crypto: Jitter RNG - Permanent and Intermittent health errors
@ 2023-03-23  7:17 Stephan Müller
  2023-03-24  9:27 ` Herbert Xu
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Stephan Müller @ 2023-03-23  7:17 UTC (permalink / raw)
  To: linux-crypto, herbert

According to SP800-90B, two health failures are allowed: the intermittend
and the permanent failure. So far, only the intermittent failure was
implemented. The permanent failure was achieved by resetting the entire
entropy source including its health test state and waiting for two or
more back-to-back health errors.

This approach is appropriate for RCT, but not for APT as APT has a
non-linear cutoff value. Thus, this patch implements 2 cutoff values
for both RCT/APT. This implies that the health state is left untouched
when an intermittent failure occurs. The noise source is reset
and a new APT powerup-self test is performed. Yet, whith the unchanged
health test state, the counting of failures continues until a permanent
failure is reached.

Any non-failing raw entropy value causes the health tests to reset.

The intermittent error has an unchanged significance level of 2^-30.
The permanent error has a significance level of 2^-60. Considering that
this level also indicates a false-positive rate (see SP800-90B section 4.2)
a false-positive must only be incurred with a low probability when
considering a fleet of Linux kernels as a whole. Hitting the permanent
error may cause a panic(), the following calculation applies: Assuming
that a fleet of 10^9 Linux kernels run concurrently with this patch in
FIPS mode and on each kernel 2 health tests are performed every minute
for one year, the chances of a false positive is about 1:1000
based on the binomial distribution.

In addition, any power-up health test errors triggered with
jent_entropy_init are treated as permanent errors.

A permanent failure causes the entire entropy source to permanently
return an error. This implies that a caller can only remedy the situation
by re-allocating a new instance of the Jitter RNG. In a subsequent
patch, a transparent re-allocation will be provided which also changes
the implied heuristic entropy assessment.

In addition, when the kernel is booted with fips=1, the Jitter RNG
is defined to be part of a FIPS module. The permanent error of the
Jitter RNG is translated as a FIPS module error. In this case, the entire
FIPS module must cease operation. This is implemented in the kernel by
invoking panic().

The patch also fixes an off-by-one in the RCT cutoff value which is now
set to 30 instead of 31. This is because the counting of the values
starts with 0.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 crypto/jitterentropy-kcapi.c |  45 ++++++-----
 crypto/jitterentropy.c       | 144 +++++++++++++----------------------
 2 files changed, 80 insertions(+), 109 deletions(-)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index 2d115bec15ae..31d0fd57791b 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -37,6 +37,7 @@
  * DAMAGE.
  */
 
+#include <linux/fips.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -102,7 +103,7 @@ void jent_get_nstime(__u64 *out)
 struct jitterentropy {
 	spinlock_t jent_lock;
 	struct rand_data *entropy_collector;
-	unsigned int reset_cnt;
+	bool disabled;
 };
 
 static int jent_kcapi_init(struct crypto_tfm *tfm)
@@ -138,29 +139,35 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
 
 	spin_lock(&rng->jent_lock);
 
-	/* Return a permanent error in case we had too many resets in a row. */
-	if (rng->reset_cnt > (1<<10)) {
+	/* Enforce a disabled entropy source. */
+	if (rng->disabled) {
 		ret = -EFAULT;
 		goto out;
 	}
 
 	ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
 
-	/* Reset RNG in case of health failures */
-	if (ret < -1) {
-		pr_warn_ratelimited("Reset Jitter RNG due to health test failure: %s failure\n",
-				    (ret == -2) ? "Repetition Count Test" :
-						  "Adaptive Proportion Test");
-
-		rng->reset_cnt++;
-
+	if (ret == -3) {
+		/* Handle permanent health test error */
+		/*
+		 * If the kernel was booted with fips=2, it implies that
+		 * the entire kernel acts as a FIPS 140 module. In this case
+		 * an SP800-90B permanent health test error is treated as
+		 * a FIPS module error.
+		 */
+		if (fips_enabled)
+			panic("Jitter RNG permanent health test failure\n");
+
+		pr_err("Jitter RNG permanent health test failure - disabling entropy source\n");
+		rng->disabled = true;
+		ret = -EFAULT;
+	} else if (ret == -2) {
+		/* Handle intermittent health test error */
+		pr_warn_ratelimited("Reset Jitter RNG due to intermittent health test failure\n");
 		ret = -EAGAIN;
-	} else {
-		rng->reset_cnt = 0;
-
-		/* Convert the Jitter RNG error into a usable error code */
-		if (ret == -1)
-			ret = -EINVAL;
+	} else if (ret == -1) {
+		/* Handle other errors */
+		ret = -EINVAL;
 	}
 
 out:
@@ -197,6 +204,10 @@ static int __init jent_mod_init(void)
 
 	ret = jent_entropy_init();
 	if (ret) {
+		/* Handle permanent health test error */
+		if (fips_enabled)
+			panic("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
+
 		pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
 		return -EFAULT;
 	}
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 93bff3213823..aa04749c6e46 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -85,10 +85,14 @@ struct rand_data {
 				      * bit generation */
 
 	/* Repetition Count Test */
-	int rct_count;			/* Number of stuck values */
+	unsigned int rct_count;			/* Number of stuck values */
 
-	/* Adaptive Proportion Test for a significance level of 2^-30 */
+	/* Intermittent health test failure threshold of 2^-30 */
+#define JENT_RCT_CUTOFF		30	/* Taken from SP800-90B sec 4.4.1 */
 #define JENT_APT_CUTOFF		325	/* Taken from SP800-90B sec 4.4.2 */
+	/* Permanent health test failure threshold of 2^-60 */
+#define JENT_RCT_CUTOFF_PERMANENT	60
+#define JENT_APT_CUTOFF_PERMANENT	355
 #define JENT_APT_WINDOW_SIZE	512	/* Data window size */
 	/* LSB of time stamp to process */
 #define JENT_APT_LSB		16
@@ -97,8 +101,6 @@ struct rand_data {
 	unsigned int apt_count;		/* APT counter */
 	unsigned int apt_base;		/* APT base reference */
 	unsigned int apt_base_set:1;	/* APT base reference set? */
-
-	unsigned int health_failure:1;	/* Permanent health failure */
 };
 
 /* Flags that can be used to initialize the RNG */
@@ -169,19 +171,26 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
 		return;
 	}
 
-	if (delta_masked == ec->apt_base) {
+	if (delta_masked == ec->apt_base)
 		ec->apt_count++;
 
-		if (ec->apt_count >= JENT_APT_CUTOFF)
-			ec->health_failure = 1;
-	}
-
 	ec->apt_observations++;
 
 	if (ec->apt_observations >= JENT_APT_WINDOW_SIZE)
 		jent_apt_reset(ec, delta_masked);
 }
 
+/* APT health test failure detection */
+static int jent_apt_permanent_failure(struct rand_data *ec)
+{
+	return (ec->apt_count >= JENT_APT_CUTOFF_PERMANENT) ? 1 : 0;
+}
+
+static int jent_apt_failure(struct rand_data *ec)
+{
+	return (ec->apt_count >= JENT_APT_CUTOFF) ? 1 : 0;
+}
+
 /***************************************************************************
  * Stuck Test and its use as Repetition Count Test
  *
@@ -206,55 +215,14 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
  */
 static void jent_rct_insert(struct rand_data *ec, int stuck)
 {
-	/*
-	 * If we have a count less than zero, a previous RCT round identified
-	 * a failure. We will not overwrite it.
-	 */
-	if (ec->rct_count < 0)
-		return;
-
 	if (stuck) {
 		ec->rct_count++;
-
-		/*
-		 * The cutoff value is based on the following consideration:
-		 * alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8.
-		 * In addition, we require an entropy value H of 1/OSR as this
-		 * is the minimum entropy required to provide full entropy.
-		 * Note, we collect 64 * OSR deltas for inserting them into
-		 * the entropy pool which should then have (close to) 64 bits
-		 * of entropy.
-		 *
-		 * Note, ec->rct_count (which equals to value B in the pseudo
-		 * code of SP800-90B section 4.4.1) starts with zero. Hence
-		 * we need to subtract one from the cutoff value as calculated
-		 * following SP800-90B.
-		 */
-		if ((unsigned int)ec->rct_count >= (31 * ec->osr)) {
-			ec->rct_count = -1;
-			ec->health_failure = 1;
-		}
 	} else {
+		/* Reset RCT */
 		ec->rct_count = 0;
 	}
 }
 
-/*
- * Is there an RCT health test failure?
- *
- * @ec [in] Reference to entropy collector
- *
- * @return
- * 	0 No health test failure
- * 	1 Permanent health test failure
- */
-static int jent_rct_failure(struct rand_data *ec)
-{
-	if (ec->rct_count < 0)
-		return 1;
-	return 0;
-}
-
 static inline __u64 jent_delta(__u64 prev, __u64 next)
 {
 #define JENT_UINT64_MAX		(__u64)(~((__u64) 0))
@@ -303,18 +271,26 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta)
 	return 0;
 }
 
-/*
- * Report any health test failures
- *
- * @ec [in] Reference to entropy collector
- *
- * @return
- * 	0 No health test failure
- * 	1 Permanent health test failure
- */
+/* RCT health test failure detection */
+static int jent_rct_permanent_failure(struct rand_data *ec)
+{
+	return (ec->rct_count >= JENT_RCT_CUTOFF_PERMANENT) ? 1 : 0;
+}
+
+static int jent_rct_failure(struct rand_data *ec)
+{
+	return (ec->rct_count >= JENT_RCT_CUTOFF) ? 1 : 0;
+}
+
+/* Report of health test failures */
 static int jent_health_failure(struct rand_data *ec)
 {
-	return ec->health_failure;
+	return jent_rct_failure(ec) | jent_apt_failure(ec);
+}
+
+static int jent_permanent_health_failure(struct rand_data *ec)
+{
+	return jent_rct_permanent_failure(ec) | jent_apt_permanent_failure(ec);
 }
 
 /***************************************************************************
@@ -600,8 +576,8 @@ static void jent_gen_entropy(struct rand_data *ec)
  *
  * The following error codes can occur:
  *	-1	entropy_collector is NULL
- *	-2	RCT failed
- *	-3	APT test failed
+ *	-2	Intermittent health failure
+ *	-3	Permanent health failure
  */
 int jent_read_entropy(struct rand_data *ec, unsigned char *data,
 		      unsigned int len)
@@ -616,39 +592,23 @@ int jent_read_entropy(struct rand_data *ec, unsigned char *data,
 
 		jent_gen_entropy(ec);
 
-		if (jent_health_failure(ec)) {
-			int ret;
-
-			if (jent_rct_failure(ec))
-				ret = -2;
-			else
-				ret = -3;
-
+		if (jent_permanent_health_failure(ec)) {
 			/*
-			 * Re-initialize the noise source
-			 *
-			 * If the health test fails, the Jitter RNG remains
-			 * in failure state and will return a health failure
-			 * during next invocation.
+			 * At this point, the Jitter RNG instance is considered
+			 * as a failed instance. There is no rerun of the
+			 * startup test any more, because the caller
+			 * is assumed to not further use this instance.
 			 */
-			if (jent_entropy_init())
-				return ret;
-
-			/* Set APT to initial state */
-			jent_apt_reset(ec, 0);
-			ec->apt_base_set = 0;
-
-			/* Set RCT to initial state */
-			ec->rct_count = 0;
-
-			/* Re-enable Jitter RNG */
-			ec->health_failure = 0;
-
+			return -3;
+		} else if (jent_health_failure(ec)) {
 			/*
-			 * Return the health test failure status to the
-			 * caller as the generated value is not appropriate.
+			 * Perform startup health tests and return permanent
+			 * error if it fails.
 			 */
-			return ret;
+			if (jent_entropy_init())
+				return -3;
+
+			return -2;
 		}
 
 		if ((DATA_SIZE_BITS / 8) < len)
-- 
2.40.0





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

* Re: [PATCH] crypto: Jitter RNG - Permanent and Intermittent health errors
  2023-03-23  7:17 [PATCH] crypto: Jitter RNG - Permanent and Intermittent health errors Stephan Müller
@ 2023-03-24  9:27 ` Herbert Xu
  2023-03-24 12:01   ` Stephan Mueller
  2023-03-24 12:30 ` [PATCH v2] " Stephan Müller
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: Herbert Xu @ 2023-03-24  9:27 UTC (permalink / raw)
  To: Stephan Müller; +Cc: linux-crypto

On Thu, Mar 23, 2023 at 08:17:14AM +0100, Stephan Müller wrote:
>
> @@ -138,29 +139,35 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
>  
>  	spin_lock(&rng->jent_lock);
>  
> -	/* Return a permanent error in case we had too many resets in a row. */
> -	if (rng->reset_cnt > (1<<10)) {
> +	/* Enforce a disabled entropy source. */
> +	if (rng->disabled) {
>  		ret = -EFAULT;
>  		goto out;
>  	}

Can we please get rid of this completely when we're not in FIPS 
mode? Remember that jent is now used by all kernel users through
drbg.  Having it fail permanently in this fashion is unacceptable.

If we're not in FIPS mode it should simply carry on or at least
seek another source of entropy, perhaps from the kernel RNG.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH] crypto: Jitter RNG - Permanent and Intermittent health errors
  2023-03-24  9:27 ` Herbert Xu
@ 2023-03-24 12:01   ` Stephan Mueller
  0 siblings, 0 replies; 13+ messages in thread
From: Stephan Mueller @ 2023-03-24 12:01 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto

Am Freitag, 24. März 2023, 10:27:37 CET schrieb Herbert Xu:

Hi Herbert,

> On Thu, Mar 23, 2023 at 08:17:14AM +0100, Stephan Müller wrote:
> > @@ -138,29 +139,35 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
> > 
> >  	spin_lock(&rng->jent_lock);
> > 
> > -	/* Return a permanent error in case we had too many resets in a row. */
> > -	if (rng->reset_cnt > (1<<10)) {
> > +	/* Enforce a disabled entropy source. */
> > +	if (rng->disabled) {
> > 
> >  		ret = -EFAULT;
> >  		goto out;
> >  	
> >  	}
> 
> Can we please get rid of this completely when we're not in FIPS
> mode? Remember that jent is now used by all kernel users through
> drbg.  Having it fail permanently in this fashion is unacceptable.
> 
> If we're not in FIPS mode it should simply carry on or at least
> seek another source of entropy, perhaps from the kernel RNG.

I will remove that from this patch. I plan to release another patch where the 
oversampling rate will be increased in case of such health errors. This 
increase in the oversampling rate would handle this issue much more 
gracefully.

Thanks

Ciao
Stephan



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

* [PATCH v2] Jitter RNG - Permanent and Intermittent health errors
  2023-03-23  7:17 [PATCH] crypto: Jitter RNG - Permanent and Intermittent health errors Stephan Müller
  2023-03-24  9:27 ` Herbert Xu
@ 2023-03-24 12:30 ` Stephan Müller
  2023-03-24 16:03   ` kernel test robot
  2023-03-24 17:00 ` [PATCH v3] " Stephan Müller
  2023-03-27  7:03 ` [PATCH v4] crypto: jitter - permanent and intermittent " Stephan Müller
  3 siblings, 1 reply; 13+ messages in thread
From: Stephan Müller @ 2023-03-24 12:30 UTC (permalink / raw)
  To: linux-crypto, herbert

According to SP800-90B, two health failures are allowed: the intermittend
and the permanent failure. So far, only the intermittent failure was
implemented. The permanent failure was achieved by resetting the entire
entropy source including its health test state and waiting for two or
more back-to-back health errors.

This approach is appropriate for RCT, but not for APT as APT has a
non-linear cutoff value. Thus, this patch implements 2 cutoff values
for both RCT/APT. This implies that the health state is left untouched
when an intermittent failure occurs. The noise source is reset
and a new APT powerup-self test is performed. Yet, whith the unchanged
health test state, the counting of failures continues until a permanent
failure is reached.

Any non-failing raw entropy value causes the health tests to reset.

The intermittent error has an unchanged significance level of 2^-30.
The permanent error has a significance level of 2^-60. Considering that
this level also indicates a false-positive rate (see SP800-90B section 4.2)
a false-positive must only be incurred with a low probability when
considering a fleet of Linux kernels as a whole. Hitting the permanent
error may cause a panic(), the following calculation applies: Assuming
that a fleet of 10^9 Linux kernels run concurrently with this patch in
FIPS mode and on each kernel 2 health tests are performed every minute
for one year, the chances of a false positive is about 1:1000
based on the binomial distribution.

In addition, any power-up health test errors triggered with
jent_entropy_init are treated as permanent errors.

A permanent failure causes the entire entropy source to permanently
return an error. This implies that a caller can only remedy the situation
by re-allocating a new instance of the Jitter RNG. In a subsequent
patch, a transparent re-allocation will be provided which also changes
the implied heuristic entropy assessment.

In addition, when the kernel is booted with fips=1, the Jitter RNG
is defined to be part of a FIPS module. The permanent error of the
Jitter RNG is translated as a FIPS module error. In this case, the entire
FIPS module must cease operation. This is implemented in the kernel by
invoking panic().

The patch also fixes an off-by-one in the RCT cutoff value which is now
set to 30 instead of 31. This is because the counting of the values
starts with 0.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---

v2:
 - Drop the enforcement of permanent disabling the entropy source

 crypto/jitterentropy-kcapi.c |  45 ++++++-----
 crypto/jitterentropy.c       | 144 +++++++++++++----------------------
 2 files changed, 76 insertions(+), 113 deletions(-)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index 2d115bec15ae..08addc63475b 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -37,6 +37,7 @@
  * DAMAGE.
  */
 
+#include <linux/fips.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -102,7 +103,6 @@ void jent_get_nstime(__u64 *out)
 struct jitterentropy {
 	spinlock_t jent_lock;
 	struct rand_data *entropy_collector;
-	unsigned int reset_cnt;
 };
 
 static int jent_kcapi_init(struct crypto_tfm *tfm)
@@ -138,29 +138,28 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
 
 	spin_lock(&rng->jent_lock);
 
-	/* Return a permanent error in case we had too many resets in a row. */
-	if (rng->reset_cnt > (1<<10)) {
-		ret = -EFAULT;
-		goto out;
-	}
-
 	ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
 
-	/* Reset RNG in case of health failures */
-	if (ret < -1) {
-		pr_warn_ratelimited("Reset Jitter RNG due to health test failure: %s failure\n",
-				    (ret == -2) ? "Repetition Count Test" :
-						  "Adaptive Proportion Test");
-
-		rng->reset_cnt++;
-
+	if (ret == -3) {
+		/* Handle permanent health test error */
+		/*
+		 * If the kernel was booted with fips=2, it implies that
+		 * the entire kernel acts as a FIPS 140 module. In this case
+		 * an SP800-90B permanent health test error is treated as
+		 * a FIPS module error.
+		 */
+		if (fips_enabled)
+			panic("Jitter RNG permanent health test failure\n");
+
+		pr_err("Jitter RNG permanent health test failure\n");
+		ret = -EFAULT;
+	} else if (ret == -2) {
+		/* Handle intermittent health test error */
+		pr_warn_ratelimited("Reset Jitter RNG due to intermittent health test failure\n");
 		ret = -EAGAIN;
-	} else {
-		rng->reset_cnt = 0;
-
-		/* Convert the Jitter RNG error into a usable error code */
-		if (ret == -1)
-			ret = -EINVAL;
+	} else if (ret == -1) {
+		/* Handle other errors */
+		ret = -EINVAL;
 	}
 
 out:
@@ -197,6 +196,10 @@ static int __init jent_mod_init(void)
 
 	ret = jent_entropy_init();
 	if (ret) {
+		/* Handle permanent health test error */
+		if (fips_enabled)
+			panic("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
+
 		pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
 		return -EFAULT;
 	}
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 93bff3213823..22f48bf4c6f5 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -85,10 +85,14 @@ struct rand_data {
 				      * bit generation */
 
 	/* Repetition Count Test */
-	int rct_count;			/* Number of stuck values */
+	unsigned int rct_count;			/* Number of stuck values */
 
-	/* Adaptive Proportion Test for a significance level of 2^-30 */
+	/* Intermittent health test failure threshold of 2^-30 */
+#define JENT_RCT_CUTOFF		30	/* Taken from SP800-90B sec 4.4.1 */
 #define JENT_APT_CUTOFF		325	/* Taken from SP800-90B sec 4.4.2 */
+	/* Permanent health test failure threshold of 2^-60 */
+#define JENT_RCT_CUTOFF_PERMANENT	60
+#define JENT_APT_CUTOFF_PERMANENT	355
 #define JENT_APT_WINDOW_SIZE	512	/* Data window size */
 	/* LSB of time stamp to process */
 #define JENT_APT_LSB		16
@@ -97,8 +101,6 @@ struct rand_data {
 	unsigned int apt_count;		/* APT counter */
 	unsigned int apt_base;		/* APT base reference */
 	unsigned int apt_base_set:1;	/* APT base reference set? */
-
-	unsigned int health_failure:1;	/* Permanent health failure */
 };
 
 /* Flags that can be used to initialize the RNG */
@@ -169,19 +171,26 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
 		return;
 	}
 
-	if (delta_masked == ec->apt_base) {
+	if (delta_masked == ec->apt_base)
 		ec->apt_count++;
 
-		if (ec->apt_count >= JENT_APT_CUTOFF)
-			ec->health_failure = 1;
-	}
-
 	ec->apt_observations++;
 
 	if (ec->apt_observations >= JENT_APT_WINDOW_SIZE)
 		jent_apt_reset(ec, delta_masked);
 }
 
+/* APT health test failure detection */
+static int jent_apt_permanent_failure(struct rand_data *ec)
+{
+	return (ec->apt_count >= JENT_APT_CUTOFF_PERMANENT) ? 1 : 0;
+}
+
+static int jent_apt_failure(struct rand_data *ec)
+{
+	return (ec->apt_count >= JENT_APT_CUTOFF) ? 1 : 0;
+}
+
 /***************************************************************************
  * Stuck Test and its use as Repetition Count Test
  *
@@ -206,55 +215,14 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
  */
 static void jent_rct_insert(struct rand_data *ec, int stuck)
 {
-	/*
-	 * If we have a count less than zero, a previous RCT round identified
-	 * a failure. We will not overwrite it.
-	 */
-	if (ec->rct_count < 0)
-		return;
-
 	if (stuck) {
 		ec->rct_count++;
-
-		/*
-		 * The cutoff value is based on the following consideration:
-		 * alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8.
-		 * In addition, we require an entropy value H of 1/OSR as this
-		 * is the minimum entropy required to provide full entropy.
-		 * Note, we collect 64 * OSR deltas for inserting them into
-		 * the entropy pool which should then have (close to) 64 bits
-		 * of entropy.
-		 *
-		 * Note, ec->rct_count (which equals to value B in the pseudo
-		 * code of SP800-90B section 4.4.1) starts with zero. Hence
-		 * we need to subtract one from the cutoff value as calculated
-		 * following SP800-90B.
-		 */
-		if ((unsigned int)ec->rct_count >= (31 * ec->osr)) {
-			ec->rct_count = -1;
-			ec->health_failure = 1;
-		}
 	} else {
+		/* Reset RCT */
 		ec->rct_count = 0;
 	}
 }
 
-/*
- * Is there an RCT health test failure?
- *
- * @ec [in] Reference to entropy collector
- *
- * @return
- * 	0 No health test failure
- * 	1 Permanent health test failure
- */
-static int jent_rct_failure(struct rand_data *ec)
-{
-	if (ec->rct_count < 0)
-		return 1;
-	return 0;
-}
-
 static inline __u64 jent_delta(__u64 prev, __u64 next)
 {
 #define JENT_UINT64_MAX		(__u64)(~((__u64) 0))
@@ -303,18 +271,26 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta)
 	return 0;
 }
 
-/*
- * Report any health test failures
- *
- * @ec [in] Reference to entropy collector
- *
- * @return
- * 	0 No health test failure
- * 	1 Permanent health test failure
- */
+/* RCT health test failure detection */
+static int jent_rct_permanent_failure(struct rand_data *ec)
+{
+	return (ec->rct_count >= JENT_RCT_CUTOFF_PERMANENT) ? 1 : 0;
+}
+
+static int jent_rct_failure(struct rand_data *ec)
+{
+	return (ec->rct_count >= JENT_RCT_CUTOFF) ? 1 : 0;
+}
+
+/* Report of health test failures */
 static int jent_health_failure(struct rand_data *ec)
 {
-	return ec->health_failure;
+	return jent_rct_failure(ec) | jent_apt_failure(ec);
+}
+
+static int jent_permanent_health_failure(struct rand_data *ec)
+{
+	return jent_rct_permanent_failure(ec) | jent_apt_permanent_failure(ec);
 }
 
 /***************************************************************************
@@ -600,8 +576,8 @@ static void jent_gen_entropy(struct rand_data *ec)
  *
  * The following error codes can occur:
  *	-1	entropy_collector is NULL
- *	-2	RCT failed
- *	-3	APT test failed
+ *	-2	Intermittent health failure
+ *	-3	Permanent health failure
  */
 int jent_read_entropy(struct rand_data *ec, unsigned char *data,
 		      unsigned int len)
@@ -616,39 +592,23 @@ int jent_read_entropy(struct rand_data *ec, unsigned char *data,
 
 		jent_gen_entropy(ec);
 
-		if (jent_health_failure(ec)) {
-			int ret;
-
-			if (jent_rct_failure(ec))
-				ret = -2;
-			else
-				ret = -3;
-
+		if (jent_permanent_health_failure(ec)) {
 			/*
-			 * Re-initialize the noise source
-			 *
-			 * If the health test fails, the Jitter RNG remains
-			 * in failure state and will return a health failure
-			 * during next invocation.
+			 * At this point, the Jitter RNG instance is considered
+			 * as a failed instance. There is no rerun of the
+			 * startup test any more, because the caller
+			 * is assumed to not further use this instance.
 			 */
-			if (jent_entropy_init())
-				return ret;
-
-			/* Set APT to initial state */
-			jent_apt_reset(ec, 0);
-			ec->apt_base_set = 0;
-
-			/* Set RCT to initial state */
-			ec->rct_count = 0;
-
-			/* Re-enable Jitter RNG */
-			ec->health_failure = 0;
-
+			return -3;
+		} else if (jent_health_failure(ec)) {
 			/*
-			 * Return the health test failure status to the
-			 * caller as the generated value is not appropriate.
+			 * Perform startup health tests and return permanent
+			 * error if it fails.
 			 */
-			return ret;
+			if (jent_entropy_init())
+				return -3;
+
+			return -2;
 		}
 
 		if ((DATA_SIZE_BITS / 8) < len)
-- 
2.40.0





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

* Re: [PATCH v2] Jitter RNG - Permanent and Intermittent health errors
  2023-03-24 12:30 ` [PATCH v2] " Stephan Müller
@ 2023-03-24 16:03   ` kernel test robot
  0 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2023-03-24 16:03 UTC (permalink / raw)
  To: Stephan Müller, linux-crypto, herbert; +Cc: llvm, oe-kbuild-all

Hi Stephan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on herbert-cryptodev-2.6/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Stephan-M-ller/Jitter-RNG-Permanent-and-Intermittent-health-errors/20230324-203251
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
patch link:    https://lore.kernel.org/r/2671913.mvXUDI8C0e%40positron.chronox.de
patch subject: [PATCH v2] Jitter RNG - Permanent and Intermittent health errors
config: hexagon-randconfig-r045-20230322 (https://download.01.org/0day-ci/archive/20230324/202303242344.goIWq8zw-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project 67409911353323ca5edf2049ef0df54132fa1ca7)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/ce362096eea814a823f7bf4aef00f8680aab9056
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Stephan-M-ller/Jitter-RNG-Permanent-and-Intermittent-health-errors/20230324-203251
        git checkout ce362096eea814a823f7bf4aef00f8680aab9056
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303242344.goIWq8zw-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> crypto/jitterentropy-kcapi.c:165:1: warning: unused label 'out' [-Wunused-label]
   out:
   ^~~~
   1 warning generated.


vim +/out +165 crypto/jitterentropy-kcapi.c

dfc9fa91938bd0 Stephan Mueller 2015-06-23  131  
dfc9fa91938bd0 Stephan Mueller 2015-06-23  132  static int jent_kcapi_random(struct crypto_rng *tfm,
dfc9fa91938bd0 Stephan Mueller 2015-06-23  133  			     const u8 *src, unsigned int slen,
dfc9fa91938bd0 Stephan Mueller 2015-06-23  134  			     u8 *rdata, unsigned int dlen)
dfc9fa91938bd0 Stephan Mueller 2015-06-23  135  {
dfc9fa91938bd0 Stephan Mueller 2015-06-23  136  	struct jitterentropy *rng = crypto_rng_ctx(tfm);
dfc9fa91938bd0 Stephan Mueller 2015-06-23  137  	int ret = 0;
dfc9fa91938bd0 Stephan Mueller 2015-06-23  138  
dfc9fa91938bd0 Stephan Mueller 2015-06-23  139  	spin_lock(&rng->jent_lock);
764428fe99e82c Stephan Müller  2020-04-17  140  
dfc9fa91938bd0 Stephan Mueller 2015-06-23  141  	ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
764428fe99e82c Stephan Müller  2020-04-17  142  
ce362096eea814 Stephan Müller  2023-03-24  143  	if (ret == -3) {
ce362096eea814 Stephan Müller  2023-03-24  144  		/* Handle permanent health test error */
ce362096eea814 Stephan Müller  2023-03-24  145  		/*
ce362096eea814 Stephan Müller  2023-03-24  146  		 * If the kernel was booted with fips=2, it implies that
ce362096eea814 Stephan Müller  2023-03-24  147  		 * the entire kernel acts as a FIPS 140 module. In this case
ce362096eea814 Stephan Müller  2023-03-24  148  		 * an SP800-90B permanent health test error is treated as
ce362096eea814 Stephan Müller  2023-03-24  149  		 * a FIPS module error.
ce362096eea814 Stephan Müller  2023-03-24  150  		 */
ce362096eea814 Stephan Müller  2023-03-24  151  		if (fips_enabled)
ce362096eea814 Stephan Müller  2023-03-24  152  			panic("Jitter RNG permanent health test failure\n");
764428fe99e82c Stephan Müller  2020-04-17  153  
ce362096eea814 Stephan Müller  2023-03-24  154  		pr_err("Jitter RNG permanent health test failure\n");
ce362096eea814 Stephan Müller  2023-03-24  155  		ret = -EFAULT;
ce362096eea814 Stephan Müller  2023-03-24  156  	} else if (ret == -2) {
ce362096eea814 Stephan Müller  2023-03-24  157  		/* Handle intermittent health test error */
ce362096eea814 Stephan Müller  2023-03-24  158  		pr_warn_ratelimited("Reset Jitter RNG due to intermittent health test failure\n");
764428fe99e82c Stephan Müller  2020-04-17  159  		ret = -EAGAIN;
ce362096eea814 Stephan Müller  2023-03-24  160  	} else if (ret == -1) {
ce362096eea814 Stephan Müller  2023-03-24  161  		/* Handle other errors */
764428fe99e82c Stephan Müller  2020-04-17  162  		ret = -EINVAL;
764428fe99e82c Stephan Müller  2020-04-17  163  	}
764428fe99e82c Stephan Müller  2020-04-17  164  
764428fe99e82c Stephan Müller  2020-04-17 @165  out:
dfc9fa91938bd0 Stephan Mueller 2015-06-23  166  	spin_unlock(&rng->jent_lock);
dfc9fa91938bd0 Stephan Mueller 2015-06-23  167  
dfc9fa91938bd0 Stephan Mueller 2015-06-23  168  	return ret;
dfc9fa91938bd0 Stephan Mueller 2015-06-23  169  }
dfc9fa91938bd0 Stephan Mueller 2015-06-23  170  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

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

* [PATCH v3] Jitter RNG - Permanent and Intermittent health errors
  2023-03-23  7:17 [PATCH] crypto: Jitter RNG - Permanent and Intermittent health errors Stephan Müller
  2023-03-24  9:27 ` Herbert Xu
  2023-03-24 12:30 ` [PATCH v2] " Stephan Müller
@ 2023-03-24 17:00 ` Stephan Müller
  2023-03-24 17:47   ` Vladis Dronov
  2023-03-27  7:03 ` [PATCH v4] crypto: jitter - permanent and intermittent " Stephan Müller
  3 siblings, 1 reply; 13+ messages in thread
From: Stephan Müller @ 2023-03-24 17:00 UTC (permalink / raw)
  To: linux-crypto, herbert

According to SP800-90B, two health failures are allowed: the intermittend
and the permanent failure. So far, only the intermittent failure was
implemented. The permanent failure was achieved by resetting the entire
entropy source including its health test state and waiting for two or
more back-to-back health errors.

This approach is appropriate for RCT, but not for APT as APT has a
non-linear cutoff value. Thus, this patch implements 2 cutoff values
for both RCT/APT. This implies that the health state is left untouched
when an intermittent failure occurs. The noise source is reset
and a new APT powerup-self test is performed. Yet, whith the unchanged
health test state, the counting of failures continues until a permanent
failure is reached.

Any non-failing raw entropy value causes the health tests to reset.

The intermittent error has an unchanged significance level of 2^-30.
The permanent error has a significance level of 2^-60. Considering that
this level also indicates a false-positive rate (see SP800-90B section 4.2)
a false-positive must only be incurred with a low probability when
considering a fleet of Linux kernels as a whole. Hitting the permanent
error may cause a panic(), the following calculation applies: Assuming
that a fleet of 10^9 Linux kernels run concurrently with this patch in
FIPS mode and on each kernel 2 health tests are performed every minute
for one year, the chances of a false positive is about 1:1000
based on the binomial distribution.

In addition, any power-up health test errors triggered with
jent_entropy_init are treated as permanent errors.

A permanent failure causes the entire entropy source to permanently
return an error. This implies that a caller can only remedy the situation
by re-allocating a new instance of the Jitter RNG. In a subsequent
patch, a transparent re-allocation will be provided which also changes
the implied heuristic entropy assessment.

In addition, when the kernel is booted with fips=1, the Jitter RNG
is defined to be part of a FIPS module. The permanent error of the
Jitter RNG is translated as a FIPS module error. In this case, the entire
FIPS module must cease operation. This is implemented in the kernel by
invoking panic().

The patch also fixes an off-by-one in the RCT cutoff value which is now
set to 30 instead of 31. This is because the counting of the values
starts with 0.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---

v3:
 - remove an unused goto target

v2:
 - Drop the enforcement of permanent disabling the entropy source

 crypto/jitterentropy-kcapi.c |  46 +++++------
 crypto/jitterentropy.c       | 144 +++++++++++++----------------------
 2 files changed, 76 insertions(+), 114 deletions(-)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index 2d115bec15ae..e48c9a339a3a 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -37,6 +37,7 @@
  * DAMAGE.
  */
 
+#include <linux/fips.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -102,7 +103,6 @@ void jent_get_nstime(__u64 *out)
 struct jitterentropy {
 	spinlock_t jent_lock;
 	struct rand_data *entropy_collector;
-	unsigned int reset_cnt;
 };
 
 static int jent_kcapi_init(struct crypto_tfm *tfm)
@@ -138,32 +138,30 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
 
 	spin_lock(&rng->jent_lock);
 
-	/* Return a permanent error in case we had too many resets in a row. */
-	if (rng->reset_cnt > (1<<10)) {
-		ret = -EFAULT;
-		goto out;
-	}
-
 	ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
 
-	/* Reset RNG in case of health failures */
-	if (ret < -1) {
-		pr_warn_ratelimited("Reset Jitter RNG due to health test failure: %s failure\n",
-				    (ret == -2) ? "Repetition Count Test" :
-						  "Adaptive Proportion Test");
-
-		rng->reset_cnt++;
-
+	if (ret == -3) {
+		/* Handle permanent health test error */
+		/*
+		 * If the kernel was booted with fips=2, it implies that
+		 * the entire kernel acts as a FIPS 140 module. In this case
+		 * an SP800-90B permanent health test error is treated as
+		 * a FIPS module error.
+		 */
+		if (fips_enabled)
+			panic("Jitter RNG permanent health test failure\n");
+
+		pr_err("Jitter RNG permanent health test failure\n");
+		ret = -EFAULT;
+	} else if (ret == -2) {
+		/* Handle intermittent health test error */
+		pr_warn_ratelimited("Reset Jitter RNG due to intermittent health test failure\n");
 		ret = -EAGAIN;
-	} else {
-		rng->reset_cnt = 0;
-
-		/* Convert the Jitter RNG error into a usable error code */
-		if (ret == -1)
-			ret = -EINVAL;
+	} else if (ret == -1) {
+		/* Handle other errors */
+		ret = -EINVAL;
 	}
 
-out:
 	spin_unlock(&rng->jent_lock);
 
 	return ret;
@@ -197,6 +195,10 @@ static int __init jent_mod_init(void)
 
 	ret = jent_entropy_init();
 	if (ret) {
+		/* Handle permanent health test error */
+		if (fips_enabled)
+			panic("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
+
 		pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
 		return -EFAULT;
 	}
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 93bff3213823..22f48bf4c6f5 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -85,10 +85,14 @@ struct rand_data {
 				      * bit generation */
 
 	/* Repetition Count Test */
-	int rct_count;			/* Number of stuck values */
+	unsigned int rct_count;			/* Number of stuck values */
 
-	/* Adaptive Proportion Test for a significance level of 2^-30 */
+	/* Intermittent health test failure threshold of 2^-30 */
+#define JENT_RCT_CUTOFF		30	/* Taken from SP800-90B sec 4.4.1 */
 #define JENT_APT_CUTOFF		325	/* Taken from SP800-90B sec 4.4.2 */
+	/* Permanent health test failure threshold of 2^-60 */
+#define JENT_RCT_CUTOFF_PERMANENT	60
+#define JENT_APT_CUTOFF_PERMANENT	355
 #define JENT_APT_WINDOW_SIZE	512	/* Data window size */
 	/* LSB of time stamp to process */
 #define JENT_APT_LSB		16
@@ -97,8 +101,6 @@ struct rand_data {
 	unsigned int apt_count;		/* APT counter */
 	unsigned int apt_base;		/* APT base reference */
 	unsigned int apt_base_set:1;	/* APT base reference set? */
-
-	unsigned int health_failure:1;	/* Permanent health failure */
 };
 
 /* Flags that can be used to initialize the RNG */
@@ -169,19 +171,26 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
 		return;
 	}
 
-	if (delta_masked == ec->apt_base) {
+	if (delta_masked == ec->apt_base)
 		ec->apt_count++;
 
-		if (ec->apt_count >= JENT_APT_CUTOFF)
-			ec->health_failure = 1;
-	}
-
 	ec->apt_observations++;
 
 	if (ec->apt_observations >= JENT_APT_WINDOW_SIZE)
 		jent_apt_reset(ec, delta_masked);
 }
 
+/* APT health test failure detection */
+static int jent_apt_permanent_failure(struct rand_data *ec)
+{
+	return (ec->apt_count >= JENT_APT_CUTOFF_PERMANENT) ? 1 : 0;
+}
+
+static int jent_apt_failure(struct rand_data *ec)
+{
+	return (ec->apt_count >= JENT_APT_CUTOFF) ? 1 : 0;
+}
+
 /***************************************************************************
  * Stuck Test and its use as Repetition Count Test
  *
@@ -206,55 +215,14 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
  */
 static void jent_rct_insert(struct rand_data *ec, int stuck)
 {
-	/*
-	 * If we have a count less than zero, a previous RCT round identified
-	 * a failure. We will not overwrite it.
-	 */
-	if (ec->rct_count < 0)
-		return;
-
 	if (stuck) {
 		ec->rct_count++;
-
-		/*
-		 * The cutoff value is based on the following consideration:
-		 * alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8.
-		 * In addition, we require an entropy value H of 1/OSR as this
-		 * is the minimum entropy required to provide full entropy.
-		 * Note, we collect 64 * OSR deltas for inserting them into
-		 * the entropy pool which should then have (close to) 64 bits
-		 * of entropy.
-		 *
-		 * Note, ec->rct_count (which equals to value B in the pseudo
-		 * code of SP800-90B section 4.4.1) starts with zero. Hence
-		 * we need to subtract one from the cutoff value as calculated
-		 * following SP800-90B.
-		 */
-		if ((unsigned int)ec->rct_count >= (31 * ec->osr)) {
-			ec->rct_count = -1;
-			ec->health_failure = 1;
-		}
 	} else {
+		/* Reset RCT */
 		ec->rct_count = 0;
 	}
 }
 
-/*
- * Is there an RCT health test failure?
- *
- * @ec [in] Reference to entropy collector
- *
- * @return
- * 	0 No health test failure
- * 	1 Permanent health test failure
- */
-static int jent_rct_failure(struct rand_data *ec)
-{
-	if (ec->rct_count < 0)
-		return 1;
-	return 0;
-}
-
 static inline __u64 jent_delta(__u64 prev, __u64 next)
 {
 #define JENT_UINT64_MAX		(__u64)(~((__u64) 0))
@@ -303,18 +271,26 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta)
 	return 0;
 }
 
-/*
- * Report any health test failures
- *
- * @ec [in] Reference to entropy collector
- *
- * @return
- * 	0 No health test failure
- * 	1 Permanent health test failure
- */
+/* RCT health test failure detection */
+static int jent_rct_permanent_failure(struct rand_data *ec)
+{
+	return (ec->rct_count >= JENT_RCT_CUTOFF_PERMANENT) ? 1 : 0;
+}
+
+static int jent_rct_failure(struct rand_data *ec)
+{
+	return (ec->rct_count >= JENT_RCT_CUTOFF) ? 1 : 0;
+}
+
+/* Report of health test failures */
 static int jent_health_failure(struct rand_data *ec)
 {
-	return ec->health_failure;
+	return jent_rct_failure(ec) | jent_apt_failure(ec);
+}
+
+static int jent_permanent_health_failure(struct rand_data *ec)
+{
+	return jent_rct_permanent_failure(ec) | jent_apt_permanent_failure(ec);
 }
 
 /***************************************************************************
@@ -600,8 +576,8 @@ static void jent_gen_entropy(struct rand_data *ec)
  *
  * The following error codes can occur:
  *	-1	entropy_collector is NULL
- *	-2	RCT failed
- *	-3	APT test failed
+ *	-2	Intermittent health failure
+ *	-3	Permanent health failure
  */
 int jent_read_entropy(struct rand_data *ec, unsigned char *data,
 		      unsigned int len)
@@ -616,39 +592,23 @@ int jent_read_entropy(struct rand_data *ec, unsigned char *data,
 
 		jent_gen_entropy(ec);
 
-		if (jent_health_failure(ec)) {
-			int ret;
-
-			if (jent_rct_failure(ec))
-				ret = -2;
-			else
-				ret = -3;
-
+		if (jent_permanent_health_failure(ec)) {
 			/*
-			 * Re-initialize the noise source
-			 *
-			 * If the health test fails, the Jitter RNG remains
-			 * in failure state and will return a health failure
-			 * during next invocation.
+			 * At this point, the Jitter RNG instance is considered
+			 * as a failed instance. There is no rerun of the
+			 * startup test any more, because the caller
+			 * is assumed to not further use this instance.
 			 */
-			if (jent_entropy_init())
-				return ret;
-
-			/* Set APT to initial state */
-			jent_apt_reset(ec, 0);
-			ec->apt_base_set = 0;
-
-			/* Set RCT to initial state */
-			ec->rct_count = 0;
-
-			/* Re-enable Jitter RNG */
-			ec->health_failure = 0;
-
+			return -3;
+		} else if (jent_health_failure(ec)) {
 			/*
-			 * Return the health test failure status to the
-			 * caller as the generated value is not appropriate.
+			 * Perform startup health tests and return permanent
+			 * error if it fails.
 			 */
-			return ret;
+			if (jent_entropy_init())
+				return -3;
+
+			return -2;
 		}
 
 		if ((DATA_SIZE_BITS / 8) < len)
-- 
2.40.0





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

* RE: [PATCH v3] Jitter RNG - Permanent and Intermittent health errors
  2023-03-24 17:00 ` [PATCH v3] " Stephan Müller
@ 2023-03-24 17:47   ` Vladis Dronov
  2023-03-24 17:54     ` Stephan Mueller
  0 siblings, 1 reply; 13+ messages in thread
From: Vladis Dronov @ 2023-03-24 17:47 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: Herbert Xu, linux-crypto, Vladis Dronov

Hi,
Aaaand I would suggest the following smallest fix, just a comment update:

+        * If the kernel was booted with fips=2, it implies that

change to:

+        * If the kernel was booted with fips=1, it implies that

Otherwise,
Reviewed-by: Vladis Dronov <vdronov@redhat.com>

Best regards,
Vladis


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

* Re: [PATCH v3] Jitter RNG - Permanent and Intermittent health errors
  2023-03-24 17:47   ` Vladis Dronov
@ 2023-03-24 17:54     ` Stephan Mueller
  2023-03-25 14:44       ` Vladis Dronov
  0 siblings, 1 reply; 13+ messages in thread
From: Stephan Mueller @ 2023-03-24 17:54 UTC (permalink / raw)
  To: Vladis Dronov; +Cc: Herbert Xu, linux-crypto, Vladis Dronov

Am Freitag, 24. März 2023, 18:47:09 CET schrieb Vladis Dronov:

Hi Vladis,

> Hi,
> Aaaand I would suggest the following smallest fix, just a comment update:
> 
> +        * If the kernel was booted with fips=2, it implies that
> 
> change to:
> 
> +        * If the kernel was booted with fips=1, it implies that

Thank you very much. I have fixed it in my local copy, but will wait for 
another bit in case there are other reports.
> 
> Otherwise,
> Reviewed-by: Vladis Dronov <vdronov@redhat.com>

Thanks, added.
> 
> Best regards,
> Vladis


Ciao
Stephan



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

* Re: [PATCH v3] Jitter RNG - Permanent and Intermittent health errors
  2023-03-24 17:54     ` Stephan Mueller
@ 2023-03-25 14:44       ` Vladis Dronov
  2023-03-26  8:51         ` Stephan Müller
  0 siblings, 1 reply; 13+ messages in thread
From: Vladis Dronov @ 2023-03-25 14:44 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: Herbert Xu, linux-crypto

Hi, Stephan,

On Fri, Mar 24, 2023 at 6:56 PM Stephan Mueller <smueller@chronox.de> wrote:
>
> Thank you very much. I have fixed it in my local copy, but will wait for
> another bit in case there are other reports.

A couple of more suggestions, if I may. These are really small,
I'm suggesting them just due to a sense of perfection.

1) A patch name. All the patches in this area look like
"crypto: jitter - <lowercase letters>". Probably a patch name could be
adjusted as "crypto: jitter - permanent and intermittent health errors"?

2) You use panic("Jitter RNG permanent health test failure\n") in your
patch. With that, probably, jent_panic() could be removed, since
nothing is using it, couldn't it?

Best regards,
Vladis


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

* Re: [PATCH v3] Jitter RNG - Permanent and Intermittent health errors
  2023-03-25 14:44       ` Vladis Dronov
@ 2023-03-26  8:51         ` Stephan Müller
  0 siblings, 0 replies; 13+ messages in thread
From: Stephan Müller @ 2023-03-26  8:51 UTC (permalink / raw)
  To: Vladis Dronov; +Cc: Herbert Xu, linux-crypto

Am Samstag, 25. März 2023, 15:44:59 CEST schrieb Vladis Dronov:

Hi Vladis,

> Hi, Stephan,
> 
> On Fri, Mar 24, 2023 at 6:56 PM Stephan Mueller <smueller@chronox.de> wrote:
> > Thank you very much. I have fixed it in my local copy, but will wait for
> > another bit in case there are other reports.
> 
> A couple of more suggestions, if I may. These are really small,
> I'm suggesting them just due to a sense of perfection.
> 
> 1) A patch name. All the patches in this area look like
> "crypto: jitter - <lowercase letters>". Probably a patch name could be
> adjusted as "crypto: jitter - permanent and intermittent health errors"?

Will do.
> 
> 2) You use panic("Jitter RNG permanent health test failure\n") in your
> patch. With that, probably, jent_panic() could be removed, since
> nothing is using it, couldn't it?

Yes, you are right. I will remove it.
> 
> Best regards,
> Vladis


Thanks a lot
Stephan



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

* [PATCH v4] crypto: jitter - permanent and intermittent health errors
  2023-03-23  7:17 [PATCH] crypto: Jitter RNG - Permanent and Intermittent health errors Stephan Müller
                   ` (2 preceding siblings ...)
  2023-03-24 17:00 ` [PATCH v3] " Stephan Müller
@ 2023-03-27  7:03 ` Stephan Müller
  2023-03-27 16:40   ` Marcelo Henrique Cerri
  2023-04-06  8:50   ` Herbert Xu
  3 siblings, 2 replies; 13+ messages in thread
From: Stephan Müller @ 2023-03-27  7:03 UTC (permalink / raw)
  To: linux-crypto, herbert; +Cc: Vladis Dronov

According to SP800-90B, two health failures are allowed: the intermittend
and the permanent failure. So far, only the intermittent failure was
implemented. The permanent failure was achieved by resetting the entire
entropy source including its health test state and waiting for two or
more back-to-back health errors.

This approach is appropriate for RCT, but not for APT as APT has a
non-linear cutoff value. Thus, this patch implements 2 cutoff values
for both RCT/APT. This implies that the health state is left untouched
when an intermittent failure occurs. The noise source is reset
and a new APT powerup-self test is performed. Yet, whith the unchanged
health test state, the counting of failures continues until a permanent
failure is reached.

Any non-failing raw entropy value causes the health tests to reset.

The intermittent error has an unchanged significance level of 2^-30.
The permanent error has a significance level of 2^-60. Considering that
this level also indicates a false-positive rate (see SP800-90B section 4.2)
a false-positive must only be incurred with a low probability when
considering a fleet of Linux kernels as a whole. Hitting the permanent
error may cause a panic(), the following calculation applies: Assuming
that a fleet of 10^9 Linux kernels run concurrently with this patch in
FIPS mode and on each kernel 2 health tests are performed every minute
for one year, the chances of a false positive is about 1:1000
based on the binomial distribution.

In addition, any power-up health test errors triggered with
jent_entropy_init are treated as permanent errors.

A permanent failure causes the entire entropy source to permanently
return an error. This implies that a caller can only remedy the situation
by re-allocating a new instance of the Jitter RNG. In a subsequent
patch, a transparent re-allocation will be provided which also changes
the implied heuristic entropy assessment.

In addition, when the kernel is booted with fips=1, the Jitter RNG
is defined to be part of a FIPS module. The permanent error of the
Jitter RNG is translated as a FIPS module error. In this case, the entire
FIPS module must cease operation. This is implemented in the kernel by
invoking panic().

The patch also fixes an off-by-one in the RCT cutoff value which is now
set to 30 instead of 31. This is because the counting of the values
starts with 0.

Reviewed-by: Vladis Dronov <vdronov@redhat.com>
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---

v4:
 - fix comment regarding fips=1
 - update patch subject to match common naming schema
 - remove now unused jent_panic function
 - added Reviewed-by line

v3:
 - remove an unused goto target

v2:
 - Drop the enforcement of permanent disabling the entropy source

 crypto/jitterentropy-kcapi.c |  51 ++++++-------
 crypto/jitterentropy.c       | 144 +++++++++++++----------------------
 crypto/jitterentropy.h       |   1 -
 3 files changed, 76 insertions(+), 120 deletions(-)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index 2d115bec15ae..b9edfaa51b27 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -37,6 +37,7 @@
  * DAMAGE.
  */
 
+#include <linux/fips.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -59,11 +60,6 @@ void jent_zfree(void *ptr)
 	kfree_sensitive(ptr);
 }
 
-void jent_panic(char *s)
-{
-	panic("%s", s);
-}
-
 void jent_memcpy(void *dest, const void *src, unsigned int n)
 {
 	memcpy(dest, src, n);
@@ -102,7 +98,6 @@ void jent_get_nstime(__u64 *out)
 struct jitterentropy {
 	spinlock_t jent_lock;
 	struct rand_data *entropy_collector;
-	unsigned int reset_cnt;
 };
 
 static int jent_kcapi_init(struct crypto_tfm *tfm)
@@ -138,32 +133,30 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
 
 	spin_lock(&rng->jent_lock);
 
-	/* Return a permanent error in case we had too many resets in a row. */
-	if (rng->reset_cnt > (1<<10)) {
-		ret = -EFAULT;
-		goto out;
-	}
-
 	ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
 
-	/* Reset RNG in case of health failures */
-	if (ret < -1) {
-		pr_warn_ratelimited("Reset Jitter RNG due to health test failure: %s failure\n",
-				    (ret == -2) ? "Repetition Count Test" :
-						  "Adaptive Proportion Test");
-
-		rng->reset_cnt++;
-
+	if (ret == -3) {
+		/* Handle permanent health test error */
+		/*
+		 * If the kernel was booted with fips=1, it implies that
+		 * the entire kernel acts as a FIPS 140 module. In this case
+		 * an SP800-90B permanent health test error is treated as
+		 * a FIPS module error.
+		 */
+		if (fips_enabled)
+			panic("Jitter RNG permanent health test failure\n");
+
+		pr_err("Jitter RNG permanent health test failure\n");
+		ret = -EFAULT;
+	} else if (ret == -2) {
+		/* Handle intermittent health test error */
+		pr_warn_ratelimited("Reset Jitter RNG due to intermittent health test failure\n");
 		ret = -EAGAIN;
-	} else {
-		rng->reset_cnt = 0;
-
-		/* Convert the Jitter RNG error into a usable error code */
-		if (ret == -1)
-			ret = -EINVAL;
+	} else if (ret == -1) {
+		/* Handle other errors */
+		ret = -EINVAL;
 	}
 
-out:
 	spin_unlock(&rng->jent_lock);
 
 	return ret;
@@ -197,6 +190,10 @@ static int __init jent_mod_init(void)
 
 	ret = jent_entropy_init();
 	if (ret) {
+		/* Handle permanent health test error */
+		if (fips_enabled)
+			panic("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
+
 		pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
 		return -EFAULT;
 	}
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 93bff3213823..22f48bf4c6f5 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -85,10 +85,14 @@ struct rand_data {
 				      * bit generation */
 
 	/* Repetition Count Test */
-	int rct_count;			/* Number of stuck values */
+	unsigned int rct_count;			/* Number of stuck values */
 
-	/* Adaptive Proportion Test for a significance level of 2^-30 */
+	/* Intermittent health test failure threshold of 2^-30 */
+#define JENT_RCT_CUTOFF		30	/* Taken from SP800-90B sec 4.4.1 */
 #define JENT_APT_CUTOFF		325	/* Taken from SP800-90B sec 4.4.2 */
+	/* Permanent health test failure threshold of 2^-60 */
+#define JENT_RCT_CUTOFF_PERMANENT	60
+#define JENT_APT_CUTOFF_PERMANENT	355
 #define JENT_APT_WINDOW_SIZE	512	/* Data window size */
 	/* LSB of time stamp to process */
 #define JENT_APT_LSB		16
@@ -97,8 +101,6 @@ struct rand_data {
 	unsigned int apt_count;		/* APT counter */
 	unsigned int apt_base;		/* APT base reference */
 	unsigned int apt_base_set:1;	/* APT base reference set? */
-
-	unsigned int health_failure:1;	/* Permanent health failure */
 };
 
 /* Flags that can be used to initialize the RNG */
@@ -169,19 +171,26 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
 		return;
 	}
 
-	if (delta_masked == ec->apt_base) {
+	if (delta_masked == ec->apt_base)
 		ec->apt_count++;
 
-		if (ec->apt_count >= JENT_APT_CUTOFF)
-			ec->health_failure = 1;
-	}
-
 	ec->apt_observations++;
 
 	if (ec->apt_observations >= JENT_APT_WINDOW_SIZE)
 		jent_apt_reset(ec, delta_masked);
 }
 
+/* APT health test failure detection */
+static int jent_apt_permanent_failure(struct rand_data *ec)
+{
+	return (ec->apt_count >= JENT_APT_CUTOFF_PERMANENT) ? 1 : 0;
+}
+
+static int jent_apt_failure(struct rand_data *ec)
+{
+	return (ec->apt_count >= JENT_APT_CUTOFF) ? 1 : 0;
+}
+
 /***************************************************************************
  * Stuck Test and its use as Repetition Count Test
  *
@@ -206,55 +215,14 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
  */
 static void jent_rct_insert(struct rand_data *ec, int stuck)
 {
-	/*
-	 * If we have a count less than zero, a previous RCT round identified
-	 * a failure. We will not overwrite it.
-	 */
-	if (ec->rct_count < 0)
-		return;
-
 	if (stuck) {
 		ec->rct_count++;
-
-		/*
-		 * The cutoff value is based on the following consideration:
-		 * alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8.
-		 * In addition, we require an entropy value H of 1/OSR as this
-		 * is the minimum entropy required to provide full entropy.
-		 * Note, we collect 64 * OSR deltas for inserting them into
-		 * the entropy pool which should then have (close to) 64 bits
-		 * of entropy.
-		 *
-		 * Note, ec->rct_count (which equals to value B in the pseudo
-		 * code of SP800-90B section 4.4.1) starts with zero. Hence
-		 * we need to subtract one from the cutoff value as calculated
-		 * following SP800-90B.
-		 */
-		if ((unsigned int)ec->rct_count >= (31 * ec->osr)) {
-			ec->rct_count = -1;
-			ec->health_failure = 1;
-		}
 	} else {
+		/* Reset RCT */
 		ec->rct_count = 0;
 	}
 }
 
-/*
- * Is there an RCT health test failure?
- *
- * @ec [in] Reference to entropy collector
- *
- * @return
- * 	0 No health test failure
- * 	1 Permanent health test failure
- */
-static int jent_rct_failure(struct rand_data *ec)
-{
-	if (ec->rct_count < 0)
-		return 1;
-	return 0;
-}
-
 static inline __u64 jent_delta(__u64 prev, __u64 next)
 {
 #define JENT_UINT64_MAX		(__u64)(~((__u64) 0))
@@ -303,18 +271,26 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta)
 	return 0;
 }
 
-/*
- * Report any health test failures
- *
- * @ec [in] Reference to entropy collector
- *
- * @return
- * 	0 No health test failure
- * 	1 Permanent health test failure
- */
+/* RCT health test failure detection */
+static int jent_rct_permanent_failure(struct rand_data *ec)
+{
+	return (ec->rct_count >= JENT_RCT_CUTOFF_PERMANENT) ? 1 : 0;
+}
+
+static int jent_rct_failure(struct rand_data *ec)
+{
+	return (ec->rct_count >= JENT_RCT_CUTOFF) ? 1 : 0;
+}
+
+/* Report of health test failures */
 static int jent_health_failure(struct rand_data *ec)
 {
-	return ec->health_failure;
+	return jent_rct_failure(ec) | jent_apt_failure(ec);
+}
+
+static int jent_permanent_health_failure(struct rand_data *ec)
+{
+	return jent_rct_permanent_failure(ec) | jent_apt_permanent_failure(ec);
 }
 
 /***************************************************************************
@@ -600,8 +576,8 @@ static void jent_gen_entropy(struct rand_data *ec)
  *
  * The following error codes can occur:
  *	-1	entropy_collector is NULL
- *	-2	RCT failed
- *	-3	APT test failed
+ *	-2	Intermittent health failure
+ *	-3	Permanent health failure
  */
 int jent_read_entropy(struct rand_data *ec, unsigned char *data,
 		      unsigned int len)
@@ -616,39 +592,23 @@ int jent_read_entropy(struct rand_data *ec, unsigned char *data,
 
 		jent_gen_entropy(ec);
 
-		if (jent_health_failure(ec)) {
-			int ret;
-
-			if (jent_rct_failure(ec))
-				ret = -2;
-			else
-				ret = -3;
-
+		if (jent_permanent_health_failure(ec)) {
 			/*
-			 * Re-initialize the noise source
-			 *
-			 * If the health test fails, the Jitter RNG remains
-			 * in failure state and will return a health failure
-			 * during next invocation.
+			 * At this point, the Jitter RNG instance is considered
+			 * as a failed instance. There is no rerun of the
+			 * startup test any more, because the caller
+			 * is assumed to not further use this instance.
 			 */
-			if (jent_entropy_init())
-				return ret;
-
-			/* Set APT to initial state */
-			jent_apt_reset(ec, 0);
-			ec->apt_base_set = 0;
-
-			/* Set RCT to initial state */
-			ec->rct_count = 0;
-
-			/* Re-enable Jitter RNG */
-			ec->health_failure = 0;
-
+			return -3;
+		} else if (jent_health_failure(ec)) {
 			/*
-			 * Return the health test failure status to the
-			 * caller as the generated value is not appropriate.
+			 * Perform startup health tests and return permanent
+			 * error if it fails.
 			 */
-			return ret;
+			if (jent_entropy_init())
+				return -3;
+
+			return -2;
 		}
 
 		if ((DATA_SIZE_BITS / 8) < len)
diff --git a/crypto/jitterentropy.h b/crypto/jitterentropy.h
index b7397b617ef0..5cc583f6bc6b 100644
--- a/crypto/jitterentropy.h
+++ b/crypto/jitterentropy.h
@@ -2,7 +2,6 @@
 
 extern void *jent_zalloc(unsigned int len);
 extern void jent_zfree(void *ptr);
-extern void jent_panic(char *s);
 extern void jent_memcpy(void *dest, const void *src, unsigned int n);
 extern void jent_get_nstime(__u64 *out);
 
-- 
2.40.0





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

* Re: [PATCH v4] crypto: jitter - permanent and intermittent health errors
  2023-03-27  7:03 ` [PATCH v4] crypto: jitter - permanent and intermittent " Stephan Müller
@ 2023-03-27 16:40   ` Marcelo Henrique Cerri
  2023-04-06  8:50   ` Herbert Xu
  1 sibling, 0 replies; 13+ messages in thread
From: Marcelo Henrique Cerri @ 2023-03-27 16:40 UTC (permalink / raw)
  To: Stephan Müller; +Cc: linux-crypto, herbert, Vladis Dronov


It looks good to me too.

I also did a quick smoke test using AF_ALG and I didn't find any issues.

Average of 10 runs doing a million reads of 8, 32, 64 and 128 bytes each
time with drbg_nopr_sha256.

Without the patch:

bsize  count    total (secs)  user (secs)  system (secs)
8      1000000  3,739         0,483        3,247
32     1000000  3,835         0,49         3,337
64     1000000  4,652         0,502        4,14
128    1000000  6,3           0,562        5,73

With the patch:

bsize  count    total (secs)  user (secs)  system (secs)
8      1000000  3,376         0,429        2,936
32     1000000  3,361         0,422        2,927
64     1000000  4,072         0,446        3,614
128    1000000  5,439         0,424        4,981

Reviewed-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>

--
Regards,
Marcelo

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

* Re: [PATCH v4] crypto: jitter - permanent and intermittent health errors
  2023-03-27  7:03 ` [PATCH v4] crypto: jitter - permanent and intermittent " Stephan Müller
  2023-03-27 16:40   ` Marcelo Henrique Cerri
@ 2023-04-06  8:50   ` Herbert Xu
  1 sibling, 0 replies; 13+ messages in thread
From: Herbert Xu @ 2023-04-06  8:50 UTC (permalink / raw)
  To: Stephan Müller; +Cc: linux-crypto, Vladis Dronov

On Mon, Mar 27, 2023 at 09:03:52AM +0200, Stephan Müller wrote:
> According to SP800-90B, two health failures are allowed: the intermittend
> and the permanent failure. So far, only the intermittent failure was
> implemented. The permanent failure was achieved by resetting the entire
> entropy source including its health test state and waiting for two or
> more back-to-back health errors.
> 
> This approach is appropriate for RCT, but not for APT as APT has a
> non-linear cutoff value. Thus, this patch implements 2 cutoff values
> for both RCT/APT. This implies that the health state is left untouched
> when an intermittent failure occurs. The noise source is reset
> and a new APT powerup-self test is performed. Yet, whith the unchanged
> health test state, the counting of failures continues until a permanent
> failure is reached.
> 
> Any non-failing raw entropy value causes the health tests to reset.
> 
> The intermittent error has an unchanged significance level of 2^-30.
> The permanent error has a significance level of 2^-60. Considering that
> this level also indicates a false-positive rate (see SP800-90B section 4.2)
> a false-positive must only be incurred with a low probability when
> considering a fleet of Linux kernels as a whole. Hitting the permanent
> error may cause a panic(), the following calculation applies: Assuming
> that a fleet of 10^9 Linux kernels run concurrently with this patch in
> FIPS mode and on each kernel 2 health tests are performed every minute
> for one year, the chances of a false positive is about 1:1000
> based on the binomial distribution.
> 
> In addition, any power-up health test errors triggered with
> jent_entropy_init are treated as permanent errors.
> 
> A permanent failure causes the entire entropy source to permanently
> return an error. This implies that a caller can only remedy the situation
> by re-allocating a new instance of the Jitter RNG. In a subsequent
> patch, a transparent re-allocation will be provided which also changes
> the implied heuristic entropy assessment.
> 
> In addition, when the kernel is booted with fips=1, the Jitter RNG
> is defined to be part of a FIPS module. The permanent error of the
> Jitter RNG is translated as a FIPS module error. In this case, the entire
> FIPS module must cease operation. This is implemented in the kernel by
> invoking panic().
> 
> The patch also fixes an off-by-one in the RCT cutoff value which is now
> set to 30 instead of 31. This is because the counting of the values
> starts with 0.
> 
> Reviewed-by: Vladis Dronov <vdronov@redhat.com>
> Signed-off-by: Stephan Mueller <smueller@chronox.de>
> ---
> 
> v4:
>  - fix comment regarding fips=1
>  - update patch subject to match common naming schema
>  - remove now unused jent_panic function
>  - added Reviewed-by line
> 
> v3:
>  - remove an unused goto target
> 
> v2:
>  - Drop the enforcement of permanent disabling the entropy source
> 
>  crypto/jitterentropy-kcapi.c |  51 ++++++-------
>  crypto/jitterentropy.c       | 144 +++++++++++++----------------------
>  crypto/jitterentropy.h       |   1 -
>  3 files changed, 76 insertions(+), 120 deletions(-)

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

end of thread, other threads:[~2023-04-06  8:50 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-23  7:17 [PATCH] crypto: Jitter RNG - Permanent and Intermittent health errors Stephan Müller
2023-03-24  9:27 ` Herbert Xu
2023-03-24 12:01   ` Stephan Mueller
2023-03-24 12:30 ` [PATCH v2] " Stephan Müller
2023-03-24 16:03   ` kernel test robot
2023-03-24 17:00 ` [PATCH v3] " Stephan Müller
2023-03-24 17:47   ` Vladis Dronov
2023-03-24 17:54     ` Stephan Mueller
2023-03-25 14:44       ` Vladis Dronov
2023-03-26  8:51         ` Stephan Müller
2023-03-27  7:03 ` [PATCH v4] crypto: jitter - permanent and intermittent " Stephan Müller
2023-03-27 16:40   ` Marcelo Henrique Cerri
2023-04-06  8:50   ` Herbert Xu

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