diff options
Diffstat (limited to 'crypto/jitterentropy-kcapi.c')
-rw-r--r-- | crypto/jitterentropy-kcapi.c | 37 |
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; |