crypto: drbg - track whether DRBG was seeded with !rng_is_initialized()
[linux-2.6-block.git] / crypto / drbg.c
index 6329c70e5bbbfc27e6532208597f3490ddb6ff87..d71c704d0cd2d4b6ab2cdf51e4bd0b89499d2f13 100644 (file)
@@ -1036,14 +1036,14 @@ static const struct drbg_state_ops drbg_hash_ops = {
  ******************************************************************/
 
 static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
-                             int reseed)
+                             int reseed, enum drbg_seed_state new_seed_state)
 {
        int ret = drbg->d_ops->update(drbg, seed, reseed);
 
        if (ret)
                return ret;
 
-       drbg->seeded = DRBG_SEED_STATE_FULL;
+       drbg->seeded = new_seed_state;
        /* 10.1.1.2 / 10.1.1.3 step 5 */
        drbg->reseed_ctr = 1;
 
@@ -1093,7 +1093,7 @@ static void drbg_async_seed(struct work_struct *work)
         */
        drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
 
-       __drbg_seed(drbg, &seedlist, true);
+       __drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
 
        if (drbg->seeded == DRBG_SEED_STATE_FULL)
                drbg->reseed_threshold = drbg_max_requests(drbg);
@@ -1123,6 +1123,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
        unsigned int entropylen = drbg_sec_strength(drbg->core->flags);
        struct drbg_string data1;
        LIST_HEAD(seedlist);
+       enum drbg_seed_state new_seed_state = DRBG_SEED_STATE_FULL;
 
        /* 9.1 / 9.2 / 9.3.1 step 3 */
        if (pers && pers->len > (drbg_max_addtl(drbg))) {
@@ -1150,6 +1151,9 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
                BUG_ON((entropylen * 2) > sizeof(entropy));
 
                /* Get seed from in-kernel /dev/urandom */
+               if (!rng_is_initialized())
+                       new_seed_state = DRBG_SEED_STATE_PARTIAL;
+
                ret = drbg_get_random_bytes(drbg, entropy, entropylen);
                if (ret)
                        goto out;
@@ -1206,7 +1210,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
                memset(drbg->C, 0, drbg_statelen(drbg));
        }
 
-       ret = __drbg_seed(drbg, &seedlist, reseed);
+       ret = __drbg_seed(drbg, &seedlist, reseed, new_seed_state);
 
 out:
        memzero_explicit(entropy, entropylen * 2);