crypto: jitter - SP800-90B compliance
[linux-2.6-block.git] / crypto / jitterentropy-kcapi.c
index a5ce8f96790f4a6953dba0c01a90ded7134a5a4d..b43684c0dade3aef07ab32adb0511bc0e592c560 100644 (file)
@@ -108,6 +108,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 +143,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;