crypto: api - Move type exit function into crypto_tfm
[safe/jmp/linux-2.6] / crypto / testmgr.c
1 /*
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>
22
23 #include "internal.h"
24 #include "testmgr.h"
25
26 /*
27  * Need slab memory for testing (size in number of pages).
28  */
29 #define XBUFSIZE        8
30
31 /*
32  * Indexes into the xbuf to simulate cross-page access.
33  */
34 #define IDX1            32
35 #define IDX2            32400
36 #define IDX3            1
37 #define IDX4            8193
38 #define IDX5            22222
39 #define IDX6            17101
40 #define IDX7            27333
41 #define IDX8            3000
42
43 /*
44 * Used by test_cipher()
45 */
46 #define ENCRYPT 1
47 #define DECRYPT 0
48
49 struct tcrypt_result {
50         struct completion completion;
51         int err;
52 };
53
54 struct aead_test_suite {
55         struct {
56                 struct aead_testvec *vecs;
57                 unsigned int count;
58         } enc, dec;
59 };
60
61 struct cipher_test_suite {
62         struct {
63                 struct cipher_testvec *vecs;
64                 unsigned int count;
65         } enc, dec;
66 };
67
68 struct comp_test_suite {
69         struct {
70                 struct comp_testvec *vecs;
71                 unsigned int count;
72         } comp, decomp;
73 };
74
75 struct hash_test_suite {
76         struct hash_testvec *vecs;
77         unsigned int count;
78 };
79
80 struct alg_test_desc {
81         const char *alg;
82         int (*test)(const struct alg_test_desc *desc, const char *driver,
83                     u32 type, u32 mask);
84
85         union {
86                 struct aead_test_suite aead;
87                 struct cipher_test_suite cipher;
88                 struct comp_test_suite comp;
89                 struct hash_test_suite hash;
90         } suite;
91 };
92
93 static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
94
95 static char *xbuf[XBUFSIZE];
96 static char *axbuf[XBUFSIZE];
97
98 static void hexdump(unsigned char *buf, unsigned int len)
99 {
100         print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
101                         16, 1,
102                         buf, len, false);
103 }
104
105 static void tcrypt_complete(struct crypto_async_request *req, int err)
106 {
107         struct tcrypt_result *res = req->data;
108
109         if (err == -EINPROGRESS)
110                 return;
111
112         res->err = err;
113         complete(&res->completion);
114 }
115
116 static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
117                      unsigned int tcount)
118 {
119         const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
120         unsigned int i, j, k, temp;
121         struct scatterlist sg[8];
122         char result[64];
123         struct ahash_request *req;
124         struct tcrypt_result tresult;
125         int ret;
126         void *hash_buff;
127
128         init_completion(&tresult.completion);
129
130         req = ahash_request_alloc(tfm, GFP_KERNEL);
131         if (!req) {
132                 printk(KERN_ERR "alg: hash: Failed to allocate request for "
133                        "%s\n", algo);
134                 ret = -ENOMEM;
135                 goto out_noreq;
136         }
137         ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
138                                    tcrypt_complete, &tresult);
139
140         for (i = 0; i < tcount; i++) {
141                 memset(result, 0, 64);
142
143                 hash_buff = xbuf[0];
144
145                 memcpy(hash_buff, template[i].plaintext, template[i].psize);
146                 sg_init_one(&sg[0], hash_buff, template[i].psize);
147
148                 if (template[i].ksize) {
149                         crypto_ahash_clear_flags(tfm, ~0);
150                         ret = crypto_ahash_setkey(tfm, template[i].key,
151                                                   template[i].ksize);
152                         if (ret) {
153                                 printk(KERN_ERR "alg: hash: setkey failed on "
154                                        "test %d for %s: ret=%d\n", i + 1, algo,
155                                        -ret);
156                                 goto out;
157                         }
158                 }
159
160                 ahash_request_set_crypt(req, sg, result, template[i].psize);
161                 ret = crypto_ahash_digest(req);
162                 switch (ret) {
163                 case 0:
164                         break;
165                 case -EINPROGRESS:
166                 case -EBUSY:
167                         ret = wait_for_completion_interruptible(
168                                 &tresult.completion);
169                         if (!ret && !(ret = tresult.err)) {
170                                 INIT_COMPLETION(tresult.completion);
171                                 break;
172                         }
173                         /* fall through */
174                 default:
175                         printk(KERN_ERR "alg: hash: digest failed on test %d "
176                                "for %s: ret=%d\n", i + 1, algo, -ret);
177                         goto out;
178                 }
179
180                 if (memcmp(result, template[i].digest,
181                            crypto_ahash_digestsize(tfm))) {
182                         printk(KERN_ERR "alg: hash: Test %d failed for %s\n",
183                                i + 1, algo);
184                         hexdump(result, crypto_ahash_digestsize(tfm));
185                         ret = -EINVAL;
186                         goto out;
187                 }
188         }
189
190         j = 0;
191         for (i = 0; i < tcount; i++) {
192                 if (template[i].np) {
193                         j++;
194                         memset(result, 0, 64);
195
196                         temp = 0;
197                         sg_init_table(sg, template[i].np);
198                         for (k = 0; k < template[i].np; k++) {
199                                 sg_set_buf(&sg[k],
200                                            memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
201                                                   offset_in_page(IDX[k]),
202                                                   template[i].plaintext + temp,
203                                                   template[i].tap[k]),
204                                            template[i].tap[k]);
205                                 temp += template[i].tap[k];
206                         }
207
208                         if (template[i].ksize) {
209                                 crypto_ahash_clear_flags(tfm, ~0);
210                                 ret = crypto_ahash_setkey(tfm, template[i].key,
211                                                           template[i].ksize);
212
213                                 if (ret) {
214                                         printk(KERN_ERR "alg: hash: setkey "
215                                                "failed on chunking test %d "
216                                                "for %s: ret=%d\n", j, algo,
217                                                -ret);
218                                         goto out;
219                                 }
220                         }
221
222                         ahash_request_set_crypt(req, sg, result,
223                                                 template[i].psize);
224                         ret = crypto_ahash_digest(req);
225                         switch (ret) {
226                         case 0:
227                                 break;
228                         case -EINPROGRESS:
229                         case -EBUSY:
230                                 ret = wait_for_completion_interruptible(
231                                         &tresult.completion);
232                                 if (!ret && !(ret = tresult.err)) {
233                                         INIT_COMPLETION(tresult.completion);
234                                         break;
235                                 }
236                                 /* fall through */
237                         default:
238                                 printk(KERN_ERR "alg: hash: digest failed "
239                                        "on chunking test %d for %s: "
240                                        "ret=%d\n", j, algo, -ret);
241                                 goto out;
242                         }
243
244                         if (memcmp(result, template[i].digest,
245                                    crypto_ahash_digestsize(tfm))) {
246                                 printk(KERN_ERR "alg: hash: Chunking test %d "
247                                        "failed for %s\n", j, algo);
248                                 hexdump(result, crypto_ahash_digestsize(tfm));
249                                 ret = -EINVAL;
250                                 goto out;
251                         }
252                 }
253         }
254
255         ret = 0;
256
257 out:
258         ahash_request_free(req);
259 out_noreq:
260         return ret;
261 }
262
263 static int test_aead(struct crypto_aead *tfm, int enc,
264                      struct aead_testvec *template, unsigned int tcount)
265 {
266         const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
267         unsigned int i, j, k, n, temp;
268         int ret = 0;
269         char *q;
270         char *key;
271         struct aead_request *req;
272         struct scatterlist sg[8];
273         struct scatterlist asg[8];
274         const char *e;
275         struct tcrypt_result result;
276         unsigned int authsize;
277         void *input;
278         void *assoc;
279         char iv[MAX_IVLEN];
280
281         if (enc == ENCRYPT)
282                 e = "encryption";
283         else
284                 e = "decryption";
285
286         init_completion(&result.completion);
287
288         req = aead_request_alloc(tfm, GFP_KERNEL);
289         if (!req) {
290                 printk(KERN_ERR "alg: aead: Failed to allocate request for "
291                        "%s\n", algo);
292                 ret = -ENOMEM;
293                 goto out;
294         }
295
296         aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
297                                   tcrypt_complete, &result);
298
299         for (i = 0, j = 0; i < tcount; i++) {
300                 if (!template[i].np) {
301                         j++;
302
303                         /* some tepmplates have no input data but they will
304                          * touch input
305                          */
306                         input = xbuf[0];
307                         assoc = axbuf[0];
308
309                         memcpy(input, template[i].input, template[i].ilen);
310                         memcpy(assoc, template[i].assoc, template[i].alen);
311                         if (template[i].iv)
312                                 memcpy(iv, template[i].iv, MAX_IVLEN);
313                         else
314                                 memset(iv, 0, MAX_IVLEN);
315
316                         crypto_aead_clear_flags(tfm, ~0);
317                         if (template[i].wk)
318                                 crypto_aead_set_flags(
319                                         tfm, CRYPTO_TFM_REQ_WEAK_KEY);
320
321                         key = template[i].key;
322
323                         ret = crypto_aead_setkey(tfm, key,
324                                                  template[i].klen);
325                         if (!ret == template[i].fail) {
326                                 printk(KERN_ERR "alg: aead: setkey failed on "
327                                        "test %d for %s: flags=%x\n", j, algo,
328                                        crypto_aead_get_flags(tfm));
329                                 goto out;
330                         } else if (ret)
331                                 continue;
332
333                         authsize = abs(template[i].rlen - template[i].ilen);
334                         ret = crypto_aead_setauthsize(tfm, authsize);
335                         if (ret) {
336                                 printk(KERN_ERR "alg: aead: Failed to set "
337                                        "authsize to %u on test %d for %s\n",
338                                        authsize, j, algo);
339                                 goto out;
340                         }
341
342                         sg_init_one(&sg[0], input,
343                                     template[i].ilen + (enc ? authsize : 0));
344
345                         sg_init_one(&asg[0], assoc, template[i].alen);
346
347                         aead_request_set_crypt(req, sg, sg,
348                                                template[i].ilen, iv);
349
350                         aead_request_set_assoc(req, asg, template[i].alen);
351
352                         ret = enc ?
353                                 crypto_aead_encrypt(req) :
354                                 crypto_aead_decrypt(req);
355
356                         switch (ret) {
357                         case 0:
358                                 break;
359                         case -EINPROGRESS:
360                         case -EBUSY:
361                                 ret = wait_for_completion_interruptible(
362                                         &result.completion);
363                                 if (!ret && !(ret = result.err)) {
364                                         INIT_COMPLETION(result.completion);
365                                         break;
366                                 }
367                                 /* fall through */
368                         default:
369                                 printk(KERN_ERR "alg: aead: %s failed on test "
370                                        "%d for %s: ret=%d\n", e, j, algo, -ret);
371                                 goto out;
372                         }
373
374                         q = input;
375                         if (memcmp(q, template[i].result, template[i].rlen)) {
376                                 printk(KERN_ERR "alg: aead: Test %d failed on "
377                                        "%s for %s\n", j, e, algo);
378                                 hexdump(q, template[i].rlen);
379                                 ret = -EINVAL;
380                                 goto out;
381                         }
382                 }
383         }
384
385         for (i = 0, j = 0; i < tcount; i++) {
386                 if (template[i].np) {
387                         j++;
388
389                         if (template[i].iv)
390                                 memcpy(iv, template[i].iv, MAX_IVLEN);
391                         else
392                                 memset(iv, 0, MAX_IVLEN);
393
394                         crypto_aead_clear_flags(tfm, ~0);
395                         if (template[i].wk)
396                                 crypto_aead_set_flags(
397                                         tfm, CRYPTO_TFM_REQ_WEAK_KEY);
398                         key = template[i].key;
399
400                         ret = crypto_aead_setkey(tfm, key, template[i].klen);
401                         if (!ret == template[i].fail) {
402                                 printk(KERN_ERR "alg: aead: setkey failed on "
403                                        "chunk test %d for %s: flags=%x\n", j,
404                                        algo, crypto_aead_get_flags(tfm));
405                                 goto out;
406                         } else if (ret)
407                                 continue;
408
409                         authsize = abs(template[i].rlen - template[i].ilen);
410
411                         ret = -EINVAL;
412                         sg_init_table(sg, template[i].np);
413                         for (k = 0, temp = 0; k < template[i].np; k++) {
414                                 if (WARN_ON(offset_in_page(IDX[k]) +
415                                             template[i].tap[k] > PAGE_SIZE))
416                                         goto out;
417
418                                 q = xbuf[IDX[k] >> PAGE_SHIFT] +
419                                     offset_in_page(IDX[k]);
420
421                                 memcpy(q, template[i].input + temp,
422                                        template[i].tap[k]);
423
424                                 n = template[i].tap[k];
425                                 if (k == template[i].np - 1 && enc)
426                                         n += authsize;
427                                 if (offset_in_page(q) + n < PAGE_SIZE)
428                                         q[n] = 0;
429
430                                 sg_set_buf(&sg[k], q, template[i].tap[k]);
431                                 temp += template[i].tap[k];
432                         }
433
434                         ret = crypto_aead_setauthsize(tfm, authsize);
435                         if (ret) {
436                                 printk(KERN_ERR "alg: aead: Failed to set "
437                                        "authsize to %u on chunk test %d for "
438                                        "%s\n", authsize, j, algo);
439                                 goto out;
440                         }
441
442                         if (enc) {
443                                 if (WARN_ON(sg[k - 1].offset +
444                                             sg[k - 1].length + authsize >
445                                             PAGE_SIZE)) {
446                                         ret = -EINVAL;
447                                         goto out;
448                                 }
449
450                                 sg[k - 1].length += authsize;
451                         }
452
453                         sg_init_table(asg, template[i].anp);
454                         for (k = 0, temp = 0; k < template[i].anp; k++) {
455                                 sg_set_buf(&asg[k],
456                                            memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
457                                                   offset_in_page(IDX[k]),
458                                                   template[i].assoc + temp,
459                                                   template[i].atap[k]),
460                                            template[i].atap[k]);
461                                 temp += template[i].atap[k];
462                         }
463
464                         aead_request_set_crypt(req, sg, sg,
465                                                template[i].ilen,
466                                                iv);
467
468                         aead_request_set_assoc(req, asg, template[i].alen);
469
470                         ret = enc ?
471                                 crypto_aead_encrypt(req) :
472                                 crypto_aead_decrypt(req);
473
474                         switch (ret) {
475                         case 0:
476                                 break;
477                         case -EINPROGRESS:
478                         case -EBUSY:
479                                 ret = wait_for_completion_interruptible(
480                                         &result.completion);
481                                 if (!ret && !(ret = result.err)) {
482                                         INIT_COMPLETION(result.completion);
483                                         break;
484                                 }
485                                 /* fall through */
486                         default:
487                                 printk(KERN_ERR "alg: aead: %s failed on "
488                                        "chunk test %d for %s: ret=%d\n", e, j,
489                                        algo, -ret);
490                                 goto out;
491                         }
492
493                         ret = -EINVAL;
494                         for (k = 0, temp = 0; k < template[i].np; k++) {
495                                 q = xbuf[IDX[k] >> PAGE_SHIFT] +
496                                     offset_in_page(IDX[k]);
497
498                                 n = template[i].tap[k];
499                                 if (k == template[i].np - 1)
500                                         n += enc ? authsize : -authsize;
501
502                                 if (memcmp(q, template[i].result + temp, n)) {
503                                         printk(KERN_ERR "alg: aead: Chunk "
504                                                "test %d failed on %s at page "
505                                                "%u for %s\n", j, e, k, algo);
506                                         hexdump(q, n);
507                                         goto out;
508                                 }
509
510                                 q += n;
511                                 if (k == template[i].np - 1 && !enc) {
512                                         if (memcmp(q, template[i].input +
513                                                       temp + n, authsize))
514                                                 n = authsize;
515                                         else
516                                                 n = 0;
517                                 } else {
518                                         for (n = 0; offset_in_page(q + n) &&
519                                                     q[n]; n++)
520                                                 ;
521                                 }
522                                 if (n) {
523                                         printk(KERN_ERR "alg: aead: Result "
524                                                "buffer corruption in chunk "
525                                                "test %d on %s at page %u for "
526                                                "%s: %u bytes:\n", j, e, k,
527                                                algo, n);
528                                         hexdump(q, n);
529                                         goto out;
530                                 }
531
532                                 temp += template[i].tap[k];
533                         }
534                 }
535         }
536
537         ret = 0;
538
539 out:
540         aead_request_free(req);
541         return ret;
542 }
543
544 static int test_cipher(struct crypto_cipher *tfm, int enc,
545                        struct cipher_testvec *template, unsigned int tcount)
546 {
547         const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
548         unsigned int i, j, k;
549         int ret;
550         char *q;
551         const char *e;
552         void *data;
553
554         if (enc == ENCRYPT)
555                 e = "encryption";
556         else
557                 e = "decryption";
558
559         j = 0;
560         for (i = 0; i < tcount; i++) {
561                 if (template[i].np)
562                         continue;
563
564                 j++;
565
566                 data = xbuf[0];
567                 memcpy(data, template[i].input, template[i].ilen);
568
569                 crypto_cipher_clear_flags(tfm, ~0);
570                 if (template[i].wk)
571                         crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
572
573                 ret = crypto_cipher_setkey(tfm, template[i].key,
574                                            template[i].klen);
575                 if (!ret == template[i].fail) {
576                         printk(KERN_ERR "alg: cipher: setkey failed "
577                                "on test %d for %s: flags=%x\n", j,
578                                algo, crypto_cipher_get_flags(tfm));
579                         goto out;
580                 } else if (ret)
581                         continue;
582
583                 for (k = 0; k < template[i].ilen;
584                      k += crypto_cipher_blocksize(tfm)) {
585                         if (enc)
586                                 crypto_cipher_encrypt_one(tfm, data + k,
587                                                           data + k);
588                         else
589                                 crypto_cipher_decrypt_one(tfm, data + k,
590                                                           data + k);
591                 }
592
593                 q = data;
594                 if (memcmp(q, template[i].result, template[i].rlen)) {
595                         printk(KERN_ERR "alg: cipher: Test %d failed "
596                                "on %s for %s\n", j, e, algo);
597                         hexdump(q, template[i].rlen);
598                         ret = -EINVAL;
599                         goto out;
600                 }
601         }
602
603         ret = 0;
604
605 out:
606         return ret;
607 }
608
609 static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
610                          struct cipher_testvec *template, unsigned int tcount)
611 {
612         const char *algo =
613                 crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
614         unsigned int i, j, k, n, temp;
615         int ret;
616         char *q;
617         struct ablkcipher_request *req;
618         struct scatterlist sg[8];
619         const char *e;
620         struct tcrypt_result result;
621         void *data;
622         char iv[MAX_IVLEN];
623
624         if (enc == ENCRYPT)
625                 e = "encryption";
626         else
627                 e = "decryption";
628
629         init_completion(&result.completion);
630
631         req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
632         if (!req) {
633                 printk(KERN_ERR "alg: skcipher: Failed to allocate request "
634                        "for %s\n", algo);
635                 ret = -ENOMEM;
636                 goto out;
637         }
638
639         ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
640                                         tcrypt_complete, &result);
641
642         j = 0;
643         for (i = 0; i < tcount; i++) {
644                 if (template[i].iv)
645                         memcpy(iv, template[i].iv, MAX_IVLEN);
646                 else
647                         memset(iv, 0, MAX_IVLEN);
648
649                 if (!(template[i].np)) {
650                         j++;
651
652                         data = xbuf[0];
653                         memcpy(data, template[i].input, template[i].ilen);
654
655                         crypto_ablkcipher_clear_flags(tfm, ~0);
656                         if (template[i].wk)
657                                 crypto_ablkcipher_set_flags(
658                                         tfm, CRYPTO_TFM_REQ_WEAK_KEY);
659
660                         ret = crypto_ablkcipher_setkey(tfm, template[i].key,
661                                                        template[i].klen);
662                         if (!ret == template[i].fail) {
663                                 printk(KERN_ERR "alg: skcipher: setkey failed "
664                                        "on test %d for %s: flags=%x\n", j,
665                                        algo, crypto_ablkcipher_get_flags(tfm));
666                                 goto out;
667                         } else if (ret)
668                                 continue;
669
670                         sg_init_one(&sg[0], data, template[i].ilen);
671
672                         ablkcipher_request_set_crypt(req, sg, sg,
673                                                      template[i].ilen, iv);
674                         ret = enc ?
675                                 crypto_ablkcipher_encrypt(req) :
676                                 crypto_ablkcipher_decrypt(req);
677
678                         switch (ret) {
679                         case 0:
680                                 break;
681                         case -EINPROGRESS:
682                         case -EBUSY:
683                                 ret = wait_for_completion_interruptible(
684                                         &result.completion);
685                                 if (!ret && !((ret = result.err))) {
686                                         INIT_COMPLETION(result.completion);
687                                         break;
688                                 }
689                                 /* fall through */
690                         default:
691                                 printk(KERN_ERR "alg: skcipher: %s failed on "
692                                        "test %d for %s: ret=%d\n", e, j, algo,
693                                        -ret);
694                                 goto out;
695                         }
696
697                         q = data;
698                         if (memcmp(q, template[i].result, template[i].rlen)) {
699                                 printk(KERN_ERR "alg: skcipher: Test %d "
700                                        "failed on %s for %s\n", j, e, algo);
701                                 hexdump(q, template[i].rlen);
702                                 ret = -EINVAL;
703                                 goto out;
704                         }
705                 }
706         }
707
708         j = 0;
709         for (i = 0; i < tcount; i++) {
710
711                 if (template[i].iv)
712                         memcpy(iv, template[i].iv, MAX_IVLEN);
713                 else
714                         memset(iv, 0, MAX_IVLEN);
715
716                 if (template[i].np) {
717                         j++;
718
719                         crypto_ablkcipher_clear_flags(tfm, ~0);
720                         if (template[i].wk)
721                                 crypto_ablkcipher_set_flags(
722                                         tfm, CRYPTO_TFM_REQ_WEAK_KEY);
723
724                         ret = crypto_ablkcipher_setkey(tfm, template[i].key,
725                                                        template[i].klen);
726                         if (!ret == template[i].fail) {
727                                 printk(KERN_ERR "alg: skcipher: setkey failed "
728                                        "on chunk test %d for %s: flags=%x\n",
729                                        j, algo,
730                                        crypto_ablkcipher_get_flags(tfm));
731                                 goto out;
732                         } else if (ret)
733                                 continue;
734
735                         temp = 0;
736                         ret = -EINVAL;
737                         sg_init_table(sg, template[i].np);
738                         for (k = 0; k < template[i].np; k++) {
739                                 if (WARN_ON(offset_in_page(IDX[k]) +
740                                             template[i].tap[k] > PAGE_SIZE))
741                                         goto out;
742
743                                 q = xbuf[IDX[k] >> PAGE_SHIFT] +
744                                     offset_in_page(IDX[k]);
745
746                                 memcpy(q, template[i].input + temp,
747                                        template[i].tap[k]);
748
749                                 if (offset_in_page(q) + template[i].tap[k] <
750                                     PAGE_SIZE)
751                                         q[template[i].tap[k]] = 0;
752
753                                 sg_set_buf(&sg[k], q, template[i].tap[k]);
754
755                                 temp += template[i].tap[k];
756                         }
757
758                         ablkcipher_request_set_crypt(req, sg, sg,
759                                         template[i].ilen, iv);
760
761                         ret = enc ?
762                                 crypto_ablkcipher_encrypt(req) :
763                                 crypto_ablkcipher_decrypt(req);
764
765                         switch (ret) {
766                         case 0:
767                                 break;
768                         case -EINPROGRESS:
769                         case -EBUSY:
770                                 ret = wait_for_completion_interruptible(
771                                         &result.completion);
772                                 if (!ret && !((ret = result.err))) {
773                                         INIT_COMPLETION(result.completion);
774                                         break;
775                                 }
776                                 /* fall through */
777                         default:
778                                 printk(KERN_ERR "alg: skcipher: %s failed on "
779                                        "chunk test %d for %s: ret=%d\n", e, j,
780                                        algo, -ret);
781                                 goto out;
782                         }
783
784                         temp = 0;
785                         ret = -EINVAL;
786                         for (k = 0; k < template[i].np; k++) {
787                                 q = xbuf[IDX[k] >> PAGE_SHIFT] +
788                                     offset_in_page(IDX[k]);
789
790                                 if (memcmp(q, template[i].result + temp,
791                                            template[i].tap[k])) {
792                                         printk(KERN_ERR "alg: skcipher: Chunk "
793                                                "test %d failed on %s at page "
794                                                "%u for %s\n", j, e, k, algo);
795                                         hexdump(q, template[i].tap[k]);
796                                         goto out;
797                                 }
798
799                                 q += template[i].tap[k];
800                                 for (n = 0; offset_in_page(q + n) && q[n]; n++)
801                                         ;
802                                 if (n) {
803                                         printk(KERN_ERR "alg: skcipher: "
804                                                "Result buffer corruption in "
805                                                "chunk test %d on %s at page "
806                                                "%u for %s: %u bytes:\n", j, e,
807                                                k, algo, n);
808                                         hexdump(q, n);
809                                         goto out;
810                                 }
811                                 temp += template[i].tap[k];
812                         }
813                 }
814         }
815
816         ret = 0;
817
818 out:
819         ablkcipher_request_free(req);
820         return ret;
821 }
822
823 static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
824                      struct comp_testvec *dtemplate, int ctcount, int dtcount)
825 {
826         const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
827         unsigned int i;
828         char result[COMP_BUF_SIZE];
829         int ret;
830
831         for (i = 0; i < ctcount; i++) {
832                 int ilen, dlen = COMP_BUF_SIZE;
833
834                 memset(result, 0, sizeof (result));
835
836                 ilen = ctemplate[i].inlen;
837                 ret = crypto_comp_compress(tfm, ctemplate[i].input,
838                                            ilen, result, &dlen);
839                 if (ret) {
840                         printk(KERN_ERR "alg: comp: compression failed "
841                                "on test %d for %s: ret=%d\n", i + 1, algo,
842                                -ret);
843                         goto out;
844                 }
845
846                 if (memcmp(result, ctemplate[i].output, dlen)) {
847                         printk(KERN_ERR "alg: comp: Compression test %d "
848                                "failed for %s\n", i + 1, algo);
849                         hexdump(result, dlen);
850                         ret = -EINVAL;
851                         goto out;
852                 }
853         }
854
855         for (i = 0; i < dtcount; i++) {
856                 int ilen, ret, dlen = COMP_BUF_SIZE;
857
858                 memset(result, 0, sizeof (result));
859
860                 ilen = dtemplate[i].inlen;
861                 ret = crypto_comp_decompress(tfm, dtemplate[i].input,
862                                              ilen, result, &dlen);
863                 if (ret) {
864                         printk(KERN_ERR "alg: comp: decompression failed "
865                                "on test %d for %s: ret=%d\n", i + 1, algo,
866                                -ret);
867                         goto out;
868                 }
869
870                 if (memcmp(result, dtemplate[i].output, dlen)) {
871                         printk(KERN_ERR "alg: comp: Decompression test %d "
872                                "failed for %s\n", i + 1, algo);
873                         hexdump(result, dlen);
874                         ret = -EINVAL;
875                         goto out;
876                 }
877         }
878
879         ret = 0;
880
881 out:
882         return ret;
883 }
884
885 static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
886                          u32 type, u32 mask)
887 {
888         struct crypto_aead *tfm;
889         int err = 0;
890
891         tfm = crypto_alloc_aead(driver, type, mask);
892         if (IS_ERR(tfm)) {
893                 printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
894                        "%ld\n", driver, PTR_ERR(tfm));
895                 return PTR_ERR(tfm);
896         }
897
898         if (desc->suite.aead.enc.vecs) {
899                 err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
900                                 desc->suite.aead.enc.count);
901                 if (err)
902                         goto out;
903         }
904
905         if (!err && desc->suite.aead.dec.vecs)
906                 err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
907                                 desc->suite.aead.dec.count);
908
909 out:
910         crypto_free_aead(tfm);
911         return err;
912 }
913
914 static int alg_test_cipher(const struct alg_test_desc *desc,
915                            const char *driver, u32 type, u32 mask)
916 {
917         struct crypto_cipher *tfm;
918         int err = 0;
919
920         tfm = crypto_alloc_cipher(driver, type, mask);
921         if (IS_ERR(tfm)) {
922                 printk(KERN_ERR "alg: cipher: Failed to load transform for "
923                        "%s: %ld\n", driver, PTR_ERR(tfm));
924                 return PTR_ERR(tfm);
925         }
926
927         if (desc->suite.cipher.enc.vecs) {
928                 err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
929                                   desc->suite.cipher.enc.count);
930                 if (err)
931                         goto out;
932         }
933
934         if (desc->suite.cipher.dec.vecs)
935                 err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
936                                   desc->suite.cipher.dec.count);
937
938 out:
939         crypto_free_cipher(tfm);
940         return err;
941 }
942
943 static int alg_test_skcipher(const struct alg_test_desc *desc,
944                              const char *driver, u32 type, u32 mask)
945 {
946         struct crypto_ablkcipher *tfm;
947         int err = 0;
948
949         tfm = crypto_alloc_ablkcipher(driver, type, mask);
950         if (IS_ERR(tfm)) {
951                 printk(KERN_ERR "alg: skcipher: Failed to load transform for "
952                        "%s: %ld\n", driver, PTR_ERR(tfm));
953                 return PTR_ERR(tfm);
954         }
955
956         if (desc->suite.cipher.enc.vecs) {
957                 err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
958                                     desc->suite.cipher.enc.count);
959                 if (err)
960                         goto out;
961         }
962
963         if (desc->suite.cipher.dec.vecs)
964                 err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
965                                     desc->suite.cipher.dec.count);
966
967 out:
968         crypto_free_ablkcipher(tfm);
969         return err;
970 }
971
972 static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
973                          u32 type, u32 mask)
974 {
975         struct crypto_comp *tfm;
976         int err;
977
978         tfm = crypto_alloc_comp(driver, type, mask);
979         if (IS_ERR(tfm)) {
980                 printk(KERN_ERR "alg: comp: Failed to load transform for %s: "
981                        "%ld\n", driver, PTR_ERR(tfm));
982                 return PTR_ERR(tfm);
983         }
984
985         err = test_comp(tfm, desc->suite.comp.comp.vecs,
986                         desc->suite.comp.decomp.vecs,
987                         desc->suite.comp.comp.count,
988                         desc->suite.comp.decomp.count);
989
990         crypto_free_comp(tfm);
991         return err;
992 }
993
994 static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
995                          u32 type, u32 mask)
996 {
997         struct crypto_ahash *tfm;
998         int err;
999
1000         tfm = crypto_alloc_ahash(driver, type, mask);
1001         if (IS_ERR(tfm)) {
1002                 printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
1003                        "%ld\n", driver, PTR_ERR(tfm));
1004                 return PTR_ERR(tfm);
1005         }
1006
1007         err = test_hash(tfm, desc->suite.hash.vecs, desc->suite.hash.count);
1008
1009         crypto_free_ahash(tfm);
1010         return err;
1011 }
1012
1013 /* Please keep this list sorted by algorithm name. */
1014 static const struct alg_test_desc alg_test_descs[] = {
1015         {
1016                 .alg = "cbc(aes)",
1017                 .test = alg_test_skcipher,
1018                 .suite = {
1019                         .cipher = {
1020                                 .enc = {
1021                                         .vecs = aes_cbc_enc_tv_template,
1022                                         .count = AES_CBC_ENC_TEST_VECTORS
1023                                 },
1024                                 .dec = {
1025                                         .vecs = aes_cbc_dec_tv_template,
1026                                         .count = AES_CBC_DEC_TEST_VECTORS
1027                                 }
1028                         }
1029                 }
1030         }, {
1031                 .alg = "cbc(anubis)",
1032                 .test = alg_test_skcipher,
1033                 .suite = {
1034                         .cipher = {
1035                                 .enc = {
1036                                         .vecs = anubis_cbc_enc_tv_template,
1037                                         .count = ANUBIS_CBC_ENC_TEST_VECTORS
1038                                 },
1039                                 .dec = {
1040                                         .vecs = anubis_cbc_dec_tv_template,
1041                                         .count = ANUBIS_CBC_DEC_TEST_VECTORS
1042                                 }
1043                         }
1044                 }
1045         }, {
1046                 .alg = "cbc(blowfish)",
1047                 .test = alg_test_skcipher,
1048                 .suite = {
1049                         .cipher = {
1050                                 .enc = {
1051                                         .vecs = bf_cbc_enc_tv_template,
1052                                         .count = BF_CBC_ENC_TEST_VECTORS
1053                                 },
1054                                 .dec = {
1055                                         .vecs = bf_cbc_dec_tv_template,
1056                                         .count = BF_CBC_DEC_TEST_VECTORS
1057                                 }
1058                         }
1059                 }
1060         }, {
1061                 .alg = "cbc(camellia)",
1062                 .test = alg_test_skcipher,
1063                 .suite = {
1064                         .cipher = {
1065                                 .enc = {
1066                                         .vecs = camellia_cbc_enc_tv_template,
1067                                         .count = CAMELLIA_CBC_ENC_TEST_VECTORS
1068                                 },
1069                                 .dec = {
1070                                         .vecs = camellia_cbc_dec_tv_template,
1071                                         .count = CAMELLIA_CBC_DEC_TEST_VECTORS
1072                                 }
1073                         }
1074                 }
1075         }, {
1076                 .alg = "cbc(des)",
1077                 .test = alg_test_skcipher,
1078                 .suite = {
1079                         .cipher = {
1080                                 .enc = {
1081                                         .vecs = des_cbc_enc_tv_template,
1082                                         .count = DES_CBC_ENC_TEST_VECTORS
1083                                 },
1084                                 .dec = {
1085                                         .vecs = des_cbc_dec_tv_template,
1086                                         .count = DES_CBC_DEC_TEST_VECTORS
1087                                 }
1088                         }
1089                 }
1090         }, {
1091                 .alg = "cbc(des3_ede)",
1092                 .test = alg_test_skcipher,
1093                 .suite = {
1094                         .cipher = {
1095                                 .enc = {
1096                                         .vecs = des3_ede_cbc_enc_tv_template,
1097                                         .count = DES3_EDE_CBC_ENC_TEST_VECTORS
1098                                 },
1099                                 .dec = {
1100                                         .vecs = des3_ede_cbc_dec_tv_template,
1101                                         .count = DES3_EDE_CBC_DEC_TEST_VECTORS
1102                                 }
1103                         }
1104                 }
1105         }, {
1106                 .alg = "cbc(twofish)",
1107                 .test = alg_test_skcipher,
1108                 .suite = {
1109                         .cipher = {
1110                                 .enc = {
1111                                         .vecs = tf_cbc_enc_tv_template,
1112                                         .count = TF_CBC_ENC_TEST_VECTORS
1113                                 },
1114                                 .dec = {
1115                                         .vecs = tf_cbc_dec_tv_template,
1116                                         .count = TF_CBC_DEC_TEST_VECTORS
1117                                 }
1118                         }
1119                 }
1120         }, {
1121                 .alg = "ccm(aes)",
1122                 .test = alg_test_aead,
1123                 .suite = {
1124                         .aead = {
1125                                 .enc = {
1126                                         .vecs = aes_ccm_enc_tv_template,
1127                                         .count = AES_CCM_ENC_TEST_VECTORS
1128                                 },
1129                                 .dec = {
1130                                         .vecs = aes_ccm_dec_tv_template,
1131                                         .count = AES_CCM_DEC_TEST_VECTORS
1132                                 }
1133                         }
1134                 }
1135         }, {
1136                 .alg = "crc32c",
1137                 .test = alg_test_hash,
1138                 .suite = {
1139                         .hash = {
1140                                 .vecs = crc32c_tv_template,
1141                                 .count = CRC32C_TEST_VECTORS
1142                         }
1143                 }
1144         }, {
1145                 .alg = "cts(cbc(aes))",
1146                 .test = alg_test_skcipher,
1147                 .suite = {
1148                         .cipher = {
1149                                 .enc = {
1150                                         .vecs = cts_mode_enc_tv_template,
1151                                         .count = CTS_MODE_ENC_TEST_VECTORS
1152                                 },
1153                                 .dec = {
1154                                         .vecs = cts_mode_dec_tv_template,
1155                                         .count = CTS_MODE_DEC_TEST_VECTORS
1156                                 }
1157                         }
1158                 }
1159         }, {
1160                 .alg = "deflate",
1161                 .test = alg_test_comp,
1162                 .suite = {
1163                         .comp = {
1164                                 .comp = {
1165                                         .vecs = deflate_comp_tv_template,
1166                                         .count = DEFLATE_COMP_TEST_VECTORS
1167                                 },
1168                                 .decomp = {
1169                                         .vecs = deflate_decomp_tv_template,
1170                                         .count = DEFLATE_DECOMP_TEST_VECTORS
1171                                 }
1172                         }
1173                 }
1174         }, {
1175                 .alg = "ecb(aes)",
1176                 .test = alg_test_skcipher,
1177                 .suite = {
1178                         .cipher = {
1179                                 .enc = {
1180                                         .vecs = aes_enc_tv_template,
1181                                         .count = AES_ENC_TEST_VECTORS
1182                                 },
1183                                 .dec = {
1184                                         .vecs = aes_dec_tv_template,
1185                                         .count = AES_DEC_TEST_VECTORS
1186                                 }
1187                         }
1188                 }
1189         }, {
1190                 .alg = "ecb(anubis)",
1191                 .test = alg_test_skcipher,
1192                 .suite = {
1193                         .cipher = {
1194                                 .enc = {
1195                                         .vecs = anubis_enc_tv_template,
1196                                         .count = ANUBIS_ENC_TEST_VECTORS
1197                                 },
1198                                 .dec = {
1199                                         .vecs = anubis_dec_tv_template,
1200                                         .count = ANUBIS_DEC_TEST_VECTORS
1201                                 }
1202                         }
1203                 }
1204         }, {
1205                 .alg = "ecb(arc4)",
1206                 .test = alg_test_skcipher,
1207                 .suite = {
1208                         .cipher = {
1209                                 .enc = {
1210                                         .vecs = arc4_enc_tv_template,
1211                                         .count = ARC4_ENC_TEST_VECTORS
1212                                 },
1213                                 .dec = {
1214                                         .vecs = arc4_dec_tv_template,
1215                                         .count = ARC4_DEC_TEST_VECTORS
1216                                 }
1217                         }
1218                 }
1219         }, {
1220                 .alg = "ecb(blowfish)",
1221                 .test = alg_test_skcipher,
1222                 .suite = {
1223                         .cipher = {
1224                                 .enc = {
1225                                         .vecs = bf_enc_tv_template,
1226                                         .count = BF_ENC_TEST_VECTORS
1227                                 },
1228                                 .dec = {
1229                                         .vecs = bf_dec_tv_template,
1230                                         .count = BF_DEC_TEST_VECTORS
1231                                 }
1232                         }
1233                 }
1234         }, {
1235                 .alg = "ecb(camellia)",
1236                 .test = alg_test_skcipher,
1237                 .suite = {
1238                         .cipher = {
1239                                 .enc = {
1240                                         .vecs = camellia_enc_tv_template,
1241                                         .count = CAMELLIA_ENC_TEST_VECTORS
1242                                 },
1243                                 .dec = {
1244                                         .vecs = camellia_dec_tv_template,
1245                                         .count = CAMELLIA_DEC_TEST_VECTORS
1246                                 }
1247                         }
1248                 }
1249         }, {
1250                 .alg = "ecb(cast5)",
1251                 .test = alg_test_skcipher,
1252                 .suite = {
1253                         .cipher = {
1254                                 .enc = {
1255                                         .vecs = cast5_enc_tv_template,
1256                                         .count = CAST5_ENC_TEST_VECTORS
1257                                 },
1258                                 .dec = {
1259                                         .vecs = cast5_dec_tv_template,
1260                                         .count = CAST5_DEC_TEST_VECTORS
1261                                 }
1262                         }
1263                 }
1264         }, {
1265                 .alg = "ecb(cast6)",
1266                 .test = alg_test_skcipher,
1267                 .suite = {
1268                         .cipher = {
1269                                 .enc = {
1270                                         .vecs = cast6_enc_tv_template,
1271                                         .count = CAST6_ENC_TEST_VECTORS
1272                                 },
1273                                 .dec = {
1274                                         .vecs = cast6_dec_tv_template,
1275                                         .count = CAST6_DEC_TEST_VECTORS
1276                                 }
1277                         }
1278                 }
1279         }, {
1280                 .alg = "ecb(des)",
1281                 .test = alg_test_skcipher,
1282                 .suite = {
1283                         .cipher = {
1284                                 .enc = {
1285                                         .vecs = des_enc_tv_template,
1286                                         .count = DES_ENC_TEST_VECTORS
1287                                 },
1288                                 .dec = {
1289                                         .vecs = des_dec_tv_template,
1290                                         .count = DES_DEC_TEST_VECTORS
1291                                 }
1292                         }
1293                 }
1294         }, {
1295                 .alg = "ecb(des3_ede)",
1296                 .test = alg_test_skcipher,
1297                 .suite = {
1298                         .cipher = {
1299                                 .enc = {
1300                                         .vecs = des3_ede_enc_tv_template,
1301                                         .count = DES3_EDE_ENC_TEST_VECTORS
1302                                 },
1303                                 .dec = {
1304                                         .vecs = des3_ede_dec_tv_template,
1305                                         .count = DES3_EDE_DEC_TEST_VECTORS
1306                                 }
1307                         }
1308                 }
1309         }, {
1310                 .alg = "ecb(khazad)",
1311                 .test = alg_test_skcipher,
1312                 .suite = {
1313                         .cipher = {
1314                                 .enc = {
1315                                         .vecs = khazad_enc_tv_template,
1316                                         .count = KHAZAD_ENC_TEST_VECTORS
1317                                 },
1318                                 .dec = {
1319                                         .vecs = khazad_dec_tv_template,
1320                                         .count = KHAZAD_DEC_TEST_VECTORS
1321                                 }
1322                         }
1323                 }
1324         }, {
1325                 .alg = "ecb(seed)",
1326                 .test = alg_test_skcipher,
1327                 .suite = {
1328                         .cipher = {
1329                                 .enc = {
1330                                         .vecs = seed_enc_tv_template,
1331                                         .count = SEED_ENC_TEST_VECTORS
1332                                 },
1333                                 .dec = {
1334                                         .vecs = seed_dec_tv_template,
1335                                         .count = SEED_DEC_TEST_VECTORS
1336                                 }
1337                         }
1338                 }
1339         }, {
1340                 .alg = "ecb(serpent)",
1341                 .test = alg_test_skcipher,
1342                 .suite = {
1343                         .cipher = {
1344                                 .enc = {
1345                                         .vecs = serpent_enc_tv_template,
1346                                         .count = SERPENT_ENC_TEST_VECTORS
1347                                 },
1348                                 .dec = {
1349                                         .vecs = serpent_dec_tv_template,
1350                                         .count = SERPENT_DEC_TEST_VECTORS
1351                                 }
1352                         }
1353                 }
1354         }, {
1355                 .alg = "ecb(tea)",
1356                 .test = alg_test_skcipher,
1357                 .suite = {
1358                         .cipher = {
1359                                 .enc = {
1360                                         .vecs = tea_enc_tv_template,
1361                                         .count = TEA_ENC_TEST_VECTORS
1362                                 },
1363                                 .dec = {
1364                                         .vecs = tea_dec_tv_template,
1365                                         .count = TEA_DEC_TEST_VECTORS
1366                                 }
1367                         }
1368                 }
1369         }, {
1370                 .alg = "ecb(tnepres)",
1371                 .test = alg_test_skcipher,
1372                 .suite = {
1373                         .cipher = {
1374                                 .enc = {
1375                                         .vecs = tnepres_enc_tv_template,
1376                                         .count = TNEPRES_ENC_TEST_VECTORS
1377                                 },
1378                                 .dec = {
1379                                         .vecs = tnepres_dec_tv_template,
1380                                         .count = TNEPRES_DEC_TEST_VECTORS
1381                                 }
1382                         }
1383                 }
1384         }, {
1385                 .alg = "ecb(twofish)",
1386                 .test = alg_test_skcipher,
1387                 .suite = {
1388                         .cipher = {
1389                                 .enc = {
1390                                         .vecs = tf_enc_tv_template,
1391                                         .count = TF_ENC_TEST_VECTORS
1392                                 },
1393                                 .dec = {
1394                                         .vecs = tf_dec_tv_template,
1395                                         .count = TF_DEC_TEST_VECTORS
1396                                 }
1397                         }
1398                 }
1399         }, {
1400                 .alg = "ecb(xeta)",
1401                 .test = alg_test_skcipher,
1402                 .suite = {
1403                         .cipher = {
1404                                 .enc = {
1405                                         .vecs = xeta_enc_tv_template,
1406                                         .count = XETA_ENC_TEST_VECTORS
1407                                 },
1408                                 .dec = {
1409                                         .vecs = xeta_dec_tv_template,
1410                                         .count = XETA_DEC_TEST_VECTORS
1411                                 }
1412                         }
1413                 }
1414         }, {
1415                 .alg = "ecb(xtea)",
1416                 .test = alg_test_skcipher,
1417                 .suite = {
1418                         .cipher = {
1419                                 .enc = {
1420                                         .vecs = xtea_enc_tv_template,
1421                                         .count = XTEA_ENC_TEST_VECTORS
1422                                 },
1423                                 .dec = {
1424                                         .vecs = xtea_dec_tv_template,
1425                                         .count = XTEA_DEC_TEST_VECTORS
1426                                 }
1427                         }
1428                 }
1429         }, {
1430                 .alg = "gcm(aes)",
1431                 .test = alg_test_aead,
1432                 .suite = {
1433                         .aead = {
1434                                 .enc = {
1435                                         .vecs = aes_gcm_enc_tv_template,
1436                                         .count = AES_GCM_ENC_TEST_VECTORS
1437                                 },
1438                                 .dec = {
1439                                         .vecs = aes_gcm_dec_tv_template,
1440                                         .count = AES_GCM_DEC_TEST_VECTORS
1441                                 }
1442                         }
1443                 }
1444         }, {
1445                 .alg = "hmac(md5)",
1446                 .test = alg_test_hash,
1447                 .suite = {
1448                         .hash = {
1449                                 .vecs = hmac_md5_tv_template,
1450                                 .count = HMAC_MD5_TEST_VECTORS
1451                         }
1452                 }
1453         }, {
1454                 .alg = "hmac(rmd128)",
1455                 .test = alg_test_hash,
1456                 .suite = {
1457                         .hash = {
1458                                 .vecs = hmac_rmd128_tv_template,
1459                                 .count = HMAC_RMD128_TEST_VECTORS
1460                         }
1461                 }
1462         }, {
1463                 .alg = "hmac(rmd160)",
1464                 .test = alg_test_hash,
1465                 .suite = {
1466                         .hash = {
1467                                 .vecs = hmac_rmd160_tv_template,
1468                                 .count = HMAC_RMD160_TEST_VECTORS
1469                         }
1470                 }
1471         }, {
1472                 .alg = "hmac(sha1)",
1473                 .test = alg_test_hash,
1474                 .suite = {
1475                         .hash = {
1476                                 .vecs = hmac_sha1_tv_template,
1477                                 .count = HMAC_SHA1_TEST_VECTORS
1478                         }
1479                 }
1480         }, {
1481                 .alg = "hmac(sha224)",
1482                 .test = alg_test_hash,
1483                 .suite = {
1484                         .hash = {
1485                                 .vecs = hmac_sha224_tv_template,
1486                                 .count = HMAC_SHA224_TEST_VECTORS
1487                         }
1488                 }
1489         }, {
1490                 .alg = "hmac(sha256)",
1491                 .test = alg_test_hash,
1492                 .suite = {
1493                         .hash = {
1494                                 .vecs = hmac_sha256_tv_template,
1495                                 .count = HMAC_SHA256_TEST_VECTORS
1496                         }
1497                 }
1498         }, {
1499                 .alg = "hmac(sha384)",
1500                 .test = alg_test_hash,
1501                 .suite = {
1502                         .hash = {
1503                                 .vecs = hmac_sha384_tv_template,
1504                                 .count = HMAC_SHA384_TEST_VECTORS
1505                         }
1506                 }
1507         }, {
1508                 .alg = "hmac(sha512)",
1509                 .test = alg_test_hash,
1510                 .suite = {
1511                         .hash = {
1512                                 .vecs = hmac_sha512_tv_template,
1513                                 .count = HMAC_SHA512_TEST_VECTORS
1514                         }
1515                 }
1516         }, {
1517                 .alg = "lrw(aes)",
1518                 .test = alg_test_skcipher,
1519                 .suite = {
1520                         .cipher = {
1521                                 .enc = {
1522                                         .vecs = aes_lrw_enc_tv_template,
1523                                         .count = AES_LRW_ENC_TEST_VECTORS
1524                                 },
1525                                 .dec = {
1526                                         .vecs = aes_lrw_dec_tv_template,
1527                                         .count = AES_LRW_DEC_TEST_VECTORS
1528                                 }
1529                         }
1530                 }
1531         }, {
1532                 .alg = "lzo",
1533                 .test = alg_test_comp,
1534                 .suite = {
1535                         .comp = {
1536                                 .comp = {
1537                                         .vecs = lzo_comp_tv_template,
1538                                         .count = LZO_COMP_TEST_VECTORS
1539                                 },
1540                                 .decomp = {
1541                                         .vecs = lzo_decomp_tv_template,
1542                                         .count = LZO_DECOMP_TEST_VECTORS
1543                                 }
1544                         }
1545                 }
1546         }, {
1547                 .alg = "md4",
1548                 .test = alg_test_hash,
1549                 .suite = {
1550                         .hash = {
1551                                 .vecs = md4_tv_template,
1552                                 .count = MD4_TEST_VECTORS
1553                         }
1554                 }
1555         }, {
1556                 .alg = "md5",
1557                 .test = alg_test_hash,
1558                 .suite = {
1559                         .hash = {
1560                                 .vecs = md5_tv_template,
1561                                 .count = MD5_TEST_VECTORS
1562                         }
1563                 }
1564         }, {
1565                 .alg = "michael_mic",
1566                 .test = alg_test_hash,
1567                 .suite = {
1568                         .hash = {
1569                                 .vecs = michael_mic_tv_template,
1570                                 .count = MICHAEL_MIC_TEST_VECTORS
1571                         }
1572                 }
1573         }, {
1574                 .alg = "pcbc(fcrypt)",
1575                 .test = alg_test_skcipher,
1576                 .suite = {
1577                         .cipher = {
1578                                 .enc = {
1579                                         .vecs = fcrypt_pcbc_enc_tv_template,
1580                                         .count = FCRYPT_ENC_TEST_VECTORS
1581                                 },
1582                                 .dec = {
1583                                         .vecs = fcrypt_pcbc_dec_tv_template,
1584                                         .count = FCRYPT_DEC_TEST_VECTORS
1585                                 }
1586                         }
1587                 }
1588         }, {
1589                 .alg = "rfc3686(ctr(aes))",
1590                 .test = alg_test_skcipher,
1591                 .suite = {
1592                         .cipher = {
1593                                 .enc = {
1594                                         .vecs = aes_ctr_enc_tv_template,
1595                                         .count = AES_CTR_ENC_TEST_VECTORS
1596                                 },
1597                                 .dec = {
1598                                         .vecs = aes_ctr_dec_tv_template,
1599                                         .count = AES_CTR_DEC_TEST_VECTORS
1600                                 }
1601                         }
1602                 }
1603         }, {
1604                 .alg = "rmd128",
1605                 .test = alg_test_hash,
1606                 .suite = {
1607                         .hash = {
1608                                 .vecs = rmd128_tv_template,
1609                                 .count = RMD128_TEST_VECTORS
1610                         }
1611                 }
1612         }, {
1613                 .alg = "rmd160",
1614                 .test = alg_test_hash,
1615                 .suite = {
1616                         .hash = {
1617                                 .vecs = rmd160_tv_template,
1618                                 .count = RMD160_TEST_VECTORS
1619                         }
1620                 }
1621         }, {
1622                 .alg = "rmd256",
1623                 .test = alg_test_hash,
1624                 .suite = {
1625                         .hash = {
1626                                 .vecs = rmd256_tv_template,
1627                                 .count = RMD256_TEST_VECTORS
1628                         }
1629                 }
1630         }, {
1631                 .alg = "rmd320",
1632                 .test = alg_test_hash,
1633                 .suite = {
1634                         .hash = {
1635                                 .vecs = rmd320_tv_template,
1636                                 .count = RMD320_TEST_VECTORS
1637                         }
1638                 }
1639         }, {
1640                 .alg = "salsa20",
1641                 .test = alg_test_skcipher,
1642                 .suite = {
1643                         .cipher = {
1644                                 .enc = {
1645                                         .vecs = salsa20_stream_enc_tv_template,
1646                                         .count = SALSA20_STREAM_ENC_TEST_VECTORS
1647                                 }
1648                         }
1649                 }
1650         }, {
1651                 .alg = "sha1",
1652                 .test = alg_test_hash,
1653                 .suite = {
1654                         .hash = {
1655                                 .vecs = sha1_tv_template,
1656                                 .count = SHA1_TEST_VECTORS
1657                         }
1658                 }
1659         }, {
1660                 .alg = "sha224",
1661                 .test = alg_test_hash,
1662                 .suite = {
1663                         .hash = {
1664                                 .vecs = sha224_tv_template,
1665                                 .count = SHA224_TEST_VECTORS
1666                         }
1667                 }
1668         }, {
1669                 .alg = "sha256",
1670                 .test = alg_test_hash,
1671                 .suite = {
1672                         .hash = {
1673                                 .vecs = sha256_tv_template,
1674                                 .count = SHA256_TEST_VECTORS
1675                         }
1676                 }
1677         }, {
1678                 .alg = "sha384",
1679                 .test = alg_test_hash,
1680                 .suite = {
1681                         .hash = {
1682                                 .vecs = sha384_tv_template,
1683                                 .count = SHA384_TEST_VECTORS
1684                         }
1685                 }
1686         }, {
1687                 .alg = "sha512",
1688                 .test = alg_test_hash,
1689                 .suite = {
1690                         .hash = {
1691                                 .vecs = sha512_tv_template,
1692                                 .count = SHA512_TEST_VECTORS
1693                         }
1694                 }
1695         }, {
1696                 .alg = "tgr128",
1697                 .test = alg_test_hash,
1698                 .suite = {
1699                         .hash = {
1700                                 .vecs = tgr128_tv_template,
1701                                 .count = TGR128_TEST_VECTORS
1702                         }
1703                 }
1704         }, {
1705                 .alg = "tgr160",
1706                 .test = alg_test_hash,
1707                 .suite = {
1708                         .hash = {
1709                                 .vecs = tgr160_tv_template,
1710                                 .count = TGR160_TEST_VECTORS
1711                         }
1712                 }
1713         }, {
1714                 .alg = "tgr192",
1715                 .test = alg_test_hash,
1716                 .suite = {
1717                         .hash = {
1718                                 .vecs = tgr192_tv_template,
1719                                 .count = TGR192_TEST_VECTORS
1720                         }
1721                 }
1722         }, {
1723                 .alg = "wp256",
1724                 .test = alg_test_hash,
1725                 .suite = {
1726                         .hash = {
1727                                 .vecs = wp256_tv_template,
1728                                 .count = WP256_TEST_VECTORS
1729                         }
1730                 }
1731         }, {
1732                 .alg = "wp384",
1733                 .test = alg_test_hash,
1734                 .suite = {
1735                         .hash = {
1736                                 .vecs = wp384_tv_template,
1737                                 .count = WP384_TEST_VECTORS
1738                         }
1739                 }
1740         }, {
1741                 .alg = "wp512",
1742                 .test = alg_test_hash,
1743                 .suite = {
1744                         .hash = {
1745                                 .vecs = wp512_tv_template,
1746                                 .count = WP512_TEST_VECTORS
1747                         }
1748                 }
1749         }, {
1750                 .alg = "xcbc(aes)",
1751                 .test = alg_test_hash,
1752                 .suite = {
1753                         .hash = {
1754                                 .vecs = aes_xcbc128_tv_template,
1755                                 .count = XCBC_AES_TEST_VECTORS
1756                         }
1757                 }
1758         }, {
1759                 .alg = "xts(aes)",
1760                 .test = alg_test_skcipher,
1761                 .suite = {
1762                         .cipher = {
1763                                 .enc = {
1764                                         .vecs = aes_xts_enc_tv_template,
1765                                         .count = AES_XTS_ENC_TEST_VECTORS
1766                                 },
1767                                 .dec = {
1768                                         .vecs = aes_xts_dec_tv_template,
1769                                         .count = AES_XTS_DEC_TEST_VECTORS
1770                                 }
1771                         }
1772                 }
1773         }
1774 };
1775
1776 static int alg_find_test(const char *alg)
1777 {
1778         int start = 0;
1779         int end = ARRAY_SIZE(alg_test_descs);
1780
1781         while (start < end) {
1782                 int i = (start + end) / 2;
1783                 int diff = strcmp(alg_test_descs[i].alg, alg);
1784
1785                 if (diff > 0) {
1786                         end = i;
1787                         continue;
1788                 }
1789
1790                 if (diff < 0) {
1791                         start = i + 1;
1792                         continue;
1793                 }
1794
1795                 return i;
1796         }
1797
1798         return -1;
1799 }
1800
1801 int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
1802 {
1803         int i;
1804         int rc;
1805
1806         if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
1807                 char nalg[CRYPTO_MAX_ALG_NAME];
1808
1809                 if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
1810                     sizeof(nalg))
1811                         return -ENAMETOOLONG;
1812
1813                 i = alg_find_test(nalg);
1814                 if (i < 0)
1815                         goto notest;
1816
1817                 return alg_test_cipher(alg_test_descs + i, driver, type, mask);
1818         }
1819
1820         i = alg_find_test(alg);
1821         if (i < 0)
1822                 goto notest;
1823
1824         rc = alg_test_descs[i].test(alg_test_descs + i, driver,
1825                                       type, mask);
1826         if (fips_enabled && rc)
1827                 panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
1828
1829         return rc;
1830
1831 notest:
1832         printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
1833         return 0;
1834 }
1835 EXPORT_SYMBOL_GPL(alg_test);
1836
1837 int __init testmgr_init(void)
1838 {
1839         int i;
1840
1841         for (i = 0; i < XBUFSIZE; i++) {
1842                 xbuf[i] = (void *)__get_free_page(GFP_KERNEL);
1843                 if (!xbuf[i])
1844                         goto err_free_xbuf;
1845         }
1846
1847         for (i = 0; i < XBUFSIZE; i++) {
1848                 axbuf[i] = (void *)__get_free_page(GFP_KERNEL);
1849                 if (!axbuf[i])
1850                         goto err_free_axbuf;
1851         }
1852
1853         return 0;
1854
1855 err_free_axbuf:
1856         for (i = 0; i < XBUFSIZE && axbuf[i]; i++)
1857                 free_page((unsigned long)axbuf[i]);
1858 err_free_xbuf:
1859         for (i = 0; i < XBUFSIZE && xbuf[i]; i++)
1860                 free_page((unsigned long)xbuf[i]);
1861
1862         return -ENOMEM;
1863 }
1864
1865 void testmgr_exit(void)
1866 {
1867         int i;
1868
1869         for (i = 0; i < XBUFSIZE; i++)
1870                 free_page((unsigned long)axbuf[i]);
1871         for (i = 0; i < XBUFSIZE; i++)
1872                 free_page((unsigned long)xbuf[i]);
1873 }