blob: bd7524cfff33e6ab71c9b37e6f98733e498a354a [file] [log] [blame]
Herbert Xuef2736f2005-06-22 13:26:03 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * Quick & dirty crypto testing module.
3 *
4 * This will only exist until we have a better testing mechanism
5 * (e.g. a char device).
6 *
7 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
8 * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
Herbert Xuef2736f2005-06-22 13:26:03 -070012 * Software Foundation; either version 2 of the License, or (at your option)
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 * any later version.
14 *
Harald Welteebfd9bc2005-06-22 13:27:23 -070015 * 2004-08-09 Added cipher speed tests (Reyk Floeter <reyk@vantronix.net>)
16 * 2003-09-14 Rewritten by Kartikey Mahendra Bhatt
17 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 */
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/mm.h>
23#include <linux/slab.h>
24#include <asm/scatterlist.h>
25#include <linux/string.h>
26#include <linux/crypto.h>
27#include <linux/highmem.h>
28#include <linux/moduleparam.h>
Harald Welteebfd9bc2005-06-22 13:27:23 -070029#include <linux/jiffies.h>
Herbert Xu6a179442005-06-22 13:29:03 -070030#include <linux/timex.h>
31#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include "tcrypt.h"
33
34/*
35 * Need to kmalloc() memory for testing kmap().
36 */
Harald Welteebfd9bc2005-06-22 13:27:23 -070037#define TVMEMSIZE 16384
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#define XBUFSIZE 32768
39
40/*
41 * Indexes into the xbuf to simulate cross-page access.
42 */
43#define IDX1 37
44#define IDX2 32400
45#define IDX3 1
46#define IDX4 8193
47#define IDX5 22222
48#define IDX6 17101
49#define IDX7 27333
50#define IDX8 3000
51
52/*
53* Used by test_cipher()
54*/
55#define ENCRYPT 1
56#define DECRYPT 0
57#define MODE_ECB 1
58#define MODE_CBC 0
59
60static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
61
Harald Welteebfd9bc2005-06-22 13:27:23 -070062/*
63 * Used by test_cipher_speed()
64 */
Herbert Xu6a179442005-06-22 13:29:03 -070065static unsigned int sec;
Harald Welteebfd9bc2005-06-22 13:27:23 -070066
Linus Torvalds1da177e2005-04-16 15:20:36 -070067static int mode;
68static char *xbuf;
69static char *tvmem;
70
71static char *check[] = {
72 "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
Herbert Xuef2736f2005-06-22 13:26:03 -070073 "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
74 "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 "khazad", "wp512", "wp384", "wp256", "tnepres", NULL
76};
77
Herbert Xuef2736f2005-06-22 13:26:03 -070078static void hexdump(unsigned char *buf, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -070079{
80 while (len--)
81 printk("%02x", *buf++);
82
83 printk("\n");
84}
85
Herbert Xuef2736f2005-06-22 13:26:03 -070086static void test_hash(char *algo, struct hash_testvec *template,
87 unsigned int tcount)
Linus Torvalds1da177e2005-04-16 15:20:36 -070088{
Herbert Xuef2736f2005-06-22 13:26:03 -070089 char *p;
90 unsigned int i, j, k, temp;
91 struct scatterlist sg[8];
92 char result[64];
93 struct crypto_tfm *tfm;
94 struct hash_testvec *hash_tv;
95 unsigned int tsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Herbert Xuef2736f2005-06-22 13:26:03 -070097 printk("\ntesting %s\n", algo);
98
99 tsize = sizeof(struct hash_testvec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 tsize *= tcount;
Herbert Xuef2736f2005-06-22 13:26:03 -0700101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 if (tsize > TVMEMSIZE) {
103 printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE);
104 return;
105 }
106
107 memcpy(tvmem, template, tsize);
Herbert Xuef2736f2005-06-22 13:26:03 -0700108 hash_tv = (void *)tvmem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 tfm = crypto_alloc_tfm(algo, 0);
110 if (tfm == NULL) {
111 printk("failed to load transform for %s\n", algo);
112 return;
113 }
114
115 for (i = 0; i < tcount; i++) {
Herbert Xuef2736f2005-06-22 13:26:03 -0700116 printk("test %u:\n", i + 1);
117 memset(result, 0, 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
119 p = hash_tv[i].plaintext;
Herbert Xuef2736f2005-06-22 13:26:03 -0700120 sg[0].page = virt_to_page(p);
121 sg[0].offset = offset_in_page(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 sg[0].length = hash_tv[i].psize;
123
Herbert Xuef2736f2005-06-22 13:26:03 -0700124 crypto_digest_init(tfm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 if (tfm->crt_u.digest.dit_setkey) {
Herbert Xuef2736f2005-06-22 13:26:03 -0700126 crypto_digest_setkey(tfm, hash_tv[i].key,
127 hash_tv[i].ksize);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 }
Herbert Xuef2736f2005-06-22 13:26:03 -0700129 crypto_digest_update(tfm, sg, 1);
130 crypto_digest_final(tfm, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
Herbert Xuef2736f2005-06-22 13:26:03 -0700132 hexdump(result, crypto_tfm_alg_digestsize(tfm));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 printk("%s\n",
Herbert Xuef2736f2005-06-22 13:26:03 -0700134 memcmp(result, hash_tv[i].digest,
135 crypto_tfm_alg_digestsize(tfm)) ?
136 "fail" : "pass");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 }
138
Herbert Xuef2736f2005-06-22 13:26:03 -0700139 printk("testing %s across pages\n", algo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
141 /* setup the dummy buffer first */
Herbert Xuef2736f2005-06-22 13:26:03 -0700142 memset(xbuf, 0, XBUFSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
144 j = 0;
145 for (i = 0; i < tcount; i++) {
146 if (hash_tv[i].np) {
147 j++;
Herbert Xuef2736f2005-06-22 13:26:03 -0700148 printk("test %u:\n", j);
149 memset(result, 0, 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151 temp = 0;
152 for (k = 0; k < hash_tv[i].np; k++) {
Herbert Xuef2736f2005-06-22 13:26:03 -0700153 memcpy(&xbuf[IDX[k]],
154 hash_tv[i].plaintext + temp,
155 hash_tv[i].tap[k]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 temp += hash_tv[i].tap[k];
157 p = &xbuf[IDX[k]];
Herbert Xuef2736f2005-06-22 13:26:03 -0700158 sg[k].page = virt_to_page(p);
159 sg[k].offset = offset_in_page(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 sg[k].length = hash_tv[i].tap[k];
161 }
162
Herbert Xuef2736f2005-06-22 13:26:03 -0700163 crypto_digest_digest(tfm, sg, hash_tv[i].np, result);
164
165 hexdump(result, crypto_tfm_alg_digestsize(tfm));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 printk("%s\n",
Herbert Xuef2736f2005-06-22 13:26:03 -0700167 memcmp(result, hash_tv[i].digest,
168 crypto_tfm_alg_digestsize(tfm)) ?
169 "fail" : "pass");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 }
171 }
Herbert Xuef2736f2005-06-22 13:26:03 -0700172
173 crypto_free_tfm(tfm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174}
175
176
177#ifdef CONFIG_CRYPTO_HMAC
178
Herbert Xuef2736f2005-06-22 13:26:03 -0700179static void test_hmac(char *algo, struct hmac_testvec *template,
180 unsigned int tcount)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181{
182 char *p;
183 unsigned int i, j, k, temp;
184 struct scatterlist sg[8];
185 char result[64];
186 struct crypto_tfm *tfm;
187 struct hmac_testvec *hmac_tv;
188 unsigned int tsize, klen;
189
190 tfm = crypto_alloc_tfm(algo, 0);
191 if (tfm == NULL) {
192 printk("failed to load transform for %s\n", algo);
193 return;
194 }
195
196 printk("\ntesting hmac_%s\n", algo);
Herbert Xuef2736f2005-06-22 13:26:03 -0700197
198 tsize = sizeof(struct hmac_testvec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199 tsize *= tcount;
200 if (tsize > TVMEMSIZE) {
201 printk("template (%u) too big for tvmem (%u)\n", tsize,
202 TVMEMSIZE);
203 goto out;
204 }
205
206 memcpy(tvmem, template, tsize);
Herbert Xuef2736f2005-06-22 13:26:03 -0700207 hmac_tv = (void *)tvmem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208
209 for (i = 0; i < tcount; i++) {
210 printk("test %u:\n", i + 1);
211 memset(result, 0, sizeof (result));
212
213 p = hmac_tv[i].plaintext;
214 klen = hmac_tv[i].ksize;
215 sg[0].page = virt_to_page(p);
216 sg[0].offset = offset_in_page(p);
217 sg[0].length = hmac_tv[i].psize;
218
219 crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result);
220
221 hexdump(result, crypto_tfm_alg_digestsize(tfm));
222 printk("%s\n",
223 memcmp(result, hmac_tv[i].digest,
224 crypto_tfm_alg_digestsize(tfm)) ? "fail" :
225 "pass");
226 }
227
228 printk("\ntesting hmac_%s across pages\n", algo);
229
230 memset(xbuf, 0, XBUFSIZE);
Herbert Xuef2736f2005-06-22 13:26:03 -0700231
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 j = 0;
233 for (i = 0; i < tcount; i++) {
234 if (hmac_tv[i].np) {
235 j++;
Herbert Xuef2736f2005-06-22 13:26:03 -0700236 printk("test %u:\n",j);
237 memset(result, 0, 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
239 temp = 0;
240 klen = hmac_tv[i].ksize;
241 for (k = 0; k < hmac_tv[i].np; k++) {
Herbert Xuef2736f2005-06-22 13:26:03 -0700242 memcpy(&xbuf[IDX[k]],
243 hmac_tv[i].plaintext + temp,
244 hmac_tv[i].tap[k]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 temp += hmac_tv[i].tap[k];
246 p = &xbuf[IDX[k]];
Herbert Xuef2736f2005-06-22 13:26:03 -0700247 sg[k].page = virt_to_page(p);
248 sg[k].offset = offset_in_page(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 sg[k].length = hmac_tv[i].tap[k];
250 }
251
Herbert Xuef2736f2005-06-22 13:26:03 -0700252 crypto_hmac(tfm, hmac_tv[i].key, &klen, sg,
253 hmac_tv[i].np, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 hexdump(result, crypto_tfm_alg_digestsize(tfm));
Herbert Xuef2736f2005-06-22 13:26:03 -0700255
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 printk("%s\n",
Herbert Xuef2736f2005-06-22 13:26:03 -0700257 memcmp(result, hmac_tv[i].digest,
258 crypto_tfm_alg_digestsize(tfm)) ?
259 "fail" : "pass");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 }
261 }
262out:
263 crypto_free_tfm(tfm);
264}
265
266#endif /* CONFIG_CRYPTO_HMAC */
267
Herbert Xuef2736f2005-06-22 13:26:03 -0700268static void test_cipher(char *algo, int mode, int enc,
269 struct cipher_testvec *template, unsigned int tcount)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270{
271 unsigned int ret, i, j, k, temp;
272 unsigned int tsize;
273 char *p, *q;
274 struct crypto_tfm *tfm;
275 char *key;
276 struct cipher_testvec *cipher_tv;
277 struct scatterlist sg[8];
Herbert Xu3cc38162005-06-22 13:26:36 -0700278 const char *e, *m;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279
280 if (enc == ENCRYPT)
Herbert Xu3cc38162005-06-22 13:26:36 -0700281 e = "encryption";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 else
Herbert Xu3cc38162005-06-22 13:26:36 -0700283 e = "decryption";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 if (mode == MODE_ECB)
Herbert Xu3cc38162005-06-22 13:26:36 -0700285 m = "ECB";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 else
Herbert Xu3cc38162005-06-22 13:26:36 -0700287 m = "CBC";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288
Herbert Xuef2736f2005-06-22 13:26:03 -0700289 printk("\ntesting %s %s %s\n", algo, m, e);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290
Herbert Xuef2736f2005-06-22 13:26:03 -0700291 tsize = sizeof (struct cipher_testvec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 tsize *= tcount;
Herbert Xuef2736f2005-06-22 13:26:03 -0700293
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 if (tsize > TVMEMSIZE) {
295 printk("template (%u) too big for tvmem (%u)\n", tsize,
296 TVMEMSIZE);
297 return;
298 }
299
300 memcpy(tvmem, template, tsize);
Herbert Xuef2736f2005-06-22 13:26:03 -0700301 cipher_tv = (void *)tvmem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302
Herbert Xuef2736f2005-06-22 13:26:03 -0700303 if (mode)
304 tfm = crypto_alloc_tfm(algo, 0);
305 else
306 tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_CBC);
307
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 if (tfm == NULL) {
309 printk("failed to load transform for %s %s\n", algo, m);
310 return;
311 }
Herbert Xuef2736f2005-06-22 13:26:03 -0700312
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 j = 0;
314 for (i = 0; i < tcount; i++) {
315 if (!(cipher_tv[i].np)) {
Herbert Xuef2736f2005-06-22 13:26:03 -0700316 j++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 printk("test %u (%d bit key):\n",
318 j, cipher_tv[i].klen * 8);
319
320 tfm->crt_flags = 0;
Herbert Xuef2736f2005-06-22 13:26:03 -0700321 if (cipher_tv[i].wk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
323 key = cipher_tv[i].key;
Herbert Xuef2736f2005-06-22 13:26:03 -0700324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);
326 if (ret) {
327 printk("setkey() failed flags=%x\n", tfm->crt_flags);
Herbert Xuef2736f2005-06-22 13:26:03 -0700328
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 if (!cipher_tv[i].fail)
330 goto out;
Herbert Xuef2736f2005-06-22 13:26:03 -0700331 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332
333 p = cipher_tv[i].input;
334 sg[0].page = virt_to_page(p);
335 sg[0].offset = offset_in_page(p);
336 sg[0].length = cipher_tv[i].ilen;
Herbert Xuef2736f2005-06-22 13:26:03 -0700337
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 if (!mode) {
339 crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
Herbert Xuef2736f2005-06-22 13:26:03 -0700340 crypto_tfm_alg_ivsize(tfm));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 }
Herbert Xuef2736f2005-06-22 13:26:03 -0700342
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 if (enc)
344 ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
345 else
346 ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
Herbert Xuef2736f2005-06-22 13:26:03 -0700347
348
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 if (ret) {
350 printk("%s () failed flags=%x\n", e, tfm->crt_flags);
351 goto out;
Herbert Xuef2736f2005-06-22 13:26:03 -0700352 }
353
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 q = kmap(sg[0].page) + sg[0].offset;
355 hexdump(q, cipher_tv[i].rlen);
Herbert Xuef2736f2005-06-22 13:26:03 -0700356
357 printk("%s\n",
358 memcmp(q, cipher_tv[i].result,
359 cipher_tv[i].rlen) ? "fail" : "pass");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 }
361 }
Herbert Xuef2736f2005-06-22 13:26:03 -0700362
363 printk("\ntesting %s %s %s across pages (chunking)\n", algo, m, e);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 memset(xbuf, 0, XBUFSIZE);
Herbert Xuef2736f2005-06-22 13:26:03 -0700365
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 j = 0;
367 for (i = 0; i < tcount; i++) {
368 if (cipher_tv[i].np) {
Herbert Xuef2736f2005-06-22 13:26:03 -0700369 j++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 printk("test %u (%d bit key):\n",
371 j, cipher_tv[i].klen * 8);
372
Herbert Xuef2736f2005-06-22 13:26:03 -0700373 tfm->crt_flags = 0;
374 if (cipher_tv[i].wk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
376 key = cipher_tv[i].key;
Herbert Xuef2736f2005-06-22 13:26:03 -0700377
378 ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 if (ret) {
380 printk("setkey() failed flags=%x\n", tfm->crt_flags);
Herbert Xuef2736f2005-06-22 13:26:03 -0700381
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 if (!cipher_tv[i].fail)
383 goto out;
384 }
385
386 temp = 0;
387 for (k = 0; k < cipher_tv[i].np; k++) {
Herbert Xuef2736f2005-06-22 13:26:03 -0700388 memcpy(&xbuf[IDX[k]],
389 cipher_tv[i].input + temp,
390 cipher_tv[i].tap[k]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 temp += cipher_tv[i].tap[k];
392 p = &xbuf[IDX[k]];
Herbert Xuef2736f2005-06-22 13:26:03 -0700393 sg[k].page = virt_to_page(p);
394 sg[k].offset = offset_in_page(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 sg[k].length = cipher_tv[i].tap[k];
396 }
Herbert Xuef2736f2005-06-22 13:26:03 -0700397
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 if (!mode) {
399 crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
Herbert Xuef2736f2005-06-22 13:26:03 -0700400 crypto_tfm_alg_ivsize(tfm));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 }
Herbert Xuef2736f2005-06-22 13:26:03 -0700402
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 if (enc)
404 ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
405 else
406 ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
Herbert Xuef2736f2005-06-22 13:26:03 -0700407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 if (ret) {
409 printk("%s () failed flags=%x\n", e, tfm->crt_flags);
410 goto out;
411 }
412
413 temp = 0;
414 for (k = 0; k < cipher_tv[i].np; k++) {
415 printk("page %u\n", k);
416 q = kmap(sg[k].page) + sg[k].offset;
417 hexdump(q, cipher_tv[i].tap[k]);
Herbert Xuef2736f2005-06-22 13:26:03 -0700418 printk("%s\n",
419 memcmp(q, cipher_tv[i].result + temp,
420 cipher_tv[i].tap[k]) ? "fail" :
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 "pass");
422 temp += cipher_tv[i].tap[k];
423 }
424 }
425 }
426
427out:
428 crypto_free_tfm(tfm);
429}
430
Herbert Xu6a179442005-06-22 13:29:03 -0700431static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
432 int blen, int sec)
433{
434 struct scatterlist sg[8];
435 unsigned long start, end;
436 int bcount;
437 int ret;
438
439 sg[0].page = virt_to_page(p);
440 sg[0].offset = offset_in_page(p);
441 sg[0].length = blen;
442
443 for (start = jiffies, end = start + sec * HZ, bcount = 0;
444 time_before(jiffies, end); bcount++) {
445 if (enc)
446 ret = crypto_cipher_encrypt(tfm, sg, sg, blen);
447 else
448 ret = crypto_cipher_decrypt(tfm, sg, sg, blen);
449
450 if (ret)
451 return ret;
452 }
453
454 printk("%d operations in %d seconds (%ld bytes)\n",
455 bcount, sec, (long)bcount * blen);
456 return 0;
457}
458
459static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p,
460 int blen)
461{
462 struct scatterlist sg[8];
463 unsigned long cycles = 0;
464 int ret = 0;
465 int i;
466
467 sg[0].page = virt_to_page(p);
468 sg[0].offset = offset_in_page(p);
469 sg[0].length = blen;
470
471 local_bh_disable();
472 local_irq_disable();
473
474 /* Warm-up run. */
475 for (i = 0; i < 4; i++) {
476 if (enc)
477 ret = crypto_cipher_encrypt(tfm, sg, sg, blen);
478 else
479 ret = crypto_cipher_decrypt(tfm, sg, sg, blen);
480
481 if (ret)
482 goto out;
483 }
484
485 /* The real thing. */
486 for (i = 0; i < 8; i++) {
487 cycles_t start, end;
488
489 start = get_cycles();
490 if (enc)
491 ret = crypto_cipher_encrypt(tfm, sg, sg, blen);
492 else
493 ret = crypto_cipher_decrypt(tfm, sg, sg, blen);
494 end = get_cycles();
495
496 if (ret)
497 goto out;
498
499 cycles += end - start;
500 }
501
502out:
503 local_irq_enable();
504 local_bh_enable();
505
506 if (ret == 0)
507 printk("1 operation in %lu cycles (%d bytes)\n",
508 (cycles + 4) / 8, blen);
509
510 return ret;
511}
512
Harald Welteebfd9bc2005-06-22 13:27:23 -0700513static void test_cipher_speed(char *algo, int mode, int enc, unsigned int sec,
Herbert Xudce907c2005-06-22 13:27:51 -0700514 struct cipher_testvec *template,
515 unsigned int tcount, struct cipher_speed *speed)
Harald Welteebfd9bc2005-06-22 13:27:23 -0700516{
Herbert Xudce907c2005-06-22 13:27:51 -0700517 unsigned int ret, i, j, iv_len;
Harald Welteebfd9bc2005-06-22 13:27:23 -0700518 unsigned char *key, *p, iv[128];
519 struct crypto_tfm *tfm;
Harald Welteebfd9bc2005-06-22 13:27:23 -0700520 const char *e, *m;
521
522 if (enc == ENCRYPT)
523 e = "encryption";
524 else
525 e = "decryption";
526 if (mode == MODE_ECB)
527 m = "ECB";
528 else
529 m = "CBC";
530
531 printk("\ntesting speed of %s %s %s\n", algo, m, e);
532
533 if (mode)
534 tfm = crypto_alloc_tfm(algo, 0);
535 else
536 tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_CBC);
537
538 if (tfm == NULL) {
539 printk("failed to load transform for %s %s\n", algo, m);
540 return;
541 }
542
543 for (i = 0; speed[i].klen != 0; i++) {
544 if ((speed[i].blen + speed[i].klen) > TVMEMSIZE) {
545 printk("template (%u) too big for tvmem (%u)\n",
546 speed[i].blen + speed[i].klen, TVMEMSIZE);
547 goto out;
548 }
549
550 printk("test %u (%d bit key, %d byte blocks): ", i,
551 speed[i].klen * 8, speed[i].blen);
552
553 memset(tvmem, 0xff, speed[i].klen + speed[i].blen);
554
555 /* set key, plain text and IV */
556 key = (unsigned char *)tvmem;
Herbert Xudce907c2005-06-22 13:27:51 -0700557 for (j = 0; j < tcount; j++) {
558 if (template[j].klen == speed[i].klen) {
559 key = template[j].key;
560 break;
561 }
562 }
Harald Welteebfd9bc2005-06-22 13:27:23 -0700563 p = (unsigned char *)tvmem + speed[i].klen;
564
565 ret = crypto_cipher_setkey(tfm, key, speed[i].klen);
566 if (ret) {
567 printk("setkey() failed flags=%x\n", tfm->crt_flags);
568 goto out;
569 }
570
571 if (!mode) {
572 iv_len = crypto_tfm_alg_ivsize(tfm);
573 memset(&iv, 0xff, iv_len);
574 crypto_cipher_set_iv(tfm, iv, iv_len);
575 }
576
Herbert Xu6a179442005-06-22 13:29:03 -0700577 if (sec)
578 ret = test_cipher_jiffies(tfm, enc, p, speed[i].blen,
579 sec);
580 else
581 ret = test_cipher_cycles(tfm, enc, p, speed[i].blen);
Harald Welteebfd9bc2005-06-22 13:27:23 -0700582
Herbert Xu6a179442005-06-22 13:29:03 -0700583 if (ret) {
584 printk("%s() failed flags=%x\n", e, tfm->crt_flags);
585 break;
Harald Welteebfd9bc2005-06-22 13:27:23 -0700586 }
Harald Welteebfd9bc2005-06-22 13:27:23 -0700587 }
588
589out:
590 crypto_free_tfm(tfm);
591}
592
Herbert Xuef2736f2005-06-22 13:26:03 -0700593static void test_deflate(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594{
595 unsigned int i;
596 char result[COMP_BUF_SIZE];
597 struct crypto_tfm *tfm;
598 struct comp_testvec *tv;
599 unsigned int tsize;
600
601 printk("\ntesting deflate compression\n");
602
603 tsize = sizeof (deflate_comp_tv_template);
604 if (tsize > TVMEMSIZE) {
605 printk("template (%u) too big for tvmem (%u)\n", tsize,
606 TVMEMSIZE);
607 return;
608 }
609
610 memcpy(tvmem, deflate_comp_tv_template, tsize);
Herbert Xuef2736f2005-06-22 13:26:03 -0700611 tv = (void *)tvmem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
613 tfm = crypto_alloc_tfm("deflate", 0);
614 if (tfm == NULL) {
615 printk("failed to load transform for deflate\n");
616 return;
617 }
618
619 for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) {
620 int ilen, ret, dlen = COMP_BUF_SIZE;
Herbert Xuef2736f2005-06-22 13:26:03 -0700621
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 printk("test %u:\n", i + 1);
623 memset(result, 0, sizeof (result));
624
625 ilen = tv[i].inlen;
626 ret = crypto_comp_compress(tfm, tv[i].input,
627 ilen, result, &dlen);
628 if (ret) {
629 printk("fail: ret=%d\n", ret);
630 continue;
631 }
632 hexdump(result, dlen);
633 printk("%s (ratio %d:%d)\n",
634 memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
635 ilen, dlen);
636 }
637
638 printk("\ntesting deflate decompression\n");
639
640 tsize = sizeof (deflate_decomp_tv_template);
641 if (tsize > TVMEMSIZE) {
642 printk("template (%u) too big for tvmem (%u)\n", tsize,
643 TVMEMSIZE);
644 goto out;
645 }
646
647 memcpy(tvmem, deflate_decomp_tv_template, tsize);
Herbert Xuef2736f2005-06-22 13:26:03 -0700648 tv = (void *)tvmem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649
650 for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) {
651 int ilen, ret, dlen = COMP_BUF_SIZE;
Herbert Xuef2736f2005-06-22 13:26:03 -0700652
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653 printk("test %u:\n", i + 1);
654 memset(result, 0, sizeof (result));
655
656 ilen = tv[i].inlen;
657 ret = crypto_comp_decompress(tfm, tv[i].input,
658 ilen, result, &dlen);
659 if (ret) {
660 printk("fail: ret=%d\n", ret);
661 continue;
662 }
663 hexdump(result, dlen);
664 printk("%s (ratio %d:%d)\n",
665 memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
666 ilen, dlen);
667 }
668out:
669 crypto_free_tfm(tfm);
670}
671
Herbert Xuef2736f2005-06-22 13:26:03 -0700672static void test_crc32c(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673{
674#define NUMVEC 6
675#define VECSIZE 40
676
677 int i, j, pass;
678 u32 crc;
679 u8 b, test_vec[NUMVEC][VECSIZE];
680 static u32 vec_results[NUMVEC] = {
681 0x0e2c157f, 0xe980ebf6, 0xde74bded,
682 0xd579c862, 0xba979ad0, 0x2b29d913
683 };
684 static u32 tot_vec_results = 0x24c5d375;
Herbert Xuef2736f2005-06-22 13:26:03 -0700685
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 struct scatterlist sg[NUMVEC];
687 struct crypto_tfm *tfm;
688 char *fmtdata = "testing crc32c initialized to %08x: %s\n";
689#define SEEDTESTVAL 0xedcba987
690 u32 seed;
691
692 printk("\ntesting crc32c\n");
693
694 tfm = crypto_alloc_tfm("crc32c", 0);
695 if (tfm == NULL) {
696 printk("failed to load transform for crc32c\n");
697 return;
698 }
Herbert Xuef2736f2005-06-22 13:26:03 -0700699
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 crypto_digest_init(tfm);
701 crypto_digest_final(tfm, (u8*)&crc);
702 printk(fmtdata, crc, (crc == 0) ? "pass" : "ERROR");
Herbert Xuef2736f2005-06-22 13:26:03 -0700703
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 /*
705 * stuff test_vec with known values, simple incrementing
706 * byte values.
707 */
708 b = 0;
709 for (i = 0; i < NUMVEC; i++) {
Herbert Xuef2736f2005-06-22 13:26:03 -0700710 for (j = 0; j < VECSIZE; j++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 test_vec[i][j] = ++b;
712 sg[i].page = virt_to_page(test_vec[i]);
713 sg[i].offset = offset_in_page(test_vec[i]);
714 sg[i].length = VECSIZE;
715 }
716
717 seed = SEEDTESTVAL;
718 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
719 crypto_digest_final(tfm, (u8*)&crc);
720 printk("testing crc32c setkey returns %08x : %s\n", crc, (crc == (SEEDTESTVAL ^ ~(u32)0)) ?
721 "pass" : "ERROR");
Herbert Xuef2736f2005-06-22 13:26:03 -0700722
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 printk("testing crc32c using update/final:\n");
724
725 pass = 1; /* assume all is well */
Herbert Xuef2736f2005-06-22 13:26:03 -0700726
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 for (i = 0; i < NUMVEC; i++) {
728 seed = ~(u32)0;
729 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
730 crypto_digest_update(tfm, &sg[i], 1);
731 crypto_digest_final(tfm, (u8*)&crc);
732 if (crc == vec_results[i]) {
733 printk(" %08x:OK", crc);
734 } else {
735 printk(" %08x:BAD, wanted %08x\n", crc, vec_results[i]);
736 pass = 0;
737 }
738 }
739
740 printk("\ntesting crc32c using incremental accumulator:\n");
741 crc = 0;
742 for (i = 0; i < NUMVEC; i++) {
743 seed = (crc ^ ~(u32)0);
744 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
745 crypto_digest_update(tfm, &sg[i], 1);
746 crypto_digest_final(tfm, (u8*)&crc);
747 }
748 if (crc == tot_vec_results) {
749 printk(" %08x:OK", crc);
750 } else {
751 printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
752 pass = 0;
753 }
754
755 printk("\ntesting crc32c using digest:\n");
756 seed = ~(u32)0;
757 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
758 crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&crc);
759 if (crc == tot_vec_results) {
760 printk(" %08x:OK", crc);
761 } else {
762 printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
763 pass = 0;
764 }
Herbert Xuef2736f2005-06-22 13:26:03 -0700765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 printk("\n%s\n", pass ? "pass" : "ERROR");
767
768 crypto_free_tfm(tfm);
769 printk("crc32c test complete\n");
770}
771
Herbert Xuef2736f2005-06-22 13:26:03 -0700772static void test_available(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773{
774 char **name = check;
Herbert Xuef2736f2005-06-22 13:26:03 -0700775
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 while (*name) {
777 printk("alg %s ", *name);
778 printk((crypto_alg_available(*name, 0)) ?
779 "found\n" : "not found\n");
780 name++;
Herbert Xuef2736f2005-06-22 13:26:03 -0700781 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782}
783
Herbert Xuef2736f2005-06-22 13:26:03 -0700784static void do_test(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785{
786 switch (mode) {
787
788 case 0:
789 test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700790
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700792
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 //DES
794 test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700795 test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
796 test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
797 test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
798
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 //DES3_EDE
800 test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700801 test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
802
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700804
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700806
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 //BLOWFISH
808 test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
809 test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
810 test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS);
811 test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700812
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 //TWOFISH
814 test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS);
815 test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS);
816 test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
817 test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700818
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 //SERPENT
820 test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS);
821 test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700822
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 //TNEPRES
824 test_cipher ("tnepres", MODE_ECB, ENCRYPT, tnepres_enc_tv_template, TNEPRES_ENC_TEST_VECTORS);
825 test_cipher ("tnepres", MODE_ECB, DECRYPT, tnepres_dec_tv_template, TNEPRES_DEC_TEST_VECTORS);
826
827 //AES
828 test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
829 test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
830
831 //CAST5
832 test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
833 test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700834
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 //CAST6
836 test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS);
837 test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS);
838
839 //ARC4
840 test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS);
841 test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS);
842
843 //TEA
844 test_cipher ("tea", MODE_ECB, ENCRYPT, tea_enc_tv_template, TEA_ENC_TEST_VECTORS);
845 test_cipher ("tea", MODE_ECB, DECRYPT, tea_dec_tv_template, TEA_DEC_TEST_VECTORS);
846
847
848 //XTEA
849 test_cipher ("xtea", MODE_ECB, ENCRYPT, xtea_enc_tv_template, XTEA_ENC_TEST_VECTORS);
850 test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS);
851
852 //KHAZAD
853 test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS);
854 test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS);
855
856 //ANUBIS
857 test_cipher ("anubis", MODE_ECB, ENCRYPT, anubis_enc_tv_template, ANUBIS_ENC_TEST_VECTORS);
858 test_cipher ("anubis", MODE_ECB, DECRYPT, anubis_dec_tv_template, ANUBIS_DEC_TEST_VECTORS);
859 test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
860 test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
861
862 test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
863 test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
864 test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS);
865 test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS);
866 test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS);
867 test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS);
868 test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS);
869 test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS);
870 test_deflate();
871 test_crc32c();
872#ifdef CONFIG_CRYPTO_HMAC
873 test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700874 test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700876#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877
878 test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
879 break;
880
881 case 1:
882 test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
883 break;
884
885 case 2:
886 test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
887 break;
888
889 case 3:
890 test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS);
891 test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
892 test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
893 test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
894 break;
895
896 case 4:
897 test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700898 test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 break;
900
901 case 5:
902 test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
903 break;
Herbert Xuef2736f2005-06-22 13:26:03 -0700904
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 case 6:
906 test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
907 break;
Herbert Xuef2736f2005-06-22 13:26:03 -0700908
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 case 7:
910 test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
911 test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
912 test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS);
913 test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS);
914 break;
915
916 case 8:
917 test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS);
918 test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS);
919 test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
920 test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
921 break;
Herbert Xuef2736f2005-06-22 13:26:03 -0700922
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 case 9:
924 test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS);
925 test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS);
926 break;
927
928 case 10:
929 test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
Herbert Xuef2736f2005-06-22 13:26:03 -0700930 test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 break;
932
933 case 11:
934 test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
935 break;
Herbert Xuef2736f2005-06-22 13:26:03 -0700936
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 case 12:
938 test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
939 break;
940
941 case 13:
942 test_deflate();
943 break;
944
945 case 14:
946 test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
947 test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS);
948 break;
949
950 case 15:
951 test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS);
952 test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS);
953 break;
954
955 case 16:
956 test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS);
957 test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS);
958 break;
959
960 case 17:
961 test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
962 break;
963
964 case 18:
965 test_crc32c();
966 break;
967
968 case 19:
969 test_cipher ("tea", MODE_ECB, ENCRYPT, tea_enc_tv_template, TEA_ENC_TEST_VECTORS);
970 test_cipher ("tea", MODE_ECB, DECRYPT, tea_dec_tv_template, TEA_DEC_TEST_VECTORS);
971 break;
972
973 case 20:
974 test_cipher ("xtea", MODE_ECB, ENCRYPT, xtea_enc_tv_template, XTEA_ENC_TEST_VECTORS);
975 test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS);
976 break;
977
978 case 21:
979 test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS);
980 test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS);
981 break;
982
983 case 22:
984 test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS);
985 break;
986
987 case 23:
988 test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS);
989 break;
990
991 case 24:
992 test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS);
993 break;
994
995 case 25:
996 test_cipher ("tnepres", MODE_ECB, ENCRYPT, tnepres_enc_tv_template, TNEPRES_ENC_TEST_VECTORS);
997 test_cipher ("tnepres", MODE_ECB, DECRYPT, tnepres_dec_tv_template, TNEPRES_DEC_TEST_VECTORS);
998 break;
999
1000 case 26:
1001 test_cipher ("anubis", MODE_ECB, ENCRYPT, anubis_enc_tv_template, ANUBIS_ENC_TEST_VECTORS);
1002 test_cipher ("anubis", MODE_ECB, DECRYPT, anubis_dec_tv_template, ANUBIS_DEC_TEST_VECTORS);
1003 test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
1004 test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
1005 break;
1006
1007 case 27:
1008 test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS);
1009 break;
1010
1011 case 28:
1012
1013 test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS);
1014 break;
1015
1016 case 29:
1017 test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS);
1018 break;
1019
1020#ifdef CONFIG_CRYPTO_HMAC
1021 case 100:
1022 test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
1023 break;
Herbert Xuef2736f2005-06-22 13:26:03 -07001024
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 case 101:
Herbert Xuef2736f2005-06-22 13:26:03 -07001026 test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 break;
Herbert Xuef2736f2005-06-22 13:26:03 -07001028
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 case 102:
1030 test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
1031 break;
1032
1033#endif
1034
Harald Welteebfd9bc2005-06-22 13:27:23 -07001035 case 200:
Herbert Xudce907c2005-06-22 13:27:51 -07001036 test_cipher_speed("aes", MODE_ECB, ENCRYPT, sec, NULL, 0,
1037 aes_speed_template);
1038 test_cipher_speed("aes", MODE_ECB, DECRYPT, sec, NULL, 0,
1039 aes_speed_template);
1040 test_cipher_speed("aes", MODE_CBC, ENCRYPT, sec, NULL, 0,
1041 aes_speed_template);
1042 test_cipher_speed("aes", MODE_CBC, DECRYPT, sec, NULL, 0,
1043 aes_speed_template);
Harald Welteebfd9bc2005-06-22 13:27:23 -07001044 break;
1045
1046 case 201:
Herbert Xudce907c2005-06-22 13:27:51 -07001047 test_cipher_speed("des3_ede", MODE_ECB, ENCRYPT, sec,
1048 des3_ede_enc_tv_template,
1049 DES3_EDE_ENC_TEST_VECTORS,
1050 des3_ede_speed_template);
1051 test_cipher_speed("des3_ede", MODE_ECB, DECRYPT, sec,
1052 des3_ede_dec_tv_template,
1053 DES3_EDE_DEC_TEST_VECTORS,
1054 des3_ede_speed_template);
1055 test_cipher_speed("des3_ede", MODE_CBC, ENCRYPT, sec,
1056 des3_ede_enc_tv_template,
1057 DES3_EDE_ENC_TEST_VECTORS,
1058 des3_ede_speed_template);
1059 test_cipher_speed("des3_ede", MODE_CBC, DECRYPT, sec,
1060 des3_ede_dec_tv_template,
1061 DES3_EDE_DEC_TEST_VECTORS,
1062 des3_ede_speed_template);
Harald Welteebfd9bc2005-06-22 13:27:23 -07001063 break;
1064
1065 case 202:
Herbert Xudce907c2005-06-22 13:27:51 -07001066 test_cipher_speed("twofish", MODE_ECB, ENCRYPT, sec, NULL, 0,
1067 twofish_speed_template);
1068 test_cipher_speed("twofish", MODE_ECB, DECRYPT, sec, NULL, 0,
1069 twofish_speed_template);
1070 test_cipher_speed("twofish", MODE_CBC, ENCRYPT, sec, NULL, 0,
1071 twofish_speed_template);
1072 test_cipher_speed("twofish", MODE_CBC, DECRYPT, sec, NULL, 0,
1073 twofish_speed_template);
Harald Welteebfd9bc2005-06-22 13:27:23 -07001074 break;
1075
1076 case 203:
Herbert Xudce907c2005-06-22 13:27:51 -07001077 test_cipher_speed("blowfish", MODE_ECB, ENCRYPT, sec, NULL, 0,
1078 blowfish_speed_template);
1079 test_cipher_speed("blowfish", MODE_ECB, DECRYPT, sec, NULL, 0,
1080 blowfish_speed_template);
1081 test_cipher_speed("blowfish", MODE_CBC, ENCRYPT, sec, NULL, 0,
1082 blowfish_speed_template);
1083 test_cipher_speed("blowfish", MODE_CBC, DECRYPT, sec, NULL, 0,
1084 blowfish_speed_template);
Harald Welteebfd9bc2005-06-22 13:27:23 -07001085 break;
1086
1087 case 204:
Herbert Xudce907c2005-06-22 13:27:51 -07001088 test_cipher_speed("des", MODE_ECB, ENCRYPT, sec, NULL, 0,
1089 des_speed_template);
1090 test_cipher_speed("des", MODE_ECB, DECRYPT, sec, NULL, 0,
1091 des_speed_template);
1092 test_cipher_speed("des", MODE_CBC, ENCRYPT, sec, NULL, 0,
1093 des_speed_template);
1094 test_cipher_speed("des", MODE_CBC, DECRYPT, sec, NULL, 0,
1095 des_speed_template);
Harald Welteebfd9bc2005-06-22 13:27:23 -07001096 break;
1097
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 case 1000:
1099 test_available();
1100 break;
Herbert Xuef2736f2005-06-22 13:26:03 -07001101
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102 default:
1103 /* useful for debugging */
1104 printk("not testing anything\n");
1105 break;
1106 }
1107}
1108
Herbert Xuef2736f2005-06-22 13:26:03 -07001109static int __init init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110{
1111 tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL);
1112 if (tvmem == NULL)
1113 return -ENOMEM;
1114
1115 xbuf = kmalloc(XBUFSIZE, GFP_KERNEL);
1116 if (xbuf == NULL) {
1117 kfree(tvmem);
1118 return -ENOMEM;
1119 }
1120
1121 do_test();
1122
1123 kfree(xbuf);
1124 kfree(tvmem);
1125 return 0;
1126}
1127
1128/*
1129 * If an init function is provided, an exit function must also be provided
1130 * to allow module unload.
1131 */
1132static void __exit fini(void) { }
1133
1134module_init(init);
1135module_exit(fini);
1136
1137module_param(mode, int, 0);
Harald Welteebfd9bc2005-06-22 13:27:23 -07001138module_param(sec, uint, 0);
Herbert Xu6a179442005-06-22 13:29:03 -07001139MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
1140 "(defaults to zero which uses CPU cycles instead)");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141
1142MODULE_LICENSE("GPL");
1143MODULE_DESCRIPTION("Quick & dirty crypto testing module");
1144MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");