]>
Commit | Line | Data |
---|---|---|
ef2736fc | 1 | /* |
1da177e4 LT |
2 | * 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> | |
e3a4ea4f | 9 | * Copyright (c) 2007 Nokia Siemens Networks |
1da177e4 LT |
10 | * |
11 | * This program is free software; you can redistribute it and/or modify it | |
12 | * under the terms of the GNU General Public License as published by the Free | |
ef2736fc | 13 | * Software Foundation; either version 2 of the License, or (at your option) |
1da177e4 LT |
14 | * any later version. |
15 | * | |
1da177e4 LT |
16 | */ |
17 | ||
18e33e6d | 18 | #include <crypto/hash.h> |
cba83564 | 19 | #include <linux/err.h> |
1da177e4 LT |
20 | #include <linux/init.h> |
21 | #include <linux/module.h> | |
1da177e4 | 22 | #include <linux/slab.h> |
378f058c | 23 | #include <linux/scatterlist.h> |
1da177e4 | 24 | #include <linux/string.h> |
1da177e4 | 25 | #include <linux/moduleparam.h> |
ebfd9bcf | 26 | #include <linux/jiffies.h> |
6a17944c HX |
27 | #include <linux/timex.h> |
28 | #include <linux/interrupt.h> | |
1da177e4 | 29 | #include "tcrypt.h" |
4e033a6b | 30 | #include "internal.h" |
1da177e4 LT |
31 | |
32 | /* | |
f139cfa7 | 33 | * Need slab memory for testing (size in number of pages). |
1da177e4 | 34 | */ |
f139cfa7 | 35 | #define TVMEMSIZE 4 |
1da177e4 LT |
36 | |
37 | /* | |
da7f033d | 38 | * Used by test_cipher_speed() |
1da177e4 LT |
39 | */ |
40 | #define ENCRYPT 1 | |
41 | #define DECRYPT 0 | |
1da177e4 | 42 | |
ebfd9bcf HW |
43 | /* |
44 | * Used by test_cipher_speed() | |
45 | */ | |
6a17944c | 46 | static unsigned int sec; |
ebfd9bcf | 47 | |
a873a5f1 SK |
48 | static char *alg = NULL; |
49 | static u32 type; | |
1da177e4 | 50 | static int mode; |
f139cfa7 | 51 | static char *tvmem[TVMEMSIZE]; |
1da177e4 LT |
52 | |
53 | static char *check[] = { | |
cd12fb90 JL |
54 | "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256", |
55 | "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", | |
56 | "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", | |
90831639 | 57 | "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", |
2998db37 | 58 | "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320", |
0c01aed5 | 59 | "lzo", "cts", "zlib", NULL |
1da177e4 LT |
60 | }; |
61 | ||
f139cfa7 HX |
62 | static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, |
63 | struct scatterlist *sg, int blen, int sec) | |
6a17944c | 64 | { |
6a17944c HX |
65 | unsigned long start, end; |
66 | int bcount; | |
67 | int ret; | |
68 | ||
6a17944c HX |
69 | for (start = jiffies, end = start + sec * HZ, bcount = 0; |
70 | time_before(jiffies, end); bcount++) { | |
71 | if (enc) | |
cba83564 | 72 | ret = crypto_blkcipher_encrypt(desc, sg, sg, blen); |
6a17944c | 73 | else |
cba83564 | 74 | ret = crypto_blkcipher_decrypt(desc, sg, sg, blen); |
6a17944c HX |
75 | |
76 | if (ret) | |
77 | return ret; | |
78 | } | |
79 | ||
80 | printk("%d operations in %d seconds (%ld bytes)\n", | |
81 | bcount, sec, (long)bcount * blen); | |
82 | return 0; | |
83 | } | |
84 | ||
f139cfa7 HX |
85 | static int test_cipher_cycles(struct blkcipher_desc *desc, int enc, |
86 | struct scatterlist *sg, int blen) | |
6a17944c | 87 | { |
6a17944c HX |
88 | unsigned long cycles = 0; |
89 | int ret = 0; | |
90 | int i; | |
91 | ||
6a17944c HX |
92 | local_bh_disable(); |
93 | local_irq_disable(); | |
94 | ||
95 | /* Warm-up run. */ | |
96 | for (i = 0; i < 4; i++) { | |
97 | if (enc) | |
cba83564 | 98 | ret = crypto_blkcipher_encrypt(desc, sg, sg, blen); |
6a17944c | 99 | else |
cba83564 | 100 | ret = crypto_blkcipher_decrypt(desc, sg, sg, blen); |
6a17944c HX |
101 | |
102 | if (ret) | |
103 | goto out; | |
104 | } | |
105 | ||
106 | /* The real thing. */ | |
107 | for (i = 0; i < 8; i++) { | |
108 | cycles_t start, end; | |
109 | ||
110 | start = get_cycles(); | |
111 | if (enc) | |
cba83564 | 112 | ret = crypto_blkcipher_encrypt(desc, sg, sg, blen); |
6a17944c | 113 | else |
cba83564 | 114 | ret = crypto_blkcipher_decrypt(desc, sg, sg, blen); |
6a17944c HX |
115 | end = get_cycles(); |
116 | ||
117 | if (ret) | |
118 | goto out; | |
119 | ||
120 | cycles += end - start; | |
121 | } | |
122 | ||
123 | out: | |
124 | local_irq_enable(); | |
125 | local_bh_enable(); | |
126 | ||
127 | if (ret == 0) | |
128 | printk("1 operation in %lu cycles (%d bytes)\n", | |
129 | (cycles + 4) / 8, blen); | |
130 | ||
131 | return ret; | |
132 | } | |
133 | ||
d5dc3927 SS |
134 | static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 }; |
135 | ||
01b32324 | 136 | static void test_cipher_speed(const char *algo, int enc, unsigned int sec, |
da7f033d | 137 | struct cipher_speed_template *template, |
d5dc3927 | 138 | unsigned int tcount, u8 *keysize) |
ebfd9bcf | 139 | { |
dce907c0 | 140 | unsigned int ret, i, j, iv_len; |
da7f033d | 141 | const char *key, iv[128]; |
cba83564 HX |
142 | struct crypto_blkcipher *tfm; |
143 | struct blkcipher_desc desc; | |
144 | const char *e; | |
d5dc3927 | 145 | u32 *b_size; |
ebfd9bcf HW |
146 | |
147 | if (enc == ENCRYPT) | |
148 | e = "encryption"; | |
149 | else | |
150 | e = "decryption"; | |
ebfd9bcf | 151 | |
cba83564 | 152 | printk("\ntesting speed of %s %s\n", algo, e); |
ebfd9bcf | 153 | |
cba83564 | 154 | tfm = crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC); |
ebfd9bcf | 155 | |
cba83564 HX |
156 | if (IS_ERR(tfm)) { |
157 | printk("failed to load transform for %s: %ld\n", algo, | |
158 | PTR_ERR(tfm)); | |
ebfd9bcf HW |
159 | return; |
160 | } | |
cba83564 HX |
161 | desc.tfm = tfm; |
162 | desc.flags = 0; | |
ebfd9bcf | 163 | |
d5dc3927 SS |
164 | i = 0; |
165 | do { | |
ebfd9bcf | 166 | |
d5dc3927 SS |
167 | b_size = block_sizes; |
168 | do { | |
f139cfa7 | 169 | struct scatterlist sg[TVMEMSIZE]; |
ebfd9bcf | 170 | |
f139cfa7 HX |
171 | if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) { |
172 | printk("template (%u) too big for " | |
173 | "tvmem (%lu)\n", *keysize + *b_size, | |
174 | TVMEMSIZE * PAGE_SIZE); | |
d5dc3927 SS |
175 | goto out; |
176 | } | |
ebfd9bcf | 177 | |
d5dc3927 SS |
178 | printk("test %u (%d bit key, %d byte blocks): ", i, |
179 | *keysize * 8, *b_size); | |
180 | ||
f139cfa7 | 181 | memset(tvmem[0], 0xff, PAGE_SIZE); |
d5dc3927 SS |
182 | |
183 | /* set key, plain text and IV */ | |
da7f033d | 184 | key = tvmem[0]; |
d5dc3927 SS |
185 | for (j = 0; j < tcount; j++) { |
186 | if (template[j].klen == *keysize) { | |
187 | key = template[j].key; | |
188 | break; | |
189 | } | |
dce907c0 | 190 | } |
ebfd9bcf | 191 | |
d5dc3927 SS |
192 | ret = crypto_blkcipher_setkey(tfm, key, *keysize); |
193 | if (ret) { | |
194 | printk("setkey() failed flags=%x\n", | |
195 | crypto_blkcipher_get_flags(tfm)); | |
196 | goto out; | |
197 | } | |
ebfd9bcf | 198 | |
f139cfa7 HX |
199 | sg_init_table(sg, TVMEMSIZE); |
200 | sg_set_buf(sg, tvmem[0] + *keysize, | |
201 | PAGE_SIZE - *keysize); | |
202 | for (j = 1; j < TVMEMSIZE; j++) { | |
203 | sg_set_buf(sg + j, tvmem[j], PAGE_SIZE); | |
204 | memset (tvmem[j], 0xff, PAGE_SIZE); | |
205 | } | |
206 | ||
d5dc3927 SS |
207 | iv_len = crypto_blkcipher_ivsize(tfm); |
208 | if (iv_len) { | |
209 | memset(&iv, 0xff, iv_len); | |
210 | crypto_blkcipher_set_iv(tfm, iv, iv_len); | |
211 | } | |
ebfd9bcf | 212 | |
d5dc3927 | 213 | if (sec) |
f139cfa7 HX |
214 | ret = test_cipher_jiffies(&desc, enc, sg, |
215 | *b_size, sec); | |
d5dc3927 | 216 | else |
f139cfa7 HX |
217 | ret = test_cipher_cycles(&desc, enc, sg, |
218 | *b_size); | |
ebfd9bcf | 219 | |
d5dc3927 SS |
220 | if (ret) { |
221 | printk("%s() failed flags=%x\n", e, desc.flags); | |
222 | break; | |
223 | } | |
224 | b_size++; | |
225 | i++; | |
226 | } while (*b_size); | |
227 | keysize++; | |
228 | } while (*keysize); | |
ebfd9bcf HW |
229 | |
230 | out: | |
cba83564 | 231 | crypto_free_blkcipher(tfm); |
ebfd9bcf HW |
232 | } |
233 | ||
f139cfa7 HX |
234 | static int test_hash_jiffies_digest(struct hash_desc *desc, |
235 | struct scatterlist *sg, int blen, | |
e9d41164 HX |
236 | char *out, int sec) |
237 | { | |
e9d41164 HX |
238 | unsigned long start, end; |
239 | int bcount; | |
240 | int ret; | |
241 | ||
242 | for (start = jiffies, end = start + sec * HZ, bcount = 0; | |
243 | time_before(jiffies, end); bcount++) { | |
e9d41164 HX |
244 | ret = crypto_hash_digest(desc, sg, blen, out); |
245 | if (ret) | |
246 | return ret; | |
247 | } | |
248 | ||
249 | printk("%6u opers/sec, %9lu bytes/sec\n", | |
250 | bcount / sec, ((long)bcount * blen) / sec); | |
251 | ||
252 | return 0; | |
253 | } | |
254 | ||
f139cfa7 HX |
255 | static int test_hash_jiffies(struct hash_desc *desc, struct scatterlist *sg, |
256 | int blen, int plen, char *out, int sec) | |
e8057928 | 257 | { |
e8057928 ML |
258 | unsigned long start, end; |
259 | int bcount, pcount; | |
e9d41164 HX |
260 | int ret; |
261 | ||
262 | if (plen == blen) | |
f139cfa7 | 263 | return test_hash_jiffies_digest(desc, sg, blen, out, sec); |
a5a613a4 | 264 | |
e8057928 ML |
265 | for (start = jiffies, end = start + sec * HZ, bcount = 0; |
266 | time_before(jiffies, end); bcount++) { | |
e9d41164 HX |
267 | ret = crypto_hash_init(desc); |
268 | if (ret) | |
269 | return ret; | |
e8057928 | 270 | for (pcount = 0; pcount < blen; pcount += plen) { |
e9d41164 HX |
271 | ret = crypto_hash_update(desc, sg, plen); |
272 | if (ret) | |
273 | return ret; | |
e8057928 ML |
274 | } |
275 | /* we assume there is enough space in 'out' for the result */ | |
e9d41164 HX |
276 | ret = crypto_hash_final(desc, out); |
277 | if (ret) | |
278 | return ret; | |
e8057928 ML |
279 | } |
280 | ||
281 | printk("%6u opers/sec, %9lu bytes/sec\n", | |
282 | bcount / sec, ((long)bcount * blen) / sec); | |
283 | ||
e9d41164 HX |
284 | return 0; |
285 | } | |
286 | ||
f139cfa7 HX |
287 | static int test_hash_cycles_digest(struct hash_desc *desc, |
288 | struct scatterlist *sg, int blen, char *out) | |
e9d41164 | 289 | { |
e9d41164 HX |
290 | unsigned long cycles = 0; |
291 | int i; | |
292 | int ret; | |
293 | ||
294 | local_bh_disable(); | |
295 | local_irq_disable(); | |
296 | ||
297 | /* Warm-up run. */ | |
298 | for (i = 0; i < 4; i++) { | |
e9d41164 HX |
299 | ret = crypto_hash_digest(desc, sg, blen, out); |
300 | if (ret) | |
301 | goto out; | |
302 | } | |
303 | ||
304 | /* The real thing. */ | |
305 | for (i = 0; i < 8; i++) { | |
306 | cycles_t start, end; | |
307 | ||
308 | start = get_cycles(); | |
309 | ||
e9d41164 HX |
310 | ret = crypto_hash_digest(desc, sg, blen, out); |
311 | if (ret) | |
312 | goto out; | |
313 | ||
314 | end = get_cycles(); | |
315 | ||
316 | cycles += end - start; | |
317 | } | |
318 | ||
319 | out: | |
320 | local_irq_enable(); | |
321 | local_bh_enable(); | |
322 | ||
323 | if (ret) | |
324 | return ret; | |
325 | ||
326 | printk("%6lu cycles/operation, %4lu cycles/byte\n", | |
327 | cycles / 8, cycles / (8 * blen)); | |
328 | ||
329 | return 0; | |
e8057928 ML |
330 | } |
331 | ||
f139cfa7 HX |
332 | static int test_hash_cycles(struct hash_desc *desc, struct scatterlist *sg, |
333 | int blen, int plen, char *out) | |
e8057928 | 334 | { |
e8057928 ML |
335 | unsigned long cycles = 0; |
336 | int i, pcount; | |
e9d41164 HX |
337 | int ret; |
338 | ||
339 | if (plen == blen) | |
f139cfa7 | 340 | return test_hash_cycles_digest(desc, sg, blen, out); |
a5a613a4 | 341 | |
e8057928 ML |
342 | local_bh_disable(); |
343 | local_irq_disable(); | |
344 | ||
345 | /* Warm-up run. */ | |
346 | for (i = 0; i < 4; i++) { | |
e9d41164 HX |
347 | ret = crypto_hash_init(desc); |
348 | if (ret) | |
349 | goto out; | |
e8057928 | 350 | for (pcount = 0; pcount < blen; pcount += plen) { |
e9d41164 HX |
351 | ret = crypto_hash_update(desc, sg, plen); |
352 | if (ret) | |
353 | goto out; | |
e8057928 | 354 | } |
29059d12 | 355 | ret = crypto_hash_final(desc, out); |
e9d41164 HX |
356 | if (ret) |
357 | goto out; | |
e8057928 ML |
358 | } |
359 | ||
360 | /* The real thing. */ | |
361 | for (i = 0; i < 8; i++) { | |
362 | cycles_t start, end; | |
363 | ||
e8057928 ML |
364 | start = get_cycles(); |
365 | ||
e9d41164 HX |
366 | ret = crypto_hash_init(desc); |
367 | if (ret) | |
368 | goto out; | |
e8057928 | 369 | for (pcount = 0; pcount < blen; pcount += plen) { |
e9d41164 HX |
370 | ret = crypto_hash_update(desc, sg, plen); |
371 | if (ret) | |
372 | goto out; | |
e8057928 | 373 | } |
e9d41164 HX |
374 | ret = crypto_hash_final(desc, out); |
375 | if (ret) | |
376 | goto out; | |
e8057928 ML |
377 | |
378 | end = get_cycles(); | |
379 | ||
380 | cycles += end - start; | |
381 | } | |
382 | ||
e9d41164 | 383 | out: |
e8057928 ML |
384 | local_irq_enable(); |
385 | local_bh_enable(); | |
386 | ||
e9d41164 HX |
387 | if (ret) |
388 | return ret; | |
389 | ||
e8057928 ML |
390 | printk("%6lu cycles/operation, %4lu cycles/byte\n", |
391 | cycles / 8, cycles / (8 * blen)); | |
392 | ||
e9d41164 | 393 | return 0; |
e8057928 ML |
394 | } |
395 | ||
01b32324 HX |
396 | static void test_hash_speed(const char *algo, unsigned int sec, |
397 | struct hash_speed *speed) | |
e8057928 | 398 | { |
f139cfa7 | 399 | struct scatterlist sg[TVMEMSIZE]; |
e9d41164 HX |
400 | struct crypto_hash *tfm; |
401 | struct hash_desc desc; | |
376bacb0 | 402 | static char output[1024]; |
e8057928 | 403 | int i; |
e9d41164 | 404 | int ret; |
e8057928 | 405 | |
376bacb0 | 406 | printk(KERN_INFO "\ntesting speed of %s\n", algo); |
e8057928 | 407 | |
e9d41164 | 408 | tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC); |
e8057928 | 409 | |
e9d41164 | 410 | if (IS_ERR(tfm)) { |
376bacb0 | 411 | printk(KERN_ERR "failed to load transform for %s: %ld\n", algo, |
e9d41164 | 412 | PTR_ERR(tfm)); |
e8057928 ML |
413 | return; |
414 | } | |
415 | ||
e9d41164 HX |
416 | desc.tfm = tfm; |
417 | desc.flags = 0; | |
418 | ||
419 | if (crypto_hash_digestsize(tfm) > sizeof(output)) { | |
376bacb0 | 420 | printk(KERN_ERR "digestsize(%u) > outputbuffer(%zu)\n", |
e9d41164 | 421 | crypto_hash_digestsize(tfm), sizeof(output)); |
e8057928 ML |
422 | goto out; |
423 | } | |
424 | ||
f139cfa7 HX |
425 | sg_init_table(sg, TVMEMSIZE); |
426 | for (i = 0; i < TVMEMSIZE; i++) { | |
427 | sg_set_buf(sg + i, tvmem[i], PAGE_SIZE); | |
428 | memset(tvmem[i], 0xff, PAGE_SIZE); | |
429 | } | |
430 | ||
e8057928 | 431 | for (i = 0; speed[i].blen != 0; i++) { |
f139cfa7 | 432 | if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) { |
376bacb0 FS |
433 | printk(KERN_ERR |
434 | "template (%u) too big for tvmem (%lu)\n", | |
f139cfa7 | 435 | speed[i].blen, TVMEMSIZE * PAGE_SIZE); |
e8057928 ML |
436 | goto out; |
437 | } | |
438 | ||
376bacb0 FS |
439 | printk(KERN_INFO "test%3u " |
440 | "(%5u byte blocks,%5u bytes per update,%4u updates): ", | |
e8057928 ML |
441 | i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen); |
442 | ||
e8057928 | 443 | if (sec) |
f139cfa7 | 444 | ret = test_hash_jiffies(&desc, sg, speed[i].blen, |
e9d41164 | 445 | speed[i].plen, output, sec); |
e8057928 | 446 | else |
f139cfa7 | 447 | ret = test_hash_cycles(&desc, sg, speed[i].blen, |
e9d41164 HX |
448 | speed[i].plen, output); |
449 | ||
450 | if (ret) { | |
376bacb0 | 451 | printk(KERN_ERR "hashing failed ret=%d\n", ret); |
e9d41164 HX |
452 | break; |
453 | } | |
e8057928 ML |
454 | } |
455 | ||
456 | out: | |
e9d41164 | 457 | crypto_free_hash(tfm); |
e8057928 ML |
458 | } |
459 | ||
ef2736fc | 460 | static void test_available(void) |
1da177e4 LT |
461 | { |
462 | char **name = check; | |
ef2736fc | 463 | |
1da177e4 LT |
464 | while (*name) { |
465 | printk("alg %s ", *name); | |
6158efc0 | 466 | printk(crypto_has_alg(*name, 0, 0) ? |
e4d5b79c | 467 | "found\n" : "not found\n"); |
1da177e4 | 468 | name++; |
ef2736fc | 469 | } |
1da177e4 LT |
470 | } |
471 | ||
01b32324 HX |
472 | static inline int tcrypt_test(const char *alg) |
473 | { | |
4e033a6b JW |
474 | int ret; |
475 | ||
476 | ret = alg_test(alg, alg, 0, 0); | |
477 | /* non-fips algs return -EINVAL in fips mode */ | |
478 | if (fips_enabled && ret == -EINVAL) | |
479 | ret = 0; | |
480 | return ret; | |
01b32324 HX |
481 | } |
482 | ||
4e033a6b | 483 | static int do_test(int m) |
01b32324 HX |
484 | { |
485 | int i; | |
4e033a6b | 486 | int ret = 0; |
01b32324 HX |
487 | |
488 | switch (m) { | |
1da177e4 | 489 | case 0: |
01b32324 | 490 | for (i = 1; i < 200; i++) |
4e033a6b | 491 | ret += do_test(i); |
1da177e4 LT |
492 | break; |
493 | ||
494 | case 1: | |
4e033a6b | 495 | ret += tcrypt_test("md5"); |
1da177e4 LT |
496 | break; |
497 | ||
498 | case 2: | |
4e033a6b | 499 | ret += tcrypt_test("sha1"); |
1da177e4 LT |
500 | break; |
501 | ||
502 | case 3: | |
4e033a6b JW |
503 | ret += tcrypt_test("ecb(des)"); |
504 | ret += tcrypt_test("cbc(des)"); | |
1da177e4 LT |
505 | break; |
506 | ||
507 | case 4: | |
4e033a6b JW |
508 | ret += tcrypt_test("ecb(des3_ede)"); |
509 | ret += tcrypt_test("cbc(des3_ede)"); | |
1da177e4 LT |
510 | break; |
511 | ||
512 | case 5: | |
4e033a6b | 513 | ret += tcrypt_test("md4"); |
1da177e4 | 514 | break; |
ef2736fc | 515 | |
1da177e4 | 516 | case 6: |
4e033a6b | 517 | ret += tcrypt_test("sha256"); |
1da177e4 | 518 | break; |
ef2736fc | 519 | |
1da177e4 | 520 | case 7: |
4e033a6b JW |
521 | ret += tcrypt_test("ecb(blowfish)"); |
522 | ret += tcrypt_test("cbc(blowfish)"); | |
1da177e4 LT |
523 | break; |
524 | ||
525 | case 8: | |
4e033a6b JW |
526 | ret += tcrypt_test("ecb(twofish)"); |
527 | ret += tcrypt_test("cbc(twofish)"); | |
1da177e4 | 528 | break; |
ef2736fc | 529 | |
1da177e4 | 530 | case 9: |
4e033a6b | 531 | ret += tcrypt_test("ecb(serpent)"); |
1da177e4 LT |
532 | break; |
533 | ||
534 | case 10: | |
4e033a6b JW |
535 | ret += tcrypt_test("ecb(aes)"); |
536 | ret += tcrypt_test("cbc(aes)"); | |
537 | ret += tcrypt_test("lrw(aes)"); | |
538 | ret += tcrypt_test("xts(aes)"); | |
539 | ret += tcrypt_test("ctr(aes)"); | |
540 | ret += tcrypt_test("rfc3686(ctr(aes))"); | |
1da177e4 LT |
541 | break; |
542 | ||
543 | case 11: | |
4e033a6b | 544 | ret += tcrypt_test("sha384"); |
1da177e4 | 545 | break; |
ef2736fc | 546 | |
1da177e4 | 547 | case 12: |
4e033a6b | 548 | ret += tcrypt_test("sha512"); |
1da177e4 LT |
549 | break; |
550 | ||
551 | case 13: | |
4e033a6b | 552 | ret += tcrypt_test("deflate"); |
1da177e4 LT |
553 | break; |
554 | ||
555 | case 14: | |
4e033a6b | 556 | ret += tcrypt_test("ecb(cast5)"); |
1da177e4 LT |
557 | break; |
558 | ||
559 | case 15: | |
4e033a6b | 560 | ret += tcrypt_test("ecb(cast6)"); |
1da177e4 LT |
561 | break; |
562 | ||
563 | case 16: | |
4e033a6b | 564 | ret += tcrypt_test("ecb(arc4)"); |
1da177e4 LT |
565 | break; |
566 | ||
567 | case 17: | |
4e033a6b | 568 | ret += tcrypt_test("michael_mic"); |
1da177e4 LT |
569 | break; |
570 | ||
571 | case 18: | |
4e033a6b | 572 | ret += tcrypt_test("crc32c"); |
1da177e4 LT |
573 | break; |
574 | ||
575 | case 19: | |
4e033a6b | 576 | ret += tcrypt_test("ecb(tea)"); |
1da177e4 LT |
577 | break; |
578 | ||
579 | case 20: | |
4e033a6b | 580 | ret += tcrypt_test("ecb(xtea)"); |
1da177e4 LT |
581 | break; |
582 | ||
583 | case 21: | |
4e033a6b | 584 | ret += tcrypt_test("ecb(khazad)"); |
1da177e4 LT |
585 | break; |
586 | ||
587 | case 22: | |
4e033a6b | 588 | ret += tcrypt_test("wp512"); |
1da177e4 LT |
589 | break; |
590 | ||
591 | case 23: | |
4e033a6b | 592 | ret += tcrypt_test("wp384"); |
1da177e4 LT |
593 | break; |
594 | ||
595 | case 24: | |
4e033a6b | 596 | ret += tcrypt_test("wp256"); |
1da177e4 LT |
597 | break; |
598 | ||
599 | case 25: | |
4e033a6b | 600 | ret += tcrypt_test("ecb(tnepres)"); |
1da177e4 LT |
601 | break; |
602 | ||
603 | case 26: | |
4e033a6b JW |
604 | ret += tcrypt_test("ecb(anubis)"); |
605 | ret += tcrypt_test("cbc(anubis)"); | |
1da177e4 LT |
606 | break; |
607 | ||
608 | case 27: | |
4e033a6b | 609 | ret += tcrypt_test("tgr192"); |
1da177e4 LT |
610 | break; |
611 | ||
612 | case 28: | |
613 | ||
4e033a6b | 614 | ret += tcrypt_test("tgr160"); |
1da177e4 LT |
615 | break; |
616 | ||
617 | case 29: | |
4e033a6b | 618 | ret += tcrypt_test("tgr128"); |
1da177e4 | 619 | break; |
2998db37 | 620 | |
fb4f10ed | 621 | case 30: |
4e033a6b | 622 | ret += tcrypt_test("ecb(xeta)"); |
fb4f10ed | 623 | break; |
1da177e4 | 624 | |
90831639 | 625 | case 31: |
4e033a6b | 626 | ret += tcrypt_test("pcbc(fcrypt)"); |
90831639 DH |
627 | break; |
628 | ||
02ab5a70 | 629 | case 32: |
4e033a6b JW |
630 | ret += tcrypt_test("ecb(camellia)"); |
631 | ret += tcrypt_test("cbc(camellia)"); | |
02ab5a70 | 632 | break; |
cd12fb90 | 633 | case 33: |
4e033a6b | 634 | ret += tcrypt_test("sha224"); |
cd12fb90 | 635 | break; |
02ab5a70 | 636 | |
2407d608 | 637 | case 34: |
4e033a6b | 638 | ret += tcrypt_test("salsa20"); |
2407d608 TSH |
639 | break; |
640 | ||
8df213d9 | 641 | case 35: |
4e033a6b | 642 | ret += tcrypt_test("gcm(aes)"); |
8df213d9 HX |
643 | break; |
644 | ||
0b77abb3 | 645 | case 36: |
4e033a6b | 646 | ret += tcrypt_test("lzo"); |
0b77abb3 ZS |
647 | break; |
648 | ||
93cc74e0 | 649 | case 37: |
4e033a6b | 650 | ret += tcrypt_test("ccm(aes)"); |
93cc74e0 JL |
651 | break; |
652 | ||
76cb9521 | 653 | case 38: |
4e033a6b | 654 | ret += tcrypt_test("cts(cbc(aes))"); |
76cb9521 KC |
655 | break; |
656 | ||
fd4adf1a | 657 | case 39: |
4e033a6b | 658 | ret += tcrypt_test("rmd128"); |
fd4adf1a AKR |
659 | break; |
660 | ||
661 | case 40: | |
4e033a6b | 662 | ret += tcrypt_test("rmd160"); |
fd4adf1a AKR |
663 | break; |
664 | ||
2998db37 | 665 | case 41: |
4e033a6b | 666 | ret += tcrypt_test("rmd256"); |
2998db37 AKR |
667 | break; |
668 | ||
669 | case 42: | |
4e033a6b | 670 | ret += tcrypt_test("rmd320"); |
01b32324 HX |
671 | break; |
672 | ||
673 | case 43: | |
4e033a6b | 674 | ret += tcrypt_test("ecb(seed)"); |
2998db37 AKR |
675 | break; |
676 | ||
0c01aed5 | 677 | case 44: |
4e033a6b | 678 | ret += tcrypt_test("zlib"); |
0c01aed5 GU |
679 | break; |
680 | ||
5d667322 | 681 | case 45: |
4e033a6b | 682 | ret += tcrypt_test("rfc4309(ccm(aes))"); |
5d667322 JW |
683 | break; |
684 | ||
1da177e4 | 685 | case 100: |
4e033a6b | 686 | ret += tcrypt_test("hmac(md5)"); |
1da177e4 | 687 | break; |
ef2736fc | 688 | |
1da177e4 | 689 | case 101: |
4e033a6b | 690 | ret += tcrypt_test("hmac(sha1)"); |
1da177e4 | 691 | break; |
ef2736fc | 692 | |
1da177e4 | 693 | case 102: |
4e033a6b | 694 | ret += tcrypt_test("hmac(sha256)"); |
1da177e4 LT |
695 | break; |
696 | ||
a28091ae | 697 | case 103: |
4e033a6b | 698 | ret += tcrypt_test("hmac(sha384)"); |
a28091ae AD |
699 | break; |
700 | ||
701 | case 104: | |
4e033a6b | 702 | ret += tcrypt_test("hmac(sha512)"); |
a28091ae | 703 | break; |
38ed9ab2 | 704 | |
cd12fb90 | 705 | case 105: |
4e033a6b | 706 | ret += tcrypt_test("hmac(sha224)"); |
cd12fb90 | 707 | break; |
1da177e4 | 708 | |
38ed9ab2 | 709 | case 106: |
4e033a6b | 710 | ret += tcrypt_test("xcbc(aes)"); |
38ed9ab2 HX |
711 | break; |
712 | ||
fd4adf1a | 713 | case 107: |
4e033a6b | 714 | ret += tcrypt_test("hmac(rmd128)"); |
fd4adf1a AKR |
715 | break; |
716 | ||
717 | case 108: | |
4e033a6b | 718 | ret += tcrypt_test("hmac(rmd160)"); |
fd4adf1a AKR |
719 | break; |
720 | ||
e08ca2da | 721 | case 150: |
4e033a6b | 722 | ret += tcrypt_test("ansi_cprng"); |
e08ca2da JW |
723 | break; |
724 | ||
ebfd9bcf | 725 | case 200: |
cba83564 | 726 | test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, |
477035c2 | 727 | speed_template_16_24_32); |
cba83564 | 728 | test_cipher_speed("ecb(aes)", DECRYPT, sec, NULL, 0, |
477035c2 | 729 | speed_template_16_24_32); |
cba83564 | 730 | test_cipher_speed("cbc(aes)", ENCRYPT, sec, NULL, 0, |
477035c2 | 731 | speed_template_16_24_32); |
cba83564 | 732 | test_cipher_speed("cbc(aes)", DECRYPT, sec, NULL, 0, |
477035c2 | 733 | speed_template_16_24_32); |
f3d1044c | 734 | test_cipher_speed("lrw(aes)", ENCRYPT, sec, NULL, 0, |
477035c2 | 735 | speed_template_32_40_48); |
f3d1044c | 736 | test_cipher_speed("lrw(aes)", DECRYPT, sec, NULL, 0, |
477035c2 | 737 | speed_template_32_40_48); |
f19f5111 | 738 | test_cipher_speed("xts(aes)", ENCRYPT, sec, NULL, 0, |
477035c2 | 739 | speed_template_32_48_64); |
f19f5111 | 740 | test_cipher_speed("xts(aes)", DECRYPT, sec, NULL, 0, |
477035c2 | 741 | speed_template_32_48_64); |
ebfd9bcf HW |
742 | break; |
743 | ||
744 | case 201: | |
cba83564 | 745 | test_cipher_speed("ecb(des3_ede)", ENCRYPT, sec, |
da7f033d | 746 | des3_speed_template, DES3_SPEED_VECTORS, |
477035c2 | 747 | speed_template_24); |
cba83564 | 748 | test_cipher_speed("ecb(des3_ede)", DECRYPT, sec, |
da7f033d | 749 | des3_speed_template, DES3_SPEED_VECTORS, |
477035c2 | 750 | speed_template_24); |
cba83564 | 751 | test_cipher_speed("cbc(des3_ede)", ENCRYPT, sec, |
da7f033d | 752 | des3_speed_template, DES3_SPEED_VECTORS, |
477035c2 | 753 | speed_template_24); |
cba83564 | 754 | test_cipher_speed("cbc(des3_ede)", DECRYPT, sec, |
da7f033d | 755 | des3_speed_template, DES3_SPEED_VECTORS, |
477035c2 | 756 | speed_template_24); |
ebfd9bcf HW |
757 | break; |
758 | ||
759 | case 202: | |
cba83564 | 760 | test_cipher_speed("ecb(twofish)", ENCRYPT, sec, NULL, 0, |
477035c2 | 761 | speed_template_16_24_32); |
cba83564 | 762 | test_cipher_speed("ecb(twofish)", DECRYPT, sec, NULL, 0, |
477035c2 | 763 | speed_template_16_24_32); |
cba83564 | 764 | test_cipher_speed("cbc(twofish)", ENCRYPT, sec, NULL, 0, |
477035c2 | 765 | speed_template_16_24_32); |
cba83564 | 766 | test_cipher_speed("cbc(twofish)", DECRYPT, sec, NULL, 0, |
477035c2 | 767 | speed_template_16_24_32); |
ebfd9bcf HW |
768 | break; |
769 | ||
770 | case 203: | |
cba83564 | 771 | test_cipher_speed("ecb(blowfish)", ENCRYPT, sec, NULL, 0, |
477035c2 | 772 | speed_template_8_32); |
cba83564 | 773 | test_cipher_speed("ecb(blowfish)", DECRYPT, sec, NULL, 0, |
477035c2 | 774 | speed_template_8_32); |
cba83564 | 775 | test_cipher_speed("cbc(blowfish)", ENCRYPT, sec, NULL, 0, |
477035c2 | 776 | speed_template_8_32); |
cba83564 | 777 | test_cipher_speed("cbc(blowfish)", DECRYPT, sec, NULL, 0, |
477035c2 | 778 | speed_template_8_32); |
ebfd9bcf HW |
779 | break; |
780 | ||
781 | case 204: | |
cba83564 | 782 | test_cipher_speed("ecb(des)", ENCRYPT, sec, NULL, 0, |
477035c2 | 783 | speed_template_8); |
cba83564 | 784 | test_cipher_speed("ecb(des)", DECRYPT, sec, NULL, 0, |
477035c2 | 785 | speed_template_8); |
cba83564 | 786 | test_cipher_speed("cbc(des)", ENCRYPT, sec, NULL, 0, |
477035c2 | 787 | speed_template_8); |
cba83564 | 788 | test_cipher_speed("cbc(des)", DECRYPT, sec, NULL, 0, |
477035c2 | 789 | speed_template_8); |
ebfd9bcf HW |
790 | break; |
791 | ||
02ab5a70 NT |
792 | case 205: |
793 | test_cipher_speed("ecb(camellia)", ENCRYPT, sec, NULL, 0, | |
477035c2 | 794 | speed_template_16_24_32); |
02ab5a70 | 795 | test_cipher_speed("ecb(camellia)", DECRYPT, sec, NULL, 0, |
477035c2 | 796 | speed_template_16_24_32); |
02ab5a70 | 797 | test_cipher_speed("cbc(camellia)", ENCRYPT, sec, NULL, 0, |
477035c2 | 798 | speed_template_16_24_32); |
02ab5a70 | 799 | test_cipher_speed("cbc(camellia)", DECRYPT, sec, NULL, 0, |
477035c2 | 800 | speed_template_16_24_32); |
02ab5a70 NT |
801 | break; |
802 | ||
5de8f1b5 TSH |
803 | case 206: |
804 | test_cipher_speed("salsa20", ENCRYPT, sec, NULL, 0, | |
477035c2 | 805 | speed_template_16_32); |
5de8f1b5 TSH |
806 | break; |
807 | ||
e8057928 ML |
808 | case 300: |
809 | /* fall through */ | |
810 | ||
811 | case 301: | |
e9d41164 | 812 | test_hash_speed("md4", sec, generic_hash_speed_template); |
e8057928 ML |
813 | if (mode > 300 && mode < 400) break; |
814 | ||
815 | case 302: | |
e9d41164 | 816 | test_hash_speed("md5", sec, generic_hash_speed_template); |
e8057928 ML |
817 | if (mode > 300 && mode < 400) break; |
818 | ||
819 | case 303: | |
e9d41164 | 820 | test_hash_speed("sha1", sec, generic_hash_speed_template); |
e8057928 ML |
821 | if (mode > 300 && mode < 400) break; |
822 | ||
823 | case 304: | |
e9d41164 | 824 | test_hash_speed("sha256", sec, generic_hash_speed_template); |
e8057928 ML |
825 | if (mode > 300 && mode < 400) break; |
826 | ||
827 | case 305: | |
e9d41164 | 828 | test_hash_speed("sha384", sec, generic_hash_speed_template); |
e8057928 ML |
829 | if (mode > 300 && mode < 400) break; |
830 | ||
831 | case 306: | |
e9d41164 | 832 | test_hash_speed("sha512", sec, generic_hash_speed_template); |
e8057928 ML |
833 | if (mode > 300 && mode < 400) break; |
834 | ||
835 | case 307: | |
e9d41164 | 836 | test_hash_speed("wp256", sec, generic_hash_speed_template); |
e8057928 ML |
837 | if (mode > 300 && mode < 400) break; |
838 | ||
839 | case 308: | |
e9d41164 | 840 | test_hash_speed("wp384", sec, generic_hash_speed_template); |
e8057928 ML |
841 | if (mode > 300 && mode < 400) break; |
842 | ||
843 | case 309: | |
e9d41164 | 844 | test_hash_speed("wp512", sec, generic_hash_speed_template); |
e8057928 ML |
845 | if (mode > 300 && mode < 400) break; |
846 | ||
847 | case 310: | |
e9d41164 | 848 | test_hash_speed("tgr128", sec, generic_hash_speed_template); |
e8057928 ML |
849 | if (mode > 300 && mode < 400) break; |
850 | ||
851 | case 311: | |
e9d41164 | 852 | test_hash_speed("tgr160", sec, generic_hash_speed_template); |
e8057928 ML |
853 | if (mode > 300 && mode < 400) break; |
854 | ||
855 | case 312: | |
e9d41164 | 856 | test_hash_speed("tgr192", sec, generic_hash_speed_template); |
e8057928 ML |
857 | if (mode > 300 && mode < 400) break; |
858 | ||
cd12fb90 JL |
859 | case 313: |
860 | test_hash_speed("sha224", sec, generic_hash_speed_template); | |
861 | if (mode > 300 && mode < 400) break; | |
862 | ||
fd4adf1a AKR |
863 | case 314: |
864 | test_hash_speed("rmd128", sec, generic_hash_speed_template); | |
865 | if (mode > 300 && mode < 400) break; | |
866 | ||
867 | case 315: | |
868 | test_hash_speed("rmd160", sec, generic_hash_speed_template); | |
869 | if (mode > 300 && mode < 400) break; | |
870 | ||
2998db37 AKR |
871 | case 316: |
872 | test_hash_speed("rmd256", sec, generic_hash_speed_template); | |
873 | if (mode > 300 && mode < 400) break; | |
874 | ||
875 | case 317: | |
876 | test_hash_speed("rmd320", sec, generic_hash_speed_template); | |
877 | if (mode > 300 && mode < 400) break; | |
878 | ||
e8057928 ML |
879 | case 399: |
880 | break; | |
881 | ||
1da177e4 LT |
882 | case 1000: |
883 | test_available(); | |
884 | break; | |
1da177e4 | 885 | } |
4e033a6b JW |
886 | |
887 | return ret; | |
1da177e4 LT |
888 | } |
889 | ||
a873a5f1 SK |
890 | static int do_alg_test(const char *alg, u32 type) |
891 | { | |
ea400657 | 892 | return crypto_has_alg(alg, type, CRYPTO_ALG_TYPE_MASK) ? 0 : -ENOENT; |
a873a5f1 SK |
893 | } |
894 | ||
3af5b90b | 895 | static int __init tcrypt_mod_init(void) |
1da177e4 | 896 | { |
e3a4ea4f | 897 | int err = -ENOMEM; |
f139cfa7 | 898 | int i; |
e3a4ea4f | 899 | |
f139cfa7 HX |
900 | for (i = 0; i < TVMEMSIZE; i++) { |
901 | tvmem[i] = (void *)__get_free_page(GFP_KERNEL); | |
902 | if (!tvmem[i]) | |
903 | goto err_free_tv; | |
904 | } | |
1da177e4 | 905 | |
a873a5f1 SK |
906 | if (alg) |
907 | err = do_alg_test(alg, type); | |
908 | else | |
909 | err = do_test(mode); | |
910 | ||
4e033a6b JW |
911 | if (err) { |
912 | printk(KERN_ERR "tcrypt: one or more tests failed!\n"); | |
913 | goto err_free_tv; | |
914 | } | |
14fdf477 | 915 | |
4e033a6b JW |
916 | /* We intentionaly return -EAGAIN to prevent keeping the module, |
917 | * unless we're running in fips mode. It does all its work from | |
918 | * init() and doesn't offer any runtime functionality, but in | |
919 | * the fips case, checking for a successful load is helpful. | |
14fdf477 ML |
920 | * => we don't need it in the memory, do we? |
921 | * -- mludvig | |
922 | */ | |
4e033a6b JW |
923 | if (!fips_enabled) |
924 | err = -EAGAIN; | |
e3a4ea4f | 925 | |
f139cfa7 HX |
926 | err_free_tv: |
927 | for (i = 0; i < TVMEMSIZE && tvmem[i]; i++) | |
928 | free_page((unsigned long)tvmem[i]); | |
e3a4ea4f MH |
929 | |
930 | return err; | |
1da177e4 LT |
931 | } |
932 | ||
933 | /* | |
934 | * If an init function is provided, an exit function must also be provided | |
935 | * to allow module unload. | |
936 | */ | |
3af5b90b | 937 | static void __exit tcrypt_mod_fini(void) { } |
1da177e4 | 938 | |
3af5b90b KB |
939 | module_init(tcrypt_mod_init); |
940 | module_exit(tcrypt_mod_fini); | |
1da177e4 | 941 | |
a873a5f1 SK |
942 | module_param(alg, charp, 0); |
943 | module_param(type, uint, 0); | |
1da177e4 | 944 | module_param(mode, int, 0); |
ebfd9bcf | 945 | module_param(sec, uint, 0); |
6a17944c HX |
946 | MODULE_PARM_DESC(sec, "Length in seconds of speed tests " |
947 | "(defaults to zero which uses CPU cycles instead)"); | |
1da177e4 LT |
948 | |
949 | MODULE_LICENSE("GPL"); | |
950 | MODULE_DESCRIPTION("Quick & dirty crypto testing module"); | |
951 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); |