mm: memmap_init: iterate over memblock regions rather that check each PFN
[linux-2.6-microblaze.git] / crypto / drbg.c
index b6929eb..37526eb 100644 (file)
@@ -1087,10 +1087,6 @@ static void drbg_async_seed(struct work_struct *work)
        if (ret)
                goto unlock;
 
-       /* If nonblocking pool is initialized, deactivate Jitter RNG */
-       crypto_free_rng(drbg->jent);
-       drbg->jent = NULL;
-
        /* Set seeded to false so that if __drbg_seed fails the
         * next generate call will trigger a reseed.
         */
@@ -1168,7 +1164,23 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
                                                   entropylen);
                        if (ret) {
                                pr_devel("DRBG: jent failed with %d\n", ret);
-                               goto out;
+
+                               /*
+                                * Do not treat the transient failure of the
+                                * Jitter RNG as an error that needs to be
+                                * reported. The combined number of the
+                                * maximum reseed threshold times the maximum
+                                * number of Jitter RNG transient errors is
+                                * less than the reseed threshold required by
+                                * SP800-90A allowing us to treat the
+                                * transient errors as such.
+                                *
+                                * However, we mandate that at least the first
+                                * seeding operation must succeed with the
+                                * Jitter RNG.
+                                */
+                               if (!reseed || ret != -EAGAIN)
+                                       goto out;
                        }
 
                        drbg_string_fill(&data1, entropy, entropylen * 2);
@@ -1294,8 +1306,10 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
        if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) {
                drbg->prev = kzalloc(drbg_sec_strength(drbg->core->flags),
                                     GFP_KERNEL);
-               if (!drbg->prev)
+               if (!drbg->prev) {
+                       ret = -ENOMEM;
                        goto fini;
+               }
                drbg->fips_primed = false;
        }
 
@@ -1492,6 +1506,8 @@ static int drbg_prepare_hrng(struct drbg_state *drbg)
        if (list_empty(&drbg->test_data.list))
                return 0;
 
+       drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
+
        INIT_WORK(&drbg->seed_work, drbg_async_seed);
 
        drbg->random_ready.owner = THIS_MODULE;
@@ -1512,8 +1528,6 @@ static int drbg_prepare_hrng(struct drbg_state *drbg)
                return err;
        }
 
-       drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
-
        /*
         * Require frequent reseeds until the seed source is fully
         * initialized.