All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephan Mueller <smueller@chronox.de>
To: linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org
Cc: aquini@redhat.com, jeremy.wayne.powell@gmail.com
Subject: [PATCH v2 6/6] Add DRBG test code to testmgr
Date: Mon, 17 Mar 2014 08:39:39 +0100	[thread overview]
Message-ID: <2717703.La8pfUukd1@myon.chronox.de> (raw)
In-Reply-To: <2836686.FjyLUn6aXI@myon.chronox.de>

The DRBG test code implements the CAVS test approach.

As discussed for the test vectors, all DRBG types are covered with
testing. However, not every backend cipher is covered with testing. To
prevent the testmgr from logging missing testing, the NULL test is
registered for all backend ciphers not covered with specific test cases.

All currently implemented DRBG types and backend ciphers are definined
in SP800-90A. Therefore, the fips_allowed flag is set for all.

Changes to v1:

  * Changes due to modification of drbg.c as documented in PATCH 1
  * Fix coding style and apply scripts/checkpatch.pl

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 7795550..baa6cb7 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <crypto/rng.h>
+#include <crypto/drbg.h>
 
 #include "internal.h"
 
@@ -108,6 +109,11 @@ struct cprng_test_suite {
 	unsigned int count;
 };
 
+struct drbg_test_suite {
+	struct drbg_testvec *vecs;
+	unsigned int count;
+};
+
 struct alg_test_desc {
 	const char *alg;
 	int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -121,6 +127,7 @@ struct alg_test_desc {
 		struct pcomp_test_suite pcomp;
 		struct hash_test_suite hash;
 		struct cprng_test_suite cprng;
+		struct drbg_test_suite drbg;
 	} suite;
 };
 
@@ -1712,6 +1719,101 @@ static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
 	return err;
 }
 
+
+static int drbg_cavs_test(struct drbg_testvec *test, int pr,
+			  const char *driver, u32 type, u32 mask)
+{
+	int ret = -EAGAIN;
+	struct crypto_rng *drng;
+	struct drbg_test_data test_data;
+	struct drbg_string addtl, pers, testentropy;
+	unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL);
+
+	if (!buf)
+		return -ENOMEM;
+
+	drng = crypto_alloc_rng(driver, type, mask);
+	if (IS_ERR(drng)) {
+		printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for"
+		       "%s\n", driver);
+		kzfree(buf);
+		return -ENOMEM;
+	}
+
+	test_data.testentropy = &testentropy;
+	drbg_string_fill(&testentropy, test->entropy, test->entropylen);
+	drbg_string_fill(&pers, test->pers, test->perslen);
+	ret = crypto_drbg_reset_test(drng, &pers, &test_data);
+	if (ret) {
+		printk(KERN_ERR "alg: drbg: Failed to reset rng\n");
+		goto outbuf;
+	}
+
+	drbg_string_fill(&addtl, test->addtla, test->addtllen);
+	if (pr) {
+		drbg_string_fill(&testentropy, test->entpra, test->entprlen);
+		ret = crypto_drbg_get_bytes_addtl_test(drng,
+			buf, test->expectedlen, &addtl,	&test_data);
+	} else {
+		ret = crypto_drbg_get_bytes_addtl(drng,
+			buf, test->expectedlen, &addtl);
+	}
+	if (ret <= 0) {
+		printk(KERN_ERR "alg: drbg: could not obtain random data for"
+		       "driver %s\n", driver);
+		goto outbuf;
+	}
+
+	drbg_string_fill(&addtl, test->addtlb, test->addtllen);
+	if (pr) {
+		drbg_string_fill(&testentropy, test->entprb, test->entprlen);
+		ret = crypto_drbg_get_bytes_addtl_test(drng,
+			buf, test->expectedlen, &addtl, &test_data);
+	} else {
+		ret = crypto_drbg_get_bytes_addtl(drng,
+			buf, test->expectedlen, &addtl);
+	}
+	if (ret <= 0) {
+		printk(KERN_ERR "alg: drbg: could not obtain random data for"
+		       "driver %s\n", driver);
+		goto outbuf;
+	}
+
+	ret = memcmp(test->expected, buf, test->expectedlen);
+
+outbuf:
+	crypto_free_rng(drng);
+	kzfree(buf);
+	return ret;
+}
+
+
+static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver,
+			 u32 type, u32 mask)
+{
+	int err = 0;
+	int pr = 0;
+	int i = 0;
+	struct drbg_testvec *template = desc->suite.drbg.vecs;
+	unsigned int tcount = desc->suite.drbg.count;
+
+	if ((0 == memcmp(driver, "drbg(pr(", 8)) ||
+	    (0 == memcmp(driver, "drbg_pr_", 8)))
+		pr = 1;
+
+	for (i = 0; i < tcount; i++) {
+		err = drbg_cavs_test(&template[i], pr, driver, type, mask);
+		if (err) {
+			printk(KERN_ERR "alg: drbg: Test %d failed for %s\n",
+			       i, driver);
+			err = -EINVAL;
+			break;
+		}
+	}
+	return err;
+
+}
+
 static int alg_test_null(const struct alg_test_desc *desc,
 			     const char *driver, u32 type, u32 mask)
 {
@@ -2273,6 +2375,171 @@ static const struct alg_test_desc alg_test_descs[] = {
 		.alg = "digest_null",
 		.test = alg_test_null,
 	}, {
+		.alg = "drbg(nopr(ctr(aes128)))",
+		.test = alg_test_drbg,
+		.fips_allowed = 1,
+		.suite = {
+			.drbg = {
+				.vecs = drbg_nopr_ctr_aes128_tv_template,
+				.count = ARRAY_SIZE(drbg_nopr_ctr_aes128_tv_template)
+			}
+		}
+	}, {
+		.alg = "drbg(nopr(ctr(aes192)))",
+		.test = alg_test_drbg,
+		.fips_allowed = 1,
+		.suite = {
+			.drbg = {
+				.vecs = drbg_nopr_ctr_aes192_tv_template,
+				.count = ARRAY_SIZE(drbg_nopr_ctr_aes192_tv_template)
+			}
+		}
+	}, {
+		.alg = "drbg(nopr(ctr(aes256)))",
+		.test = alg_test_drbg,
+		.fips_allowed = 1,
+		.suite = {
+			.drbg = {
+				.vecs = drbg_nopr_ctr_aes256_tv_template,
+				.count = ARRAY_SIZE(drbg_nopr_ctr_aes256_tv_template)
+			}
+		}
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(nopr(hmac(sha256))) test */
+		.alg = "drbg(nopr(hmac(sha1)))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		.alg = "drbg(nopr(hmac(sha256)))",
+		.test = alg_test_drbg,
+		.fips_allowed = 1,
+		.suite = {
+			.drbg = {
+				.vecs = drbg_nopr_hmac_sha256_tv_template,
+				.count =
+				ARRAY_SIZE(drbg_nopr_hmac_sha256_tv_template)
+			}
+		}
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(nopr(hmac(sha256))) test */
+		.alg = "drbg(nopr(hmac(sha384)))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(nopr(hmac(sha256))) test */
+		.alg = "drbg(nopr(hmac(sha512)))",
+		.test = alg_test_null,
+		.fips_allowed = 1,
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(nopr(sha256)) test */
+		.alg = "drbg(nopr(sha1))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		.alg = "drbg(nopr(sha256))",
+		.test = alg_test_drbg,
+		.fips_allowed = 1,
+		.suite = {
+			.drbg = {
+				.vecs = drbg_nopr_sha256_tv_template,
+				.count = ARRAY_SIZE(drbg_nopr_sha256_tv_template)
+			}
+		}
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(nopr(sha256)) test */
+		.alg = "drbg(nopr(sha384))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(nopr(sha256)) test */
+		.alg = "drbg(nopr(sha512))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		.alg = "drbg(pr(ctr(aes128)))",
+		.test = alg_test_drbg,
+		.fips_allowed = 1,
+		.suite = {
+			.drbg = {
+				.vecs = drbg_pr_ctr_aes128_tv_template,
+				.count = ARRAY_SIZE(drbg_pr_ctr_aes128_tv_template)
+			}
+		}
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(pr(aes128)) test */
+		.alg = "drbg(pr(ctr(aes192)))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(pr(aes128)) test */
+		.alg = "drbg(pr(ctr(aes256)))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(pr(hmac(sha256))) test */
+		.alg = "drbg(pr(hmac(sha1)))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		.alg = "drbg(pr(hmac(sha256)))",
+		.test = alg_test_drbg,
+		.fips_allowed = 1,
+		.suite = {
+			.drbg = {
+				.vecs = drbg_pr_hmac_sha256_tv_template,
+				.count = ARRAY_SIZE(drbg_pr_hmac_sha256_tv_template)
+			}
+		}
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(pr(hmac(sha256))) test */
+		.alg = "drbg(pr(hmac(sha384)))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(pr(hmac(sha256))) test */
+		.alg = "drbg(pr(hmac(sha512)))",
+		.test = alg_test_null,
+		.fips_allowed = 1,
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(pr(sha256)) test */
+		.alg = "drbg(pr(sha1))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		.alg = "drbg(pr(sha256))",
+		.test = alg_test_drbg,
+		.fips_allowed = 1,
+		.suite = {
+			.drbg = {
+				.vecs = drbg_pr_sha256_tv_template,
+				.count = ARRAY_SIZE(drbg_pr_sha256_tv_template)
+			}
+		}
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(pr(sha256)) test */
+		.alg = "drbg(pr(sha384))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
+		/* There is no need to specifically test the DRBG with every
+		 * backend cipher -- covered by drbg(pr(sha256)) test */
+		.alg = "drbg(pr(sha512))",
+		.fips_allowed = 1,
+		.test = alg_test_null,
+	}, {
 		.alg = "ecb(__aes-aesni)",
 		.test = alg_test_null,
 		.fips_allowed = 1,

  reply	other threads:[~2014-03-17  7:39 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-08 23:43 [PATCH 0/6] SP800-90A Deterministic Random Bit Generator Stephan Mueller
2014-03-08 23:46 ` [PATCH 1/6] " Stephan Mueller
2014-03-08 23:46   ` [PATCH 2/6] header file for DRBG Stephan Mueller
2014-03-08 23:47     ` [PATCH 3/6] DRBG kernel configuration options Stephan Mueller
2014-03-08 23:48       ` [PATCH 4/6] compile the DRBG code Stephan Mueller
2014-03-08 23:49         ` [PATCH 5/6] DRBG testmgr test vectors Stephan Mueller
2014-03-08 23:50           ` [PATCH 6/6] Add DRBG test code to testmgr Stephan Mueller
2014-03-10 13:56     ` [PATCH 2/6] header file for DRBG Rafael Aquini
2014-03-10 13:36   ` [PATCH 1/6] SP800-90A Deterministic Random Bit Generator Rafael Aquini
2014-03-17  7:34   ` [PATCH v2 " Stephan Mueller
2014-03-17  7:35     ` [PATCH v2 2/6] header file for DRBG Stephan Mueller
2014-03-17  7:35       ` [PATCH v2 3/6] DRBG kernel configuration options Stephan Mueller
2014-03-17  7:37         ` [PATCH v2 4/6] compile the DRBG code Stephan Mueller
2014-03-17  7:38           ` [PATCH v2 5/6] DRBG testmgr test vectors Stephan Mueller
2014-03-17  7:39             ` Stephan Mueller [this message]
2014-04-11 18:07       ` [PATCH v4 2/6] header file for DRBG Stephan Mueller
2014-03-19  7:51     ` [PATCH v2 1/6] SP800-90A Deterministic Random Bit Generator Stephan Mueller
2014-03-20  8:12     ` Clemens Ladisch
2014-03-20 13:30       ` Stephan Mueller
2014-03-27 19:53     ` [PATCH v3 " Stephan Mueller
2014-03-27 19:56     ` Stephan Mueller
2014-04-11 18:07       ` [PATCH v4 " Stephan Mueller
2014-04-11 18:20         ` Joe Perches
2014-04-11 19:24           ` Stephan Mueller
2014-04-15  5:35         ` [PATCH v5 " Stephan Mueller
2014-04-15  5:51           ` Joe Perches
2014-04-15  6:08             ` Stephan Mueller
2014-04-26 20:13           ` [PATCH v6 " Stephan Mueller
2014-05-20 21:32             ` Rafael Aquini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2717703.La8pfUukd1@myon.chronox.de \
    --to=smueller@chronox.de \
    --cc=aquini@redhat.com \
    --cc=jeremy.wayne.powell@gmail.com \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.