blob: 8fcea70ed267092d0b8f5ebf69f4a62cabd47da3 [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
Herbert Xufd57f222009-05-29 16:05:42 +1000188 ret = -EINVAL;
189 if (WARN_ON(template[i].psize > PAGE_SIZE))
190 goto out;
191
Herbert Xuda7f0332008-07-31 17:08:25 +0800192 memcpy(hash_buff, template[i].plaintext, template[i].psize);
193 sg_init_one(&sg[0], hash_buff, template[i].psize);
194
195 if (template[i].ksize) {
196 crypto_ahash_clear_flags(tfm, ~0);
197 ret = crypto_ahash_setkey(tfm, template[i].key,
198 template[i].ksize);
199 if (ret) {
200 printk(KERN_ERR "alg: hash: setkey failed on "
201 "test %d for %s: ret=%d\n", i + 1, algo,
202 -ret);
203 goto out;
204 }
205 }
206
207 ahash_request_set_crypt(req, sg, result, template[i].psize);
208 ret = crypto_ahash_digest(req);
209 switch (ret) {
210 case 0:
211 break;
212 case -EINPROGRESS:
213 case -EBUSY:
214 ret = wait_for_completion_interruptible(
215 &tresult.completion);
216 if (!ret && !(ret = tresult.err)) {
217 INIT_COMPLETION(tresult.completion);
218 break;
219 }
220 /* fall through */
221 default:
222 printk(KERN_ERR "alg: hash: digest failed on test %d "
223 "for %s: ret=%d\n", i + 1, algo, -ret);
224 goto out;
225 }
226
227 if (memcmp(result, template[i].digest,
228 crypto_ahash_digestsize(tfm))) {
229 printk(KERN_ERR "alg: hash: Test %d failed for %s\n",
230 i + 1, algo);
231 hexdump(result, crypto_ahash_digestsize(tfm));
232 ret = -EINVAL;
233 goto out;
234 }
235 }
236
237 j = 0;
238 for (i = 0; i < tcount; i++) {
239 if (template[i].np) {
240 j++;
241 memset(result, 0, 64);
242
243 temp = 0;
244 sg_init_table(sg, template[i].np);
Herbert Xufd57f222009-05-29 16:05:42 +1000245 ret = -EINVAL;
Herbert Xuda7f0332008-07-31 17:08:25 +0800246 for (k = 0; k < template[i].np; k++) {
Herbert Xufd57f222009-05-29 16:05:42 +1000247 if (WARN_ON(offset_in_page(IDX[k]) +
248 template[i].tap[k] > PAGE_SIZE))
249 goto out;
Herbert Xuda7f0332008-07-31 17:08:25 +0800250 sg_set_buf(&sg[k],
251 memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
252 offset_in_page(IDX[k]),
253 template[i].plaintext + temp,
254 template[i].tap[k]),
255 template[i].tap[k]);
256 temp += template[i].tap[k];
257 }
258
259 if (template[i].ksize) {
260 crypto_ahash_clear_flags(tfm, ~0);
261 ret = crypto_ahash_setkey(tfm, template[i].key,
262 template[i].ksize);
263
264 if (ret) {
265 printk(KERN_ERR "alg: hash: setkey "
266 "failed on chunking test %d "
267 "for %s: ret=%d\n", j, algo,
268 -ret);
269 goto out;
270 }
271 }
272
273 ahash_request_set_crypt(req, sg, result,
274 template[i].psize);
275 ret = crypto_ahash_digest(req);
276 switch (ret) {
277 case 0:
278 break;
279 case -EINPROGRESS:
280 case -EBUSY:
281 ret = wait_for_completion_interruptible(
282 &tresult.completion);
283 if (!ret && !(ret = tresult.err)) {
284 INIT_COMPLETION(tresult.completion);
285 break;
286 }
287 /* fall through */
288 default:
289 printk(KERN_ERR "alg: hash: digest failed "
290 "on chunking test %d for %s: "
291 "ret=%d\n", j, algo, -ret);
292 goto out;
293 }
294
295 if (memcmp(result, template[i].digest,
296 crypto_ahash_digestsize(tfm))) {
297 printk(KERN_ERR "alg: hash: Chunking test %d "
298 "failed for %s\n", j, algo);
299 hexdump(result, crypto_ahash_digestsize(tfm));
300 ret = -EINVAL;
301 goto out;
302 }
303 }
304 }
305
306 ret = 0;
307
308out:
309 ahash_request_free(req);
310out_noreq:
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800311 testmgr_free_buf(xbuf);
312out_nobuf:
Herbert Xuda7f0332008-07-31 17:08:25 +0800313 return ret;
314}
315
316static int test_aead(struct crypto_aead *tfm, int enc,
317 struct aead_testvec *template, unsigned int tcount)
318{
319 const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
320 unsigned int i, j, k, n, temp;
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800321 int ret = -ENOMEM;
Herbert Xuda7f0332008-07-31 17:08:25 +0800322 char *q;
323 char *key;
324 struct aead_request *req;
325 struct scatterlist sg[8];
326 struct scatterlist asg[8];
327 const char *e;
328 struct tcrypt_result result;
329 unsigned int authsize;
330 void *input;
331 void *assoc;
332 char iv[MAX_IVLEN];
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800333 char *xbuf[XBUFSIZE];
334 char *axbuf[XBUFSIZE];
335
336 if (testmgr_alloc_buf(xbuf))
337 goto out_noxbuf;
338 if (testmgr_alloc_buf(axbuf))
339 goto out_noaxbuf;
Herbert Xuda7f0332008-07-31 17:08:25 +0800340
341 if (enc == ENCRYPT)
342 e = "encryption";
343 else
344 e = "decryption";
345
346 init_completion(&result.completion);
347
348 req = aead_request_alloc(tfm, GFP_KERNEL);
349 if (!req) {
350 printk(KERN_ERR "alg: aead: Failed to allocate request for "
351 "%s\n", algo);
Herbert Xuda7f0332008-07-31 17:08:25 +0800352 goto out;
353 }
354
355 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
356 tcrypt_complete, &result);
357
358 for (i = 0, j = 0; i < tcount; i++) {
359 if (!template[i].np) {
360 j++;
361
362 /* some tepmplates have no input data but they will
363 * touch input
364 */
365 input = xbuf[0];
366 assoc = axbuf[0];
367
Herbert Xufd57f222009-05-29 16:05:42 +1000368 ret = -EINVAL;
369 if (WARN_ON(template[i].ilen > PAGE_SIZE ||
370 template[i].alen > PAGE_SIZE))
371 goto out;
372
Herbert Xuda7f0332008-07-31 17:08:25 +0800373 memcpy(input, template[i].input, template[i].ilen);
374 memcpy(assoc, template[i].assoc, template[i].alen);
375 if (template[i].iv)
376 memcpy(iv, template[i].iv, MAX_IVLEN);
377 else
378 memset(iv, 0, MAX_IVLEN);
379
380 crypto_aead_clear_flags(tfm, ~0);
381 if (template[i].wk)
382 crypto_aead_set_flags(
383 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
384
385 key = template[i].key;
386
387 ret = crypto_aead_setkey(tfm, key,
388 template[i].klen);
389 if (!ret == template[i].fail) {
390 printk(KERN_ERR "alg: aead: setkey failed on "
391 "test %d for %s: flags=%x\n", j, algo,
392 crypto_aead_get_flags(tfm));
393 goto out;
394 } else if (ret)
395 continue;
396
397 authsize = abs(template[i].rlen - template[i].ilen);
398 ret = crypto_aead_setauthsize(tfm, authsize);
399 if (ret) {
400 printk(KERN_ERR "alg: aead: Failed to set "
401 "authsize to %u on test %d for %s\n",
402 authsize, j, algo);
403 goto out;
404 }
405
406 sg_init_one(&sg[0], input,
407 template[i].ilen + (enc ? authsize : 0));
408
409 sg_init_one(&asg[0], assoc, template[i].alen);
410
411 aead_request_set_crypt(req, sg, sg,
412 template[i].ilen, iv);
413
414 aead_request_set_assoc(req, asg, template[i].alen);
415
416 ret = enc ?
417 crypto_aead_encrypt(req) :
418 crypto_aead_decrypt(req);
419
420 switch (ret) {
421 case 0:
Jarod Wilsone44a1b42009-05-04 19:22:11 +0800422 if (template[i].novrfy) {
423 /* verification was supposed to fail */
424 printk(KERN_ERR "alg: aead: %s failed "
425 "on test %d for %s: ret was 0, "
426 "expected -EBADMSG\n",
427 e, j, algo);
428 /* so really, we got a bad message */
429 ret = -EBADMSG;
430 goto out;
431 }
Herbert Xuda7f0332008-07-31 17:08:25 +0800432 break;
433 case -EINPROGRESS:
434 case -EBUSY:
435 ret = wait_for_completion_interruptible(
436 &result.completion);
437 if (!ret && !(ret = result.err)) {
438 INIT_COMPLETION(result.completion);
439 break;
440 }
Jarod Wilsone44a1b42009-05-04 19:22:11 +0800441 case -EBADMSG:
442 if (template[i].novrfy)
443 /* verification failure was expected */
444 continue;
Herbert Xuda7f0332008-07-31 17:08:25 +0800445 /* fall through */
446 default:
447 printk(KERN_ERR "alg: aead: %s failed on test "
448 "%d for %s: ret=%d\n", e, j, algo, -ret);
449 goto out;
450 }
451
452 q = input;
453 if (memcmp(q, template[i].result, template[i].rlen)) {
454 printk(KERN_ERR "alg: aead: Test %d failed on "
455 "%s for %s\n", j, e, algo);
456 hexdump(q, template[i].rlen);
457 ret = -EINVAL;
458 goto out;
459 }
460 }
461 }
462
463 for (i = 0, j = 0; i < tcount; i++) {
464 if (template[i].np) {
465 j++;
466
467 if (template[i].iv)
468 memcpy(iv, template[i].iv, MAX_IVLEN);
469 else
470 memset(iv, 0, MAX_IVLEN);
471
472 crypto_aead_clear_flags(tfm, ~0);
473 if (template[i].wk)
474 crypto_aead_set_flags(
475 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
476 key = template[i].key;
477
478 ret = crypto_aead_setkey(tfm, key, template[i].klen);
479 if (!ret == template[i].fail) {
480 printk(KERN_ERR "alg: aead: setkey failed on "
481 "chunk test %d for %s: flags=%x\n", j,
482 algo, crypto_aead_get_flags(tfm));
483 goto out;
484 } else if (ret)
485 continue;
486
487 authsize = abs(template[i].rlen - template[i].ilen);
488
489 ret = -EINVAL;
490 sg_init_table(sg, template[i].np);
491 for (k = 0, temp = 0; k < template[i].np; k++) {
492 if (WARN_ON(offset_in_page(IDX[k]) +
493 template[i].tap[k] > PAGE_SIZE))
494 goto out;
495
496 q = xbuf[IDX[k] >> PAGE_SHIFT] +
497 offset_in_page(IDX[k]);
498
499 memcpy(q, template[i].input + temp,
500 template[i].tap[k]);
501
502 n = template[i].tap[k];
503 if (k == template[i].np - 1 && enc)
504 n += authsize;
505 if (offset_in_page(q) + n < PAGE_SIZE)
506 q[n] = 0;
507
508 sg_set_buf(&sg[k], q, template[i].tap[k]);
509 temp += template[i].tap[k];
510 }
511
512 ret = crypto_aead_setauthsize(tfm, authsize);
513 if (ret) {
514 printk(KERN_ERR "alg: aead: Failed to set "
515 "authsize to %u on chunk test %d for "
516 "%s\n", authsize, j, algo);
517 goto out;
518 }
519
520 if (enc) {
521 if (WARN_ON(sg[k - 1].offset +
522 sg[k - 1].length + authsize >
523 PAGE_SIZE)) {
524 ret = -EINVAL;
525 goto out;
526 }
527
528 sg[k - 1].length += authsize;
529 }
530
531 sg_init_table(asg, template[i].anp);
Herbert Xufd57f222009-05-29 16:05:42 +1000532 ret = -EINVAL;
Herbert Xuda7f0332008-07-31 17:08:25 +0800533 for (k = 0, temp = 0; k < template[i].anp; k++) {
Herbert Xufd57f222009-05-29 16:05:42 +1000534 if (WARN_ON(offset_in_page(IDX[k]) +
535 template[i].atap[k] > PAGE_SIZE))
536 goto out;
Herbert Xuda7f0332008-07-31 17:08:25 +0800537 sg_set_buf(&asg[k],
538 memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
539 offset_in_page(IDX[k]),
540 template[i].assoc + temp,
541 template[i].atap[k]),
542 template[i].atap[k]);
543 temp += template[i].atap[k];
544 }
545
546 aead_request_set_crypt(req, sg, sg,
547 template[i].ilen,
548 iv);
549
550 aead_request_set_assoc(req, asg, template[i].alen);
551
552 ret = enc ?
553 crypto_aead_encrypt(req) :
554 crypto_aead_decrypt(req);
555
556 switch (ret) {
557 case 0:
Jarod Wilsone44a1b42009-05-04 19:22:11 +0800558 if (template[i].novrfy) {
559 /* verification was supposed to fail */
560 printk(KERN_ERR "alg: aead: %s failed "
561 "on chunk test %d for %s: ret "
562 "was 0, expected -EBADMSG\n",
563 e, j, algo);
564 /* so really, we got a bad message */
565 ret = -EBADMSG;
566 goto out;
567 }
Herbert Xuda7f0332008-07-31 17:08:25 +0800568 break;
569 case -EINPROGRESS:
570 case -EBUSY:
571 ret = wait_for_completion_interruptible(
572 &result.completion);
573 if (!ret && !(ret = result.err)) {
574 INIT_COMPLETION(result.completion);
575 break;
576 }
Jarod Wilsone44a1b42009-05-04 19:22:11 +0800577 case -EBADMSG:
578 if (template[i].novrfy)
579 /* verification failure was expected */
580 continue;
Herbert Xuda7f0332008-07-31 17:08:25 +0800581 /* fall through */
582 default:
583 printk(KERN_ERR "alg: aead: %s failed on "
584 "chunk test %d for %s: ret=%d\n", e, j,
585 algo, -ret);
586 goto out;
587 }
588
589 ret = -EINVAL;
590 for (k = 0, temp = 0; k < template[i].np; k++) {
591 q = xbuf[IDX[k] >> PAGE_SHIFT] +
592 offset_in_page(IDX[k]);
593
594 n = template[i].tap[k];
595 if (k == template[i].np - 1)
596 n += enc ? authsize : -authsize;
597
598 if (memcmp(q, template[i].result + temp, n)) {
599 printk(KERN_ERR "alg: aead: Chunk "
600 "test %d failed on %s at page "
601 "%u for %s\n", j, e, k, algo);
602 hexdump(q, n);
603 goto out;
604 }
605
606 q += n;
607 if (k == template[i].np - 1 && !enc) {
608 if (memcmp(q, template[i].input +
609 temp + n, authsize))
610 n = authsize;
611 else
612 n = 0;
613 } else {
614 for (n = 0; offset_in_page(q + n) &&
615 q[n]; n++)
616 ;
617 }
618 if (n) {
619 printk(KERN_ERR "alg: aead: Result "
620 "buffer corruption in chunk "
621 "test %d on %s at page %u for "
622 "%s: %u bytes:\n", j, e, k,
623 algo, n);
624 hexdump(q, n);
625 goto out;
626 }
627
628 temp += template[i].tap[k];
629 }
630 }
631 }
632
633 ret = 0;
634
635out:
636 aead_request_free(req);
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800637 testmgr_free_buf(axbuf);
638out_noaxbuf:
639 testmgr_free_buf(xbuf);
640out_noxbuf:
Herbert Xuda7f0332008-07-31 17:08:25 +0800641 return ret;
642}
643
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000644static int test_cipher(struct crypto_cipher *tfm, int enc,
Herbert Xuda7f0332008-07-31 17:08:25 +0800645 struct cipher_testvec *template, unsigned int tcount)
646{
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000647 const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
648 unsigned int i, j, k;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000649 char *q;
650 const char *e;
651 void *data;
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800652 char *xbuf[XBUFSIZE];
653 int ret = -ENOMEM;
654
655 if (testmgr_alloc_buf(xbuf))
656 goto out_nobuf;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000657
658 if (enc == ENCRYPT)
659 e = "encryption";
660 else
661 e = "decryption";
662
663 j = 0;
664 for (i = 0; i < tcount; i++) {
665 if (template[i].np)
666 continue;
667
668 j++;
669
Herbert Xufd57f222009-05-29 16:05:42 +1000670 ret = -EINVAL;
671 if (WARN_ON(template[i].ilen > PAGE_SIZE))
672 goto out;
673
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000674 data = xbuf[0];
675 memcpy(data, template[i].input, template[i].ilen);
676
677 crypto_cipher_clear_flags(tfm, ~0);
678 if (template[i].wk)
679 crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
680
681 ret = crypto_cipher_setkey(tfm, template[i].key,
682 template[i].klen);
683 if (!ret == template[i].fail) {
684 printk(KERN_ERR "alg: cipher: setkey failed "
685 "on test %d for %s: flags=%x\n", j,
686 algo, crypto_cipher_get_flags(tfm));
687 goto out;
688 } else if (ret)
689 continue;
690
691 for (k = 0; k < template[i].ilen;
692 k += crypto_cipher_blocksize(tfm)) {
693 if (enc)
694 crypto_cipher_encrypt_one(tfm, data + k,
695 data + k);
696 else
697 crypto_cipher_decrypt_one(tfm, data + k,
698 data + k);
699 }
700
701 q = data;
702 if (memcmp(q, template[i].result, template[i].rlen)) {
703 printk(KERN_ERR "alg: cipher: Test %d failed "
704 "on %s for %s\n", j, e, algo);
705 hexdump(q, template[i].rlen);
706 ret = -EINVAL;
707 goto out;
708 }
709 }
710
711 ret = 0;
712
713out:
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800714 testmgr_free_buf(xbuf);
715out_nobuf:
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000716 return ret;
717}
718
719static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
720 struct cipher_testvec *template, unsigned int tcount)
721{
Herbert Xuda7f0332008-07-31 17:08:25 +0800722 const char *algo =
723 crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
724 unsigned int i, j, k, n, temp;
Herbert Xuda7f0332008-07-31 17:08:25 +0800725 char *q;
726 struct ablkcipher_request *req;
727 struct scatterlist sg[8];
728 const char *e;
729 struct tcrypt_result result;
730 void *data;
731 char iv[MAX_IVLEN];
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800732 char *xbuf[XBUFSIZE];
733 int ret = -ENOMEM;
734
735 if (testmgr_alloc_buf(xbuf))
736 goto out_nobuf;
Herbert Xuda7f0332008-07-31 17:08:25 +0800737
738 if (enc == ENCRYPT)
739 e = "encryption";
740 else
741 e = "decryption";
742
743 init_completion(&result.completion);
744
745 req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
746 if (!req) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000747 printk(KERN_ERR "alg: skcipher: Failed to allocate request "
748 "for %s\n", algo);
Herbert Xuda7f0332008-07-31 17:08:25 +0800749 goto out;
750 }
751
752 ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
753 tcrypt_complete, &result);
754
755 j = 0;
756 for (i = 0; i < tcount; i++) {
757 if (template[i].iv)
758 memcpy(iv, template[i].iv, MAX_IVLEN);
759 else
760 memset(iv, 0, MAX_IVLEN);
761
762 if (!(template[i].np)) {
763 j++;
764
Herbert Xufd57f222009-05-29 16:05:42 +1000765 ret = -EINVAL;
766 if (WARN_ON(template[i].ilen > PAGE_SIZE))
767 goto out;
768
Herbert Xuda7f0332008-07-31 17:08:25 +0800769 data = xbuf[0];
770 memcpy(data, template[i].input, template[i].ilen);
771
772 crypto_ablkcipher_clear_flags(tfm, ~0);
773 if (template[i].wk)
774 crypto_ablkcipher_set_flags(
775 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
776
777 ret = crypto_ablkcipher_setkey(tfm, template[i].key,
778 template[i].klen);
779 if (!ret == template[i].fail) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000780 printk(KERN_ERR "alg: skcipher: setkey failed "
Herbert Xuda7f0332008-07-31 17:08:25 +0800781 "on test %d for %s: flags=%x\n", j,
782 algo, crypto_ablkcipher_get_flags(tfm));
783 goto out;
784 } else if (ret)
785 continue;
786
787 sg_init_one(&sg[0], data, template[i].ilen);
788
789 ablkcipher_request_set_crypt(req, sg, sg,
790 template[i].ilen, iv);
791 ret = enc ?
792 crypto_ablkcipher_encrypt(req) :
793 crypto_ablkcipher_decrypt(req);
794
795 switch (ret) {
796 case 0:
797 break;
798 case -EINPROGRESS:
799 case -EBUSY:
800 ret = wait_for_completion_interruptible(
801 &result.completion);
802 if (!ret && !((ret = result.err))) {
803 INIT_COMPLETION(result.completion);
804 break;
805 }
806 /* fall through */
807 default:
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000808 printk(KERN_ERR "alg: skcipher: %s failed on "
Herbert Xuda7f0332008-07-31 17:08:25 +0800809 "test %d for %s: ret=%d\n", e, j, algo,
810 -ret);
811 goto out;
812 }
813
814 q = data;
815 if (memcmp(q, template[i].result, template[i].rlen)) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000816 printk(KERN_ERR "alg: skcipher: Test %d "
817 "failed on %s for %s\n", j, e, algo);
Herbert Xuda7f0332008-07-31 17:08:25 +0800818 hexdump(q, template[i].rlen);
819 ret = -EINVAL;
820 goto out;
821 }
822 }
823 }
824
825 j = 0;
826 for (i = 0; i < tcount; i++) {
827
828 if (template[i].iv)
829 memcpy(iv, template[i].iv, MAX_IVLEN);
830 else
831 memset(iv, 0, MAX_IVLEN);
832
833 if (template[i].np) {
834 j++;
835
836 crypto_ablkcipher_clear_flags(tfm, ~0);
837 if (template[i].wk)
838 crypto_ablkcipher_set_flags(
839 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
840
841 ret = crypto_ablkcipher_setkey(tfm, template[i].key,
842 template[i].klen);
843 if (!ret == template[i].fail) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000844 printk(KERN_ERR "alg: skcipher: setkey failed "
Herbert Xuda7f0332008-07-31 17:08:25 +0800845 "on chunk test %d for %s: flags=%x\n",
846 j, algo,
847 crypto_ablkcipher_get_flags(tfm));
848 goto out;
849 } else if (ret)
850 continue;
851
852 temp = 0;
853 ret = -EINVAL;
854 sg_init_table(sg, template[i].np);
855 for (k = 0; k < template[i].np; k++) {
856 if (WARN_ON(offset_in_page(IDX[k]) +
857 template[i].tap[k] > PAGE_SIZE))
858 goto out;
859
860 q = xbuf[IDX[k] >> PAGE_SHIFT] +
861 offset_in_page(IDX[k]);
862
863 memcpy(q, template[i].input + temp,
864 template[i].tap[k]);
865
866 if (offset_in_page(q) + template[i].tap[k] <
867 PAGE_SIZE)
868 q[template[i].tap[k]] = 0;
869
870 sg_set_buf(&sg[k], q, template[i].tap[k]);
871
872 temp += template[i].tap[k];
873 }
874
875 ablkcipher_request_set_crypt(req, sg, sg,
876 template[i].ilen, iv);
877
878 ret = enc ?
879 crypto_ablkcipher_encrypt(req) :
880 crypto_ablkcipher_decrypt(req);
881
882 switch (ret) {
883 case 0:
884 break;
885 case -EINPROGRESS:
886 case -EBUSY:
887 ret = wait_for_completion_interruptible(
888 &result.completion);
889 if (!ret && !((ret = result.err))) {
890 INIT_COMPLETION(result.completion);
891 break;
892 }
893 /* fall through */
894 default:
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000895 printk(KERN_ERR "alg: skcipher: %s failed on "
Herbert Xuda7f0332008-07-31 17:08:25 +0800896 "chunk test %d for %s: ret=%d\n", e, j,
897 algo, -ret);
898 goto out;
899 }
900
901 temp = 0;
902 ret = -EINVAL;
903 for (k = 0; k < template[i].np; k++) {
904 q = xbuf[IDX[k] >> PAGE_SHIFT] +
905 offset_in_page(IDX[k]);
906
907 if (memcmp(q, template[i].result + temp,
908 template[i].tap[k])) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000909 printk(KERN_ERR "alg: skcipher: Chunk "
Herbert Xuda7f0332008-07-31 17:08:25 +0800910 "test %d failed on %s at page "
911 "%u for %s\n", j, e, k, algo);
912 hexdump(q, template[i].tap[k]);
913 goto out;
914 }
915
916 q += template[i].tap[k];
917 for (n = 0; offset_in_page(q + n) && q[n]; n++)
918 ;
919 if (n) {
Herbert Xu1aa4ecd2008-08-17 17:01:56 +1000920 printk(KERN_ERR "alg: skcipher: "
Herbert Xuda7f0332008-07-31 17:08:25 +0800921 "Result buffer corruption in "
922 "chunk test %d on %s at page "
923 "%u for %s: %u bytes:\n", j, e,
924 k, algo, n);
925 hexdump(q, n);
926 goto out;
927 }
928 temp += template[i].tap[k];
929 }
930 }
931 }
932
933 ret = 0;
934
935out:
936 ablkcipher_request_free(req);
Herbert Xuf8b0d4d2009-05-06 14:15:47 +0800937 testmgr_free_buf(xbuf);
938out_nobuf:
Herbert Xuda7f0332008-07-31 17:08:25 +0800939 return ret;
940}
941
942static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
943 struct comp_testvec *dtemplate, int ctcount, int dtcount)
944{
945 const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
946 unsigned int i;
947 char result[COMP_BUF_SIZE];
948 int ret;
949
950 for (i = 0; i < ctcount; i++) {
Geert Uytterhoevenc79cf912009-03-29 15:44:19 +0800951 int ilen;
952 unsigned int dlen = COMP_BUF_SIZE;
Herbert Xuda7f0332008-07-31 17:08:25 +0800953
954 memset(result, 0, sizeof (result));
955
956 ilen = ctemplate[i].inlen;
957 ret = crypto_comp_compress(tfm, ctemplate[i].input,
958 ilen, result, &dlen);
959 if (ret) {
960 printk(KERN_ERR "alg: comp: compression failed "
961 "on test %d for %s: ret=%d\n", i + 1, algo,
962 -ret);
963 goto out;
964 }
965
Geert Uytterhoevenb812eb02008-11-28 20:51:28 +0800966 if (dlen != ctemplate[i].outlen) {
967 printk(KERN_ERR "alg: comp: Compression test %d "
968 "failed for %s: output len = %d\n", i + 1, algo,
969 dlen);
970 ret = -EINVAL;
971 goto out;
972 }
973
Herbert Xuda7f0332008-07-31 17:08:25 +0800974 if (memcmp(result, ctemplate[i].output, dlen)) {
975 printk(KERN_ERR "alg: comp: Compression test %d "
976 "failed for %s\n", i + 1, algo);
977 hexdump(result, dlen);
978 ret = -EINVAL;
979 goto out;
980 }
981 }
982
983 for (i = 0; i < dtcount; i++) {
Geert Uytterhoevenc79cf912009-03-29 15:44:19 +0800984 int ilen;
985 unsigned int dlen = COMP_BUF_SIZE;
Herbert Xuda7f0332008-07-31 17:08:25 +0800986
987 memset(result, 0, sizeof (result));
988
989 ilen = dtemplate[i].inlen;
990 ret = crypto_comp_decompress(tfm, dtemplate[i].input,
991 ilen, result, &dlen);
992 if (ret) {
993 printk(KERN_ERR "alg: comp: decompression failed "
994 "on test %d for %s: ret=%d\n", i + 1, algo,
995 -ret);
996 goto out;
997 }
998
Geert Uytterhoevenb812eb02008-11-28 20:51:28 +0800999 if (dlen != dtemplate[i].outlen) {
1000 printk(KERN_ERR "alg: comp: Decompression test %d "
1001 "failed for %s: output len = %d\n", i + 1, algo,
1002 dlen);
1003 ret = -EINVAL;
1004 goto out;
1005 }
1006
Herbert Xuda7f0332008-07-31 17:08:25 +08001007 if (memcmp(result, dtemplate[i].output, dlen)) {
1008 printk(KERN_ERR "alg: comp: Decompression test %d "
1009 "failed for %s\n", i + 1, algo);
1010 hexdump(result, dlen);
1011 ret = -EINVAL;
1012 goto out;
1013 }
1014 }
1015
1016 ret = 0;
1017
1018out:
1019 return ret;
1020}
1021
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001022static int test_pcomp(struct crypto_pcomp *tfm,
1023 struct pcomp_testvec *ctemplate,
1024 struct pcomp_testvec *dtemplate, int ctcount,
1025 int dtcount)
1026{
1027 const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
1028 unsigned int i;
1029 char result[COMP_BUF_SIZE];
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001030 int res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001031
1032 for (i = 0; i < ctcount; i++) {
1033 struct comp_request req;
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001034 unsigned int produced = 0;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001035
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001036 res = crypto_compress_setup(tfm, ctemplate[i].params,
1037 ctemplate[i].paramsize);
1038 if (res) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001039 pr_err("alg: pcomp: compression setup failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001040 "%d for %s: error=%d\n", i + 1, algo, res);
1041 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001042 }
1043
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001044 res = crypto_compress_init(tfm);
1045 if (res) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001046 pr_err("alg: pcomp: compression init failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001047 "%d for %s: error=%d\n", i + 1, algo, res);
1048 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001049 }
1050
1051 memset(result, 0, sizeof(result));
1052
1053 req.next_in = ctemplate[i].input;
1054 req.avail_in = ctemplate[i].inlen / 2;
1055 req.next_out = result;
1056 req.avail_out = ctemplate[i].outlen / 2;
1057
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001058 res = crypto_compress_update(tfm, &req);
1059 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001060 pr_err("alg: pcomp: compression update failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001061 "%d for %s: error=%d\n", i + 1, algo, res);
1062 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001063 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001064 if (res > 0)
1065 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001066
1067 /* Add remaining input data */
1068 req.avail_in += (ctemplate[i].inlen + 1) / 2;
1069
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001070 res = crypto_compress_update(tfm, &req);
1071 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001072 pr_err("alg: pcomp: compression update failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001073 "%d for %s: error=%d\n", i + 1, algo, res);
1074 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001075 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001076 if (res > 0)
1077 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001078
1079 /* Provide remaining output space */
1080 req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
1081
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001082 res = crypto_compress_final(tfm, &req);
1083 if (res < 0) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001084 pr_err("alg: pcomp: compression final failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001085 "%d for %s: error=%d\n", i + 1, algo, res);
1086 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001087 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001088 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001089
1090 if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
1091 pr_err("alg: comp: Compression test %d failed for %s: "
1092 "output len = %d (expected %d)\n", i + 1, algo,
1093 COMP_BUF_SIZE - req.avail_out,
1094 ctemplate[i].outlen);
1095 return -EINVAL;
1096 }
1097
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001098 if (produced != ctemplate[i].outlen) {
1099 pr_err("alg: comp: Compression test %d failed for %s: "
1100 "returned len = %u (expected %d)\n", i + 1,
1101 algo, produced, ctemplate[i].outlen);
1102 return -EINVAL;
1103 }
1104
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001105 if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
1106 pr_err("alg: pcomp: Compression test %d failed for "
1107 "%s\n", i + 1, algo);
1108 hexdump(result, ctemplate[i].outlen);
1109 return -EINVAL;
1110 }
1111 }
1112
1113 for (i = 0; i < dtcount; i++) {
1114 struct comp_request req;
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001115 unsigned int produced = 0;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001116
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001117 res = crypto_decompress_setup(tfm, dtemplate[i].params,
1118 dtemplate[i].paramsize);
1119 if (res) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001120 pr_err("alg: pcomp: decompression setup failed on "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001121 "test %d for %s: error=%d\n", i + 1, algo, res);
1122 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001123 }
1124
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001125 res = crypto_decompress_init(tfm);
1126 if (res) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001127 pr_err("alg: pcomp: decompression init failed on test "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001128 "%d for %s: error=%d\n", i + 1, algo, res);
1129 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001130 }
1131
1132 memset(result, 0, sizeof(result));
1133
1134 req.next_in = dtemplate[i].input;
1135 req.avail_in = dtemplate[i].inlen / 2;
1136 req.next_out = result;
1137 req.avail_out = dtemplate[i].outlen / 2;
1138
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001139 res = crypto_decompress_update(tfm, &req);
1140 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001141 pr_err("alg: pcomp: decompression update failed on "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001142 "test %d for %s: error=%d\n", i + 1, algo, res);
1143 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001144 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001145 if (res > 0)
1146 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001147
1148 /* Add remaining input data */
1149 req.avail_in += (dtemplate[i].inlen + 1) / 2;
1150
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001151 res = crypto_decompress_update(tfm, &req);
1152 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001153 pr_err("alg: pcomp: decompression update failed on "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001154 "test %d for %s: error=%d\n", i + 1, algo, res);
1155 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001156 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001157 if (res > 0)
1158 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001159
1160 /* Provide remaining output space */
1161 req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
1162
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001163 res = crypto_decompress_final(tfm, &req);
1164 if (res < 0 && (res != -EAGAIN || req.avail_in)) {
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001165 pr_err("alg: pcomp: decompression final failed on "
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001166 "test %d for %s: error=%d\n", i + 1, algo, res);
1167 return res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001168 }
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001169 if (res > 0)
1170 produced += res;
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001171
1172 if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
1173 pr_err("alg: comp: Decompression test %d failed for "
1174 "%s: output len = %d (expected %d)\n", i + 1,
1175 algo, COMP_BUF_SIZE - req.avail_out,
1176 dtemplate[i].outlen);
1177 return -EINVAL;
1178 }
1179
Geert Uytterhoeven3ce858c2009-05-27 15:05:02 +10001180 if (produced != dtemplate[i].outlen) {
1181 pr_err("alg: comp: Decompression test %d failed for "
1182 "%s: returned len = %u (expected %d)\n", i + 1,
1183 algo, produced, dtemplate[i].outlen);
1184 return -EINVAL;
1185 }
1186
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001187 if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
1188 pr_err("alg: pcomp: Decompression test %d failed for "
1189 "%s\n", i + 1, algo);
1190 hexdump(result, dtemplate[i].outlen);
1191 return -EINVAL;
1192 }
1193 }
1194
1195 return 0;
1196}
1197
Jarod Wilson7647d6c2009-05-04 19:44:50 +08001198
1199static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
1200 unsigned int tcount)
1201{
1202 const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
1203 int err, i, j, seedsize;
1204 u8 *seed;
1205 char result[32];
1206
1207 seedsize = crypto_rng_seedsize(tfm);
1208
1209 seed = kmalloc(seedsize, GFP_KERNEL);
1210 if (!seed) {
1211 printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
1212 "for %s\n", algo);
1213 return -ENOMEM;
1214 }
1215
1216 for (i = 0; i < tcount; i++) {
1217 memset(result, 0, 32);
1218
1219 memcpy(seed, template[i].v, template[i].vlen);
1220 memcpy(seed + template[i].vlen, template[i].key,
1221 template[i].klen);
1222 memcpy(seed + template[i].vlen + template[i].klen,
1223 template[i].dt, template[i].dtlen);
1224
1225 err = crypto_rng_reset(tfm, seed, seedsize);
1226 if (err) {
1227 printk(KERN_ERR "alg: cprng: Failed to reset rng "
1228 "for %s\n", algo);
1229 goto out;
1230 }
1231
1232 for (j = 0; j < template[i].loops; j++) {
1233 err = crypto_rng_get_bytes(tfm, result,
1234 template[i].rlen);
1235 if (err != template[i].rlen) {
1236 printk(KERN_ERR "alg: cprng: Failed to obtain "
1237 "the correct amount of random data for "
1238 "%s (requested %d, got %d)\n", algo,
1239 template[i].rlen, err);
1240 goto out;
1241 }
1242 }
1243
1244 err = memcmp(result, template[i].result,
1245 template[i].rlen);
1246 if (err) {
1247 printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
1248 i, algo);
1249 hexdump(result, template[i].rlen);
1250 err = -EINVAL;
1251 goto out;
1252 }
1253 }
1254
1255out:
1256 kfree(seed);
1257 return err;
1258}
1259
Herbert Xuda7f0332008-07-31 17:08:25 +08001260static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
1261 u32 type, u32 mask)
1262{
1263 struct crypto_aead *tfm;
1264 int err = 0;
1265
1266 tfm = crypto_alloc_aead(driver, type, mask);
1267 if (IS_ERR(tfm)) {
1268 printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
1269 "%ld\n", driver, PTR_ERR(tfm));
1270 return PTR_ERR(tfm);
1271 }
1272
1273 if (desc->suite.aead.enc.vecs) {
1274 err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
1275 desc->suite.aead.enc.count);
1276 if (err)
1277 goto out;
1278 }
1279
1280 if (!err && desc->suite.aead.dec.vecs)
1281 err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
1282 desc->suite.aead.dec.count);
1283
1284out:
1285 crypto_free_aead(tfm);
1286 return err;
1287}
1288
1289static int alg_test_cipher(const struct alg_test_desc *desc,
1290 const char *driver, u32 type, u32 mask)
1291{
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001292 struct crypto_cipher *tfm;
Herbert Xuda7f0332008-07-31 17:08:25 +08001293 int err = 0;
1294
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001295 tfm = crypto_alloc_cipher(driver, type, mask);
Herbert Xuda7f0332008-07-31 17:08:25 +08001296 if (IS_ERR(tfm)) {
1297 printk(KERN_ERR "alg: cipher: Failed to load transform for "
1298 "%s: %ld\n", driver, PTR_ERR(tfm));
1299 return PTR_ERR(tfm);
1300 }
1301
1302 if (desc->suite.cipher.enc.vecs) {
1303 err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
1304 desc->suite.cipher.enc.count);
1305 if (err)
1306 goto out;
1307 }
1308
1309 if (desc->suite.cipher.dec.vecs)
1310 err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
1311 desc->suite.cipher.dec.count);
1312
1313out:
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001314 crypto_free_cipher(tfm);
1315 return err;
1316}
1317
1318static int alg_test_skcipher(const struct alg_test_desc *desc,
1319 const char *driver, u32 type, u32 mask)
1320{
1321 struct crypto_ablkcipher *tfm;
1322 int err = 0;
1323
1324 tfm = crypto_alloc_ablkcipher(driver, type, mask);
1325 if (IS_ERR(tfm)) {
1326 printk(KERN_ERR "alg: skcipher: Failed to load transform for "
1327 "%s: %ld\n", driver, PTR_ERR(tfm));
1328 return PTR_ERR(tfm);
1329 }
1330
1331 if (desc->suite.cipher.enc.vecs) {
1332 err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
1333 desc->suite.cipher.enc.count);
1334 if (err)
1335 goto out;
1336 }
1337
1338 if (desc->suite.cipher.dec.vecs)
1339 err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
1340 desc->suite.cipher.dec.count);
1341
1342out:
Herbert Xuda7f0332008-07-31 17:08:25 +08001343 crypto_free_ablkcipher(tfm);
1344 return err;
1345}
1346
1347static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
1348 u32 type, u32 mask)
1349{
1350 struct crypto_comp *tfm;
1351 int err;
1352
1353 tfm = crypto_alloc_comp(driver, type, mask);
1354 if (IS_ERR(tfm)) {
1355 printk(KERN_ERR "alg: comp: Failed to load transform for %s: "
1356 "%ld\n", driver, PTR_ERR(tfm));
1357 return PTR_ERR(tfm);
1358 }
1359
1360 err = test_comp(tfm, desc->suite.comp.comp.vecs,
1361 desc->suite.comp.decomp.vecs,
1362 desc->suite.comp.comp.count,
1363 desc->suite.comp.decomp.count);
1364
1365 crypto_free_comp(tfm);
1366 return err;
1367}
1368
Geert Uytterhoeven8064efb2009-03-04 15:08:03 +08001369static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
1370 u32 type, u32 mask)
1371{
1372 struct crypto_pcomp *tfm;
1373 int err;
1374
1375 tfm = crypto_alloc_pcomp(driver, type, mask);
1376 if (IS_ERR(tfm)) {
1377 pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
1378 driver, PTR_ERR(tfm));
1379 return PTR_ERR(tfm);
1380 }
1381
1382 err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
1383 desc->suite.pcomp.decomp.vecs,
1384 desc->suite.pcomp.comp.count,
1385 desc->suite.pcomp.decomp.count);
1386
1387 crypto_free_pcomp(tfm);
1388 return err;
1389}
1390
Herbert Xuda7f0332008-07-31 17:08:25 +08001391static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
1392 u32 type, u32 mask)
1393{
1394 struct crypto_ahash *tfm;
1395 int err;
1396
1397 tfm = crypto_alloc_ahash(driver, type, mask);
1398 if (IS_ERR(tfm)) {
1399 printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
1400 "%ld\n", driver, PTR_ERR(tfm));
1401 return PTR_ERR(tfm);
1402 }
1403
1404 err = test_hash(tfm, desc->suite.hash.vecs, desc->suite.hash.count);
1405
1406 crypto_free_ahash(tfm);
1407 return err;
1408}
1409
Herbert Xu8e3ee852008-11-07 14:58:52 +08001410static int alg_test_crc32c(const struct alg_test_desc *desc,
1411 const char *driver, u32 type, u32 mask)
1412{
1413 struct crypto_shash *tfm;
1414 u32 val;
1415 int err;
1416
1417 err = alg_test_hash(desc, driver, type, mask);
1418 if (err)
1419 goto out;
1420
1421 tfm = crypto_alloc_shash(driver, type, mask);
1422 if (IS_ERR(tfm)) {
1423 printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
1424 "%ld\n", driver, PTR_ERR(tfm));
1425 err = PTR_ERR(tfm);
1426 goto out;
1427 }
1428
1429 do {
1430 struct {
1431 struct shash_desc shash;
1432 char ctx[crypto_shash_descsize(tfm)];
1433 } sdesc;
1434
1435 sdesc.shash.tfm = tfm;
1436 sdesc.shash.flags = 0;
1437
1438 *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
1439 err = crypto_shash_final(&sdesc.shash, (u8 *)&val);
1440 if (err) {
1441 printk(KERN_ERR "alg: crc32c: Operation failed for "
1442 "%s: %d\n", driver, err);
1443 break;
1444 }
1445
1446 if (val != ~420553207) {
1447 printk(KERN_ERR "alg: crc32c: Test failed for %s: "
1448 "%d\n", driver, val);
1449 err = -EINVAL;
1450 }
1451 } while (0);
1452
1453 crypto_free_shash(tfm);
1454
1455out:
1456 return err;
1457}
1458
Jarod Wilson7647d6c2009-05-04 19:44:50 +08001459static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
1460 u32 type, u32 mask)
1461{
1462 struct crypto_rng *rng;
1463 int err;
1464
1465 rng = crypto_alloc_rng(driver, type, mask);
1466 if (IS_ERR(rng)) {
1467 printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
1468 "%ld\n", driver, PTR_ERR(rng));
1469 return PTR_ERR(rng);
1470 }
1471
1472 err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
1473
1474 crypto_free_rng(rng);
1475
1476 return err;
1477}
1478
Herbert Xuda7f0332008-07-31 17:08:25 +08001479/* Please keep this list sorted by algorithm name. */
1480static const struct alg_test_desc alg_test_descs[] = {
1481 {
Jarod Wilsone08ca2d2009-05-04 19:46:29 +08001482 .alg = "ansi_cprng",
1483 .test = alg_test_cprng,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001484 .fips_allowed = 1,
Jarod Wilsone08ca2d2009-05-04 19:46:29 +08001485 .suite = {
1486 .cprng = {
1487 .vecs = ansi_cprng_aes_tv_template,
1488 .count = ANSI_CPRNG_AES_TEST_VECTORS
1489 }
1490 }
1491 }, {
Herbert Xuda7f0332008-07-31 17:08:25 +08001492 .alg = "cbc(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001493 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001494 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001495 .suite = {
1496 .cipher = {
1497 .enc = {
1498 .vecs = aes_cbc_enc_tv_template,
1499 .count = AES_CBC_ENC_TEST_VECTORS
1500 },
1501 .dec = {
1502 .vecs = aes_cbc_dec_tv_template,
1503 .count = AES_CBC_DEC_TEST_VECTORS
1504 }
1505 }
1506 }
1507 }, {
1508 .alg = "cbc(anubis)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001509 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001510 .suite = {
1511 .cipher = {
1512 .enc = {
1513 .vecs = anubis_cbc_enc_tv_template,
1514 .count = ANUBIS_CBC_ENC_TEST_VECTORS
1515 },
1516 .dec = {
1517 .vecs = anubis_cbc_dec_tv_template,
1518 .count = ANUBIS_CBC_DEC_TEST_VECTORS
1519 }
1520 }
1521 }
1522 }, {
1523 .alg = "cbc(blowfish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001524 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001525 .suite = {
1526 .cipher = {
1527 .enc = {
1528 .vecs = bf_cbc_enc_tv_template,
1529 .count = BF_CBC_ENC_TEST_VECTORS
1530 },
1531 .dec = {
1532 .vecs = bf_cbc_dec_tv_template,
1533 .count = BF_CBC_DEC_TEST_VECTORS
1534 }
1535 }
1536 }
1537 }, {
1538 .alg = "cbc(camellia)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001539 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001540 .suite = {
1541 .cipher = {
1542 .enc = {
1543 .vecs = camellia_cbc_enc_tv_template,
1544 .count = CAMELLIA_CBC_ENC_TEST_VECTORS
1545 },
1546 .dec = {
1547 .vecs = camellia_cbc_dec_tv_template,
1548 .count = CAMELLIA_CBC_DEC_TEST_VECTORS
1549 }
1550 }
1551 }
1552 }, {
1553 .alg = "cbc(des)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001554 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001555 .suite = {
1556 .cipher = {
1557 .enc = {
1558 .vecs = des_cbc_enc_tv_template,
1559 .count = DES_CBC_ENC_TEST_VECTORS
1560 },
1561 .dec = {
1562 .vecs = des_cbc_dec_tv_template,
1563 .count = DES_CBC_DEC_TEST_VECTORS
1564 }
1565 }
1566 }
1567 }, {
1568 .alg = "cbc(des3_ede)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001569 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001570 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001571 .suite = {
1572 .cipher = {
1573 .enc = {
1574 .vecs = des3_ede_cbc_enc_tv_template,
1575 .count = DES3_EDE_CBC_ENC_TEST_VECTORS
1576 },
1577 .dec = {
1578 .vecs = des3_ede_cbc_dec_tv_template,
1579 .count = DES3_EDE_CBC_DEC_TEST_VECTORS
1580 }
1581 }
1582 }
1583 }, {
1584 .alg = "cbc(twofish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001585 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001586 .suite = {
1587 .cipher = {
1588 .enc = {
1589 .vecs = tf_cbc_enc_tv_template,
1590 .count = TF_CBC_ENC_TEST_VECTORS
1591 },
1592 .dec = {
1593 .vecs = tf_cbc_dec_tv_template,
1594 .count = TF_CBC_DEC_TEST_VECTORS
1595 }
1596 }
1597 }
1598 }, {
1599 .alg = "ccm(aes)",
1600 .test = alg_test_aead,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001601 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001602 .suite = {
1603 .aead = {
1604 .enc = {
1605 .vecs = aes_ccm_enc_tv_template,
1606 .count = AES_CCM_ENC_TEST_VECTORS
1607 },
1608 .dec = {
1609 .vecs = aes_ccm_dec_tv_template,
1610 .count = AES_CCM_DEC_TEST_VECTORS
1611 }
1612 }
1613 }
1614 }, {
1615 .alg = "crc32c",
Herbert Xu8e3ee852008-11-07 14:58:52 +08001616 .test = alg_test_crc32c,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001617 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001618 .suite = {
1619 .hash = {
1620 .vecs = crc32c_tv_template,
1621 .count = CRC32C_TEST_VECTORS
1622 }
1623 }
1624 }, {
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08001625 .alg = "ctr(aes)",
1626 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001627 .fips_allowed = 1,
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08001628 .suite = {
1629 .cipher = {
1630 .enc = {
1631 .vecs = aes_ctr_enc_tv_template,
1632 .count = AES_CTR_ENC_TEST_VECTORS
1633 },
1634 .dec = {
1635 .vecs = aes_ctr_dec_tv_template,
1636 .count = AES_CTR_DEC_TEST_VECTORS
1637 }
1638 }
1639 }
1640 }, {
Herbert Xuda7f0332008-07-31 17:08:25 +08001641 .alg = "cts(cbc(aes))",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001642 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001643 .suite = {
1644 .cipher = {
1645 .enc = {
1646 .vecs = cts_mode_enc_tv_template,
1647 .count = CTS_MODE_ENC_TEST_VECTORS
1648 },
1649 .dec = {
1650 .vecs = cts_mode_dec_tv_template,
1651 .count = CTS_MODE_DEC_TEST_VECTORS
1652 }
1653 }
1654 }
1655 }, {
1656 .alg = "deflate",
1657 .test = alg_test_comp,
1658 .suite = {
1659 .comp = {
1660 .comp = {
1661 .vecs = deflate_comp_tv_template,
1662 .count = DEFLATE_COMP_TEST_VECTORS
1663 },
1664 .decomp = {
1665 .vecs = deflate_decomp_tv_template,
1666 .count = DEFLATE_DECOMP_TEST_VECTORS
1667 }
1668 }
1669 }
1670 }, {
1671 .alg = "ecb(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001672 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001673 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001674 .suite = {
1675 .cipher = {
1676 .enc = {
1677 .vecs = aes_enc_tv_template,
1678 .count = AES_ENC_TEST_VECTORS
1679 },
1680 .dec = {
1681 .vecs = aes_dec_tv_template,
1682 .count = AES_DEC_TEST_VECTORS
1683 }
1684 }
1685 }
1686 }, {
1687 .alg = "ecb(anubis)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001688 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001689 .suite = {
1690 .cipher = {
1691 .enc = {
1692 .vecs = anubis_enc_tv_template,
1693 .count = ANUBIS_ENC_TEST_VECTORS
1694 },
1695 .dec = {
1696 .vecs = anubis_dec_tv_template,
1697 .count = ANUBIS_DEC_TEST_VECTORS
1698 }
1699 }
1700 }
1701 }, {
1702 .alg = "ecb(arc4)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001703 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001704 .suite = {
1705 .cipher = {
1706 .enc = {
1707 .vecs = arc4_enc_tv_template,
1708 .count = ARC4_ENC_TEST_VECTORS
1709 },
1710 .dec = {
1711 .vecs = arc4_dec_tv_template,
1712 .count = ARC4_DEC_TEST_VECTORS
1713 }
1714 }
1715 }
1716 }, {
1717 .alg = "ecb(blowfish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001718 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001719 .suite = {
1720 .cipher = {
1721 .enc = {
1722 .vecs = bf_enc_tv_template,
1723 .count = BF_ENC_TEST_VECTORS
1724 },
1725 .dec = {
1726 .vecs = bf_dec_tv_template,
1727 .count = BF_DEC_TEST_VECTORS
1728 }
1729 }
1730 }
1731 }, {
1732 .alg = "ecb(camellia)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001733 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001734 .suite = {
1735 .cipher = {
1736 .enc = {
1737 .vecs = camellia_enc_tv_template,
1738 .count = CAMELLIA_ENC_TEST_VECTORS
1739 },
1740 .dec = {
1741 .vecs = camellia_dec_tv_template,
1742 .count = CAMELLIA_DEC_TEST_VECTORS
1743 }
1744 }
1745 }
1746 }, {
1747 .alg = "ecb(cast5)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001748 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001749 .suite = {
1750 .cipher = {
1751 .enc = {
1752 .vecs = cast5_enc_tv_template,
1753 .count = CAST5_ENC_TEST_VECTORS
1754 },
1755 .dec = {
1756 .vecs = cast5_dec_tv_template,
1757 .count = CAST5_DEC_TEST_VECTORS
1758 }
1759 }
1760 }
1761 }, {
1762 .alg = "ecb(cast6)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001763 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001764 .suite = {
1765 .cipher = {
1766 .enc = {
1767 .vecs = cast6_enc_tv_template,
1768 .count = CAST6_ENC_TEST_VECTORS
1769 },
1770 .dec = {
1771 .vecs = cast6_dec_tv_template,
1772 .count = CAST6_DEC_TEST_VECTORS
1773 }
1774 }
1775 }
1776 }, {
1777 .alg = "ecb(des)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001778 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001779 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001780 .suite = {
1781 .cipher = {
1782 .enc = {
1783 .vecs = des_enc_tv_template,
1784 .count = DES_ENC_TEST_VECTORS
1785 },
1786 .dec = {
1787 .vecs = des_dec_tv_template,
1788 .count = DES_DEC_TEST_VECTORS
1789 }
1790 }
1791 }
1792 }, {
1793 .alg = "ecb(des3_ede)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001794 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001795 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001796 .suite = {
1797 .cipher = {
1798 .enc = {
1799 .vecs = des3_ede_enc_tv_template,
1800 .count = DES3_EDE_ENC_TEST_VECTORS
1801 },
1802 .dec = {
1803 .vecs = des3_ede_dec_tv_template,
1804 .count = DES3_EDE_DEC_TEST_VECTORS
1805 }
1806 }
1807 }
1808 }, {
1809 .alg = "ecb(khazad)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001810 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001811 .suite = {
1812 .cipher = {
1813 .enc = {
1814 .vecs = khazad_enc_tv_template,
1815 .count = KHAZAD_ENC_TEST_VECTORS
1816 },
1817 .dec = {
1818 .vecs = khazad_dec_tv_template,
1819 .count = KHAZAD_DEC_TEST_VECTORS
1820 }
1821 }
1822 }
1823 }, {
1824 .alg = "ecb(seed)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001825 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001826 .suite = {
1827 .cipher = {
1828 .enc = {
1829 .vecs = seed_enc_tv_template,
1830 .count = SEED_ENC_TEST_VECTORS
1831 },
1832 .dec = {
1833 .vecs = seed_dec_tv_template,
1834 .count = SEED_DEC_TEST_VECTORS
1835 }
1836 }
1837 }
1838 }, {
1839 .alg = "ecb(serpent)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001840 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001841 .suite = {
1842 .cipher = {
1843 .enc = {
1844 .vecs = serpent_enc_tv_template,
1845 .count = SERPENT_ENC_TEST_VECTORS
1846 },
1847 .dec = {
1848 .vecs = serpent_dec_tv_template,
1849 .count = SERPENT_DEC_TEST_VECTORS
1850 }
1851 }
1852 }
1853 }, {
1854 .alg = "ecb(tea)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001855 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001856 .suite = {
1857 .cipher = {
1858 .enc = {
1859 .vecs = tea_enc_tv_template,
1860 .count = TEA_ENC_TEST_VECTORS
1861 },
1862 .dec = {
1863 .vecs = tea_dec_tv_template,
1864 .count = TEA_DEC_TEST_VECTORS
1865 }
1866 }
1867 }
1868 }, {
1869 .alg = "ecb(tnepres)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001870 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001871 .suite = {
1872 .cipher = {
1873 .enc = {
1874 .vecs = tnepres_enc_tv_template,
1875 .count = TNEPRES_ENC_TEST_VECTORS
1876 },
1877 .dec = {
1878 .vecs = tnepres_dec_tv_template,
1879 .count = TNEPRES_DEC_TEST_VECTORS
1880 }
1881 }
1882 }
1883 }, {
1884 .alg = "ecb(twofish)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001885 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001886 .suite = {
1887 .cipher = {
1888 .enc = {
1889 .vecs = tf_enc_tv_template,
1890 .count = TF_ENC_TEST_VECTORS
1891 },
1892 .dec = {
1893 .vecs = tf_dec_tv_template,
1894 .count = TF_DEC_TEST_VECTORS
1895 }
1896 }
1897 }
1898 }, {
1899 .alg = "ecb(xeta)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001900 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001901 .suite = {
1902 .cipher = {
1903 .enc = {
1904 .vecs = xeta_enc_tv_template,
1905 .count = XETA_ENC_TEST_VECTORS
1906 },
1907 .dec = {
1908 .vecs = xeta_dec_tv_template,
1909 .count = XETA_DEC_TEST_VECTORS
1910 }
1911 }
1912 }
1913 }, {
1914 .alg = "ecb(xtea)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10001915 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08001916 .suite = {
1917 .cipher = {
1918 .enc = {
1919 .vecs = xtea_enc_tv_template,
1920 .count = XTEA_ENC_TEST_VECTORS
1921 },
1922 .dec = {
1923 .vecs = xtea_dec_tv_template,
1924 .count = XTEA_DEC_TEST_VECTORS
1925 }
1926 }
1927 }
1928 }, {
1929 .alg = "gcm(aes)",
1930 .test = alg_test_aead,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001931 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001932 .suite = {
1933 .aead = {
1934 .enc = {
1935 .vecs = aes_gcm_enc_tv_template,
1936 .count = AES_GCM_ENC_TEST_VECTORS
1937 },
1938 .dec = {
1939 .vecs = aes_gcm_dec_tv_template,
1940 .count = AES_GCM_DEC_TEST_VECTORS
1941 }
1942 }
1943 }
1944 }, {
1945 .alg = "hmac(md5)",
1946 .test = alg_test_hash,
1947 .suite = {
1948 .hash = {
1949 .vecs = hmac_md5_tv_template,
1950 .count = HMAC_MD5_TEST_VECTORS
1951 }
1952 }
1953 }, {
1954 .alg = "hmac(rmd128)",
1955 .test = alg_test_hash,
1956 .suite = {
1957 .hash = {
1958 .vecs = hmac_rmd128_tv_template,
1959 .count = HMAC_RMD128_TEST_VECTORS
1960 }
1961 }
1962 }, {
1963 .alg = "hmac(rmd160)",
1964 .test = alg_test_hash,
1965 .suite = {
1966 .hash = {
1967 .vecs = hmac_rmd160_tv_template,
1968 .count = HMAC_RMD160_TEST_VECTORS
1969 }
1970 }
1971 }, {
1972 .alg = "hmac(sha1)",
1973 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001974 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001975 .suite = {
1976 .hash = {
1977 .vecs = hmac_sha1_tv_template,
1978 .count = HMAC_SHA1_TEST_VECTORS
1979 }
1980 }
1981 }, {
1982 .alg = "hmac(sha224)",
1983 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001984 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001985 .suite = {
1986 .hash = {
1987 .vecs = hmac_sha224_tv_template,
1988 .count = HMAC_SHA224_TEST_VECTORS
1989 }
1990 }
1991 }, {
1992 .alg = "hmac(sha256)",
1993 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10001994 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08001995 .suite = {
1996 .hash = {
1997 .vecs = hmac_sha256_tv_template,
1998 .count = HMAC_SHA256_TEST_VECTORS
1999 }
2000 }
2001 }, {
2002 .alg = "hmac(sha384)",
2003 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002004 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002005 .suite = {
2006 .hash = {
2007 .vecs = hmac_sha384_tv_template,
2008 .count = HMAC_SHA384_TEST_VECTORS
2009 }
2010 }
2011 }, {
2012 .alg = "hmac(sha512)",
2013 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002014 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002015 .suite = {
2016 .hash = {
2017 .vecs = hmac_sha512_tv_template,
2018 .count = HMAC_SHA512_TEST_VECTORS
2019 }
2020 }
2021 }, {
2022 .alg = "lrw(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002023 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002024 .suite = {
2025 .cipher = {
2026 .enc = {
2027 .vecs = aes_lrw_enc_tv_template,
2028 .count = AES_LRW_ENC_TEST_VECTORS
2029 },
2030 .dec = {
2031 .vecs = aes_lrw_dec_tv_template,
2032 .count = AES_LRW_DEC_TEST_VECTORS
2033 }
2034 }
2035 }
2036 }, {
2037 .alg = "lzo",
2038 .test = alg_test_comp,
2039 .suite = {
2040 .comp = {
2041 .comp = {
2042 .vecs = lzo_comp_tv_template,
2043 .count = LZO_COMP_TEST_VECTORS
2044 },
2045 .decomp = {
2046 .vecs = lzo_decomp_tv_template,
2047 .count = LZO_DECOMP_TEST_VECTORS
2048 }
2049 }
2050 }
2051 }, {
2052 .alg = "md4",
2053 .test = alg_test_hash,
2054 .suite = {
2055 .hash = {
2056 .vecs = md4_tv_template,
2057 .count = MD4_TEST_VECTORS
2058 }
2059 }
2060 }, {
2061 .alg = "md5",
2062 .test = alg_test_hash,
2063 .suite = {
2064 .hash = {
2065 .vecs = md5_tv_template,
2066 .count = MD5_TEST_VECTORS
2067 }
2068 }
2069 }, {
2070 .alg = "michael_mic",
2071 .test = alg_test_hash,
2072 .suite = {
2073 .hash = {
2074 .vecs = michael_mic_tv_template,
2075 .count = MICHAEL_MIC_TEST_VECTORS
2076 }
2077 }
2078 }, {
2079 .alg = "pcbc(fcrypt)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002080 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002081 .suite = {
2082 .cipher = {
2083 .enc = {
2084 .vecs = fcrypt_pcbc_enc_tv_template,
2085 .count = FCRYPT_ENC_TEST_VECTORS
2086 },
2087 .dec = {
2088 .vecs = fcrypt_pcbc_dec_tv_template,
2089 .count = FCRYPT_DEC_TEST_VECTORS
2090 }
2091 }
2092 }
2093 }, {
2094 .alg = "rfc3686(ctr(aes))",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002095 .test = alg_test_skcipher,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002096 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002097 .suite = {
2098 .cipher = {
2099 .enc = {
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08002100 .vecs = aes_ctr_rfc3686_enc_tv_template,
2101 .count = AES_CTR_3686_ENC_TEST_VECTORS
Herbert Xuda7f0332008-07-31 17:08:25 +08002102 },
2103 .dec = {
Jarod Wilsonf7cb80f2009-05-06 17:29:17 +08002104 .vecs = aes_ctr_rfc3686_dec_tv_template,
2105 .count = AES_CTR_3686_DEC_TEST_VECTORS
Herbert Xuda7f0332008-07-31 17:08:25 +08002106 }
2107 }
2108 }
2109 }, {
Jarod Wilson5d667322009-05-04 19:23:40 +08002110 .alg = "rfc4309(ccm(aes))",
2111 .test = alg_test_aead,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002112 .fips_allowed = 1,
Jarod Wilson5d667322009-05-04 19:23:40 +08002113 .suite = {
2114 .aead = {
2115 .enc = {
2116 .vecs = aes_ccm_rfc4309_enc_tv_template,
2117 .count = AES_CCM_4309_ENC_TEST_VECTORS
2118 },
2119 .dec = {
2120 .vecs = aes_ccm_rfc4309_dec_tv_template,
2121 .count = AES_CCM_4309_DEC_TEST_VECTORS
2122 }
2123 }
2124 }
2125 }, {
Herbert Xuda7f0332008-07-31 17:08:25 +08002126 .alg = "rmd128",
2127 .test = alg_test_hash,
2128 .suite = {
2129 .hash = {
2130 .vecs = rmd128_tv_template,
2131 .count = RMD128_TEST_VECTORS
2132 }
2133 }
2134 }, {
2135 .alg = "rmd160",
2136 .test = alg_test_hash,
2137 .suite = {
2138 .hash = {
2139 .vecs = rmd160_tv_template,
2140 .count = RMD160_TEST_VECTORS
2141 }
2142 }
2143 }, {
2144 .alg = "rmd256",
2145 .test = alg_test_hash,
2146 .suite = {
2147 .hash = {
2148 .vecs = rmd256_tv_template,
2149 .count = RMD256_TEST_VECTORS
2150 }
2151 }
2152 }, {
2153 .alg = "rmd320",
2154 .test = alg_test_hash,
2155 .suite = {
2156 .hash = {
2157 .vecs = rmd320_tv_template,
2158 .count = RMD320_TEST_VECTORS
2159 }
2160 }
2161 }, {
2162 .alg = "salsa20",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002163 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002164 .suite = {
2165 .cipher = {
2166 .enc = {
2167 .vecs = salsa20_stream_enc_tv_template,
2168 .count = SALSA20_STREAM_ENC_TEST_VECTORS
2169 }
2170 }
2171 }
2172 }, {
2173 .alg = "sha1",
2174 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002175 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002176 .suite = {
2177 .hash = {
2178 .vecs = sha1_tv_template,
2179 .count = SHA1_TEST_VECTORS
2180 }
2181 }
2182 }, {
2183 .alg = "sha224",
2184 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002185 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002186 .suite = {
2187 .hash = {
2188 .vecs = sha224_tv_template,
2189 .count = SHA224_TEST_VECTORS
2190 }
2191 }
2192 }, {
2193 .alg = "sha256",
2194 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002195 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002196 .suite = {
2197 .hash = {
2198 .vecs = sha256_tv_template,
2199 .count = SHA256_TEST_VECTORS
2200 }
2201 }
2202 }, {
2203 .alg = "sha384",
2204 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002205 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002206 .suite = {
2207 .hash = {
2208 .vecs = sha384_tv_template,
2209 .count = SHA384_TEST_VECTORS
2210 }
2211 }
2212 }, {
2213 .alg = "sha512",
2214 .test = alg_test_hash,
Jarod Wilsona1915d52009-05-15 15:16:03 +10002215 .fips_allowed = 1,
Herbert Xuda7f0332008-07-31 17:08:25 +08002216 .suite = {
2217 .hash = {
2218 .vecs = sha512_tv_template,
2219 .count = SHA512_TEST_VECTORS
2220 }
2221 }
2222 }, {
2223 .alg = "tgr128",
2224 .test = alg_test_hash,
2225 .suite = {
2226 .hash = {
2227 .vecs = tgr128_tv_template,
2228 .count = TGR128_TEST_VECTORS
2229 }
2230 }
2231 }, {
2232 .alg = "tgr160",
2233 .test = alg_test_hash,
2234 .suite = {
2235 .hash = {
2236 .vecs = tgr160_tv_template,
2237 .count = TGR160_TEST_VECTORS
2238 }
2239 }
2240 }, {
2241 .alg = "tgr192",
2242 .test = alg_test_hash,
2243 .suite = {
2244 .hash = {
2245 .vecs = tgr192_tv_template,
2246 .count = TGR192_TEST_VECTORS
2247 }
2248 }
2249 }, {
2250 .alg = "wp256",
2251 .test = alg_test_hash,
2252 .suite = {
2253 .hash = {
2254 .vecs = wp256_tv_template,
2255 .count = WP256_TEST_VECTORS
2256 }
2257 }
2258 }, {
2259 .alg = "wp384",
2260 .test = alg_test_hash,
2261 .suite = {
2262 .hash = {
2263 .vecs = wp384_tv_template,
2264 .count = WP384_TEST_VECTORS
2265 }
2266 }
2267 }, {
2268 .alg = "wp512",
2269 .test = alg_test_hash,
2270 .suite = {
2271 .hash = {
2272 .vecs = wp512_tv_template,
2273 .count = WP512_TEST_VECTORS
2274 }
2275 }
2276 }, {
2277 .alg = "xcbc(aes)",
2278 .test = alg_test_hash,
2279 .suite = {
2280 .hash = {
2281 .vecs = aes_xcbc128_tv_template,
2282 .count = XCBC_AES_TEST_VECTORS
2283 }
2284 }
2285 }, {
2286 .alg = "xts(aes)",
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002287 .test = alg_test_skcipher,
Herbert Xuda7f0332008-07-31 17:08:25 +08002288 .suite = {
2289 .cipher = {
2290 .enc = {
2291 .vecs = aes_xts_enc_tv_template,
2292 .count = AES_XTS_ENC_TEST_VECTORS
2293 },
2294 .dec = {
2295 .vecs = aes_xts_dec_tv_template,
2296 .count = AES_XTS_DEC_TEST_VECTORS
2297 }
2298 }
2299 }
Geert Uytterhoeven0c01aed2009-03-04 15:42:15 +08002300 }, {
2301 .alg = "zlib",
2302 .test = alg_test_pcomp,
2303 .suite = {
2304 .pcomp = {
2305 .comp = {
2306 .vecs = zlib_comp_tv_template,
2307 .count = ZLIB_COMP_TEST_VECTORS
2308 },
2309 .decomp = {
2310 .vecs = zlib_decomp_tv_template,
2311 .count = ZLIB_DECOMP_TEST_VECTORS
2312 }
2313 }
2314 }
Herbert Xuda7f0332008-07-31 17:08:25 +08002315 }
2316};
2317
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002318static int alg_find_test(const char *alg)
Herbert Xuda7f0332008-07-31 17:08:25 +08002319{
2320 int start = 0;
2321 int end = ARRAY_SIZE(alg_test_descs);
2322
2323 while (start < end) {
2324 int i = (start + end) / 2;
2325 int diff = strcmp(alg_test_descs[i].alg, alg);
2326
2327 if (diff > 0) {
2328 end = i;
2329 continue;
2330 }
2331
2332 if (diff < 0) {
2333 start = i + 1;
2334 continue;
2335 }
2336
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002337 return i;
Herbert Xuda7f0332008-07-31 17:08:25 +08002338 }
2339
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002340 return -1;
2341}
2342
2343int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
2344{
2345 int i;
Neil Hormand12d6b62008-10-12 20:36:51 +08002346 int rc;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002347
2348 if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
2349 char nalg[CRYPTO_MAX_ALG_NAME];
2350
2351 if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
2352 sizeof(nalg))
2353 return -ENAMETOOLONG;
2354
2355 i = alg_find_test(nalg);
2356 if (i < 0)
2357 goto notest;
2358
Jarod Wilsona3bef3a2009-05-15 15:17:05 +10002359 if (fips_enabled && !alg_test_descs[i].fips_allowed)
2360 goto non_fips_alg;
2361
Jarod Wilson941fb322009-05-04 19:49:23 +08002362 rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
2363 goto test_done;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002364 }
2365
2366 i = alg_find_test(alg);
2367 if (i < 0)
2368 goto notest;
2369
Jarod Wilsona3bef3a2009-05-15 15:17:05 +10002370 if (fips_enabled && !alg_test_descs[i].fips_allowed)
2371 goto non_fips_alg;
2372
Neil Hormand12d6b62008-10-12 20:36:51 +08002373 rc = alg_test_descs[i].test(alg_test_descs + i, driver,
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002374 type, mask);
Jarod Wilson941fb322009-05-04 19:49:23 +08002375test_done:
Neil Hormand12d6b62008-10-12 20:36:51 +08002376 if (fips_enabled && rc)
2377 panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
2378
Jarod Wilson29ecd4a2009-05-04 19:51:17 +08002379 if (fips_enabled && !rc)
2380 printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
2381 driver, alg);
2382
Neil Hormand12d6b62008-10-12 20:36:51 +08002383 return rc;
Herbert Xu1aa4ecd2008-08-17 17:01:56 +10002384
2385notest:
Herbert Xuda7f0332008-07-31 17:08:25 +08002386 printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
2387 return 0;
Jarod Wilsona3bef3a2009-05-15 15:17:05 +10002388non_fips_alg:
2389 return -EINVAL;
Herbert Xuda7f0332008-07-31 17:08:25 +08002390}
2391EXPORT_SYMBOL_GPL(alg_test);