Re: [PATCH v2 1/6] SP800-90A Deterministic Random Bit Generator

2014-03-20 Thread Stephan Mueller
Am Donnerstag, 20. März 2014, 09:12:55 schrieb Clemens Ladisch:

Hi Clemens,

> Stephan Mueller wrote:
> > This is a clean-room implementation of the DRBG defined in SP800-90A.
> 
> Why?  I guess it's for certification?

As per SP800-131A, the ANSI X9.31 DRNG is sunset by the end of 2014 and not 
allowed to be used in FIPS 140-2 compliant environments. The kernel crypto API 
implements an ANSI X9.31 DRNG in crypto/ansi_cprng.c as the only DRNG that 
complies with FIPS 140-2 at this time.

Without a replacement for this ANSI X9.31 DRNG, the kernel will not have an 
FIPS 140-2 approved DRNG any more starting from 2015.
> 
> > +static bool drbg_fips_continuous_test(struct drbg_state *drbg,
> > +unsigned char *buf)
> > ...
> > +   ret = memcmp(drbg->prev, buf, drbg_blocklen(drbg));
> > +   ...
> > +   /* invert the memcmp result, because the test shall pass when the
> > +* two compared values do not match */
> > +   if (ret)
> > +   return true;
> > +   else
> > +   return false;
> 
> This looks strange.  The return value of memcmp() is not really
> a boolean, and the code appears not to match the comment because the
> numeric value of ret is not actually inverted.  How about this:

Correct, the comment does not match the code as I had invered the logic of 
drbg_fips_continuous_test as per Rafael's comment. Yet, I did not update the 
comment.
> 
>   ret = memcmp(...);
>   ...
>   /* the test shall pass when the compared values are not equal */
>   return ret != 0;

I will add that change.
> 
> 
> Regards,
> Clemens


Thanks
Stephan
-- 
| Cui bono? |
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/6] SP800-90A Deterministic Random Bit Generator

2014-03-20 Thread Clemens Ladisch
Stephan Mueller wrote:
> This is a clean-room implementation of the DRBG defined in SP800-90A.

Why?  I guess it's for certification?

> +static bool drbg_fips_continuous_test(struct drbg_state *drbg,
> +  unsigned char *buf)
> ...
> + ret = memcmp(drbg->prev, buf, drbg_blocklen(drbg));
> + ...
> + /* invert the memcmp result, because the test shall pass when the
> +  * two compared values do not match */
> + if (ret)
> + return true;
> + else
> + return false;

This looks strange.  The return value of memcmp() is not really
a boolean, and the code appears not to match the comment because the
numeric value of ret is not actually inverted.  How about this:

ret = memcmp(...);
...
/* the test shall pass when the compared values are not equal */
return ret != 0;


Regards,
Clemens
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/6] SP800-90A Deterministic Random Bit Generator

2014-03-19 Thread Stephan Mueller
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-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/6] SP800-90A Deterministic Random Bit Generator

2014-03-17 Thread Stephan Mueller
This is a clean-room implementation of the DRBG defined in SP800-90A.
All three viable DRBGs defined in the standard are implemented:

 * HMAC: This is the leanest DRBG and compiled per default
 * Hash: The more complex DRBG can be enabled at compile time
 * CTR: The most complex DRBG can also be enabled at compile time

The DRBG implementation offers the following:

 * All three DRBG types are implemented with a derivation function.
 * All DRBG types are available with and without prediction resistance.
 * All SHA types of SHA-1, SHA-256, SHA-384, SHA-512 are available for
 * the HMAC and Hash DRBGs.
 * All AES types of AES-128, AES-192 and AES-256 are available for the
 * CTR DRBG.
 * A self test is implemented with drbg_healthcheck().
 * The FIPS 140-2 continuous self test is implemented.
 * Additional cipher primitives, such as Serpent or Twofish, can be
 * added to the DRBG without changing the implementation. The only
 * change necessary is to the DRBG definition given in the cores[]
 * array.

Changes to v1:

 * Overhauling code structure for simpler code as suggested by Rafael Aquini:
 - each DRBG type exports only two crypto functions,
 - the individual DRBG implementations structure closely according to
   SP 800-90A,
 - using struct drbg_string to refer to buffers to avoid too many
   function parameters and prevent multiple data structure conversions
 - use inline more thoroughly
 - replace macros with small inline functions
 - remove unnecessary indirections
 - replace of large stack variables with a scratch buffer allocated at
   the beginning of DRBG operation -- see comments about scratchpad
   throughout the code
 * Revamping DRBG flags usage: flags are only intended to select the appropriate
   DRBG type and DRBG strength. Flags are not intended to be visible to
   external callers.
 * Adding comments throughout the code to refer to the appropriate steps
   documented in SP 800-90A.
 * Fix invocation of kernel crypto API hash
 * Fix coding style and apply scripts/checkpatch.pl
 * Change locking approach: only very small code sections are guarded by a lock.
   This implies that the entire DRBG operates on a shadow copy of the original
   DRBG state -- see comments for drbg_copy_drbg
 * Perform thorough testing:
   - Performing of a full scale CAVS test with CAVS interface available at
 http://www.chronox.de/drbg.html
   - Performing tests by obtaining data which is not a multiple of cipher block
 size and check it with the ent tool to ensure that the generation loop
 does not reuse stale buffers to avoid errors like CVE-2013-4345.

Signed-off-by: Stephan Mueller 
---
 create mode 100644 crypto/drbg.c

diff --git a/crypto/drbg.c b/crypto/drbg.c
new file mode 100644
index 000..808852b
--- /dev/null
+++ b/crypto/drbg.c
@@ -0,0 +1,1790 @@
+/*
+ * DRBG: Deterministic Random Bits Generator
+ *   Based on NIST Recommended DRBG from NIST SP800-90A with the following
+ *   properties:
+ * * CTR DRBG with DF with AES-128, AES-192, AES-256 cores
+ * * Hash DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores
+ * * HMAC DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores
+ * * with and without prediction resistance
+ *
+ * Copyright Stephan Mueller , 2014
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, and the entire permission notice in its entirety,
+ *including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *products derived from this software without specific prior
+ *written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU General Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions.  (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRA