blob: 376ea88158b97502795be796d0b788b6b4b23d51 [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];
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001005 int res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001006
1007 for (i = 0; i < ctcount; i++) {
1008 struct comp_request req;
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001009 unsigned int produced = 0;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001010
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001011 res = crypto_compress_setup(tfm, ctemplate[i].params,
1012 ctemplate[i].paramsize);
1013 if (res) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001014 pr_err("alg: pcomp: compression setup failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001015 "%d for %s: error=%d\n", i + 1, algo, res);
1016 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001017 }
1018
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001019 res = crypto_compress_init(tfm);
1020 if (res) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001021 pr_err("alg: pcomp: compression init failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001022 "%d for %s: error=%d\n", i + 1, algo, res);
1023 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001024 }
1025
1026 memset(result, 0, sizeof(result));
1027
1028 req.next_in = ctemplate[i].input;
1029 req.avail_in = ctemplate[i].inlen / 2;
1030 req.next_out = result;
1031 req.avail_out = ctemplate[i].outlen / 2;
1032
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001033 res = crypto_compress_update(tfm, &req);
1034 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001035 pr_err("alg: pcomp: compression update failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001036 "%d for %s: error=%d\n", i + 1, algo, res);
1037 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001038 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001039 if (res > 0)
1040 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001041
1042 /* Add remaining input data */
1043 req.avail_in += (ctemplate[i].inlen + 1) / 2;
1044
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001045 res = crypto_compress_update(tfm, &req);
1046 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001047 pr_err("alg: pcomp: compression update failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001048 "%d for %s: error=%d\n", i + 1, algo, res);
1049 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001050 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001051 if (res > 0)
1052 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001053
1054 /* Provide remaining output space */
1055 req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
1056
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001057 res = crypto_compress_final(tfm, &req);
1058 if (res < 0) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001059 pr_err("alg: pcomp: compression final failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001060 "%d for %s: error=%d\n", i + 1, algo, res);
1061 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001062 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001063 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001064
1065 if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
1066 pr_err("alg: comp: Compression test %d failed for %s: "
1067 "output len = %d (expected %d)\n", i + 1, algo,
1068 COMP_BUF_SIZE - req.avail_out,
1069 ctemplate[i].outlen);
1070 return -EINVAL;
1071 }
1072
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001073 if (produced != ctemplate[i].outlen) {
1074 pr_err("alg: comp: Compression test %d failed for %s: "
1075 "returned len = %u (expected %d)\n", i + 1,
1076 algo, produced, ctemplate[i].outlen);
1077 return -EINVAL;
1078 }
1079
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001080 if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
1081 pr_err("alg: pcomp: Compression test %d failed for "
1082 "%s\n", i + 1, algo);
1083 hexdump(result, ctemplate[i].outlen);
1084 return -EINVAL;
1085 }
1086 }
1087
1088 for (i = 0; i < dtcount; i++) {
1089 struct comp_request req;
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001090 unsigned int produced = 0;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001091
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001092 res = crypto_decompress_setup(tfm, dtemplate[i].params,
1093 dtemplate[i].paramsize);
1094 if (res) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001095 pr_err("alg: pcomp: decompression setup failed on "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001096 "test %d for %s: error=%d\n", i + 1, algo, res);
1097 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001098 }
1099
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001100 res = crypto_decompress_init(tfm);
1101 if (res) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001102 pr_err("alg: pcomp: decompression init failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001103 "%d for %s: error=%d\n", i + 1, algo, res);
1104 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001105 }
1106
1107 memset(result, 0, sizeof(result));
1108
1109 req.next_in = dtemplate[i].input;
1110 req.avail_in = dtemplate[i].inlen / 2;
1111 req.next_out = result;
1112 req.avail_out = dtemplate[i].outlen / 2;
1113
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001114 res = crypto_decompress_update(tfm, &req);
1115 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001116 pr_err("alg: pcomp: decompression update failed on "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001117 "test %d for %s: error=%d\n", i + 1, algo, res);
1118 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001119 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001120 if (res > 0)
1121 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001122
1123 /* Add remaining input data */
1124 req.avail_in += (dtemplate[i].inlen + 1) / 2;
1125
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001126 res = crypto_decompress_update(tfm, &req);
1127 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001128 pr_err("alg: pcomp: decompression update failed on "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001129 "test %d for %s: error=%d\n", i + 1, algo, res);
1130 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001131 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001132 if (res > 0)
1133 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001134
1135 /* Provide remaining output space */
1136 req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
1137
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001138 res = crypto_decompress_final(tfm, &req);
1139 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001140 pr_err("alg: pcomp: decompression final failed on "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001141 "test %d for %s: error=%d\n", i + 1, algo, res);
1142 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001143 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001144 if (res > 0)
1145 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001146
1147 if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
1148 pr_err("alg: comp: Decompression test %d failed for "
1149 "%s: output len = %d (expected %d)\n", i + 1,
1150 algo, COMP_BUF_SIZE - req.avail_out,
1151 dtemplate[i].outlen);
1152 return -EINVAL;
1153 }
1154
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001155 if (produced != dtemplate[i].outlen) {
1156 pr_err("alg: comp: Decompression test %d failed for "
1157 "%s: returned len = %u (expected %d)\n", i + 1,
1158 algo, produced, dtemplate[i].outlen);
1159 return -EINVAL;
1160 }
1161
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001162 if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
1163 pr_err("alg: pcomp: Decompression test %d failed for "
1164 "%s\n", i + 1, algo);
1165 hexdump(result, dtemplate[i].outlen);
1166 return -EINVAL;
1167 }
1168 }
1169
1170 return 0;
1171}
1172
Jarod Wilson7647d6c2009-05-04 19:44:50 +08001173
1174static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
1175 unsigned int tcount)
1176{
1177 const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
1178 int err, i, j, seedsize;
1179 u8 *seed;
1180 char result[32];
1181
1182 seedsize = crypto_rng_seedsize(tfm);
1183
1184 seed = kmalloc(seedsize, GFP_KERNEL);
1185 if (!seed) {
1186 printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
1187 "for %s\n", algo);
1188 return -ENOMEM;
1189 }
1190
1191 for (i = 0; i < tcount; i++) {
1192 memset(result, 0, 32);
1193
1194 memcpy(seed, template[i].v, template[i].vlen);
1195 memcpy(seed + template[i].vlen, template[i].key,
1196 template[i].klen);
1197 memcpy(seed + template[i].vlen + template[i].klen,
1198 template[i].dt, template[i].dtlen);
1199
1200 err = crypto_rng_reset(tfm, seed, seedsize);
1201 if (err) {
1202 printk(KERN_ERR "alg: cprng: Failed to reset rng "
1203 "for %s\n", algo);
1204 goto out;
1205 }
1206
1207 for (j = 0; j < template[i].loops; j++) {
1208 err = crypto_rng_get_bytes(tfm, result,
1209 template[i].rlen);
1210 if (err != template[i].rlen) {
1211 printk(KERN_ERR "alg: cprng: Failed to obtain "
1212 "the correct amount of random data for "
1213 "%s (requested %d, got %d)\n", algo,
1214 template[i].rlen, err);
1215 goto out;
1216 }
1217 }
1218
1219 err = memcmp(result, template[i].result,
1220 template[i].rlen);
1221 if (err) {
1222 printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
1223 i, algo);
1224 hexdump(result, template[i].rlen);
1225 err = -EINVAL;
1226 goto out;
1227 }
1228 }
1229
1230out:
1231 kfree(seed);
1232 return err;
1233}
1234
Herbert Xuda7f0332008-07-31 17:08:25 +08001235static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
1236 u32 type, u32 mask)
1237{
1238 struct crypto_aead *tfm;
1239 int err = 0;
1240
1241 tfm = crypto_alloc_aead(driver, type, mask);
1242 if (IS_ERR(tfm)) {
1243 printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
1244 "%ld\n", driver, PTR_ERR(tfm));
1245 return PTR_ERR(tfm);
1246 }
1247
1248 if (desc->suite.aead.enc.vecs) {
1249 err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
1250 desc->suite.aead.enc.count);
1251 if (err)
1252 goto out;
1253 }
1254
1255 if (!err && desc->suite.aead.dec.vecs)
1256 err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
1257 desc->suite.aead.dec.count);
1258
1259out:
1260 crypto_free_aead(tfm);
1261 return err;
1262}
1263
1264static int alg_test_cipher(const struct alg_test_desc *desc,
1265 const char *driver, u32 type, u32 mask)
1266{
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001267 struct crypto_cipher *tfm;
Herbert Xuda7f0332008-07-31 17:08:25 +08001268 int err = 0;
1269
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001270 tfm = crypto_alloc_cipher(driver, type, mask);
Herbert Xuda7f0332008-07-31 17:08:25 +08001271 if (IS_ERR(tfm)) {
1272 printk(KERN_ERR "alg: cipher: Failed to load transform for "
1273 "%s: %ld\n", driver, PTR_ERR(tfm));
1274 return PTR_ERR(tfm);
1275 }
1276
1277 if (desc->suite.cipher.enc.vecs) {
1278 err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
1279 desc->suite.cipher.enc.count);
1280 if (err)
1281 goto out;
1282 }
1283
1284 if (desc->suite.cipher.dec.vecs)
1285 err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
1286 desc->suite.cipher.dec.count);
1287
1288out:
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001289 crypto_free_cipher(tfm);
1290 return err;
1291}
1292
1293static int alg_test_skcipher(const struct alg_test_desc *desc,
1294 const char *driver, u32 type, u32 mask)
1295{
1296 struct crypto_ablkcipher *tfm;
1297 int err = 0;
1298
1299 tfm = crypto_alloc_ablkcipher(driver, type, mask);
1300 if (IS_ERR(tfm)) {
1301 printk(KERN_ERR "alg: skcipher: Failed to load transform for "
1302 "%s: %ld\n", driver, PTR_ERR(tfm));
1303 return PTR_ERR(tfm);
1304 }
1305
1306 if (desc->suite.cipher.enc.vecs) {
1307 err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
1308 desc->suite.cipher.enc.count);
1309 if (err)
1310 goto out;
1311 }
1312
1313 if (desc->suite.cipher.dec.vecs)
1314 err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
1315 desc->suite.cipher.dec.count);
1316
1317out:
Herbert Xuda7f0332008-07-31 17:08:25 +08001318 crypto_free_ablkcipher(tfm);
1319 return err;
1320}
1321
1322static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
1323 u32 type, u32 mask)
1324{
1325 struct crypto_comp *tfm;
1326 int err;
1327
1328 tfm = crypto_alloc_comp(driver, type, mask);
1329 if (IS_ERR(tfm)) {
1330 printk(KERN_ERR "alg: comp: Failed to load transform for %s: "
1331 "%ld\n", driver, PTR_ERR(tfm));
1332 return PTR_ERR(tfm);
1333 }
1334
1335 err = test_comp(tfm, desc->suite.comp.comp.vecs,
1336 desc->suite.comp.decomp.vecs,
1337 desc->suite.comp.comp.count,
1338 desc->suite.comp.decomp.count);
1339
1340 crypto_free_comp(tfm);
1341 return err;
1342}
1343
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001344static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
1345 u32 type, u32 mask)
1346{
1347 struct crypto_pcomp *tfm;
1348 int err;
1349
1350 tfm = crypto_alloc_pcomp(driver, type, mask);
1351 if (IS_ERR(tfm)) {
1352 pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
1353 driver, PTR_ERR(tfm));
1354 return PTR_ERR(tfm);
1355 }
1356
1357 err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
1358 desc->suite.pcomp.decomp.vecs,
1359 desc->suite.pcomp.comp.count,
1360 desc->suite.pcomp.decomp.count);
1361
1362 crypto_free_pcomp(tfm);
1363 return err;
1364}
1365
Herbert Xuda7f0332008-07-31 17:08:25 +08001366static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
1367 u32 type, u32 mask)
1368{
1369 struct crypto_ahash *tfm;
1370 int err;
1371
1372 tfm = crypto_alloc_ahash(driver, type, mask);
1373 if (IS_ERR(tfm)) {
1374 printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
1375 "%ld\n", driver, PTR_ERR(tfm));
1376 return PTR_ERR(tfm);
1377 }
1378
1379 err = test_hash(tfm, desc->suite.hash.vecs, desc->suite.hash.count);
1380
1381 crypto_free_ahash(tfm);
1382 return err;
1383}
1384
Herbert Xu8e3ee852008-11-07 14:58:52 +08001385static int alg_test_crc32c(const struct alg_test_desc *desc,
1386 const char *driver, u32 type, u32 mask)
1387{
1388 struct crypto_shash *tfm;
1389 u32 val;
1390 int err;
1391
1392 err = alg_test_hash(desc, driver, type, mask);
1393 if (err)
1394 goto out;
1395
1396 tfm = crypto_alloc_shash(driver, type, mask);
1397 if (IS_ERR(tfm)) {
1398 printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
1399 "%ld\n", driver, PTR_ERR(tfm));
1400 err = PTR_ERR(tfm);
1401 goto out;
1402 }
1403
1404 do {
1405 struct {
1406 struct shash_desc shash;
1407 char ctx[crypto_shash_descsize(tfm)];
1408 } sdesc;
1409
1410 sdesc.shash.tfm = tfm;
1411 sdesc.shash.flags = 0;
1412
1413 *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
1414 err = crypto_shash_final(&sdesc.shash, (u8 *)&val);
1415 if (err) {
1416 printk(KERN_ERR "alg: crc32c: Operation failed for "
1417 "%s: %d\n", driver, err);
1418 break;
1419 }
1420
1421 if (val != ~420553207) {
1422 printk(KERN_ERR "alg: crc32c: Test failed for %s: "
1423 "%d\n", driver, val);
1424 err = -EINVAL;
1425 }
1426 } while (0);
1427
1428 crypto_free_shash(tfm);
1429
1430out:
1431 return err;
1432}
1433
Jarod Wilson7647d6c2009-05-04 19:44:50 +08001434static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
1435 u32 type, u32 mask)
1436{
1437 struct crypto_rng *rng;
1438 int err;
1439
1440 rng = crypto_alloc_rng(driver, type, mask);
1441 if (IS_ERR(rng)) {
1442 printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
1443 "%ld\n", driver, PTR_ERR(rng));
1444 return PTR_ERR(rng);
1445 }
1446
1447 err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
1448
1449 crypto_free_rng(rng);
1450
1451 return err;
1452}
1453
Herbert Xuda7f0332008-07-31 17:08:25 +08001454/* Please keep this list sorted by algorithm name. */
1455static const struct alg_test_desc alg_test_descs[] = {
1456 {
Jarod Wilsone08ca2d2009-05-04 19:46:29 +08001457 .alg = "ansi_cprng",
1458 .test = alg_test_cprng,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001459 .fips_allowed = 1,
Jarod Wilsone08ca2d2009-05-04 19:46:29 +08001460 .suite = {
1461 .cprng = {
1462 .vecs = ansi_cprng_aes_tv_template,
1463 .count = ANSI_CPRNG_AES_TEST_VECTORS
1464 }
1465 }
1466 }, {
Herbert Xuda7f0332008-07-31 17:08:25 +08001467 .alg = "cbc(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001468 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001469 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001470 .suite = {
1471 .cipher = {
1472 .enc = {
1473 .vecs = aes_cbc_enc_tv_template,
1474 .count = AES_CBC_ENC_TEST_VECTORS
1475 },
1476 .dec = {
1477 .vecs = aes_cbc_dec_tv_template,
1478 .count = AES_CBC_DEC_TEST_VECTORS
1479 }
1480 }
1481 }
1482 }, {
1483 .alg = "cbc(anubis)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001484 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001485 .suite = {
1486 .cipher = {
1487 .enc = {
1488 .vecs = anubis_cbc_enc_tv_template,
1489 .count = ANUBIS_CBC_ENC_TEST_VECTORS
1490 },
1491 .dec = {
1492 .vecs = anubis_cbc_dec_tv_template,
1493 .count = ANUBIS_CBC_DEC_TEST_VECTORS
1494 }
1495 }
1496 }
1497 }, {
1498 .alg = "cbc(blowfish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001499 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001500 .suite = {
1501 .cipher = {
1502 .enc = {
1503 .vecs = bf_cbc_enc_tv_template,
1504 .count = BF_CBC_ENC_TEST_VECTORS
1505 },
1506 .dec = {
1507 .vecs = bf_cbc_dec_tv_template,
1508 .count = BF_CBC_DEC_TEST_VECTORS
1509 }
1510 }
1511 }
1512 }, {
1513 .alg = "cbc(camellia)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001514 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001515 .suite = {
1516 .cipher = {
1517 .enc = {
1518 .vecs = camellia_cbc_enc_tv_template,
1519 .count = CAMELLIA_CBC_ENC_TEST_VECTORS
1520 },
1521 .dec = {
1522 .vecs = camellia_cbc_dec_tv_template,
1523 .count = CAMELLIA_CBC_DEC_TEST_VECTORS
1524 }
1525 }
1526 }
1527 }, {
1528 .alg = "cbc(des)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001529 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001530 .suite = {
1531 .cipher = {
1532 .enc = {
1533 .vecs = des_cbc_enc_tv_template,
1534 .count = DES_CBC_ENC_TEST_VECTORS
1535 },
1536 .dec = {
1537 .vecs = des_cbc_dec_tv_template,
1538 .count = DES_CBC_DEC_TEST_VECTORS
1539 }
1540 }
1541 }
1542 }, {
1543 .alg = "cbc(des3_ede)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001544 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001545 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001546 .suite = {
1547 .cipher = {
1548 .enc = {
1549 .vecs = des3_ede_cbc_enc_tv_template,
1550 .count = DES3_EDE_CBC_ENC_TEST_VECTORS
1551 },
1552 .dec = {
1553 .vecs = des3_ede_cbc_dec_tv_template,
1554 .count = DES3_EDE_CBC_DEC_TEST_VECTORS
1555 }
1556 }
1557 }
1558 }, {
1559 .alg = "cbc(twofish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001560 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001561 .suite = {
1562 .cipher = {
1563 .enc = {
1564 .vecs = tf_cbc_enc_tv_template,
1565 .count = TF_CBC_ENC_TEST_VECTORS
1566 },
1567 .dec = {
1568 .vecs = tf_cbc_dec_tv_template,
1569 .count = TF_CBC_DEC_TEST_VECTORS
1570 }
1571 }
1572 }
1573 }, {
1574 .alg = "ccm(aes)",
1575 .test = alg_test_aead,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001576 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001577 .suite = {
1578 .aead = {
1579 .enc = {
1580 .vecs = aes_ccm_enc_tv_template,
1581 .count = AES_CCM_ENC_TEST_VECTORS
1582 },
1583 .dec = {
1584 .vecs = aes_ccm_dec_tv_template,
1585 .count = AES_CCM_DEC_TEST_VECTORS
1586 }
1587 }
1588 }
1589 }, {
1590 .alg = "crc32c",
Herbert Xu8e3ee852008-11-07 14:58:52 +08001591 .test = alg_test_crc32c,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001592 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001593 .suite = {
1594 .hash = {
1595 .vecs = crc32c_tv_template,
1596 .count = CRC32C_TEST_VECTORS
1597 }
1598 }
1599 }, {
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08001600 .alg = "ctr(aes)",
1601 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001602 .fips_allowed = 1,
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08001603 .suite = {
1604 .cipher = {
1605 .enc = {
1606 .vecs = aes_ctr_enc_tv_template,
1607 .count = AES_CTR_ENC_TEST_VECTORS
1608 },
1609 .dec = {
1610 .vecs = aes_ctr_dec_tv_template,
1611 .count = AES_CTR_DEC_TEST_VECTORS
1612 }
1613 }
1614 }
1615 }, {
Herbert Xuda7f0332008-07-31 17:08:25 +08001616 .alg = "cts(cbc(aes))",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001617 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001618 .suite = {
1619 .cipher = {
1620 .enc = {
1621 .vecs = cts_mode_enc_tv_template,
1622 .count = CTS_MODE_ENC_TEST_VECTORS
1623 },
1624 .dec = {
1625 .vecs = cts_mode_dec_tv_template,
1626 .count = CTS_MODE_DEC_TEST_VECTORS
1627 }
1628 }
1629 }
1630 }, {
1631 .alg = "deflate",
1632 .test = alg_test_comp,
1633 .suite = {
1634 .comp = {
1635 .comp = {
1636 .vecs = deflate_comp_tv_template,
1637 .count = DEFLATE_COMP_TEST_VECTORS
1638 },
1639 .decomp = {
1640 .vecs = deflate_decomp_tv_template,
1641 .count = DEFLATE_DECOMP_TEST_VECTORS
1642 }
1643 }
1644 }
1645 }, {
1646 .alg = "ecb(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001647 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001648 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001649 .suite = {
1650 .cipher = {
1651 .enc = {
1652 .vecs = aes_enc_tv_template,
1653 .count = AES_ENC_TEST_VECTORS
1654 },
1655 .dec = {
1656 .vecs = aes_dec_tv_template,
1657 .count = AES_DEC_TEST_VECTORS
1658 }
1659 }
1660 }
1661 }, {
1662 .alg = "ecb(anubis)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001663 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001664 .suite = {
1665 .cipher = {
1666 .enc = {
1667 .vecs = anubis_enc_tv_template,
1668 .count = ANUBIS_ENC_TEST_VECTORS
1669 },
1670 .dec = {
1671 .vecs = anubis_dec_tv_template,
1672 .count = ANUBIS_DEC_TEST_VECTORS
1673 }
1674 }
1675 }
1676 }, {
1677 .alg = "ecb(arc4)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001678 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001679 .suite = {
1680 .cipher = {
1681 .enc = {
1682 .vecs = arc4_enc_tv_template,
1683 .count = ARC4_ENC_TEST_VECTORS
1684 },
1685 .dec = {
1686 .vecs = arc4_dec_tv_template,
1687 .count = ARC4_DEC_TEST_VECTORS
1688 }
1689 }
1690 }
1691 }, {
1692 .alg = "ecb(blowfish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001693 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001694 .suite = {
1695 .cipher = {
1696 .enc = {
1697 .vecs = bf_enc_tv_template,
1698 .count = BF_ENC_TEST_VECTORS
1699 },
1700 .dec = {
1701 .vecs = bf_dec_tv_template,
1702 .count = BF_DEC_TEST_VECTORS
1703 }
1704 }
1705 }
1706 }, {
1707 .alg = "ecb(camellia)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001708 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001709 .suite = {
1710 .cipher = {
1711 .enc = {
1712 .vecs = camellia_enc_tv_template,
1713 .count = CAMELLIA_ENC_TEST_VECTORS
1714 },
1715 .dec = {
1716 .vecs = camellia_dec_tv_template,
1717 .count = CAMELLIA_DEC_TEST_VECTORS
1718 }
1719 }
1720 }
1721 }, {
1722 .alg = "ecb(cast5)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001723 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001724 .suite = {
1725 .cipher = {
1726 .enc = {
1727 .vecs = cast5_enc_tv_template,
1728 .count = CAST5_ENC_TEST_VECTORS
1729 },
1730 .dec = {
1731 .vecs = cast5_dec_tv_template,
1732 .count = CAST5_DEC_TEST_VECTORS
1733 }
1734 }
1735 }
1736 }, {
1737 .alg = "ecb(cast6)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001738 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001739 .suite = {
1740 .cipher = {
1741 .enc = {
1742 .vecs = cast6_enc_tv_template,
1743 .count = CAST6_ENC_TEST_VECTORS
1744 },
1745 .dec = {
1746 .vecs = cast6_dec_tv_template,
1747 .count = CAST6_DEC_TEST_VECTORS
1748 }
1749 }
1750 }
1751 }, {
1752 .alg = "ecb(des)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001753 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001754 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001755 .suite = {
1756 .cipher = {
1757 .enc = {
1758 .vecs = des_enc_tv_template,
1759 .count = DES_ENC_TEST_VECTORS
1760 },
1761 .dec = {
1762 .vecs = des_dec_tv_template,
1763 .count = DES_DEC_TEST_VECTORS
1764 }
1765 }
1766 }
1767 }, {
1768 .alg = "ecb(des3_ede)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001769 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001770 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001771 .suite = {
1772 .cipher = {
1773 .enc = {
1774 .vecs = des3_ede_enc_tv_template,
1775 .count = DES3_EDE_ENC_TEST_VECTORS
1776 },
1777 .dec = {
1778 .vecs = des3_ede_dec_tv_template,
1779 .count = DES3_EDE_DEC_TEST_VECTORS
1780 }
1781 }
1782 }
1783 }, {
1784 .alg = "ecb(khazad)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001785 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001786 .suite = {
1787 .cipher = {
1788 .enc = {
1789 .vecs = khazad_enc_tv_template,
1790 .count = KHAZAD_ENC_TEST_VECTORS
1791 },
1792 .dec = {
1793 .vecs = khazad_dec_tv_template,
1794 .count = KHAZAD_DEC_TEST_VECTORS
1795 }
1796 }
1797 }
1798 }, {
1799 .alg = "ecb(seed)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001800 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001801 .suite = {
1802 .cipher = {
1803 .enc = {
1804 .vecs = seed_enc_tv_template,
1805 .count = SEED_ENC_TEST_VECTORS
1806 },
1807 .dec = {
1808 .vecs = seed_dec_tv_template,
1809 .count = SEED_DEC_TEST_VECTORS
1810 }
1811 }
1812 }
1813 }, {
1814 .alg = "ecb(serpent)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001815 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001816 .suite = {
1817 .cipher = {
1818 .enc = {
1819 .vecs = serpent_enc_tv_template,
1820 .count = SERPENT_ENC_TEST_VECTORS
1821 },
1822 .dec = {
1823 .vecs = serpent_dec_tv_template,
1824 .count = SERPENT_DEC_TEST_VECTORS
1825 }
1826 }
1827 }
1828 }, {
1829 .alg = "ecb(tea)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001830 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001831 .suite = {
1832 .cipher = {
1833 .enc = {
1834 .vecs = tea_enc_tv_template,
1835 .count = TEA_ENC_TEST_VECTORS
1836 },
1837 .dec = {
1838 .vecs = tea_dec_tv_template,
1839 .count = TEA_DEC_TEST_VECTORS
1840 }
1841 }
1842 }
1843 }, {
1844 .alg = "ecb(tnepres)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001845 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001846 .suite = {
1847 .cipher = {
1848 .enc = {
1849 .vecs = tnepres_enc_tv_template,
1850 .count = TNEPRES_ENC_TEST_VECTORS
1851 },
1852 .dec = {
1853 .vecs = tnepres_dec_tv_template,
1854 .count = TNEPRES_DEC_TEST_VECTORS
1855 }
1856 }
1857 }
1858 }, {
1859 .alg = "ecb(twofish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001860 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001861 .suite = {
1862 .cipher = {
1863 .enc = {
1864 .vecs = tf_enc_tv_template,
1865 .count = TF_ENC_TEST_VECTORS
1866 },
1867 .dec = {
1868 .vecs = tf_dec_tv_template,
1869 .count = TF_DEC_TEST_VECTORS
1870 }
1871 }
1872 }
1873 }, {
1874 .alg = "ecb(xeta)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001875 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001876 .suite = {
1877 .cipher = {
1878 .enc = {
1879 .vecs = xeta_enc_tv_template,
1880 .count = XETA_ENC_TEST_VECTORS
1881 },
1882 .dec = {
1883 .vecs = xeta_dec_tv_template,
1884 .count = XETA_DEC_TEST_VECTORS
1885 }
1886 }
1887 }
1888 }, {
1889 .alg = "ecb(xtea)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001890 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001891 .suite = {
1892 .cipher = {
1893 .enc = {
1894 .vecs = xtea_enc_tv_template,
1895 .count = XTEA_ENC_TEST_VECTORS
1896 },
1897 .dec = {
1898 .vecs = xtea_dec_tv_template,
1899 .count = XTEA_DEC_TEST_VECTORS
1900 }
1901 }
1902 }
1903 }, {
1904 .alg = "gcm(aes)",
1905 .test = alg_test_aead,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001906 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001907 .suite = {
1908 .aead = {
1909 .enc = {
1910 .vecs = aes_gcm_enc_tv_template,
1911 .count = AES_GCM_ENC_TEST_VECTORS
1912 },
1913 .dec = {
1914 .vecs = aes_gcm_dec_tv_template,
1915 .count = AES_GCM_DEC_TEST_VECTORS
1916 }
1917 }
1918 }
1919 }, {
1920 .alg = "hmac(md5)",
1921 .test = alg_test_hash,
1922 .suite = {
1923 .hash = {
1924 .vecs = hmac_md5_tv_template,
1925 .count = HMAC_MD5_TEST_VECTORS
1926 }
1927 }
1928 }, {
1929 .alg = "hmac(rmd128)",
1930 .test = alg_test_hash,
1931 .suite = {
1932 .hash = {
1933 .vecs = hmac_rmd128_tv_template,
1934 .count = HMAC_RMD128_TEST_VECTORS
1935 }
1936 }
1937 }, {
1938 .alg = "hmac(rmd160)",
1939 .test = alg_test_hash,
1940 .suite = {
1941 .hash = {
1942 .vecs = hmac_rmd160_tv_template,
1943 .count = HMAC_RMD160_TEST_VECTORS
1944 }
1945 }
1946 }, {
1947 .alg = "hmac(sha1)",
1948 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001949 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001950 .suite = {
1951 .hash = {
1952 .vecs = hmac_sha1_tv_template,
1953 .count = HMAC_SHA1_TEST_VECTORS
1954 }
1955 }
1956 }, {
1957 .alg = "hmac(sha224)",
1958 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001959 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001960 .suite = {
1961 .hash = {
1962 .vecs = hmac_sha224_tv_template,
1963 .count = HMAC_SHA224_TEST_VECTORS
1964 }
1965 }
1966 }, {
1967 .alg = "hmac(sha256)",
1968 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001969 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001970 .suite = {
1971 .hash = {
1972 .vecs = hmac_sha256_tv_template,
1973 .count = HMAC_SHA256_TEST_VECTORS
1974 }
1975 }
1976 }, {
1977 .alg = "hmac(sha384)",
1978 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001979 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001980 .suite = {
1981 .hash = {
1982 .vecs = hmac_sha384_tv_template,
1983 .count = HMAC_SHA384_TEST_VECTORS
1984 }
1985 }
1986 }, {
1987 .alg = "hmac(sha512)",
1988 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001989 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001990 .suite = {
1991 .hash = {
1992 .vecs = hmac_sha512_tv_template,
1993 .count = HMAC_SHA512_TEST_VECTORS
1994 }
1995 }
1996 }, {
1997 .alg = "lrw(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001998 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001999 .suite = {
2000 .cipher = {
2001 .enc = {
2002 .vecs = aes_lrw_enc_tv_template,
2003 .count = AES_LRW_ENC_TEST_VECTORS
2004 },
2005 .dec = {
2006 .vecs = aes_lrw_dec_tv_template,
2007 .count = AES_LRW_DEC_TEST_VECTORS
2008 }
2009 }
2010 }
2011 }, {
2012 .alg = "lzo",
2013 .test = alg_test_comp,
2014 .suite = {
2015 .comp = {
2016 .comp = {
2017 .vecs = lzo_comp_tv_template,
2018 .count = LZO_COMP_TEST_VECTORS
2019 },
2020 .decomp = {
2021 .vecs = lzo_decomp_tv_template,
2022 .count = LZO_DECOMP_TEST_VECTORS
2023 }
2024 }
2025 }
2026 }, {
2027 .alg = "md4",
2028 .test = alg_test_hash,
2029 .suite = {
2030 .hash = {
2031 .vecs = md4_tv_template,
2032 .count = MD4_TEST_VECTORS
2033 }
2034 }
2035 }, {
2036 .alg = "md5",
2037 .test = alg_test_hash,
2038 .suite = {
2039 .hash = {
2040 .vecs = md5_tv_template,
2041 .count = MD5_TEST_VECTORS
2042 }
2043 }
2044 }, {
2045 .alg = "michael_mic",
2046 .test = alg_test_hash,
2047 .suite = {
2048 .hash = {
2049 .vecs = michael_mic_tv_template,
2050 .count = MICHAEL_MIC_TEST_VECTORS
2051 }
2052 }
2053 }, {
2054 .alg = "pcbc(fcrypt)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002055 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002056 .suite = {
2057 .cipher = {
2058 .enc = {
2059 .vecs = fcrypt_pcbc_enc_tv_template,
2060 .count = FCRYPT_ENC_TEST_VECTORS
2061 },
2062 .dec = {
2063 .vecs = fcrypt_pcbc_dec_tv_template,
2064 .count = FCRYPT_DEC_TEST_VECTORS
2065 }
2066 }
2067 }
2068 }, {
2069 .alg = "rfc3686(ctr(aes))",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002070 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002071 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002072 .suite = {
2073 .cipher = {
2074 .enc = {
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08002075 .vecs = aes_ctr_rfc3686_enc_tv_template,
2076 .count = AES_CTR_3686_ENC_TEST_VECTORS
Herbert Xuda7f0332008-07-31 17:08:25 +08002077 },
2078 .dec = {
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08002079 .vecs = aes_ctr_rfc3686_dec_tv_template,
2080 .count = AES_CTR_3686_DEC_TEST_VECTORS
Herbert Xuda7f0332008-07-31 17:08:25 +08002081 }
2082 }
2083 }
2084 }, {
Jarod Wilson5d667322009-05-04 19:23:40 +08002085 .alg = "rfc4309(ccm(aes))",
2086 .test = alg_test_aead,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002087 .fips_allowed = 1,
Jarod Wilson5d667322009-05-04 19:23:40 +08002088 .suite = {
2089 .aead = {
2090 .enc = {
2091 .vecs = aes_ccm_rfc4309_enc_tv_template,
2092 .count = AES_CCM_4309_ENC_TEST_VECTORS
2093 },
2094 .dec = {
2095 .vecs = aes_ccm_rfc4309_dec_tv_template,
2096 .count = AES_CCM_4309_DEC_TEST_VECTORS
2097 }
2098 }
2099 }
2100 }, {
Herbert Xuda7f0332008-07-31 17:08:25 +08002101 .alg = "rmd128",
2102 .test = alg_test_hash,
2103 .suite = {
2104 .hash = {
2105 .vecs = rmd128_tv_template,
2106 .count = RMD128_TEST_VECTORS
2107 }
2108 }
2109 }, {
2110 .alg = "rmd160",
2111 .test = alg_test_hash,
2112 .suite = {
2113 .hash = {
2114 .vecs = rmd160_tv_template,
2115 .count = RMD160_TEST_VECTORS
2116 }
2117 }
2118 }, {
2119 .alg = "rmd256",
2120 .test = alg_test_hash,
2121 .suite = {
2122 .hash = {
2123 .vecs = rmd256_tv_template,
2124 .count = RMD256_TEST_VECTORS
2125 }
2126 }
2127 }, {
2128 .alg = "rmd320",
2129 .test = alg_test_hash,
2130 .suite = {
2131 .hash = {
2132 .vecs = rmd320_tv_template,
2133 .count = RMD320_TEST_VECTORS
2134 }
2135 }
2136 }, {
2137 .alg = "salsa20",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002138 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002139 .suite = {
2140 .cipher = {
2141 .enc = {
2142 .vecs = salsa20_stream_enc_tv_template,
2143 .count = SALSA20_STREAM_ENC_TEST_VECTORS
2144 }
2145 }
2146 }
2147 }, {
2148 .alg = "sha1",
2149 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002150 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002151 .suite = {
2152 .hash = {
2153 .vecs = sha1_tv_template,
2154 .count = SHA1_TEST_VECTORS
2155 }
2156 }
2157 }, {
2158 .alg = "sha224",
2159 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002160 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002161 .suite = {
2162 .hash = {
2163 .vecs = sha224_tv_template,
2164 .count = SHA224_TEST_VECTORS
2165 }
2166 }
2167 }, {
2168 .alg = "sha256",
2169 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002170 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002171 .suite = {
2172 .hash = {
2173 .vecs = sha256_tv_template,
2174 .count = SHA256_TEST_VECTORS
2175 }
2176 }
2177 }, {
2178 .alg = "sha384",
2179 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002180 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002181 .suite = {
2182 .hash = {
2183 .vecs = sha384_tv_template,
2184 .count = SHA384_TEST_VECTORS
2185 }
2186 }
2187 }, {
2188 .alg = "sha512",
2189 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002190 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002191 .suite = {
2192 .hash = {
2193 .vecs = sha512_tv_template,
2194 .count = SHA512_TEST_VECTORS
2195 }
2196 }
2197 }, {
2198 .alg = "tgr128",
2199 .test = alg_test_hash,
2200 .suite = {
2201 .hash = {
2202 .vecs = tgr128_tv_template,
2203 .count = TGR128_TEST_VECTORS
2204 }
2205 }
2206 }, {
2207 .alg = "tgr160",
2208 .test = alg_test_hash,
2209 .suite = {
2210 .hash = {
2211 .vecs = tgr160_tv_template,
2212 .count = TGR160_TEST_VECTORS
2213 }
2214 }
2215 }, {
2216 .alg = "tgr192",
2217 .test = alg_test_hash,
2218 .suite = {
2219 .hash = {
2220 .vecs = tgr192_tv_template,
2221 .count = TGR192_TEST_VECTORS
2222 }
2223 }
2224 }, {
2225 .alg = "wp256",
2226 .test = alg_test_hash,
2227 .suite = {
2228 .hash = {
2229 .vecs = wp256_tv_template,
2230 .count = WP256_TEST_VECTORS
2231 }
2232 }
2233 }, {
2234 .alg = "wp384",
2235 .test = alg_test_hash,
2236 .suite = {
2237 .hash = {
2238 .vecs = wp384_tv_template,
2239 .count = WP384_TEST_VECTORS
2240 }
2241 }
2242 }, {
2243 .alg = "wp512",
2244 .test = alg_test_hash,
2245 .suite = {
2246 .hash = {
2247 .vecs = wp512_tv_template,
2248 .count = WP512_TEST_VECTORS
2249 }
2250 }
2251 }, {
2252 .alg = "xcbc(aes)",
2253 .test = alg_test_hash,
2254 .suite = {
2255 .hash = {
2256 .vecs = aes_xcbc128_tv_template,
2257 .count = XCBC_AES_TEST_VECTORS
2258 }
2259 }
2260 }, {
2261 .alg = "xts(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002262 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002263 .suite = {
2264 .cipher = {
2265 .enc = {
2266 .vecs = aes_xts_enc_tv_template,
2267 .count = AES_XTS_ENC_TEST_VECTORS
2268 },
2269 .dec = {
2270 .vecs = aes_xts_dec_tv_template,
2271 .count = AES_XTS_DEC_TEST_VECTORS
2272 }
2273 }
2274 }
Geert Uytterhoeven0c01aed2009-03-04 15:42:15 +08002275 }, {
2276 .alg = "zlib",
2277 .test = alg_test_pcomp,
2278 .suite = {
2279 .pcomp = {
2280 .comp = {
2281 .vecs = zlib_comp_tv_template,
2282 .count = ZLIB_COMP_TEST_VECTORS
2283 },
2284 .decomp = {
2285 .vecs = zlib_decomp_tv_template,
2286 .count = ZLIB_DECOMP_TEST_VECTORS
2287 }
2288 }
2289 }
Herbert Xuda7f0332008-07-31 17:08:25 +08002290 }
2291};
2292
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002293static int alg_find_test(const char *alg)
Herbert Xuda7f0332008-07-31 17:08:25 +08002294{
2295 int start = 0;
2296 int end = ARRAY_SIZE(alg_test_descs);
2297
2298 while (start < end) {
2299 int i = (start + end) / 2;
2300 int diff = strcmp(alg_test_descs[i].alg, alg);
2301
2302 if (diff > 0) {
2303 end = i;
2304 continue;
2305 }
2306
2307 if (diff < 0) {
2308 start = i + 1;
2309 continue;
2310 }
2311
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002312 return i;
Herbert Xuda7f0332008-07-31 17:08:25 +08002313 }
2314
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002315 return -1;
2316}
2317
2318int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
2319{
2320 int i;
Neil Hormand12d6b62008-10-12 20:36:51 +08002321 int rc;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002322
2323 if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
2324 char nalg[CRYPTO_MAX_ALG_NAME];
2325
2326 if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
2327 sizeof(nalg))
2328 return -ENAMETOOLONG;
2329
2330 i = alg_find_test(nalg);
2331 if (i < 0)
2332 goto notest;
2333
Jarod Wilsona3bef3a2009-05-15 15:17:05 +10002334 if (fips_enabled && !alg_test_descs[i].fips_allowed)
2335 goto non_fips_alg;
2336
Jarod Wilson941fb322009-05-04 19:49:23 +08002337 rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
2338 goto test_done;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002339 }
2340
2341 i = alg_find_test(alg);
2342 if (i < 0)
2343 goto notest;
2344
Jarod Wilsona3bef3a2009-05-15 15:17:05 +10002345 if (fips_enabled && !alg_test_descs[i].fips_allowed)
2346 goto non_fips_alg;
2347
Neil Hormand12d6b62008-10-12 20:36:51 +08002348 rc = alg_test_descs[i].test(alg_test_descs + i, driver,
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002349 type, mask);
Jarod Wilson941fb322009-05-04 19:49:23 +08002350test_done:
Neil Hormand12d6b62008-10-12 20:36:51 +08002351 if (fips_enabled && rc)
2352 panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
2353
Jarod Wilson29ecd4a2009-05-04 19:51:17 +08002354 if (fips_enabled && !rc)
2355 printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
2356 driver, alg);
2357
Neil Hormand12d6b62008-10-12 20:36:51 +08002358 return rc;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002359
2360notest:
Herbert Xuda7f0332008-07-31 17:08:25 +08002361 printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
2362 return 0;
Jarod Wilsona3bef3a2009-05-15 15:17:05 +10002363non_fips_alg:
2364 return -EINVAL;
Herbert Xuda7f0332008-07-31 17:08:25 +08002365}
2366EXPORT_SYMBOL_GPL(alg_test);