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> | |
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 | |
ef2736fc | 12 | * Software Foundation; either version 2 of the License, or (at your option) |
1da177e4 LT |
13 | * any later version. |
14 | * | |
15 | * 14 - 09 - 2003 | |
16 | * Rewritten by Kartikey Mahendra Bhatt | |
17 | */ | |
18 | ||
19 | #include <linux/init.h> | |
20 | #include <linux/module.h> | |
21 | #include <linux/mm.h> | |
22 | #include <linux/slab.h> | |
23 | #include <asm/scatterlist.h> | |
24 | #include <linux/string.h> | |
25 | #include <linux/crypto.h> | |
26 | #include <linux/highmem.h> | |
27 | #include <linux/moduleparam.h> | |
28 | #include "tcrypt.h" | |
29 | ||
30 | /* | |
31 | * Need to kmalloc() memory for testing kmap(). | |
32 | */ | |
33 | #define TVMEMSIZE 4096 | |
34 | #define XBUFSIZE 32768 | |
35 | ||
36 | /* | |
37 | * Indexes into the xbuf to simulate cross-page access. | |
38 | */ | |
39 | #define IDX1 37 | |
40 | #define IDX2 32400 | |
41 | #define IDX3 1 | |
42 | #define IDX4 8193 | |
43 | #define IDX5 22222 | |
44 | #define IDX6 17101 | |
45 | #define IDX7 27333 | |
46 | #define IDX8 3000 | |
47 | ||
48 | /* | |
49 | * Used by test_cipher() | |
50 | */ | |
51 | #define ENCRYPT 1 | |
52 | #define DECRYPT 0 | |
53 | #define MODE_ECB 1 | |
54 | #define MODE_CBC 0 | |
55 | ||
56 | static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; | |
57 | ||
58 | static int mode; | |
59 | static char *xbuf; | |
60 | static char *tvmem; | |
61 | ||
62 | static char *check[] = { | |
63 | "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", | |
ef2736fc HX |
64 | "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", |
65 | "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", | |
1da177e4 LT |
66 | "khazad", "wp512", "wp384", "wp256", "tnepres", NULL |
67 | }; | |
68 | ||
ef2736fc | 69 | static void hexdump(unsigned char *buf, unsigned int len) |
1da177e4 LT |
70 | { |
71 | while (len--) | |
72 | printk("%02x", *buf++); | |
73 | ||
74 | printk("\n"); | |
75 | } | |
76 | ||
ef2736fc HX |
77 | static void test_hash(char *algo, struct hash_testvec *template, |
78 | unsigned int tcount) | |
1da177e4 | 79 | { |
ef2736fc HX |
80 | char *p; |
81 | unsigned int i, j, k, temp; | |
82 | struct scatterlist sg[8]; | |
83 | char result[64]; | |
84 | struct crypto_tfm *tfm; | |
85 | struct hash_testvec *hash_tv; | |
86 | unsigned int tsize; | |
87 | ||
88 | printk("\ntesting %s\n", algo); | |
89 | ||
90 | tsize = sizeof(struct hash_testvec); | |
1da177e4 | 91 | tsize *= tcount; |
ef2736fc | 92 | |
1da177e4 LT |
93 | if (tsize > TVMEMSIZE) { |
94 | printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); | |
95 | return; | |
96 | } | |
97 | ||
98 | memcpy(tvmem, template, tsize); | |
ef2736fc | 99 | hash_tv = (void *)tvmem; |
1da177e4 LT |
100 | tfm = crypto_alloc_tfm(algo, 0); |
101 | if (tfm == NULL) { | |
102 | printk("failed to load transform for %s\n", algo); | |
103 | return; | |
104 | } | |
105 | ||
106 | for (i = 0; i < tcount; i++) { | |
ef2736fc HX |
107 | printk("test %u:\n", i + 1); |
108 | memset(result, 0, 64); | |
1da177e4 LT |
109 | |
110 | p = hash_tv[i].plaintext; | |
ef2736fc HX |
111 | sg[0].page = virt_to_page(p); |
112 | sg[0].offset = offset_in_page(p); | |
1da177e4 LT |
113 | sg[0].length = hash_tv[i].psize; |
114 | ||
ef2736fc | 115 | crypto_digest_init(tfm); |
1da177e4 | 116 | if (tfm->crt_u.digest.dit_setkey) { |
ef2736fc HX |
117 | crypto_digest_setkey(tfm, hash_tv[i].key, |
118 | hash_tv[i].ksize); | |
1da177e4 | 119 | } |
ef2736fc HX |
120 | crypto_digest_update(tfm, sg, 1); |
121 | crypto_digest_final(tfm, result); | |
1da177e4 | 122 | |
ef2736fc | 123 | hexdump(result, crypto_tfm_alg_digestsize(tfm)); |
1da177e4 | 124 | printk("%s\n", |
ef2736fc HX |
125 | memcmp(result, hash_tv[i].digest, |
126 | crypto_tfm_alg_digestsize(tfm)) ? | |
127 | "fail" : "pass"); | |
1da177e4 LT |
128 | } |
129 | ||
ef2736fc | 130 | printk("testing %s across pages\n", algo); |
1da177e4 LT |
131 | |
132 | /* setup the dummy buffer first */ | |
ef2736fc | 133 | memset(xbuf, 0, XBUFSIZE); |
1da177e4 LT |
134 | |
135 | j = 0; | |
136 | for (i = 0; i < tcount; i++) { | |
137 | if (hash_tv[i].np) { | |
138 | j++; | |
ef2736fc HX |
139 | printk("test %u:\n", j); |
140 | memset(result, 0, 64); | |
1da177e4 LT |
141 | |
142 | temp = 0; | |
143 | for (k = 0; k < hash_tv[i].np; k++) { | |
ef2736fc HX |
144 | memcpy(&xbuf[IDX[k]], |
145 | hash_tv[i].plaintext + temp, | |
146 | hash_tv[i].tap[k]); | |
1da177e4 LT |
147 | temp += hash_tv[i].tap[k]; |
148 | p = &xbuf[IDX[k]]; | |
ef2736fc HX |
149 | sg[k].page = virt_to_page(p); |
150 | sg[k].offset = offset_in_page(p); | |
1da177e4 LT |
151 | sg[k].length = hash_tv[i].tap[k]; |
152 | } | |
153 | ||
ef2736fc HX |
154 | crypto_digest_digest(tfm, sg, hash_tv[i].np, result); |
155 | ||
156 | hexdump(result, crypto_tfm_alg_digestsize(tfm)); | |
1da177e4 | 157 | printk("%s\n", |
ef2736fc HX |
158 | memcmp(result, hash_tv[i].digest, |
159 | crypto_tfm_alg_digestsize(tfm)) ? | |
160 | "fail" : "pass"); | |
1da177e4 LT |
161 | } |
162 | } | |
ef2736fc HX |
163 | |
164 | crypto_free_tfm(tfm); | |
1da177e4 LT |
165 | } |
166 | ||
167 | ||
168 | #ifdef CONFIG_CRYPTO_HMAC | |
169 | ||
ef2736fc HX |
170 | static void test_hmac(char *algo, struct hmac_testvec *template, |
171 | unsigned int tcount) | |
1da177e4 LT |
172 | { |
173 | char *p; | |
174 | unsigned int i, j, k, temp; | |
175 | struct scatterlist sg[8]; | |
176 | char result[64]; | |
177 | struct crypto_tfm *tfm; | |
178 | struct hmac_testvec *hmac_tv; | |
179 | unsigned int tsize, klen; | |
180 | ||
181 | tfm = crypto_alloc_tfm(algo, 0); | |
182 | if (tfm == NULL) { | |
183 | printk("failed to load transform for %s\n", algo); | |
184 | return; | |
185 | } | |
186 | ||
187 | printk("\ntesting hmac_%s\n", algo); | |
ef2736fc HX |
188 | |
189 | tsize = sizeof(struct hmac_testvec); | |
1da177e4 LT |
190 | tsize *= tcount; |
191 | if (tsize > TVMEMSIZE) { | |
192 | printk("template (%u) too big for tvmem (%u)\n", tsize, | |
193 | TVMEMSIZE); | |
194 | goto out; | |
195 | } | |
196 | ||
197 | memcpy(tvmem, template, tsize); | |
ef2736fc | 198 | hmac_tv = (void *)tvmem; |
1da177e4 LT |
199 | |
200 | for (i = 0; i < tcount; i++) { | |
201 | printk("test %u:\n", i + 1); | |
202 | memset(result, 0, sizeof (result)); | |
203 | ||
204 | p = hmac_tv[i].plaintext; | |
205 | klen = hmac_tv[i].ksize; | |
206 | sg[0].page = virt_to_page(p); | |
207 | sg[0].offset = offset_in_page(p); | |
208 | sg[0].length = hmac_tv[i].psize; | |
209 | ||
210 | crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result); | |
211 | ||
212 | hexdump(result, crypto_tfm_alg_digestsize(tfm)); | |
213 | printk("%s\n", | |
214 | memcmp(result, hmac_tv[i].digest, | |
215 | crypto_tfm_alg_digestsize(tfm)) ? "fail" : | |
216 | "pass"); | |
217 | } | |
218 | ||
219 | printk("\ntesting hmac_%s across pages\n", algo); | |
220 | ||
221 | memset(xbuf, 0, XBUFSIZE); | |
ef2736fc | 222 | |
1da177e4 LT |
223 | j = 0; |
224 | for (i = 0; i < tcount; i++) { | |
225 | if (hmac_tv[i].np) { | |
226 | j++; | |
ef2736fc HX |
227 | printk("test %u:\n",j); |
228 | memset(result, 0, 64); | |
1da177e4 LT |
229 | |
230 | temp = 0; | |
231 | klen = hmac_tv[i].ksize; | |
232 | for (k = 0; k < hmac_tv[i].np; k++) { | |
ef2736fc HX |
233 | memcpy(&xbuf[IDX[k]], |
234 | hmac_tv[i].plaintext + temp, | |
235 | hmac_tv[i].tap[k]); | |
1da177e4 LT |
236 | temp += hmac_tv[i].tap[k]; |
237 | p = &xbuf[IDX[k]]; | |
ef2736fc HX |
238 | sg[k].page = virt_to_page(p); |
239 | sg[k].offset = offset_in_page(p); | |
1da177e4 LT |
240 | sg[k].length = hmac_tv[i].tap[k]; |
241 | } | |
242 | ||
ef2736fc HX |
243 | crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, |
244 | hmac_tv[i].np, result); | |
1da177e4 | 245 | hexdump(result, crypto_tfm_alg_digestsize(tfm)); |
ef2736fc | 246 | |
1da177e4 | 247 | printk("%s\n", |
ef2736fc HX |
248 | memcmp(result, hmac_tv[i].digest, |
249 | crypto_tfm_alg_digestsize(tfm)) ? | |
250 | "fail" : "pass"); | |
1da177e4 LT |
251 | } |
252 | } | |
253 | out: | |
254 | crypto_free_tfm(tfm); | |
255 | } | |
256 | ||
257 | #endif /* CONFIG_CRYPTO_HMAC */ | |
258 | ||
ef2736fc HX |
259 | static void test_cipher(char *algo, int mode, int enc, |
260 | struct cipher_testvec *template, unsigned int tcount) | |
1da177e4 LT |
261 | { |
262 | unsigned int ret, i, j, k, temp; | |
263 | unsigned int tsize; | |
264 | char *p, *q; | |
265 | struct crypto_tfm *tfm; | |
266 | char *key; | |
267 | struct cipher_testvec *cipher_tv; | |
268 | struct scatterlist sg[8]; | |
3cc3816f | 269 | const char *e, *m; |
1da177e4 LT |
270 | |
271 | if (enc == ENCRYPT) | |
3cc3816f | 272 | e = "encryption"; |
1da177e4 | 273 | else |
3cc3816f | 274 | e = "decryption"; |
1da177e4 | 275 | if (mode == MODE_ECB) |
3cc3816f | 276 | m = "ECB"; |
1da177e4 | 277 | else |
3cc3816f | 278 | m = "CBC"; |
1da177e4 | 279 | |
ef2736fc | 280 | printk("\ntesting %s %s %s\n", algo, m, e); |
1da177e4 | 281 | |
ef2736fc | 282 | tsize = sizeof (struct cipher_testvec); |
1da177e4 | 283 | tsize *= tcount; |
ef2736fc | 284 | |
1da177e4 LT |
285 | if (tsize > TVMEMSIZE) { |
286 | printk("template (%u) too big for tvmem (%u)\n", tsize, | |
287 | TVMEMSIZE); | |
288 | return; | |
289 | } | |
290 | ||
291 | memcpy(tvmem, template, tsize); | |
ef2736fc HX |
292 | cipher_tv = (void *)tvmem; |
293 | ||
294 | if (mode) | |
295 | tfm = crypto_alloc_tfm(algo, 0); | |
296 | else | |
297 | tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_CBC); | |
1da177e4 | 298 | |
1da177e4 LT |
299 | if (tfm == NULL) { |
300 | printk("failed to load transform for %s %s\n", algo, m); | |
301 | return; | |
302 | } | |
ef2736fc | 303 | |
1da177e4 LT |
304 | j = 0; |
305 | for (i = 0; i < tcount; i++) { | |
306 | if (!(cipher_tv[i].np)) { | |
ef2736fc | 307 | j++; |
1da177e4 LT |
308 | printk("test %u (%d bit key):\n", |
309 | j, cipher_tv[i].klen * 8); | |
310 | ||
311 | tfm->crt_flags = 0; | |
ef2736fc | 312 | if (cipher_tv[i].wk) |
1da177e4 LT |
313 | tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY; |
314 | key = cipher_tv[i].key; | |
ef2736fc | 315 | |
1da177e4 LT |
316 | ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen); |
317 | if (ret) { | |
318 | printk("setkey() failed flags=%x\n", tfm->crt_flags); | |
ef2736fc | 319 | |
1da177e4 LT |
320 | if (!cipher_tv[i].fail) |
321 | goto out; | |
ef2736fc | 322 | } |
1da177e4 LT |
323 | |
324 | p = cipher_tv[i].input; | |
325 | sg[0].page = virt_to_page(p); | |
326 | sg[0].offset = offset_in_page(p); | |
327 | sg[0].length = cipher_tv[i].ilen; | |
ef2736fc | 328 | |
1da177e4 LT |
329 | if (!mode) { |
330 | crypto_cipher_set_iv(tfm, cipher_tv[i].iv, | |
ef2736fc | 331 | crypto_tfm_alg_ivsize(tfm)); |
1da177e4 | 332 | } |
ef2736fc | 333 | |
1da177e4 LT |
334 | if (enc) |
335 | ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen); | |
336 | else | |
337 | ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen); | |
ef2736fc HX |
338 | |
339 | ||
1da177e4 LT |
340 | if (ret) { |
341 | printk("%s () failed flags=%x\n", e, tfm->crt_flags); | |
342 | goto out; | |
ef2736fc HX |
343 | } |
344 | ||
1da177e4 LT |
345 | q = kmap(sg[0].page) + sg[0].offset; |
346 | hexdump(q, cipher_tv[i].rlen); | |
ef2736fc HX |
347 | |
348 | printk("%s\n", | |
349 | memcmp(q, cipher_tv[i].result, | |
350 | cipher_tv[i].rlen) ? "fail" : "pass"); | |
1da177e4 LT |
351 | } |
352 | } | |
ef2736fc HX |
353 | |
354 | printk("\ntesting %s %s %s across pages (chunking)\n", algo, m, e); | |
1da177e4 | 355 | memset(xbuf, 0, XBUFSIZE); |
ef2736fc | 356 | |
1da177e4 LT |
357 | j = 0; |
358 | for (i = 0; i < tcount; i++) { | |
359 | if (cipher_tv[i].np) { | |
ef2736fc | 360 | j++; |
1da177e4 LT |
361 | printk("test %u (%d bit key):\n", |
362 | j, cipher_tv[i].klen * 8); | |
363 | ||
ef2736fc HX |
364 | tfm->crt_flags = 0; |
365 | if (cipher_tv[i].wk) | |
1da177e4 LT |
366 | tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY; |
367 | key = cipher_tv[i].key; | |
ef2736fc HX |
368 | |
369 | ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen); | |
1da177e4 LT |
370 | if (ret) { |
371 | printk("setkey() failed flags=%x\n", tfm->crt_flags); | |
ef2736fc | 372 | |
1da177e4 LT |
373 | if (!cipher_tv[i].fail) |
374 | goto out; | |
375 | } | |
376 | ||
377 | temp = 0; | |
378 | for (k = 0; k < cipher_tv[i].np; k++) { | |
ef2736fc HX |
379 | memcpy(&xbuf[IDX[k]], |
380 | cipher_tv[i].input + temp, | |
381 | cipher_tv[i].tap[k]); | |
1da177e4 LT |
382 | temp += cipher_tv[i].tap[k]; |
383 | p = &xbuf[IDX[k]]; | |
ef2736fc HX |
384 | sg[k].page = virt_to_page(p); |
385 | sg[k].offset = offset_in_page(p); | |
1da177e4 LT |
386 | sg[k].length = cipher_tv[i].tap[k]; |
387 | } | |
ef2736fc | 388 | |
1da177e4 LT |
389 | if (!mode) { |
390 | crypto_cipher_set_iv(tfm, cipher_tv[i].iv, | |
ef2736fc | 391 | crypto_tfm_alg_ivsize(tfm)); |
1da177e4 | 392 | } |
ef2736fc | 393 | |
1da177e4 LT |
394 | if (enc) |
395 | ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen); | |
396 | else | |
397 | ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen); | |
ef2736fc | 398 | |
1da177e4 LT |
399 | if (ret) { |
400 | printk("%s () failed flags=%x\n", e, tfm->crt_flags); | |
401 | goto out; | |
402 | } | |
403 | ||
404 | temp = 0; | |
405 | for (k = 0; k < cipher_tv[i].np; k++) { | |
406 | printk("page %u\n", k); | |
407 | q = kmap(sg[k].page) + sg[k].offset; | |
408 | hexdump(q, cipher_tv[i].tap[k]); | |
ef2736fc HX |
409 | printk("%s\n", |
410 | memcmp(q, cipher_tv[i].result + temp, | |
411 | cipher_tv[i].tap[k]) ? "fail" : | |
1da177e4 LT |
412 | "pass"); |
413 | temp += cipher_tv[i].tap[k]; | |
414 | } | |
415 | } | |
416 | } | |
417 | ||
418 | out: | |
419 | crypto_free_tfm(tfm); | |
420 | } | |
421 | ||
ef2736fc | 422 | static void test_deflate(void) |
1da177e4 LT |
423 | { |
424 | unsigned int i; | |
425 | char result[COMP_BUF_SIZE]; | |
426 | struct crypto_tfm *tfm; | |
427 | struct comp_testvec *tv; | |
428 | unsigned int tsize; | |
429 | ||
430 | printk("\ntesting deflate compression\n"); | |
431 | ||
432 | tsize = sizeof (deflate_comp_tv_template); | |
433 | if (tsize > TVMEMSIZE) { | |
434 | printk("template (%u) too big for tvmem (%u)\n", tsize, | |
435 | TVMEMSIZE); | |
436 | return; | |
437 | } | |
438 | ||
439 | memcpy(tvmem, deflate_comp_tv_template, tsize); | |
ef2736fc | 440 | tv = (void *)tvmem; |
1da177e4 LT |
441 | |
442 | tfm = crypto_alloc_tfm("deflate", 0); | |
443 | if (tfm == NULL) { | |
444 | printk("failed to load transform for deflate\n"); | |
445 | return; | |
446 | } | |
447 | ||
448 | for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) { | |
449 | int ilen, ret, dlen = COMP_BUF_SIZE; | |
ef2736fc | 450 | |
1da177e4 LT |
451 | printk("test %u:\n", i + 1); |
452 | memset(result, 0, sizeof (result)); | |
453 | ||
454 | ilen = tv[i].inlen; | |
455 | ret = crypto_comp_compress(tfm, tv[i].input, | |
456 | ilen, result, &dlen); | |
457 | if (ret) { | |
458 | printk("fail: ret=%d\n", ret); | |
459 | continue; | |
460 | } | |
461 | hexdump(result, dlen); | |
462 | printk("%s (ratio %d:%d)\n", | |
463 | memcmp(result, tv[i].output, dlen) ? "fail" : "pass", | |
464 | ilen, dlen); | |
465 | } | |
466 | ||
467 | printk("\ntesting deflate decompression\n"); | |
468 | ||
469 | tsize = sizeof (deflate_decomp_tv_template); | |
470 | if (tsize > TVMEMSIZE) { | |
471 | printk("template (%u) too big for tvmem (%u)\n", tsize, | |
472 | TVMEMSIZE); | |
473 | goto out; | |
474 | } | |
475 | ||
476 | memcpy(tvmem, deflate_decomp_tv_template, tsize); | |
ef2736fc | 477 | tv = (void *)tvmem; |
1da177e4 LT |
478 | |
479 | for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) { | |
480 | int ilen, ret, dlen = COMP_BUF_SIZE; | |
ef2736fc | 481 | |
1da177e4 LT |
482 | printk("test %u:\n", i + 1); |
483 | memset(result, 0, sizeof (result)); | |
484 | ||
485 | ilen = tv[i].inlen; | |
486 | ret = crypto_comp_decompress(tfm, tv[i].input, | |
487 | ilen, result, &dlen); | |
488 | if (ret) { | |
489 | printk("fail: ret=%d\n", ret); | |
490 | continue; | |
491 | } | |
492 | hexdump(result, dlen); | |
493 | printk("%s (ratio %d:%d)\n", | |
494 | memcmp(result, tv[i].output, dlen) ? "fail" : "pass", | |
495 | ilen, dlen); | |
496 | } | |
497 | out: | |
498 | crypto_free_tfm(tfm); | |
499 | } | |
500 | ||
ef2736fc | 501 | static void test_crc32c(void) |
1da177e4 LT |
502 | { |
503 | #define NUMVEC 6 | |
504 | #define VECSIZE 40 | |
505 | ||
506 | int i, j, pass; | |
507 | u32 crc; | |
508 | u8 b, test_vec[NUMVEC][VECSIZE]; | |
509 | static u32 vec_results[NUMVEC] = { | |
510 | 0x0e2c157f, 0xe980ebf6, 0xde74bded, | |
511 | 0xd579c862, 0xba979ad0, 0x2b29d913 | |
512 | }; | |
513 | static u32 tot_vec_results = 0x24c5d375; | |
ef2736fc | 514 | |
1da177e4 LT |
515 | struct scatterlist sg[NUMVEC]; |
516 | struct crypto_tfm *tfm; | |
517 | char *fmtdata = "testing crc32c initialized to %08x: %s\n"; | |
518 | #define SEEDTESTVAL 0xedcba987 | |
519 | u32 seed; | |
520 | ||
521 | printk("\ntesting crc32c\n"); | |
522 | ||
523 | tfm = crypto_alloc_tfm("crc32c", 0); | |
524 | if (tfm == NULL) { | |
525 | printk("failed to load transform for crc32c\n"); | |
526 | return; | |
527 | } | |
ef2736fc | 528 | |
1da177e4 LT |
529 | crypto_digest_init(tfm); |
530 | crypto_digest_final(tfm, (u8*)&crc); | |
531 | printk(fmtdata, crc, (crc == 0) ? "pass" : "ERROR"); | |
ef2736fc | 532 | |
1da177e4 LT |
533 | /* |
534 | * stuff test_vec with known values, simple incrementing | |
535 | * byte values. | |
536 | */ | |
537 | b = 0; | |
538 | for (i = 0; i < NUMVEC; i++) { | |
ef2736fc | 539 | for (j = 0; j < VECSIZE; j++) |
1da177e4 LT |
540 | test_vec[i][j] = ++b; |
541 | sg[i].page = virt_to_page(test_vec[i]); | |
542 | sg[i].offset = offset_in_page(test_vec[i]); | |
543 | sg[i].length = VECSIZE; | |
544 | } | |
545 | ||
546 | seed = SEEDTESTVAL; | |
547 | (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); | |
548 | crypto_digest_final(tfm, (u8*)&crc); | |
549 | printk("testing crc32c setkey returns %08x : %s\n", crc, (crc == (SEEDTESTVAL ^ ~(u32)0)) ? | |
550 | "pass" : "ERROR"); | |
ef2736fc | 551 | |
1da177e4 LT |
552 | printk("testing crc32c using update/final:\n"); |
553 | ||
554 | pass = 1; /* assume all is well */ | |
ef2736fc | 555 | |
1da177e4 LT |
556 | for (i = 0; i < NUMVEC; i++) { |
557 | seed = ~(u32)0; | |
558 | (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); | |
559 | crypto_digest_update(tfm, &sg[i], 1); | |
560 | crypto_digest_final(tfm, (u8*)&crc); | |
561 | if (crc == vec_results[i]) { | |
562 | printk(" %08x:OK", crc); | |
563 | } else { | |
564 | printk(" %08x:BAD, wanted %08x\n", crc, vec_results[i]); | |
565 | pass = 0; | |
566 | } | |
567 | } | |
568 | ||
569 | printk("\ntesting crc32c using incremental accumulator:\n"); | |
570 | crc = 0; | |
571 | for (i = 0; i < NUMVEC; i++) { | |
572 | seed = (crc ^ ~(u32)0); | |
573 | (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); | |
574 | crypto_digest_update(tfm, &sg[i], 1); | |
575 | crypto_digest_final(tfm, (u8*)&crc); | |
576 | } | |
577 | if (crc == tot_vec_results) { | |
578 | printk(" %08x:OK", crc); | |
579 | } else { | |
580 | printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results); | |
581 | pass = 0; | |
582 | } | |
583 | ||
584 | printk("\ntesting crc32c using digest:\n"); | |
585 | seed = ~(u32)0; | |
586 | (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); | |
587 | crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&crc); | |
588 | if (crc == tot_vec_results) { | |
589 | printk(" %08x:OK", crc); | |
590 | } else { | |
591 | printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results); | |
592 | pass = 0; | |
593 | } | |
ef2736fc | 594 | |
1da177e4 LT |
595 | printk("\n%s\n", pass ? "pass" : "ERROR"); |
596 | ||
597 | crypto_free_tfm(tfm); | |
598 | printk("crc32c test complete\n"); | |
599 | } | |
600 | ||
ef2736fc | 601 | static void test_available(void) |
1da177e4 LT |
602 | { |
603 | char **name = check; | |
ef2736fc | 604 | |
1da177e4 LT |
605 | while (*name) { |
606 | printk("alg %s ", *name); | |
607 | printk((crypto_alg_available(*name, 0)) ? | |
608 | "found\n" : "not found\n"); | |
609 | name++; | |
ef2736fc | 610 | } |
1da177e4 LT |
611 | } |
612 | ||
ef2736fc | 613 | static void do_test(void) |
1da177e4 LT |
614 | { |
615 | switch (mode) { | |
616 | ||
617 | case 0: | |
618 | test_hash("md5", md5_tv_template, MD5_TEST_VECTORS); | |
ef2736fc | 619 | |
1da177e4 | 620 | test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS); |
ef2736fc | 621 | |
1da177e4 LT |
622 | //DES |
623 | test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS); | |
ef2736fc HX |
624 | test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS); |
625 | test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS); | |
626 | test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS); | |
627 | ||
1da177e4 LT |
628 | //DES3_EDE |
629 | test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS); | |
ef2736fc HX |
630 | test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS); |
631 | ||
1da177e4 | 632 | test_hash("md4", md4_tv_template, MD4_TEST_VECTORS); |
ef2736fc | 633 | |
1da177e4 | 634 | test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS); |
ef2736fc | 635 | |
1da177e4 LT |
636 | //BLOWFISH |
637 | test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS); | |
638 | test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS); | |
639 | test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS); | |
640 | test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS); | |
ef2736fc | 641 | |
1da177e4 LT |
642 | //TWOFISH |
643 | test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS); | |
644 | test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS); | |
645 | test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS); | |
646 | test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS); | |
ef2736fc | 647 | |
1da177e4 LT |
648 | //SERPENT |
649 | test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS); | |
650 | test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS); | |
ef2736fc | 651 | |
1da177e4 LT |
652 | //TNEPRES |
653 | test_cipher ("tnepres", MODE_ECB, ENCRYPT, tnepres_enc_tv_template, TNEPRES_ENC_TEST_VECTORS); | |
654 | test_cipher ("tnepres", MODE_ECB, DECRYPT, tnepres_dec_tv_template, TNEPRES_DEC_TEST_VECTORS); | |
655 | ||
656 | //AES | |
657 | test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS); | |
658 | test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS); | |
659 | ||
660 | //CAST5 | |
661 | test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS); | |
662 | test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS); | |
ef2736fc | 663 | |
1da177e4 LT |
664 | //CAST6 |
665 | test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS); | |
666 | test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS); | |
667 | ||
668 | //ARC4 | |
669 | test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS); | |
670 | test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); | |
671 | ||
672 | //TEA | |
673 | test_cipher ("tea", MODE_ECB, ENCRYPT, tea_enc_tv_template, TEA_ENC_TEST_VECTORS); | |
674 | test_cipher ("tea", MODE_ECB, DECRYPT, tea_dec_tv_template, TEA_DEC_TEST_VECTORS); | |
675 | ||
676 | ||
677 | //XTEA | |
678 | test_cipher ("xtea", MODE_ECB, ENCRYPT, xtea_enc_tv_template, XTEA_ENC_TEST_VECTORS); | |
679 | test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS); | |
680 | ||
681 | //KHAZAD | |
682 | test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS); | |
683 | test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS); | |
684 | ||
685 | //ANUBIS | |
686 | test_cipher ("anubis", MODE_ECB, ENCRYPT, anubis_enc_tv_template, ANUBIS_ENC_TEST_VECTORS); | |
687 | test_cipher ("anubis", MODE_ECB, DECRYPT, anubis_dec_tv_template, ANUBIS_DEC_TEST_VECTORS); | |
688 | test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); | |
689 | test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); | |
690 | ||
691 | test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); | |
692 | test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); | |
693 | test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); | |
694 | test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS); | |
695 | test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS); | |
696 | test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS); | |
697 | test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS); | |
698 | test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS); | |
699 | test_deflate(); | |
700 | test_crc32c(); | |
701 | #ifdef CONFIG_CRYPTO_HMAC | |
702 | test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); | |
ef2736fc | 703 | test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); |
1da177e4 | 704 | test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); |
ef2736fc | 705 | #endif |
1da177e4 LT |
706 | |
707 | test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); | |
708 | break; | |
709 | ||
710 | case 1: | |
711 | test_hash("md5", md5_tv_template, MD5_TEST_VECTORS); | |
712 | break; | |
713 | ||
714 | case 2: | |
715 | test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS); | |
716 | break; | |
717 | ||
718 | case 3: | |
719 | test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS); | |
720 | test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS); | |
721 | test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS); | |
722 | test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS); | |
723 | break; | |
724 | ||
725 | case 4: | |
726 | test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS); | |
ef2736fc | 727 | test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS); |
1da177e4 LT |
728 | break; |
729 | ||
730 | case 5: | |
731 | test_hash("md4", md4_tv_template, MD4_TEST_VECTORS); | |
732 | break; | |
ef2736fc | 733 | |
1da177e4 LT |
734 | case 6: |
735 | test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS); | |
736 | break; | |
ef2736fc | 737 | |
1da177e4 LT |
738 | case 7: |
739 | test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS); | |
740 | test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS); | |
741 | test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS); | |
742 | test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS); | |
743 | break; | |
744 | ||
745 | case 8: | |
746 | test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS); | |
747 | test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS); | |
748 | test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS); | |
749 | test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS); | |
750 | break; | |
ef2736fc | 751 | |
1da177e4 LT |
752 | case 9: |
753 | test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS); | |
754 | test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS); | |
755 | break; | |
756 | ||
757 | case 10: | |
758 | test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS); | |
ef2736fc | 759 | test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS); |
1da177e4 LT |
760 | break; |
761 | ||
762 | case 11: | |
763 | test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); | |
764 | break; | |
ef2736fc | 765 | |
1da177e4 LT |
766 | case 12: |
767 | test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); | |
768 | break; | |
769 | ||
770 | case 13: | |
771 | test_deflate(); | |
772 | break; | |
773 | ||
774 | case 14: | |
775 | test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS); | |
776 | test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS); | |
777 | break; | |
778 | ||
779 | case 15: | |
780 | test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS); | |
781 | test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS); | |
782 | break; | |
783 | ||
784 | case 16: | |
785 | test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS); | |
786 | test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); | |
787 | break; | |
788 | ||
789 | case 17: | |
790 | test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); | |
791 | break; | |
792 | ||
793 | case 18: | |
794 | test_crc32c(); | |
795 | break; | |
796 | ||
797 | case 19: | |
798 | test_cipher ("tea", MODE_ECB, ENCRYPT, tea_enc_tv_template, TEA_ENC_TEST_VECTORS); | |
799 | test_cipher ("tea", MODE_ECB, DECRYPT, tea_dec_tv_template, TEA_DEC_TEST_VECTORS); | |
800 | break; | |
801 | ||
802 | case 20: | |
803 | test_cipher ("xtea", MODE_ECB, ENCRYPT, xtea_enc_tv_template, XTEA_ENC_TEST_VECTORS); | |
804 | test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS); | |
805 | break; | |
806 | ||
807 | case 21: | |
808 | test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS); | |
809 | test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS); | |
810 | break; | |
811 | ||
812 | case 22: | |
813 | test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); | |
814 | break; | |
815 | ||
816 | case 23: | |
817 | test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS); | |
818 | break; | |
819 | ||
820 | case 24: | |
821 | test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS); | |
822 | break; | |
823 | ||
824 | case 25: | |
825 | test_cipher ("tnepres", MODE_ECB, ENCRYPT, tnepres_enc_tv_template, TNEPRES_ENC_TEST_VECTORS); | |
826 | test_cipher ("tnepres", MODE_ECB, DECRYPT, tnepres_dec_tv_template, TNEPRES_DEC_TEST_VECTORS); | |
827 | break; | |
828 | ||
829 | case 26: | |
830 | test_cipher ("anubis", MODE_ECB, ENCRYPT, anubis_enc_tv_template, ANUBIS_ENC_TEST_VECTORS); | |
831 | test_cipher ("anubis", MODE_ECB, DECRYPT, anubis_dec_tv_template, ANUBIS_DEC_TEST_VECTORS); | |
832 | test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); | |
833 | test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); | |
834 | break; | |
835 | ||
836 | case 27: | |
837 | test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS); | |
838 | break; | |
839 | ||
840 | case 28: | |
841 | ||
842 | test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS); | |
843 | break; | |
844 | ||
845 | case 29: | |
846 | test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS); | |
847 | break; | |
848 | ||
849 | #ifdef CONFIG_CRYPTO_HMAC | |
850 | case 100: | |
851 | test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); | |
852 | break; | |
ef2736fc | 853 | |
1da177e4 | 854 | case 101: |
ef2736fc | 855 | test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); |
1da177e4 | 856 | break; |
ef2736fc | 857 | |
1da177e4 LT |
858 | case 102: |
859 | test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); | |
860 | break; | |
861 | ||
862 | #endif | |
863 | ||
864 | case 1000: | |
865 | test_available(); | |
866 | break; | |
ef2736fc | 867 | |
1da177e4 LT |
868 | default: |
869 | /* useful for debugging */ | |
870 | printk("not testing anything\n"); | |
871 | break; | |
872 | } | |
873 | } | |
874 | ||
ef2736fc | 875 | static int __init init(void) |
1da177e4 LT |
876 | { |
877 | tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL); | |
878 | if (tvmem == NULL) | |
879 | return -ENOMEM; | |
880 | ||
881 | xbuf = kmalloc(XBUFSIZE, GFP_KERNEL); | |
882 | if (xbuf == NULL) { | |
883 | kfree(tvmem); | |
884 | return -ENOMEM; | |
885 | } | |
886 | ||
887 | do_test(); | |
888 | ||
889 | kfree(xbuf); | |
890 | kfree(tvmem); | |
891 | return 0; | |
892 | } | |
893 | ||
894 | /* | |
895 | * If an init function is provided, an exit function must also be provided | |
896 | * to allow module unload. | |
897 | */ | |
898 | static void __exit fini(void) { } | |
899 | ||
900 | module_init(init); | |
901 | module_exit(fini); | |
902 | ||
903 | module_param(mode, int, 0); | |
904 | ||
905 | MODULE_LICENSE("GPL"); | |
906 | MODULE_DESCRIPTION("Quick & dirty crypto testing module"); | |
907 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); |