blob: 51bae62c332a4f0f1f889d823dee444cb2f9acaa [file] [log] [blame]
Herbert Xuda7f0332008-07-31 17:08:25 +08001/*
2 * Algorithm testing framework and tests.
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
6 * Copyright (c) 2007 Nokia Siemens Networks
7 * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 */
15
16#include <crypto/hash.h>
17#include <linux/err.h>
18#include <linux/module.h>
19#include <linux/scatterlist.h>
20#include <linux/slab.h>
21#include <linux/string.h>
Jarod Wilson7647d6c2009-05-04 19:44:50 +080022#include <crypto/rng.h>
Herbert Xuda7f0332008-07-31 17:08:25 +080023
24#include "internal.h"
25#include "testmgr.h"
26
27/*
28 * Need slab memory for testing (size in number of pages).
29 */
30#define XBUFSIZE 8
31
32/*
33 * Indexes into the xbuf to simulate cross-page access.
34 */
35#define IDX1 32
36#define IDX2 32400
37#define IDX3 1
38#define IDX4 8193
39#define IDX5 22222
40#define IDX6 17101
41#define IDX7 27333
42#define IDX8 3000
43
44/*
45* Used by test_cipher()
46*/
47#define ENCRYPT 1
48#define DECRYPT 0
49
50struct tcrypt_result {
51 struct completion completion;
52 int err;
53};
54
55struct aead_test_suite {
56 struct {
57 struct aead_testvec *vecs;
58 unsigned int count;
59 } enc, dec;
60};
61
62struct cipher_test_suite {
63 struct {
64 struct cipher_testvec *vecs;
65 unsigned int count;
66 } enc, dec;
67};
68
69struct comp_test_suite {
70 struct {
71 struct comp_testvec *vecs;
72 unsigned int count;
73 } comp, decomp;
74};
75
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +080076struct pcomp_test_suite {
77 struct {
78 struct pcomp_testvec *vecs;
79 unsigned int count;
80 } comp, decomp;
81};
82
Herbert Xuda7f0332008-07-31 17:08:25 +080083struct hash_test_suite {
84 struct hash_testvec *vecs;
85 unsigned int count;
86};
87
Jarod Wilson7647d6c2009-05-04 19:44:50 +080088struct cprng_test_suite {
89 struct cprng_testvec *vecs;
90 unsigned int count;
91};
92
Herbert Xuda7f0332008-07-31 17:08:25 +080093struct alg_test_desc {
94 const char *alg;
95 int (*test)(const struct alg_test_desc *desc, const char *driver,
96 u32 type, u32 mask);
Jarod Wilsona1915d52009-05-15 15:16:03 +100097 int fips_allowed; /* set if alg is allowed in fips mode */
Herbert Xuda7f0332008-07-31 17:08:25 +080098
99 union {
100 struct aead_test_suite aead;
101 struct cipher_test_suite cipher;
102 struct comp_test_suite comp;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +0800103 struct pcomp_test_suite pcomp;
Herbert Xuda7f0332008-07-31 17:08:25 +0800104 struct hash_test_suite hash;
Jarod Wilson7647d6c2009-05-04 19:44:50 +0800105 struct cprng_test_suite cprng;
Herbert Xuda7f0332008-07-31 17:08:25 +0800106 } suite;
107};
108
109static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
110
Herbert Xuda7f0332008-07-31 17:08:25 +0800111static void hexdump(unsigned char *buf, unsigned int len)
112{
113 print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
114 16, 1,
115 buf, len, false);
116}
117
118static void tcrypt_complete(struct crypto_async_request *req, int err)
119{
120 struct tcrypt_result *res = req->data;
121
122 if (err == -EINPROGRESS)
123 return;
124
125 res->err = err;
126 complete(&res->completion);
127}
128
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800129static int testmgr_alloc_buf(char *buf[XBUFSIZE])
130{
131 int i;
132
133 for (i = 0; i < XBUFSIZE; i++) {
134 buf[i] = (void *)__get_free_page(GFP_KERNEL);
135 if (!buf[i])
136 goto err_free_buf;
137 }
138
139 return 0;
140
141err_free_buf:
142 while (i-- > 0)
143 free_page((unsigned long)buf[i]);
144
145 return -ENOMEM;
146}
147
148static void testmgr_free_buf(char *buf[XBUFSIZE])
149{
150 int i;
151
152 for (i = 0; i < XBUFSIZE; i++)
153 free_page((unsigned long)buf[i]);
154}
155
Herbert Xuda7f0332008-07-31 17:08:25 +0800156static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
157 unsigned int tcount)
158{
159 const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
160 unsigned int i, j, k, temp;
161 struct scatterlist sg[8];
162 char result[64];
163 struct ahash_request *req;
164 struct tcrypt_result tresult;
Herbert Xuda7f0332008-07-31 17:08:25 +0800165 void *hash_buff;
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800166 char *xbuf[XBUFSIZE];
167 int ret = -ENOMEM;
168
169 if (testmgr_alloc_buf(xbuf))
170 goto out_nobuf;
Herbert Xuda7f0332008-07-31 17:08:25 +0800171
172 init_completion(&tresult.completion);
173
174 req = ahash_request_alloc(tfm, GFP_KERNEL);
175 if (!req) {
176 printk(KERN_ERR "alg: hash: Failed to allocate request for "
177 "%s\n", algo);
Herbert Xuda7f0332008-07-31 17:08:25 +0800178 goto out_noreq;
179 }
180 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
181 tcrypt_complete, &tresult);
182
183 for (i = 0; i < tcount; i++) {
184 memset(result, 0, 64);
185
186 hash_buff = xbuf[0];
187
188 memcpy(hash_buff, template[i].plaintext, template[i].psize);
189 sg_init_one(&sg[0], hash_buff, template[i].psize);
190
191 if (template[i].ksize) {
192 crypto_ahash_clear_flags(tfm, ~0);
193 ret = crypto_ahash_setkey(tfm, template[i].key,
194 template[i].ksize);
195 if (ret) {
196 printk(KERN_ERR "alg: hash: setkey failed on "
197 "test %d for %s: ret=%d\n", i + 1, algo,
198 -ret);
199 goto out;
200 }
201 }
202
203 ahash_request_set_crypt(req, sg, result, template[i].psize);
204 ret = crypto_ahash_digest(req);
205 switch (ret) {
206 case 0:
207 break;
208 case -EINPROGRESS:
209 case -EBUSY:
210 ret = wait_for_completion_interruptible(
211 &tresult.completion);
212 if (!ret && !(ret = tresult.err)) {
213 INIT_COMPLETION(tresult.completion);
214 break;
215 }
216 /* fall through */
217 default:
218 printk(KERN_ERR "alg: hash: digest failed on test %d "
219 "for %s: ret=%d\n", i + 1, algo, -ret);
220 goto out;
221 }
222
223 if (memcmp(result, template[i].digest,
224 crypto_ahash_digestsize(tfm))) {
225 printk(KERN_ERR "alg: hash: Test %d failed for %s\n",
226 i + 1, algo);
227 hexdump(result, crypto_ahash_digestsize(tfm));
228 ret = -EINVAL;
229 goto out;
230 }
231 }
232
233 j = 0;
234 for (i = 0; i < tcount; i++) {
235 if (template[i].np) {
236 j++;
237 memset(result, 0, 64);
238
239 temp = 0;
240 sg_init_table(sg, template[i].np);
241 for (k = 0; k < template[i].np; k++) {
242 sg_set_buf(&sg[k],
243 memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
244 offset_in_page(IDX[k]),
245 template[i].plaintext + temp,
246 template[i].tap[k]),
247 template[i].tap[k]);
248 temp += template[i].tap[k];
249 }
250
251 if (template[i].ksize) {
252 crypto_ahash_clear_flags(tfm, ~0);
253 ret = crypto_ahash_setkey(tfm, template[i].key,
254 template[i].ksize);
255
256 if (ret) {
257 printk(KERN_ERR "alg: hash: setkey "
258 "failed on chunking test %d "
259 "for %s: ret=%d\n", j, algo,
260 -ret);
261 goto out;
262 }
263 }
264
265 ahash_request_set_crypt(req, sg, result,
266 template[i].psize);
267 ret = crypto_ahash_digest(req);
268 switch (ret) {
269 case 0:
270 break;
271 case -EINPROGRESS:
272 case -EBUSY:
273 ret = wait_for_completion_interruptible(
274 &tresult.completion);
275 if (!ret && !(ret = tresult.err)) {
276 INIT_COMPLETION(tresult.completion);
277 break;
278 }
279 /* fall through */
280 default:
281 printk(KERN_ERR "alg: hash: digest failed "
282 "on chunking test %d for %s: "
283 "ret=%d\n", j, algo, -ret);
284 goto out;
285 }
286
287 if (memcmp(result, template[i].digest,
288 crypto_ahash_digestsize(tfm))) {
289 printk(KERN_ERR "alg: hash: Chunking test %d "
290 "failed for %s\n", j, algo);
291 hexdump(result, crypto_ahash_digestsize(tfm));
292 ret = -EINVAL;
293 goto out;
294 }
295 }
296 }
297
298 ret = 0;
299
300out:
301 ahash_request_free(req);
302out_noreq:
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800303 testmgr_free_buf(xbuf);
304out_nobuf:
Herbert Xuda7f0332008-07-31 17:08:25 +0800305 return ret;
306}
307
308static int test_aead(struct crypto_aead *tfm, int enc,
309 struct aead_testvec *template, unsigned int tcount)
310{
311 const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
312 unsigned int i, j, k, n, temp;
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800313 int ret = -ENOMEM;
Herbert Xuda7f0332008-07-31 17:08:25 +0800314 char *q;
315 char *key;
316 struct aead_request *req;
317 struct scatterlist sg[8];
318 struct scatterlist asg[8];
319 const char *e;
320 struct tcrypt_result result;
321 unsigned int authsize;
322 void *input;
323 void *assoc;
324 char iv[MAX_IVLEN];
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800325 char *xbuf[XBUFSIZE];
326 char *axbuf[XBUFSIZE];
327
328 if (testmgr_alloc_buf(xbuf))
329 goto out_noxbuf;
330 if (testmgr_alloc_buf(axbuf))
331 goto out_noaxbuf;
Herbert Xuda7f0332008-07-31 17:08:25 +0800332
333 if (enc == ENCRYPT)
334 e = "encryption";
335 else
336 e = "decryption";
337
338 init_completion(&result.completion);
339
340 req = aead_request_alloc(tfm, GFP_KERNEL);
341 if (!req) {
342 printk(KERN_ERR "alg: aead: Failed to allocate request for "
343 "%s\n", algo);
Herbert Xuda7f0332008-07-31 17:08:25 +0800344 goto out;
345 }
346
347 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
348 tcrypt_complete, &result);
349
350 for (i = 0, j = 0; i < tcount; i++) {
351 if (!template[i].np) {
352 j++;
353
354 /* some tepmplates have no input data but they will
355 * touch input
356 */
357 input = xbuf[0];
358 assoc = axbuf[0];
359
360 memcpy(input, template[i].input, template[i].ilen);
361 memcpy(assoc, template[i].assoc, template[i].alen);
362 if (template[i].iv)
363 memcpy(iv, template[i].iv, MAX_IVLEN);
364 else
365 memset(iv, 0, MAX_IVLEN);
366
367 crypto_aead_clear_flags(tfm, ~0);
368 if (template[i].wk)
369 crypto_aead_set_flags(
370 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
371
372 key = template[i].key;
373
374 ret = crypto_aead_setkey(tfm, key,
375 template[i].klen);
376 if (!ret == template[i].fail) {
377 printk(KERN_ERR "alg: aead: setkey failed on "
378 "test %d for %s: flags=%x\n", j, algo,
379 crypto_aead_get_flags(tfm));
380 goto out;
381 } else if (ret)
382 continue;
383
384 authsize = abs(template[i].rlen - template[i].ilen);
385 ret = crypto_aead_setauthsize(tfm, authsize);
386 if (ret) {
387 printk(KERN_ERR "alg: aead: Failed to set "
388 "authsize to %u on test %d for %s\n",
389 authsize, j, algo);
390 goto out;
391 }
392
393 sg_init_one(&sg[0], input,
394 template[i].ilen + (enc ? authsize : 0));
395
396 sg_init_one(&asg[0], assoc, template[i].alen);
397
398 aead_request_set_crypt(req, sg, sg,
399 template[i].ilen, iv);
400
401 aead_request_set_assoc(req, asg, template[i].alen);
402
403 ret = enc ?
404 crypto_aead_encrypt(req) :
405 crypto_aead_decrypt(req);
406
407 switch (ret) {
408 case 0:
Jarod Wilsone44a1b42009-05-04 19:22:11 +0800409 if (template[i].novrfy) {
410 /* verification was supposed to fail */
411 printk(KERN_ERR "alg: aead: %s failed "
412 "on test %d for %s: ret was 0, "
413 "expected -EBADMSG\n",
414 e, j, algo);
415 /* so really, we got a bad message */
416 ret = -EBADMSG;
417 goto out;
418 }
Herbert Xuda7f0332008-07-31 17:08:25 +0800419 break;
420 case -EINPROGRESS:
421 case -EBUSY:
422 ret = wait_for_completion_interruptible(
423 &result.completion);
424 if (!ret && !(ret = result.err)) {
425 INIT_COMPLETION(result.completion);
426 break;
427 }
Jarod Wilsone44a1b42009-05-04 19:22:11 +0800428 case -EBADMSG:
429 if (template[i].novrfy)
430 /* verification failure was expected */
431 continue;
Herbert Xuda7f0332008-07-31 17:08:25 +0800432 /* fall through */
433 default:
434 printk(KERN_ERR "alg: aead: %s failed on test "
435 "%d for %s: ret=%d\n", e, j, algo, -ret);
436 goto out;
437 }
438
439 q = input;
440 if (memcmp(q, template[i].result, template[i].rlen)) {
441 printk(KERN_ERR "alg: aead: Test %d failed on "
442 "%s for %s\n", j, e, algo);
443 hexdump(q, template[i].rlen);
444 ret = -EINVAL;
445 goto out;
446 }
447 }
448 }
449
450 for (i = 0, j = 0; i < tcount; i++) {
451 if (template[i].np) {
452 j++;
453
454 if (template[i].iv)
455 memcpy(iv, template[i].iv, MAX_IVLEN);
456 else
457 memset(iv, 0, MAX_IVLEN);
458
459 crypto_aead_clear_flags(tfm, ~0);
460 if (template[i].wk)
461 crypto_aead_set_flags(
462 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
463 key = template[i].key;
464
465 ret = crypto_aead_setkey(tfm, key, template[i].klen);
466 if (!ret == template[i].fail) {
467 printk(KERN_ERR "alg: aead: setkey failed on "
468 "chunk test %d for %s: flags=%x\n", j,
469 algo, crypto_aead_get_flags(tfm));
470 goto out;
471 } else if (ret)
472 continue;
473
474 authsize = abs(template[i].rlen - template[i].ilen);
475
476 ret = -EINVAL;
477 sg_init_table(sg, template[i].np);
478 for (k = 0, temp = 0; k < template[i].np; k++) {
479 if (WARN_ON(offset_in_page(IDX[k]) +
480 template[i].tap[k] > PAGE_SIZE))
481 goto out;
482
483 q = xbuf[IDX[k] >> PAGE_SHIFT] +
484 offset_in_page(IDX[k]);
485
486 memcpy(q, template[i].input + temp,
487 template[i].tap[k]);
488
489 n = template[i].tap[k];
490 if (k == template[i].np - 1 && enc)
491 n += authsize;
492 if (offset_in_page(q) + n < PAGE_SIZE)
493 q[n] = 0;
494
495 sg_set_buf(&sg[k], q, template[i].tap[k]);
496 temp += template[i].tap[k];
497 }
498
499 ret = crypto_aead_setauthsize(tfm, authsize);
500 if (ret) {
501 printk(KERN_ERR "alg: aead: Failed to set "
502 "authsize to %u on chunk test %d for "
503 "%s\n", authsize, j, algo);
504 goto out;
505 }
506
507 if (enc) {
508 if (WARN_ON(sg[k - 1].offset +
509 sg[k - 1].length + authsize >
510 PAGE_SIZE)) {
511 ret = -EINVAL;
512 goto out;
513 }
514
515 sg[k - 1].length += authsize;
516 }
517
518 sg_init_table(asg, template[i].anp);
519 for (k = 0, temp = 0; k < template[i].anp; k++) {
520 sg_set_buf(&asg[k],
521 memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
522 offset_in_page(IDX[k]),
523 template[i].assoc + temp,
524 template[i].atap[k]),
525 template[i].atap[k]);
526 temp += template[i].atap[k];
527 }
528
529 aead_request_set_crypt(req, sg, sg,
530 template[i].ilen,
531 iv);
532
533 aead_request_set_assoc(req, asg, template[i].alen);
534
535 ret = enc ?
536 crypto_aead_encrypt(req) :
537 crypto_aead_decrypt(req);
538
539 switch (ret) {
540 case 0:
Jarod Wilsone44a1b42009-05-04 19:22:11 +0800541 if (template[i].novrfy) {
542 /* verification was supposed to fail */
543 printk(KERN_ERR "alg: aead: %s failed "
544 "on chunk test %d for %s: ret "
545 "was 0, expected -EBADMSG\n",
546 e, j, algo);
547 /* so really, we got a bad message */
548 ret = -EBADMSG;
549 goto out;
550 }
Herbert Xuda7f0332008-07-31 17:08:25 +0800551 break;
552 case -EINPROGRESS:
553 case -EBUSY:
554 ret = wait_for_completion_interruptible(
555 &result.completion);
556 if (!ret && !(ret = result.err)) {
557 INIT_COMPLETION(result.completion);
558 break;
559 }
Jarod Wilsone44a1b42009-05-04 19:22:11 +0800560 case -EBADMSG:
561 if (template[i].novrfy)
562 /* verification failure was expected */
563 continue;
Herbert Xuda7f0332008-07-31 17:08:25 +0800564 /* fall through */
565 default:
566 printk(KERN_ERR "alg: aead: %s failed on "
567 "chunk test %d for %s: ret=%d\n", e, j,
568 algo, -ret);
569 goto out;
570 }
571
572 ret = -EINVAL;
573 for (k = 0, temp = 0; k < template[i].np; k++) {
574 q = xbuf[IDX[k] >> PAGE_SHIFT] +
575 offset_in_page(IDX[k]);
576
577 n = template[i].tap[k];
578 if (k == template[i].np - 1)
579 n += enc ? authsize : -authsize;
580
581 if (memcmp(q, template[i].result + temp, n)) {
582 printk(KERN_ERR "alg: aead: Chunk "
583 "test %d failed on %s at page "
584 "%u for %s\n", j, e, k, algo);
585 hexdump(q, n);
586 goto out;
587 }
588
589 q += n;
590 if (k == template[i].np - 1 && !enc) {
591 if (memcmp(q, template[i].input +
592 temp + n, authsize))
593 n = authsize;
594 else
595 n = 0;
596 } else {
597 for (n = 0; offset_in_page(q + n) &&
598 q[n]; n++)
599 ;
600 }
601 if (n) {
602 printk(KERN_ERR "alg: aead: Result "
603 "buffer corruption in chunk "
604 "test %d on %s at page %u for "
605 "%s: %u bytes:\n", j, e, k,
606 algo, n);
607 hexdump(q, n);
608 goto out;
609 }
610
611 temp += template[i].tap[k];
612 }
613 }
614 }
615
616 ret = 0;
617
618out:
619 aead_request_free(req);
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800620 testmgr_free_buf(axbuf);
621out_noaxbuf:
622 testmgr_free_buf(xbuf);
623out_noxbuf:
Herbert Xuda7f0332008-07-31 17:08:25 +0800624 return ret;
625}
626
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000627static int test_cipher(struct crypto_cipher *tfm, int enc,
Herbert Xuda7f0332008-07-31 17:08:25 +0800628 struct cipher_testvec *template, unsigned int tcount)
629{
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000630 const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
631 unsigned int i, j, k;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000632 char *q;
633 const char *e;
634 void *data;
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800635 char *xbuf[XBUFSIZE];
636 int ret = -ENOMEM;
637
638 if (testmgr_alloc_buf(xbuf))
639 goto out_nobuf;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000640
641 if (enc == ENCRYPT)
642 e = "encryption";
643 else
644 e = "decryption";
645
646 j = 0;
647 for (i = 0; i < tcount; i++) {
648 if (template[i].np)
649 continue;
650
651 j++;
652
653 data = xbuf[0];
654 memcpy(data, template[i].input, template[i].ilen);
655
656 crypto_cipher_clear_flags(tfm, ~0);
657 if (template[i].wk)
658 crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
659
660 ret = crypto_cipher_setkey(tfm, template[i].key,
661 template[i].klen);
662 if (!ret == template[i].fail) {
663 printk(KERN_ERR "alg: cipher: setkey failed "
664 "on test %d for %s: flags=%x\n", j,
665 algo, crypto_cipher_get_flags(tfm));
666 goto out;
667 } else if (ret)
668 continue;
669
670 for (k = 0; k < template[i].ilen;
671 k += crypto_cipher_blocksize(tfm)) {
672 if (enc)
673 crypto_cipher_encrypt_one(tfm, data + k,
674 data + k);
675 else
676 crypto_cipher_decrypt_one(tfm, data + k,
677 data + k);
678 }
679
680 q = data;
681 if (memcmp(q, template[i].result, template[i].rlen)) {
682 printk(KERN_ERR "alg: cipher: Test %d failed "
683 "on %s for %s\n", j, e, algo);
684 hexdump(q, template[i].rlen);
685 ret = -EINVAL;
686 goto out;
687 }
688 }
689
690 ret = 0;
691
692out:
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800693 testmgr_free_buf(xbuf);
694out_nobuf:
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000695 return ret;
696}
697
698static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
699 struct cipher_testvec *template, unsigned int tcount)
700{
Herbert Xuda7f0332008-07-31 17:08:25 +0800701 const char *algo =
702 crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
703 unsigned int i, j, k, n, temp;
Herbert Xuda7f0332008-07-31 17:08:25 +0800704 char *q;
705 struct ablkcipher_request *req;
706 struct scatterlist sg[8];
707 const char *e;
708 struct tcrypt_result result;
709 void *data;
710 char iv[MAX_IVLEN];
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800711 char *xbuf[XBUFSIZE];
712 int ret = -ENOMEM;
713
714 if (testmgr_alloc_buf(xbuf))
715 goto out_nobuf;
Herbert Xuda7f0332008-07-31 17:08:25 +0800716
717 if (enc == ENCRYPT)
718 e = "encryption";
719 else
720 e = "decryption";
721
722 init_completion(&result.completion);
723
724 req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
725 if (!req) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000726 printk(KERN_ERR "alg: skcipher: Failed to allocate request "
727 "for %s\n", algo);
Herbert Xuda7f0332008-07-31 17:08:25 +0800728 goto out;
729 }
730
731 ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
732 tcrypt_complete, &result);
733
734 j = 0;
735 for (i = 0; i < tcount; i++) {
736 if (template[i].iv)
737 memcpy(iv, template[i].iv, MAX_IVLEN);
738 else
739 memset(iv, 0, MAX_IVLEN);
740
741 if (!(template[i].np)) {
742 j++;
743
744 data = xbuf[0];
745 memcpy(data, template[i].input, template[i].ilen);
746
747 crypto_ablkcipher_clear_flags(tfm, ~0);
748 if (template[i].wk)
749 crypto_ablkcipher_set_flags(
750 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
751
752 ret = crypto_ablkcipher_setkey(tfm, template[i].key,
753 template[i].klen);
754 if (!ret == template[i].fail) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000755 printk(KERN_ERR "alg: skcipher: setkey failed "
Herbert Xuda7f0332008-07-31 17:08:25 +0800756 "on test %d for %s: flags=%x\n", j,
757 algo, crypto_ablkcipher_get_flags(tfm));
758 goto out;
759 } else if (ret)
760 continue;
761
762 sg_init_one(&sg[0], data, template[i].ilen);
763
764 ablkcipher_request_set_crypt(req, sg, sg,
765 template[i].ilen, iv);
766 ret = enc ?
767 crypto_ablkcipher_encrypt(req) :
768 crypto_ablkcipher_decrypt(req);
769
770 switch (ret) {
771 case 0:
772 break;
773 case -EINPROGRESS:
774 case -EBUSY:
775 ret = wait_for_completion_interruptible(
776 &result.completion);
777 if (!ret && !((ret = result.err))) {
778 INIT_COMPLETION(result.completion);
779 break;
780 }
781 /* fall through */
782 default:
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000783 printk(KERN_ERR "alg: skcipher: %s failed on "
Herbert Xuda7f0332008-07-31 17:08:25 +0800784 "test %d for %s: ret=%d\n", e, j, algo,
785 -ret);
786 goto out;
787 }
788
789 q = data;
790 if (memcmp(q, template[i].result, template[i].rlen)) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000791 printk(KERN_ERR "alg: skcipher: Test %d "
792 "failed on %s for %s\n", j, e, algo);
Herbert Xuda7f0332008-07-31 17:08:25 +0800793 hexdump(q, template[i].rlen);
794 ret = -EINVAL;
795 goto out;
796 }
797 }
798 }
799
800 j = 0;
801 for (i = 0; i < tcount; i++) {
802
803 if (template[i].iv)
804 memcpy(iv, template[i].iv, MAX_IVLEN);
805 else
806 memset(iv, 0, MAX_IVLEN);
807
808 if (template[i].np) {
809 j++;
810
811 crypto_ablkcipher_clear_flags(tfm, ~0);
812 if (template[i].wk)
813 crypto_ablkcipher_set_flags(
814 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
815
816 ret = crypto_ablkcipher_setkey(tfm, template[i].key,
817 template[i].klen);
818 if (!ret == template[i].fail) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000819 printk(KERN_ERR "alg: skcipher: setkey failed "
Herbert Xuda7f0332008-07-31 17:08:25 +0800820 "on chunk test %d for %s: flags=%x\n",
821 j, algo,
822 crypto_ablkcipher_get_flags(tfm));
823 goto out;
824 } else if (ret)
825 continue;
826
827 temp = 0;
828 ret = -EINVAL;
829 sg_init_table(sg, template[i].np);
830 for (k = 0; k < template[i].np; k++) {
831 if (WARN_ON(offset_in_page(IDX[k]) +
832 template[i].tap[k] > PAGE_SIZE))
833 goto out;
834
835 q = xbuf[IDX[k] >> PAGE_SHIFT] +
836 offset_in_page(IDX[k]);
837
838 memcpy(q, template[i].input + temp,
839 template[i].tap[k]);
840
841 if (offset_in_page(q) + template[i].tap[k] <
842 PAGE_SIZE)
843 q[template[i].tap[k]] = 0;
844
845 sg_set_buf(&sg[k], q, template[i].tap[k]);
846
847 temp += template[i].tap[k];
848 }
849
850 ablkcipher_request_set_crypt(req, sg, sg,
851 template[i].ilen, iv);
852
853 ret = enc ?
854 crypto_ablkcipher_encrypt(req) :
855 crypto_ablkcipher_decrypt(req);
856
857 switch (ret) {
858 case 0:
859 break;
860 case -EINPROGRESS:
861 case -EBUSY:
862 ret = wait_for_completion_interruptible(
863 &result.completion);
864 if (!ret && !((ret = result.err))) {
865 INIT_COMPLETION(result.completion);
866 break;
867 }
868 /* fall through */
869 default:
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000870 printk(KERN_ERR "alg: skcipher: %s failed on "
Herbert Xuda7f0332008-07-31 17:08:25 +0800871 "chunk test %d for %s: ret=%d\n", e, j,
872 algo, -ret);
873 goto out;
874 }
875
876 temp = 0;
877 ret = -EINVAL;
878 for (k = 0; k < template[i].np; k++) {
879 q = xbuf[IDX[k] >> PAGE_SHIFT] +
880 offset_in_page(IDX[k]);
881
882 if (memcmp(q, template[i].result + temp,
883 template[i].tap[k])) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000884 printk(KERN_ERR "alg: skcipher: Chunk "
Herbert Xuda7f0332008-07-31 17:08:25 +0800885 "test %d failed on %s at page "
886 "%u for %s\n", j, e, k, algo);
887 hexdump(q, template[i].tap[k]);
888 goto out;
889 }
890
891 q += template[i].tap[k];
892 for (n = 0; offset_in_page(q + n) && q[n]; n++)
893 ;
894 if (n) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000895 printk(KERN_ERR "alg: skcipher: "
Herbert Xuda7f0332008-07-31 17:08:25 +0800896 "Result buffer corruption in "
897 "chunk test %d on %s at page "
898 "%u for %s: %u bytes:\n", j, e,
899 k, algo, n);
900 hexdump(q, n);
901 goto out;
902 }
903 temp += template[i].tap[k];
904 }
905 }
906 }
907
908 ret = 0;
909
910out:
911 ablkcipher_request_free(req);
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800912 testmgr_free_buf(xbuf);
913out_nobuf:
Herbert Xuda7f0332008-07-31 17:08:25 +0800914 return ret;
915}
916
917static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
918 struct comp_testvec *dtemplate, int ctcount, int dtcount)
919{
920 const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
921 unsigned int i;
922 char result[COMP_BUF_SIZE];
923 int ret;
924
925 for (i = 0; i < ctcount; i++) {
Geert Uytterhoevenc79cf912009-03-29 15:44:19 +0800926 int ilen;
927 unsigned int dlen = COMP_BUF_SIZE;
Herbert Xuda7f0332008-07-31 17:08:25 +0800928
929 memset(result, 0, sizeof (result));
930
931 ilen = ctemplate[i].inlen;
932 ret = crypto_comp_compress(tfm, ctemplate[i].input,
933 ilen, result, &dlen);
934 if (ret) {
935 printk(KERN_ERR "alg: comp: compression failed "
936 "on test %d for %s: ret=%d\n", i + 1, algo,
937 -ret);
938 goto out;
939 }
940
Geert Uytterhoevenb812eb02008-11-28 20:51:28 +0800941 if (dlen != ctemplate[i].outlen) {
942 printk(KERN_ERR "alg: comp: Compression test %d "
943 "failed for %s: output len = %d\n", i + 1, algo,
944 dlen);
945 ret = -EINVAL;
946 goto out;
947 }
948
Herbert Xuda7f0332008-07-31 17:08:25 +0800949 if (memcmp(result, ctemplate[i].output, dlen)) {
950 printk(KERN_ERR "alg: comp: Compression test %d "
951 "failed for %s\n", i + 1, algo);
952 hexdump(result, dlen);
953 ret = -EINVAL;
954 goto out;
955 }
956 }
957
958 for (i = 0; i < dtcount; i++) {
Geert Uytterhoevenc79cf912009-03-29 15:44:19 +0800959 int ilen;
960 unsigned int dlen = COMP_BUF_SIZE;
Herbert Xuda7f0332008-07-31 17:08:25 +0800961
962 memset(result, 0, sizeof (result));
963
964 ilen = dtemplate[i].inlen;
965 ret = crypto_comp_decompress(tfm, dtemplate[i].input,
966 ilen, result, &dlen);
967 if (ret) {
968 printk(KERN_ERR "alg: comp: decompression failed "
969 "on test %d for %s: ret=%d\n", i + 1, algo,
970 -ret);
971 goto out;
972 }
973
Geert Uytterhoevenb812eb02008-11-28 20:51:28 +0800974 if (dlen != dtemplate[i].outlen) {
975 printk(KERN_ERR "alg: comp: Decompression test %d "
976 "failed for %s: output len = %d\n", i + 1, algo,
977 dlen);
978 ret = -EINVAL;
979 goto out;
980 }
981
Herbert Xuda7f0332008-07-31 17:08:25 +0800982 if (memcmp(result, dtemplate[i].output, dlen)) {
983 printk(KERN_ERR "alg: comp: Decompression test %d "
984 "failed for %s\n", i + 1, algo);
985 hexdump(result, dlen);
986 ret = -EINVAL;
987 goto out;
988 }
989 }
990
991 ret = 0;
992
993out:
994 return ret;
995}
996
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +0800997static int test_pcomp(struct crypto_pcomp *tfm,
998 struct pcomp_testvec *ctemplate,
999 struct pcomp_testvec *dtemplate, int ctcount,
1000 int dtcount)
1001{
1002 const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
1003 unsigned int i;
1004 char result[COMP_BUF_SIZE];
1005 int error;
1006
1007 for (i = 0; i < ctcount; i++) {
1008 struct comp_request req;
1009
1010 error = crypto_compress_setup(tfm, ctemplate[i].params,
1011 ctemplate[i].paramsize);
1012 if (error) {
1013 pr_err("alg: pcomp: compression setup failed on test "
1014 "%d for %s: error=%d\n", i + 1, algo, error);
1015 return error;
1016 }
1017
1018 error = crypto_compress_init(tfm);
1019 if (error) {
1020 pr_err("alg: pcomp: compression init failed on test "
1021 "%d for %s: error=%d\n", i + 1, algo, error);
1022 return error;
1023 }
1024
1025 memset(result, 0, sizeof(result));
1026
1027 req.next_in = ctemplate[i].input;
1028 req.avail_in = ctemplate[i].inlen / 2;
1029 req.next_out = result;
1030 req.avail_out = ctemplate[i].outlen / 2;
1031
1032 error = crypto_compress_update(tfm, &req);
1033 if (error && (error != -EAGAIN || req.avail_in)) {
1034 pr_err("alg: pcomp: compression update failed on test "
1035 "%d for %s: error=%d\n", i + 1, algo, error);
1036 return error;
1037 }
1038
1039 /* Add remaining input data */
1040 req.avail_in += (ctemplate[i].inlen + 1) / 2;
1041
1042 error = crypto_compress_update(tfm, &req);
1043 if (error && (error != -EAGAIN || req.avail_in)) {
1044 pr_err("alg: pcomp: compression update failed on test "
1045 "%d for %s: error=%d\n", i + 1, algo, error);
1046 return error;
1047 }
1048
1049 /* Provide remaining output space */
1050 req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
1051
1052 error = crypto_compress_final(tfm, &req);
1053 if (error) {
1054 pr_err("alg: pcomp: compression final failed on test "
1055 "%d for %s: error=%d\n", i + 1, algo, error);
1056 return error;
1057 }
1058
1059 if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
1060 pr_err("alg: comp: Compression test %d failed for %s: "
1061 "output len = %d (expected %d)\n", i + 1, algo,
1062 COMP_BUF_SIZE - req.avail_out,
1063 ctemplate[i].outlen);
1064 return -EINVAL;
1065 }
1066
1067 if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
1068 pr_err("alg: pcomp: Compression test %d failed for "
1069 "%s\n", i + 1, algo);
1070 hexdump(result, ctemplate[i].outlen);
1071 return -EINVAL;
1072 }
1073 }
1074
1075 for (i = 0; i < dtcount; i++) {
1076 struct comp_request req;
1077
1078 error = crypto_decompress_setup(tfm, dtemplate[i].params,
1079 dtemplate[i].paramsize);
1080 if (error) {
1081 pr_err("alg: pcomp: decompression setup failed on "
1082 "test %d for %s: error=%d\n", i + 1, algo,
1083 error);
1084 return error;
1085 }
1086
1087 error = crypto_decompress_init(tfm);
1088 if (error) {
1089 pr_err("alg: pcomp: decompression init failed on test "
1090 "%d for %s: error=%d\n", i + 1, algo, error);
1091 return error;
1092 }
1093
1094 memset(result, 0, sizeof(result));
1095
1096 req.next_in = dtemplate[i].input;
1097 req.avail_in = dtemplate[i].inlen / 2;
1098 req.next_out = result;
1099 req.avail_out = dtemplate[i].outlen / 2;
1100
1101 error = crypto_decompress_update(tfm, &req);
1102 if (error && (error != -EAGAIN || req.avail_in)) {
1103 pr_err("alg: pcomp: decompression update failed on "
1104 "test %d for %s: error=%d\n", i + 1, algo,
1105 error);
1106 return error;
1107 }
1108
1109 /* Add remaining input data */
1110 req.avail_in += (dtemplate[i].inlen + 1) / 2;
1111
1112 error = crypto_decompress_update(tfm, &req);
1113 if (error && (error != -EAGAIN || req.avail_in)) {
1114 pr_err("alg: pcomp: decompression update failed on "
1115 "test %d for %s: error=%d\n", i + 1, algo,
1116 error);
1117 return error;
1118 }
1119
1120 /* Provide remaining output space */
1121 req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
1122
1123 error = crypto_decompress_final(tfm, &req);
1124 if (error && (error != -EAGAIN || req.avail_in)) {
1125 pr_err("alg: pcomp: decompression final failed on "
1126 "test %d for %s: error=%d\n", i + 1, algo,
1127 error);
1128 return error;
1129 }
1130
1131 if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
1132 pr_err("alg: comp: Decompression test %d failed for "
1133 "%s: output len = %d (expected %d)\n", i + 1,
1134 algo, COMP_BUF_SIZE - req.avail_out,
1135 dtemplate[i].outlen);
1136 return -EINVAL;
1137 }
1138
1139 if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
1140 pr_err("alg: pcomp: Decompression test %d failed for "
1141 "%s\n", i + 1, algo);
1142 hexdump(result, dtemplate[i].outlen);
1143 return -EINVAL;
1144 }
1145 }
1146
1147 return 0;
1148}
1149
Jarod Wilson7647d6c2009-05-04 19:44:50 +08001150
1151static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
1152 unsigned int tcount)
1153{
1154 const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
1155 int err, i, j, seedsize;
1156 u8 *seed;
1157 char result[32];
1158
1159 seedsize = crypto_rng_seedsize(tfm);
1160
1161 seed = kmalloc(seedsize, GFP_KERNEL);
1162 if (!seed) {
1163 printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
1164 "for %s\n", algo);
1165 return -ENOMEM;
1166 }
1167
1168 for (i = 0; i < tcount; i++) {
1169 memset(result, 0, 32);
1170
1171 memcpy(seed, template[i].v, template[i].vlen);
1172 memcpy(seed + template[i].vlen, template[i].key,
1173 template[i].klen);
1174 memcpy(seed + template[i].vlen + template[i].klen,
1175 template[i].dt, template[i].dtlen);
1176
1177 err = crypto_rng_reset(tfm, seed, seedsize);
1178 if (err) {
1179 printk(KERN_ERR "alg: cprng: Failed to reset rng "
1180 "for %s\n", algo);
1181 goto out;
1182 }
1183
1184 for (j = 0; j < template[i].loops; j++) {
1185 err = crypto_rng_get_bytes(tfm, result,
1186 template[i].rlen);
1187 if (err != template[i].rlen) {
1188 printk(KERN_ERR "alg: cprng: Failed to obtain "
1189 "the correct amount of random data for "
1190 "%s (requested %d, got %d)\n", algo,
1191 template[i].rlen, err);
1192 goto out;
1193 }
1194 }
1195
1196 err = memcmp(result, template[i].result,
1197 template[i].rlen);
1198 if (err) {
1199 printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
1200 i, algo);
1201 hexdump(result, template[i].rlen);
1202 err = -EINVAL;
1203 goto out;
1204 }
1205 }
1206
1207out:
1208 kfree(seed);
1209 return err;
1210}
1211
Herbert Xuda7f0332008-07-31 17:08:25 +08001212static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
1213 u32 type, u32 mask)
1214{
1215 struct crypto_aead *tfm;
1216 int err = 0;
1217
1218 tfm = crypto_alloc_aead(driver, type, mask);
1219 if (IS_ERR(tfm)) {
1220 printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
1221 "%ld\n", driver, PTR_ERR(tfm));
1222 return PTR_ERR(tfm);
1223 }
1224
1225 if (desc->suite.aead.enc.vecs) {
1226 err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
1227 desc->suite.aead.enc.count);
1228 if (err)
1229 goto out;
1230 }
1231
1232 if (!err && desc->suite.aead.dec.vecs)
1233 err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
1234 desc->suite.aead.dec.count);
1235
1236out:
1237 crypto_free_aead(tfm);
1238 return err;
1239}
1240
1241static int alg_test_cipher(const struct alg_test_desc *desc,
1242 const char *driver, u32 type, u32 mask)
1243{
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001244 struct crypto_cipher *tfm;
Herbert Xuda7f0332008-07-31 17:08:25 +08001245 int err = 0;
1246
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001247 tfm = crypto_alloc_cipher(driver, type, mask);
Herbert Xuda7f0332008-07-31 17:08:25 +08001248 if (IS_ERR(tfm)) {
1249 printk(KERN_ERR "alg: cipher: Failed to load transform for "
1250 "%s: %ld\n", driver, PTR_ERR(tfm));
1251 return PTR_ERR(tfm);
1252 }
1253
1254 if (desc->suite.cipher.enc.vecs) {
1255 err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
1256 desc->suite.cipher.enc.count);
1257 if (err)
1258 goto out;
1259 }
1260
1261 if (desc->suite.cipher.dec.vecs)
1262 err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
1263 desc->suite.cipher.dec.count);
1264
1265out:
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001266 crypto_free_cipher(tfm);
1267 return err;
1268}
1269
1270static int alg_test_skcipher(const struct alg_test_desc *desc,
1271 const char *driver, u32 type, u32 mask)
1272{
1273 struct crypto_ablkcipher *tfm;
1274 int err = 0;
1275
1276 tfm = crypto_alloc_ablkcipher(driver, type, mask);
1277 if (IS_ERR(tfm)) {
1278 printk(KERN_ERR "alg: skcipher: Failed to load transform for "
1279 "%s: %ld\n", driver, PTR_ERR(tfm));
1280 return PTR_ERR(tfm);
1281 }
1282
1283 if (desc->suite.cipher.enc.vecs) {
1284 err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
1285 desc->suite.cipher.enc.count);
1286 if (err)
1287 goto out;
1288 }
1289
1290 if (desc->suite.cipher.dec.vecs)
1291 err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
1292 desc->suite.cipher.dec.count);
1293
1294out:
Herbert Xuda7f0332008-07-31 17:08:25 +08001295 crypto_free_ablkcipher(tfm);
1296 return err;
1297}
1298
1299static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
1300 u32 type, u32 mask)
1301{
1302 struct crypto_comp *tfm;
1303 int err;
1304
1305 tfm = crypto_alloc_comp(driver, type, mask);
1306 if (IS_ERR(tfm)) {
1307 printk(KERN_ERR "alg: comp: Failed to load transform for %s: "
1308 "%ld\n", driver, PTR_ERR(tfm));
1309 return PTR_ERR(tfm);
1310 }
1311
1312 err = test_comp(tfm, desc->suite.comp.comp.vecs,
1313 desc->suite.comp.decomp.vecs,
1314 desc->suite.comp.comp.count,
1315 desc->suite.comp.decomp.count);
1316
1317 crypto_free_comp(tfm);
1318 return err;
1319}
1320
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001321static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
1322 u32 type, u32 mask)
1323{
1324 struct crypto_pcomp *tfm;
1325 int err;
1326
1327 tfm = crypto_alloc_pcomp(driver, type, mask);
1328 if (IS_ERR(tfm)) {
1329 pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
1330 driver, PTR_ERR(tfm));
1331 return PTR_ERR(tfm);
1332 }
1333
1334 err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
1335 desc->suite.pcomp.decomp.vecs,
1336 desc->suite.pcomp.comp.count,
1337 desc->suite.pcomp.decomp.count);
1338
1339 crypto_free_pcomp(tfm);
1340 return err;
1341}
1342
Herbert Xuda7f0332008-07-31 17:08:25 +08001343static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
1344 u32 type, u32 mask)
1345{
1346 struct crypto_ahash *tfm;
1347 int err;
1348
1349 tfm = crypto_alloc_ahash(driver, type, mask);
1350 if (IS_ERR(tfm)) {
1351 printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
1352 "%ld\n", driver, PTR_ERR(tfm));
1353 return PTR_ERR(tfm);
1354 }
1355
1356 err = test_hash(tfm, desc->suite.hash.vecs, desc->suite.hash.count);
1357
1358 crypto_free_ahash(tfm);
1359 return err;
1360}
1361
Herbert Xu8e3ee852008-11-07 14:58:52 +08001362static int alg_test_crc32c(const struct alg_test_desc *desc,
1363 const char *driver, u32 type, u32 mask)
1364{
1365 struct crypto_shash *tfm;
1366 u32 val;
1367 int err;
1368
1369 err = alg_test_hash(desc, driver, type, mask);
1370 if (err)
1371 goto out;
1372
1373 tfm = crypto_alloc_shash(driver, type, mask);
1374 if (IS_ERR(tfm)) {
1375 printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
1376 "%ld\n", driver, PTR_ERR(tfm));
1377 err = PTR_ERR(tfm);
1378 goto out;
1379 }
1380
1381 do {
1382 struct {
1383 struct shash_desc shash;
1384 char ctx[crypto_shash_descsize(tfm)];
1385 } sdesc;
1386
1387 sdesc.shash.tfm = tfm;
1388 sdesc.shash.flags = 0;
1389
1390 *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
1391 err = crypto_shash_final(&sdesc.shash, (u8 *)&val);
1392 if (err) {
1393 printk(KERN_ERR "alg: crc32c: Operation failed for "
1394 "%s: %d\n", driver, err);
1395 break;
1396 }
1397
1398 if (val != ~420553207) {
1399 printk(KERN_ERR "alg: crc32c: Test failed for %s: "
1400 "%d\n", driver, val);
1401 err = -EINVAL;
1402 }
1403 } while (0);
1404
1405 crypto_free_shash(tfm);
1406
1407out:
1408 return err;
1409}
1410
Jarod Wilson7647d6c2009-05-04 19:44:50 +08001411static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
1412 u32 type, u32 mask)
1413{
1414 struct crypto_rng *rng;
1415 int err;
1416
1417 rng = crypto_alloc_rng(driver, type, mask);
1418 if (IS_ERR(rng)) {
1419 printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
1420 "%ld\n", driver, PTR_ERR(rng));
1421 return PTR_ERR(rng);
1422 }
1423
1424 err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
1425
1426 crypto_free_rng(rng);
1427
1428 return err;
1429}
1430
Herbert Xuda7f0332008-07-31 17:08:25 +08001431/* Please keep this list sorted by algorithm name. */
1432static const struct alg_test_desc alg_test_descs[] = {
1433 {
Jarod Wilsone08ca2d2009-05-04 19:46:29 +08001434 .alg = "ansi_cprng",
1435 .test = alg_test_cprng,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001436 .fips_allowed = 1,
Jarod Wilsone08ca2d2009-05-04 19:46:29 +08001437 .suite = {
1438 .cprng = {
1439 .vecs = ansi_cprng_aes_tv_template,
1440 .count = ANSI_CPRNG_AES_TEST_VECTORS
1441 }
1442 }
1443 }, {
Herbert Xuda7f0332008-07-31 17:08:25 +08001444 .alg = "cbc(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001445 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001446 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001447 .suite = {
1448 .cipher = {
1449 .enc = {
1450 .vecs = aes_cbc_enc_tv_template,
1451 .count = AES_CBC_ENC_TEST_VECTORS
1452 },
1453 .dec = {
1454 .vecs = aes_cbc_dec_tv_template,
1455 .count = AES_CBC_DEC_TEST_VECTORS
1456 }
1457 }
1458 }
1459 }, {
1460 .alg = "cbc(anubis)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001461 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001462 .suite = {
1463 .cipher = {
1464 .enc = {
1465 .vecs = anubis_cbc_enc_tv_template,
1466 .count = ANUBIS_CBC_ENC_TEST_VECTORS
1467 },
1468 .dec = {
1469 .vecs = anubis_cbc_dec_tv_template,
1470 .count = ANUBIS_CBC_DEC_TEST_VECTORS
1471 }
1472 }
1473 }
1474 }, {
1475 .alg = "cbc(blowfish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001476 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001477 .suite = {
1478 .cipher = {
1479 .enc = {
1480 .vecs = bf_cbc_enc_tv_template,
1481 .count = BF_CBC_ENC_TEST_VECTORS
1482 },
1483 .dec = {
1484 .vecs = bf_cbc_dec_tv_template,
1485 .count = BF_CBC_DEC_TEST_VECTORS
1486 }
1487 }
1488 }
1489 }, {
1490 .alg = "cbc(camellia)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001491 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001492 .suite = {
1493 .cipher = {
1494 .enc = {
1495 .vecs = camellia_cbc_enc_tv_template,
1496 .count = CAMELLIA_CBC_ENC_TEST_VECTORS
1497 },
1498 .dec = {
1499 .vecs = camellia_cbc_dec_tv_template,
1500 .count = CAMELLIA_CBC_DEC_TEST_VECTORS
1501 }
1502 }
1503 }
1504 }, {
1505 .alg = "cbc(des)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001506 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001507 .suite = {
1508 .cipher = {
1509 .enc = {
1510 .vecs = des_cbc_enc_tv_template,
1511 .count = DES_CBC_ENC_TEST_VECTORS
1512 },
1513 .dec = {
1514 .vecs = des_cbc_dec_tv_template,
1515 .count = DES_CBC_DEC_TEST_VECTORS
1516 }
1517 }
1518 }
1519 }, {
1520 .alg = "cbc(des3_ede)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001521 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001522 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001523 .suite = {
1524 .cipher = {
1525 .enc = {
1526 .vecs = des3_ede_cbc_enc_tv_template,
1527 .count = DES3_EDE_CBC_ENC_TEST_VECTORS
1528 },
1529 .dec = {
1530 .vecs = des3_ede_cbc_dec_tv_template,
1531 .count = DES3_EDE_CBC_DEC_TEST_VECTORS
1532 }
1533 }
1534 }
1535 }, {
1536 .alg = "cbc(twofish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001537 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001538 .suite = {
1539 .cipher = {
1540 .enc = {
1541 .vecs = tf_cbc_enc_tv_template,
1542 .count = TF_CBC_ENC_TEST_VECTORS
1543 },
1544 .dec = {
1545 .vecs = tf_cbc_dec_tv_template,
1546 .count = TF_CBC_DEC_TEST_VECTORS
1547 }
1548 }
1549 }
1550 }, {
1551 .alg = "ccm(aes)",
1552 .test = alg_test_aead,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001553 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001554 .suite = {
1555 .aead = {
1556 .enc = {
1557 .vecs = aes_ccm_enc_tv_template,
1558 .count = AES_CCM_ENC_TEST_VECTORS
1559 },
1560 .dec = {
1561 .vecs = aes_ccm_dec_tv_template,
1562 .count = AES_CCM_DEC_TEST_VECTORS
1563 }
1564 }
1565 }
1566 }, {
1567 .alg = "crc32c",
Herbert Xu8e3ee852008-11-07 14:58:52 +08001568 .test = alg_test_crc32c,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001569 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001570 .suite = {
1571 .hash = {
1572 .vecs = crc32c_tv_template,
1573 .count = CRC32C_TEST_VECTORS
1574 }
1575 }
1576 }, {
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08001577 .alg = "ctr(aes)",
1578 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001579 .fips_allowed = 1,
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08001580 .suite = {
1581 .cipher = {
1582 .enc = {
1583 .vecs = aes_ctr_enc_tv_template,
1584 .count = AES_CTR_ENC_TEST_VECTORS
1585 },
1586 .dec = {
1587 .vecs = aes_ctr_dec_tv_template,
1588 .count = AES_CTR_DEC_TEST_VECTORS
1589 }
1590 }
1591 }
1592 }, {
Herbert Xuda7f0332008-07-31 17:08:25 +08001593 .alg = "cts(cbc(aes))",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001594 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001595 .suite = {
1596 .cipher = {
1597 .enc = {
1598 .vecs = cts_mode_enc_tv_template,
1599 .count = CTS_MODE_ENC_TEST_VECTORS
1600 },
1601 .dec = {
1602 .vecs = cts_mode_dec_tv_template,
1603 .count = CTS_MODE_DEC_TEST_VECTORS
1604 }
1605 }
1606 }
1607 }, {
1608 .alg = "deflate",
1609 .test = alg_test_comp,
1610 .suite = {
1611 .comp = {
1612 .comp = {
1613 .vecs = deflate_comp_tv_template,
1614 .count = DEFLATE_COMP_TEST_VECTORS
1615 },
1616 .decomp = {
1617 .vecs = deflate_decomp_tv_template,
1618 .count = DEFLATE_DECOMP_TEST_VECTORS
1619 }
1620 }
1621 }
1622 }, {
1623 .alg = "ecb(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001624 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001625 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001626 .suite = {
1627 .cipher = {
1628 .enc = {
1629 .vecs = aes_enc_tv_template,
1630 .count = AES_ENC_TEST_VECTORS
1631 },
1632 .dec = {
1633 .vecs = aes_dec_tv_template,
1634 .count = AES_DEC_TEST_VECTORS
1635 }
1636 }
1637 }
1638 }, {
1639 .alg = "ecb(anubis)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001640 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001641 .suite = {
1642 .cipher = {
1643 .enc = {
1644 .vecs = anubis_enc_tv_template,
1645 .count = ANUBIS_ENC_TEST_VECTORS
1646 },
1647 .dec = {
1648 .vecs = anubis_dec_tv_template,
1649 .count = ANUBIS_DEC_TEST_VECTORS
1650 }
1651 }
1652 }
1653 }, {
1654 .alg = "ecb(arc4)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001655 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001656 .suite = {
1657 .cipher = {
1658 .enc = {
1659 .vecs = arc4_enc_tv_template,
1660 .count = ARC4_ENC_TEST_VECTORS
1661 },
1662 .dec = {
1663 .vecs = arc4_dec_tv_template,
1664 .count = ARC4_DEC_TEST_VECTORS
1665 }
1666 }
1667 }
1668 }, {
1669 .alg = "ecb(blowfish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001670 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001671 .suite = {
1672 .cipher = {
1673 .enc = {
1674 .vecs = bf_enc_tv_template,
1675 .count = BF_ENC_TEST_VECTORS
1676 },
1677 .dec = {
1678 .vecs = bf_dec_tv_template,
1679 .count = BF_DEC_TEST_VECTORS
1680 }
1681 }
1682 }
1683 }, {
1684 .alg = "ecb(camellia)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001685 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001686 .suite = {
1687 .cipher = {
1688 .enc = {
1689 .vecs = camellia_enc_tv_template,
1690 .count = CAMELLIA_ENC_TEST_VECTORS
1691 },
1692 .dec = {
1693 .vecs = camellia_dec_tv_template,
1694 .count = CAMELLIA_DEC_TEST_VECTORS
1695 }
1696 }
1697 }
1698 }, {
1699 .alg = "ecb(cast5)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001700 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001701 .suite = {
1702 .cipher = {
1703 .enc = {
1704 .vecs = cast5_enc_tv_template,
1705 .count = CAST5_ENC_TEST_VECTORS
1706 },
1707 .dec = {
1708 .vecs = cast5_dec_tv_template,
1709 .count = CAST5_DEC_TEST_VECTORS
1710 }
1711 }
1712 }
1713 }, {
1714 .alg = "ecb(cast6)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001715 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001716 .suite = {
1717 .cipher = {
1718 .enc = {
1719 .vecs = cast6_enc_tv_template,
1720 .count = CAST6_ENC_TEST_VECTORS
1721 },
1722 .dec = {
1723 .vecs = cast6_dec_tv_template,
1724 .count = CAST6_DEC_TEST_VECTORS
1725 }
1726 }
1727 }
1728 }, {
1729 .alg = "ecb(des)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001730 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001731 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001732 .suite = {
1733 .cipher = {
1734 .enc = {
1735 .vecs = des_enc_tv_template,
1736 .count = DES_ENC_TEST_VECTORS
1737 },
1738 .dec = {
1739 .vecs = des_dec_tv_template,
1740 .count = DES_DEC_TEST_VECTORS
1741 }
1742 }
1743 }
1744 }, {
1745 .alg = "ecb(des3_ede)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001746 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001747 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001748 .suite = {
1749 .cipher = {
1750 .enc = {
1751 .vecs = des3_ede_enc_tv_template,
1752 .count = DES3_EDE_ENC_TEST_VECTORS
1753 },
1754 .dec = {
1755 .vecs = des3_ede_dec_tv_template,
1756 .count = DES3_EDE_DEC_TEST_VECTORS
1757 }
1758 }
1759 }
1760 }, {
1761 .alg = "ecb(khazad)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001762 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001763 .suite = {
1764 .cipher = {
1765 .enc = {
1766 .vecs = khazad_enc_tv_template,
1767 .count = KHAZAD_ENC_TEST_VECTORS
1768 },
1769 .dec = {
1770 .vecs = khazad_dec_tv_template,
1771 .count = KHAZAD_DEC_TEST_VECTORS
1772 }
1773 }
1774 }
1775 }, {
1776 .alg = "ecb(seed)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001777 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001778 .suite = {
1779 .cipher = {
1780 .enc = {
1781 .vecs = seed_enc_tv_template,
1782 .count = SEED_ENC_TEST_VECTORS
1783 },
1784 .dec = {
1785 .vecs = seed_dec_tv_template,
1786 .count = SEED_DEC_TEST_VECTORS
1787 }
1788 }
1789 }
1790 }, {
1791 .alg = "ecb(serpent)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001792 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001793 .suite = {
1794 .cipher = {
1795 .enc = {
1796 .vecs = serpent_enc_tv_template,
1797 .count = SERPENT_ENC_TEST_VECTORS
1798 },
1799 .dec = {
1800 .vecs = serpent_dec_tv_template,
1801 .count = SERPENT_DEC_TEST_VECTORS
1802 }
1803 }
1804 }
1805 }, {
1806 .alg = "ecb(tea)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001807 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001808 .suite = {
1809 .cipher = {
1810 .enc = {
1811 .vecs = tea_enc_tv_template,
1812 .count = TEA_ENC_TEST_VECTORS
1813 },
1814 .dec = {
1815 .vecs = tea_dec_tv_template,
1816 .count = TEA_DEC_TEST_VECTORS
1817 }
1818 }
1819 }
1820 }, {
1821 .alg = "ecb(tnepres)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001822 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001823 .suite = {
1824 .cipher = {
1825 .enc = {
1826 .vecs = tnepres_enc_tv_template,
1827 .count = TNEPRES_ENC_TEST_VECTORS
1828 },
1829 .dec = {
1830 .vecs = tnepres_dec_tv_template,
1831 .count = TNEPRES_DEC_TEST_VECTORS
1832 }
1833 }
1834 }
1835 }, {
1836 .alg = "ecb(twofish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001837 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001838 .suite = {
1839 .cipher = {
1840 .enc = {
1841 .vecs = tf_enc_tv_template,
1842 .count = TF_ENC_TEST_VECTORS
1843 },
1844 .dec = {
1845 .vecs = tf_dec_tv_template,
1846 .count = TF_DEC_TEST_VECTORS
1847 }
1848 }
1849 }
1850 }, {
1851 .alg = "ecb(xeta)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001852 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001853 .suite = {
1854 .cipher = {
1855 .enc = {
1856 .vecs = xeta_enc_tv_template,
1857 .count = XETA_ENC_TEST_VECTORS
1858 },
1859 .dec = {
1860 .vecs = xeta_dec_tv_template,
1861 .count = XETA_DEC_TEST_VECTORS
1862 }
1863 }
1864 }
1865 }, {
1866 .alg = "ecb(xtea)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001867 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001868 .suite = {
1869 .cipher = {
1870 .enc = {
1871 .vecs = xtea_enc_tv_template,
1872 .count = XTEA_ENC_TEST_VECTORS
1873 },
1874 .dec = {
1875 .vecs = xtea_dec_tv_template,
1876 .count = XTEA_DEC_TEST_VECTORS
1877 }
1878 }
1879 }
1880 }, {
1881 .alg = "gcm(aes)",
1882 .test = alg_test_aead,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001883 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001884 .suite = {
1885 .aead = {
1886 .enc = {
1887 .vecs = aes_gcm_enc_tv_template,
1888 .count = AES_GCM_ENC_TEST_VECTORS
1889 },
1890 .dec = {
1891 .vecs = aes_gcm_dec_tv_template,
1892 .count = AES_GCM_DEC_TEST_VECTORS
1893 }
1894 }
1895 }
1896 }, {
1897 .alg = "hmac(md5)",
1898 .test = alg_test_hash,
1899 .suite = {
1900 .hash = {
1901 .vecs = hmac_md5_tv_template,
1902 .count = HMAC_MD5_TEST_VECTORS
1903 }
1904 }
1905 }, {
1906 .alg = "hmac(rmd128)",
1907 .test = alg_test_hash,
1908 .suite = {
1909 .hash = {
1910 .vecs = hmac_rmd128_tv_template,
1911 .count = HMAC_RMD128_TEST_VECTORS
1912 }
1913 }
1914 }, {
1915 .alg = "hmac(rmd160)",
1916 .test = alg_test_hash,
1917 .suite = {
1918 .hash = {
1919 .vecs = hmac_rmd160_tv_template,
1920 .count = HMAC_RMD160_TEST_VECTORS
1921 }
1922 }
1923 }, {
1924 .alg = "hmac(sha1)",
1925 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001926 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001927 .suite = {
1928 .hash = {
1929 .vecs = hmac_sha1_tv_template,
1930 .count = HMAC_SHA1_TEST_VECTORS
1931 }
1932 }
1933 }, {
1934 .alg = "hmac(sha224)",
1935 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001936 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001937 .suite = {
1938 .hash = {
1939 .vecs = hmac_sha224_tv_template,
1940 .count = HMAC_SHA224_TEST_VECTORS
1941 }
1942 }
1943 }, {
1944 .alg = "hmac(sha256)",
1945 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001946 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001947 .suite = {
1948 .hash = {
1949 .vecs = hmac_sha256_tv_template,
1950 .count = HMAC_SHA256_TEST_VECTORS
1951 }
1952 }
1953 }, {
1954 .alg = "hmac(sha384)",
1955 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001956 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001957 .suite = {
1958 .hash = {
1959 .vecs = hmac_sha384_tv_template,
1960 .count = HMAC_SHA384_TEST_VECTORS
1961 }
1962 }
1963 }, {
1964 .alg = "hmac(sha512)",
1965 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001966 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001967 .suite = {
1968 .hash = {
1969 .vecs = hmac_sha512_tv_template,
1970 .count = HMAC_SHA512_TEST_VECTORS
1971 }
1972 }
1973 }, {
1974 .alg = "lrw(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001975 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001976 .suite = {
1977 .cipher = {
1978 .enc = {
1979 .vecs = aes_lrw_enc_tv_template,
1980 .count = AES_LRW_ENC_TEST_VECTORS
1981 },
1982 .dec = {
1983 .vecs = aes_lrw_dec_tv_template,
1984 .count = AES_LRW_DEC_TEST_VECTORS
1985 }
1986 }
1987 }
1988 }, {
1989 .alg = "lzo",
1990 .test = alg_test_comp,
1991 .suite = {
1992 .comp = {
1993 .comp = {
1994 .vecs = lzo_comp_tv_template,
1995 .count = LZO_COMP_TEST_VECTORS
1996 },
1997 .decomp = {
1998 .vecs = lzo_decomp_tv_template,
1999 .count = LZO_DECOMP_TEST_VECTORS
2000 }
2001 }
2002 }
2003 }, {
2004 .alg = "md4",
2005 .test = alg_test_hash,
2006 .suite = {
2007 .hash = {
2008 .vecs = md4_tv_template,
2009 .count = MD4_TEST_VECTORS
2010 }
2011 }
2012 }, {
2013 .alg = "md5",
2014 .test = alg_test_hash,
2015 .suite = {
2016 .hash = {
2017 .vecs = md5_tv_template,
2018 .count = MD5_TEST_VECTORS
2019 }
2020 }
2021 }, {
2022 .alg = "michael_mic",
2023 .test = alg_test_hash,
2024 .suite = {
2025 .hash = {
2026 .vecs = michael_mic_tv_template,
2027 .count = MICHAEL_MIC_TEST_VECTORS
2028 }
2029 }
2030 }, {
2031 .alg = "pcbc(fcrypt)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002032 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002033 .suite = {
2034 .cipher = {
2035 .enc = {
2036 .vecs = fcrypt_pcbc_enc_tv_template,
2037 .count = FCRYPT_ENC_TEST_VECTORS
2038 },
2039 .dec = {
2040 .vecs = fcrypt_pcbc_dec_tv_template,
2041 .count = FCRYPT_DEC_TEST_VECTORS
2042 }
2043 }
2044 }
2045 }, {
2046 .alg = "rfc3686(ctr(aes))",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002047 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002048 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002049 .suite = {
2050 .cipher = {
2051 .enc = {
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08002052 .vecs = aes_ctr_rfc3686_enc_tv_template,
2053 .count = AES_CTR_3686_ENC_TEST_VECTORS
Herbert Xuda7f0332008-07-31 17:08:25 +08002054 },
2055 .dec = {
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08002056 .vecs = aes_ctr_rfc3686_dec_tv_template,
2057 .count = AES_CTR_3686_DEC_TEST_VECTORS
Herbert Xuda7f0332008-07-31 17:08:25 +08002058 }
2059 }
2060 }
2061 }, {
Jarod Wilson5d667322009-05-04 19:23:40 +08002062 .alg = "rfc4309(ccm(aes))",
2063 .test = alg_test_aead,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002064 .fips_allowed = 1,
Jarod Wilson5d667322009-05-04 19:23:40 +08002065 .suite = {
2066 .aead = {
2067 .enc = {
2068 .vecs = aes_ccm_rfc4309_enc_tv_template,
2069 .count = AES_CCM_4309_ENC_TEST_VECTORS
2070 },
2071 .dec = {
2072 .vecs = aes_ccm_rfc4309_dec_tv_template,
2073 .count = AES_CCM_4309_DEC_TEST_VECTORS
2074 }
2075 }
2076 }
2077 }, {
Herbert Xuda7f0332008-07-31 17:08:25 +08002078 .alg = "rmd128",
2079 .test = alg_test_hash,
2080 .suite = {
2081 .hash = {
2082 .vecs = rmd128_tv_template,
2083 .count = RMD128_TEST_VECTORS
2084 }
2085 }
2086 }, {
2087 .alg = "rmd160",
2088 .test = alg_test_hash,
2089 .suite = {
2090 .hash = {
2091 .vecs = rmd160_tv_template,
2092 .count = RMD160_TEST_VECTORS
2093 }
2094 }
2095 }, {
2096 .alg = "rmd256",
2097 .test = alg_test_hash,
2098 .suite = {
2099 .hash = {
2100 .vecs = rmd256_tv_template,
2101 .count = RMD256_TEST_VECTORS
2102 }
2103 }
2104 }, {
2105 .alg = "rmd320",
2106 .test = alg_test_hash,
2107 .suite = {
2108 .hash = {
2109 .vecs = rmd320_tv_template,
2110 .count = RMD320_TEST_VECTORS
2111 }
2112 }
2113 }, {
2114 .alg = "salsa20",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002115 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002116 .suite = {
2117 .cipher = {
2118 .enc = {
2119 .vecs = salsa20_stream_enc_tv_template,
2120 .count = SALSA20_STREAM_ENC_TEST_VECTORS
2121 }
2122 }
2123 }
2124 }, {
2125 .alg = "sha1",
2126 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002127 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002128 .suite = {
2129 .hash = {
2130 .vecs = sha1_tv_template,
2131 .count = SHA1_TEST_VECTORS
2132 }
2133 }
2134 }, {
2135 .alg = "sha224",
2136 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002137 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002138 .suite = {
2139 .hash = {
2140 .vecs = sha224_tv_template,
2141 .count = SHA224_TEST_VECTORS
2142 }
2143 }
2144 }, {
2145 .alg = "sha256",
2146 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002147 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002148 .suite = {
2149 .hash = {
2150 .vecs = sha256_tv_template,
2151 .count = SHA256_TEST_VECTORS
2152 }
2153 }
2154 }, {
2155 .alg = "sha384",
2156 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002157 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002158 .suite = {
2159 .hash = {
2160 .vecs = sha384_tv_template,
2161 .count = SHA384_TEST_VECTORS
2162 }
2163 }
2164 }, {
2165 .alg = "sha512",
2166 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002167 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002168 .suite = {
2169 .hash = {
2170 .vecs = sha512_tv_template,
2171 .count = SHA512_TEST_VECTORS
2172 }
2173 }
2174 }, {
2175 .alg = "tgr128",
2176 .test = alg_test_hash,
2177 .suite = {
2178 .hash = {
2179 .vecs = tgr128_tv_template,
2180 .count = TGR128_TEST_VECTORS
2181 }
2182 }
2183 }, {
2184 .alg = "tgr160",
2185 .test = alg_test_hash,
2186 .suite = {
2187 .hash = {
2188 .vecs = tgr160_tv_template,
2189 .count = TGR160_TEST_VECTORS
2190 }
2191 }
2192 }, {
2193 .alg = "tgr192",
2194 .test = alg_test_hash,
2195 .suite = {
2196 .hash = {
2197 .vecs = tgr192_tv_template,
2198 .count = TGR192_TEST_VECTORS
2199 }
2200 }
2201 }, {
2202 .alg = "wp256",
2203 .test = alg_test_hash,
2204 .suite = {
2205 .hash = {
2206 .vecs = wp256_tv_template,
2207 .count = WP256_TEST_VECTORS
2208 }
2209 }
2210 }, {
2211 .alg = "wp384",
2212 .test = alg_test_hash,
2213 .suite = {
2214 .hash = {
2215 .vecs = wp384_tv_template,
2216 .count = WP384_TEST_VECTORS
2217 }
2218 }
2219 }, {
2220 .alg = "wp512",
2221 .test = alg_test_hash,
2222 .suite = {
2223 .hash = {
2224 .vecs = wp512_tv_template,
2225 .count = WP512_TEST_VECTORS
2226 }
2227 }
2228 }, {
2229 .alg = "xcbc(aes)",
2230 .test = alg_test_hash,
2231 .suite = {
2232 .hash = {
2233 .vecs = aes_xcbc128_tv_template,
2234 .count = XCBC_AES_TEST_VECTORS
2235 }
2236 }
2237 }, {
2238 .alg = "xts(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002239 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002240 .suite = {
2241 .cipher = {
2242 .enc = {
2243 .vecs = aes_xts_enc_tv_template,
2244 .count = AES_XTS_ENC_TEST_VECTORS
2245 },
2246 .dec = {
2247 .vecs = aes_xts_dec_tv_template,
2248 .count = AES_XTS_DEC_TEST_VECTORS
2249 }
2250 }
2251 }
Geert Uytterhoeven0c01aed2009-03-04 15:42:15 +08002252 }, {
2253 .alg = "zlib",
2254 .test = alg_test_pcomp,
2255 .suite = {
2256 .pcomp = {
2257 .comp = {
2258 .vecs = zlib_comp_tv_template,
2259 .count = ZLIB_COMP_TEST_VECTORS
2260 },
2261 .decomp = {
2262 .vecs = zlib_decomp_tv_template,
2263 .count = ZLIB_DECOMP_TEST_VECTORS
2264 }
2265 }
2266 }
Herbert Xuda7f0332008-07-31 17:08:25 +08002267 }
2268};
2269
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002270static int alg_find_test(const char *alg)
Herbert Xuda7f0332008-07-31 17:08:25 +08002271{
2272 int start = 0;
2273 int end = ARRAY_SIZE(alg_test_descs);
2274
2275 while (start < end) {
2276 int i = (start + end) / 2;
2277 int diff = strcmp(alg_test_descs[i].alg, alg);
2278
2279 if (diff > 0) {
2280 end = i;
2281 continue;
2282 }
2283
2284 if (diff < 0) {
2285 start = i + 1;
2286 continue;
2287 }
2288
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002289 return i;
Herbert Xuda7f0332008-07-31 17:08:25 +08002290 }
2291
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002292 return -1;
2293}
2294
2295int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
2296{
2297 int i;
Neil Hormand12d6b62008-10-12 20:36:51 +08002298 int rc;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002299
2300 if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
2301 char nalg[CRYPTO_MAX_ALG_NAME];
2302
2303 if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
2304 sizeof(nalg))
2305 return -ENAMETOOLONG;
2306
2307 i = alg_find_test(nalg);
2308 if (i < 0)
2309 goto notest;
2310
Jarod Wilson941fb322009-05-04 19:49:23 +08002311 rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
2312 goto test_done;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002313 }
2314
2315 i = alg_find_test(alg);
2316 if (i < 0)
2317 goto notest;
2318
Neil Hormand12d6b62008-10-12 20:36:51 +08002319 rc = alg_test_descs[i].test(alg_test_descs + i, driver,
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002320 type, mask);
Jarod Wilson941fb322009-05-04 19:49:23 +08002321test_done:
Neil Hormand12d6b62008-10-12 20:36:51 +08002322 if (fips_enabled && rc)
2323 panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
2324
Jarod Wilson29ecd4a2009-05-04 19:51:17 +08002325 if (fips_enabled && !rc)
2326 printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
2327 driver, alg);
2328
Neil Hormand12d6b62008-10-12 20:36:51 +08002329 return rc;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002330
2331notest:
Herbert Xuda7f0332008-07-31 17:08:25 +08002332 printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
2333 return 0;
2334}
2335EXPORT_SYMBOL_GPL(alg_test);