Commit 7647d6ce2077d9e1c3d72359f6b4492be129cfe8

Authored by Jarod Wilson
Committed by Herbert Xu
1 parent 5d667322a2

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

... ... @@ -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  
... ... @@ -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 /*