aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/jitterentropy-kcapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/jitterentropy-kcapi.c')
-rw-r--r--crypto/jitterentropy-kcapi.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index a5ce8f96790f..2d115bec15ae 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -37,11 +37,10 @@
* DAMAGE.
*/
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/fips.h>
#include <linux/time.h>
-#include <linux/crypto.h>
#include <crypto/internal/rng.h>
#include "jitterentropy.h"
@@ -57,12 +56,7 @@ void *jent_zalloc(unsigned int len)
void jent_zfree(void *ptr)
{
- kzfree(ptr);
-}
-
-int jent_fips_enabled(void)
-{
- return fips_enabled;
+ kfree_sensitive(ptr);
}
void jent_panic(char *s)
@@ -108,6 +102,7 @@ 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)
@@ -142,7 +137,33 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
int ret = 0;
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++;
+
+ ret = -EAGAIN;
+ } else {
+ rng->reset_cnt = 0;
+
+ /* Convert the Jitter RNG error into a usable error code */
+ if (ret == -1)
+ ret = -EINVAL;
+ }
+
+out:
spin_unlock(&rng->jent_lock);
return ret;