diff options
author | Jarod Wilson <jarod@redhat.com> | 2009-05-04 07:44:50 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2009-06-02 00:04:38 -0400 |
commit | 7647d6ce2077d9e1c3d72359f6b4492be129cfe8 (patch) | |
tree | f4d961ef1cd4c6d69c87e5090dba7a631bc004a1 /crypto/testmgr.c | |
parent | 5d667322a25ab4ecb91176db118fd663fee4da35 (diff) |
crypto: testmgr - Add infrastructure for ansi_cprng self-tests
Add some necessary infrastructure to make it possible to run
self-tests for ansi_cprng. The bits are likely very specific
to the ANSI X9.31 CPRNG in AES mode, and thus perhaps should
be named more specifically if/when we grow additional CPRNG
support...
Successfully tested against the cryptodev-2.6 tree and a
Red Hat Enterprise Linux 5.x kernel with the follow-on
patch that adds the actual test vectors.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r-- | crypto/testmgr.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 40c10789f7f3..adc54cfd39df 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/scatterlist.h> | 19 | #include <linux/scatterlist.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <crypto/rng.h> | ||
22 | 23 | ||
23 | #include "internal.h" | 24 | #include "internal.h" |
24 | #include "testmgr.h" | 25 | #include "testmgr.h" |
@@ -84,6 +85,11 @@ struct hash_test_suite { | |||
84 | unsigned int count; | 85 | unsigned int count; |
85 | }; | 86 | }; |
86 | 87 | ||
88 | struct cprng_test_suite { | ||
89 | struct cprng_testvec *vecs; | ||
90 | unsigned int count; | ||
91 | }; | ||
92 | |||
87 | struct alg_test_desc { | 93 | struct alg_test_desc { |
88 | const char *alg; | 94 | const char *alg; |
89 | int (*test)(const struct alg_test_desc *desc, const char *driver, | 95 | int (*test)(const struct alg_test_desc *desc, const char *driver, |
@@ -95,6 +101,7 @@ struct alg_test_desc { | |||
95 | struct comp_test_suite comp; | 101 | struct comp_test_suite comp; |
96 | struct pcomp_test_suite pcomp; | 102 | struct pcomp_test_suite pcomp; |
97 | struct hash_test_suite hash; | 103 | struct hash_test_suite hash; |
104 | struct cprng_test_suite cprng; | ||
98 | } suite; | 105 | } suite; |
99 | }; | 106 | }; |
100 | 107 | ||
@@ -1089,6 +1096,68 @@ static int test_pcomp(struct crypto_pcomp *tfm, | |||
1089 | return 0; | 1096 | return 0; |
1090 | } | 1097 | } |
1091 | 1098 | ||
1099 | |||
1100 | static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template, | ||
1101 | unsigned int tcount) | ||
1102 | { | ||
1103 | const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm)); | ||
1104 | int err, i, j, seedsize; | ||
1105 | u8 *seed; | ||
1106 | char result[32]; | ||
1107 | |||
1108 | seedsize = crypto_rng_seedsize(tfm); | ||
1109 | |||
1110 | seed = kmalloc(seedsize, GFP_KERNEL); | ||
1111 | if (!seed) { | ||
1112 | printk(KERN_ERR "alg: cprng: Failed to allocate seed space " | ||
1113 | "for %s\n", algo); | ||
1114 | return -ENOMEM; | ||
1115 | } | ||
1116 | |||
1117 | for (i = 0; i < tcount; i++) { | ||
1118 | memset(result, 0, 32); | ||
1119 | |||
1120 | memcpy(seed, template[i].v, template[i].vlen); | ||
1121 | memcpy(seed + template[i].vlen, template[i].key, | ||
1122 | template[i].klen); | ||
1123 | memcpy(seed + template[i].vlen + template[i].klen, | ||
1124 | template[i].dt, template[i].dtlen); | ||
1125 | |||
1126 | err = crypto_rng_reset(tfm, seed, seedsize); | ||
1127 | if (err) { | ||
1128 | printk(KERN_ERR "alg: cprng: Failed to reset rng " | ||
1129 | "for %s\n", algo); | ||
1130 | goto out; | ||
1131 | } | ||
1132 | |||
1133 | for (j = 0; j < template[i].loops; j++) { | ||
1134 | err = crypto_rng_get_bytes(tfm, result, | ||
1135 | template[i].rlen); | ||
1136 | if (err != template[i].rlen) { | ||
1137 | printk(KERN_ERR "alg: cprng: Failed to obtain " | ||
1138 | "the correct amount of random data for " | ||
1139 | "%s (requested %d, got %d)\n", algo, | ||
1140 | template[i].rlen, err); | ||
1141 | goto out; | ||
1142 | } | ||
1143 | } | ||
1144 | |||
1145 | err = memcmp(result, template[i].result, | ||
1146 | template[i].rlen); | ||
1147 | if (err) { | ||
1148 | printk(KERN_ERR "alg: cprng: Test %d failed for %s\n", | ||
1149 | i, algo); | ||
1150 | hexdump(result, template[i].rlen); | ||
1151 | err = -EINVAL; | ||
1152 | goto out; | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1156 | out: | ||
1157 | kfree(seed); | ||
1158 | return err; | ||
1159 | } | ||
1160 | |||
1092 | static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, | 1161 | static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, |
1093 | u32 type, u32 mask) | 1162 | u32 type, u32 mask) |
1094 | { | 1163 | { |
@@ -1288,6 +1357,26 @@ out: | |||
1288 | return err; | 1357 | return err; |
1289 | } | 1358 | } |
1290 | 1359 | ||
1360 | static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, | ||
1361 | u32 type, u32 mask) | ||
1362 | { | ||
1363 | struct crypto_rng *rng; | ||
1364 | int err; | ||
1365 | |||
1366 | rng = crypto_alloc_rng(driver, type, mask); | ||
1367 | if (IS_ERR(rng)) { | ||
1368 | printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " | ||
1369 | "%ld\n", driver, PTR_ERR(rng)); | ||
1370 | return PTR_ERR(rng); | ||
1371 | } | ||
1372 | |||
1373 | err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count); | ||
1374 | |||
1375 | crypto_free_rng(rng); | ||
1376 | |||
1377 | return err; | ||
1378 | } | ||
1379 | |||
1291 | /* Please keep this list sorted by algorithm name. */ | 1380 | /* Please keep this list sorted by algorithm name. */ |
1292 | static const struct alg_test_desc alg_test_descs[] = { | 1381 | static const struct alg_test_desc alg_test_descs[] = { |
1293 | { | 1382 | { |