Am Montag, 17. März 2014, 08:34:06 schrieb Stephan Mueller:

> +static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
> +                  bool reseed)
> +{
> +     int ret = 0;
> +     unsigned char *entropy = NULL;
> +     size_t entropylen = 0;
> +     struct drbg_string data1;
> +     struct drbg_string *data2;
> +
> +     /* 9.1 / 9.2 / 9.3.1 step 3 */
> +     if (pers && pers->len > (drbg_max_addtl(drbg)))
> +             return -EINVAL;
> +
> +     if (drbg->test_data) {
> +             data1.buf = drbg->test_data->testentropy->buf;
> +             data1.len = drbg->test_data->testentropy->len;
> +             data1.next = NULL;
> +     } else {
> +             /* Gather entropy equal to the security strength of the DRBG.
> +              * With a derivation function, a nonce is required in addition
> +              * to the entropy. A nonce must be at least 1/2 of the 
security
> +              * strength of the DRBG in size. Thus, entropy * nonce is 3/2
> +              * of the strength. The consideration of a nonce is only
> +              * applicable during initial seeding. */
> +             entropylen = (drbg_sec_strength(drbg->core->flags) / 8);

drbg_sec_strength returns the strength in bytes, thus the division by 8 must 
be removed

> +             if (!entropylen)
> +                     return -EFAULT;
> +             if (!reseed)
> +                     /* make sure we round up strength/2 in
> +                      * case it is not divisible by 2 */
> +                     entropylen = ((entropylen + 1) / 2) * 3;
> +
> +             entropy = kzalloc(entropylen, GFP_KERNEL);
> +             if (!entropy)
> +                     return -ENOMEM;
> +             get_random_bytes(entropy, entropylen);
> +             drbg_string_fill(&data1, entropy, entropylen);
> +     }
> +
> +     /* concatenation of entropy with personalization str / addtl input) */
> +     if (pers && 0 < pers->len) {
> +             data2 = pers;
> +             data2->next = NULL;
> +             data1.next = data2;
> +     }
> +
> +     ret = drbg->d_ops->update(drbg, &data1, reseed);
> +     if (ret)
> +             goto out;
> +
> +     drbg->seeded = true;
> +     /* 10.1.1.2 / 10.1.1.3 step 5 */
> +     drbg->reseed_ctr = 1;
> +
> +out:
> +     if (entropy)
> +             kzfree(entropy);
> +     return ret;
> +}
> +

[...] 
> +static unsigned int drbg_generate(struct drbg_state *drbg,
> +                               unsigned char *buf, unsigned int buflen,
> +                               struct drbg_string *addtl)
> +{
> +     unsigned int len = 0;
> +     struct drbg_state *shadow = NULL;
> +
> +     if (0 == buflen || !buf)
> +             return 0;
> +     if (addtl && NULL == addtl->buf && 0 < addtl->len)
> +             return 0;
> +
> +     if (drbg_make_shadow(drbg, &shadow))
> +             return 0;
> +     /* 9.3.1 step 2 */
> +     if (buflen > (drbg_max_request_bytes(shadow)))
> +             goto err;
> +     /* 9.3.1 step 3 is implicit with the chosen DRBG */
> +     /* 9.3.1 step 4 */
> +     if (addtl && addtl->len > (drbg_max_addtl(shadow)))
> +             goto err;
> +     /* 9.3.1 step 5 is implicit with the chosen DRBG */
> +     /* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c -- the spec is a
> +      * bit convoluted here, we make it simpler */
> +     if ((drbg_max_requests(shadow)) < shadow->reseed_ctr)
> +             shadow->seeded = false;
> +
> +     /* allocate cipher handle */
> +     if (shadow->d_ops->crypto_init && shadow->d_ops->crypto_init(shadow))
> +             goto err;
> +
> +     if (shadow->pr || !shadow->seeded) {
> +             /* 9.3.1 steps 7.1 through 7.3 */
> +             if (drbg_seed(shadow, addtl, true))
> +                     goto err;
> +             /* 9.3.1 step 7.4 */
> +             addtl = NULL;
> +     }
> +     /* 9.3.1 step 8 and 10 */
> +     len = drbg->d_ops->generate(shadow, buf, buflen, addtl);

This needs to be shadow->d_ops
> +
> +     /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */
> +     shadow->reseed_ctr++;
> +
> +err:
> +     if (shadow->d_ops->crypto_fini)
> +             shadow->d_ops->crypto_fini(shadow);
> +     drbg_restore_shadow(drbg, &shadow);
> +     return len;
> +}

Ciao
Stephan
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to