Commit 7647d6ce2077d9e1c3d72359f6b4492be129cfe8
Committed by
Herbert Xu
1 parent
5d667322a2
Exists in
master
and in
4 other branches
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>
Showing 2 changed files with 101 additions and 0 deletions Side-by-side Diff
crypto/testmgr.c
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | #include <linux/scatterlist.h> |
20 | 20 | #include <linux/slab.h> |
21 | 21 | #include <linux/string.h> |
22 | +#include <crypto/rng.h> | |
22 | 23 | |
23 | 24 | #include "internal.h" |
24 | 25 | #include "testmgr.h" |
... | ... | @@ -84,6 +85,11 @@ |
84 | 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 | 93 | struct alg_test_desc { |
88 | 94 | const char *alg; |
89 | 95 | int (*test)(const struct alg_test_desc *desc, const char *driver, |
... | ... | @@ -95,6 +101,7 @@ |
95 | 101 | struct comp_test_suite comp; |
96 | 102 | struct pcomp_test_suite pcomp; |
97 | 103 | struct hash_test_suite hash; |
104 | + struct cprng_test_suite cprng; | |
98 | 105 | } suite; |
99 | 106 | }; |
100 | 107 | |
... | ... | @@ -1089,6 +1096,68 @@ |
1089 | 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 | 1161 | static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, |
1093 | 1162 | u32 type, u32 mask) |
1094 | 1163 | { |
... | ... | @@ -1285,6 +1354,26 @@ |
1285 | 1354 | crypto_free_shash(tfm); |
1286 | 1355 | |
1287 | 1356 | out: |
1357 | + return err; | |
1358 | +} | |
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 | + | |
1288 | 1377 | return err; |
1289 | 1378 | } |
1290 | 1379 |
crypto/testmgr.h
... | ... | @@ -70,6 +70,18 @@ |
70 | 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 | 85 | static char zeroed_string[48]; |
74 | 86 | |
75 | 87 | /* |