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 | |
| 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')
| -rw-r--r-- | crypto/testmgr.c | 89 | ||||
| -rw-r--r-- | crypto/testmgr.h | 12 |
2 files changed, 101 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 | { |
diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 5add65196a98..13d5a61d0e77 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h | |||
| @@ -70,6 +70,18 @@ struct aead_testvec { | |||
| 70 | unsigned short rlen; | 70 | unsigned short rlen; |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | struct cprng_testvec { | ||
| 74 | char *key; | ||
| 75 | char *dt; | ||
| 76 | char *v; | ||
| 77 | char *result; | ||
| 78 | unsigned char klen; | ||
| 79 | unsigned short dtlen; | ||
| 80 | unsigned short vlen; | ||
| 81 | unsigned short rlen; | ||
| 82 | unsigned short loops; | ||
| 83 | }; | ||
| 84 | |||
| 73 | static char zeroed_string[48]; | 85 | static char zeroed_string[48]; |
| 74 | 86 | ||
| 75 | /* | 87 | /* |
