aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarod Wilson <jarod@redhat.com>2009-05-04 07:44:50 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2009-06-02 00:04:38 -0400
commit7647d6ce2077d9e1c3d72359f6b4492be129cfe8 (patch)
treef4d961ef1cd4c6d69c87e5090dba7a631bc004a1
parent5d667322a25ab4ecb91176db118fd663fee4da35 (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>
-rw-r--r--crypto/testmgr.c89
-rw-r--r--crypto/testmgr.h12
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
88struct cprng_test_suite {
89 struct cprng_testvec *vecs;
90 unsigned int count;
91};
92
87struct alg_test_desc { 93struct 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
1100static 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
1156out:
1157 kfree(seed);
1158 return err;
1159}
1160
1092static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, 1161static 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
1360static 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. */
1292static const struct alg_test_desc alg_test_descs[] = { 1381static 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
73struct 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
73static char zeroed_string[48]; 85static char zeroed_string[48];
74 86
75/* 87/*