tcrypt.c 20.2 KB
Newer Older
1
/*
L
Linus Torvalds 已提交
2 3 4 5 6 7 8
 * Quick & dirty crypto testing module.
 *
 * This will only exist until we have a better testing mechanism
 * (e.g. a char device).
 *
 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
 * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
9
 * Copyright (c) 2007 Nokia Siemens Networks
L
Linus Torvalds 已提交
10 11 12
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
13
 * Software Foundation; either version 2 of the License, or (at your option)
L
Linus Torvalds 已提交
14 15 16 17
 * any later version.
 *
 */

18
#include <crypto/hash.h>
19
#include <linux/err.h>
L
Linus Torvalds 已提交
20
#include <linux/init.h>
21
#include <linux/gfp.h>
L
Linus Torvalds 已提交
22
#include <linux/module.h>
23
#include <linux/scatterlist.h>
L
Linus Torvalds 已提交
24 25
#include <linux/string.h>
#include <linux/moduleparam.h>
H
Harald Welte 已提交
26
#include <linux/jiffies.h>
27 28
#include <linux/timex.h>
#include <linux/interrupt.h>
L
Linus Torvalds 已提交
29
#include "tcrypt.h"
30
#include "internal.h"
L
Linus Torvalds 已提交
31 32

/*
33
 * Need slab memory for testing (size in number of pages).
L
Linus Torvalds 已提交
34
 */
35
#define TVMEMSIZE	4
L
Linus Torvalds 已提交
36 37

/*
38
* Used by test_cipher_speed()
L
Linus Torvalds 已提交
39 40 41 42
*/
#define ENCRYPT 1
#define DECRYPT 0

H
Harald Welte 已提交
43 44 45
/*
 * Used by test_cipher_speed()
 */
46
static unsigned int sec;
H
Harald Welte 已提交
47

48 49
static char *alg = NULL;
static u32 type;
H
Herbert Xu 已提交
50
static u32 mask;
L
Linus Torvalds 已提交
51
static int mode;
52
static char *tvmem[TVMEMSIZE];
L
Linus Torvalds 已提交
53 54

static char *check[] = {
55 56 57
	"des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256",
	"blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes",
	"cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
58
	"khazad", "wp512", "wp384", "wp256", "tnepres", "xeta",  "fcrypt",
59
	"camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
60
	"lzo", "cts", "zlib", NULL
L
Linus Torvalds 已提交
61 62
};

63 64
static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
			       struct scatterlist *sg, int blen, int sec)
65 66 67 68 69 70 71 72
{
	unsigned long start, end;
	int bcount;
	int ret;

	for (start = jiffies, end = start + sec * HZ, bcount = 0;
	     time_before(jiffies, end); bcount++) {
		if (enc)
73
			ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
74
		else
75
			ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
76 77 78 79 80 81 82 83 84 85

		if (ret)
			return ret;
	}

	printk("%d operations in %d seconds (%ld bytes)\n",
	       bcount, sec, (long)bcount * blen);
	return 0;
}

86 87
static int test_cipher_cycles(struct blkcipher_desc *desc, int enc,
			      struct scatterlist *sg, int blen)
88 89 90 91 92 93 94 95 96 97 98
{
	unsigned long cycles = 0;
	int ret = 0;
	int i;

	local_bh_disable();
	local_irq_disable();

	/* Warm-up run. */
	for (i = 0; i < 4; i++) {
		if (enc)
99
			ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
100
		else
101
			ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
102 103 104 105 106 107 108 109 110 111 112

		if (ret)
			goto out;
	}

	/* The real thing. */
	for (i = 0; i < 8; i++) {
		cycles_t start, end;

		start = get_cycles();
		if (enc)
113
			ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
114
		else
115
			ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
		end = get_cycles();

		if (ret)
			goto out;

		cycles += end - start;
	}

out:
	local_irq_enable();
	local_bh_enable();

	if (ret == 0)
		printk("1 operation in %lu cycles (%d bytes)\n",
		       (cycles + 4) / 8, blen);

	return ret;
}

135 136
static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 };

137
static void test_cipher_speed(const char *algo, int enc, unsigned int sec,
138
			      struct cipher_speed_template *template,
139
			      unsigned int tcount, u8 *keysize)
H
Harald Welte 已提交
140
{
141
	unsigned int ret, i, j, iv_len;
142
	const char *key, iv[128];
143 144 145
	struct crypto_blkcipher *tfm;
	struct blkcipher_desc desc;
	const char *e;
146
	u32 *b_size;
H
Harald Welte 已提交
147 148 149 150 151 152

	if (enc == ENCRYPT)
	        e = "encryption";
	else
		e = "decryption";

153
	printk("\ntesting speed of %s %s\n", algo, e);
H
Harald Welte 已提交
154

155
	tfm = crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
H
Harald Welte 已提交
156

157 158 159
	if (IS_ERR(tfm)) {
		printk("failed to load transform for %s: %ld\n", algo,
		       PTR_ERR(tfm));
H
Harald Welte 已提交
160 161
		return;
	}
162 163
	desc.tfm = tfm;
	desc.flags = 0;
H
Harald Welte 已提交
164

165 166
	i = 0;
	do {
H
Harald Welte 已提交
167

168 169
		b_size = block_sizes;
		do {
170
			struct scatterlist sg[TVMEMSIZE];
H
Harald Welte 已提交
171

172 173 174 175
			if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
				printk("template (%u) too big for "
				       "tvmem (%lu)\n", *keysize + *b_size,
				       TVMEMSIZE * PAGE_SIZE);
176 177
				goto out;
			}
H
Harald Welte 已提交
178

179 180 181
			printk("test %u (%d bit key, %d byte blocks): ", i,
					*keysize * 8, *b_size);

182
			memset(tvmem[0], 0xff, PAGE_SIZE);
183 184

			/* set key, plain text and IV */
185
			key = tvmem[0];
186 187 188 189 190
			for (j = 0; j < tcount; j++) {
				if (template[j].klen == *keysize) {
					key = template[j].key;
					break;
				}
191
			}
H
Harald Welte 已提交
192

193 194 195 196 197 198
			ret = crypto_blkcipher_setkey(tfm, key, *keysize);
			if (ret) {
				printk("setkey() failed flags=%x\n",
						crypto_blkcipher_get_flags(tfm));
				goto out;
			}
H
Harald Welte 已提交
199

200 201 202 203 204 205 206 207
			sg_init_table(sg, TVMEMSIZE);
			sg_set_buf(sg, tvmem[0] + *keysize,
				   PAGE_SIZE - *keysize);
			for (j = 1; j < TVMEMSIZE; j++) {
				sg_set_buf(sg + j, tvmem[j], PAGE_SIZE);
				memset (tvmem[j], 0xff, PAGE_SIZE);
			}

208 209 210 211 212
			iv_len = crypto_blkcipher_ivsize(tfm);
			if (iv_len) {
				memset(&iv, 0xff, iv_len);
				crypto_blkcipher_set_iv(tfm, iv, iv_len);
			}
H
Harald Welte 已提交
213

214
			if (sec)
215 216
				ret = test_cipher_jiffies(&desc, enc, sg,
							  *b_size, sec);
217
			else
218 219
				ret = test_cipher_cycles(&desc, enc, sg,
							 *b_size);
H
Harald Welte 已提交
220

221 222 223 224 225 226 227 228 229
			if (ret) {
				printk("%s() failed flags=%x\n", e, desc.flags);
				break;
			}
			b_size++;
			i++;
		} while (*b_size);
		keysize++;
	} while (*keysize);
H
Harald Welte 已提交
230 231

out:
232
	crypto_free_blkcipher(tfm);
H
Harald Welte 已提交
233 234
}

235 236
static int test_hash_jiffies_digest(struct hash_desc *desc,
				    struct scatterlist *sg, int blen,
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
				    char *out, int sec)
{
	unsigned long start, end;
	int bcount;
	int ret;

	for (start = jiffies, end = start + sec * HZ, bcount = 0;
	     time_before(jiffies, end); bcount++) {
		ret = crypto_hash_digest(desc, sg, blen, out);
		if (ret)
			return ret;
	}

	printk("%6u opers/sec, %9lu bytes/sec\n",
	       bcount / sec, ((long)bcount * blen) / sec);

	return 0;
}

256 257
static int test_hash_jiffies(struct hash_desc *desc, struct scatterlist *sg,
			     int blen, int plen, char *out, int sec)
258 259 260
{
	unsigned long start, end;
	int bcount, pcount;
261 262 263
	int ret;

	if (plen == blen)
264
		return test_hash_jiffies_digest(desc, sg, blen, out, sec);
265

266 267
	for (start = jiffies, end = start + sec * HZ, bcount = 0;
	     time_before(jiffies, end); bcount++) {
268 269 270
		ret = crypto_hash_init(desc);
		if (ret)
			return ret;
271
		for (pcount = 0; pcount < blen; pcount += plen) {
272 273 274
			ret = crypto_hash_update(desc, sg, plen);
			if (ret)
				return ret;
275 276
		}
		/* we assume there is enough space in 'out' for the result */
277 278 279
		ret = crypto_hash_final(desc, out);
		if (ret)
			return ret;
280 281 282 283 284
	}

	printk("%6u opers/sec, %9lu bytes/sec\n",
	       bcount / sec, ((long)bcount * blen) / sec);

285 286 287
	return 0;
}

288 289
static int test_hash_cycles_digest(struct hash_desc *desc,
				   struct scatterlist *sg, int blen, char *out)
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
{
	unsigned long cycles = 0;
	int i;
	int ret;

	local_bh_disable();
	local_irq_disable();

	/* Warm-up run. */
	for (i = 0; i < 4; i++) {
		ret = crypto_hash_digest(desc, sg, blen, out);
		if (ret)
			goto out;
	}

	/* The real thing. */
	for (i = 0; i < 8; i++) {
		cycles_t start, end;

		start = get_cycles();

		ret = crypto_hash_digest(desc, sg, blen, out);
		if (ret)
			goto out;

		end = get_cycles();

		cycles += end - start;
	}

out:
	local_irq_enable();
	local_bh_enable();

	if (ret)
		return ret;

	printk("%6lu cycles/operation, %4lu cycles/byte\n",
	       cycles / 8, cycles / (8 * blen));

	return 0;
331 332
}

333 334
static int test_hash_cycles(struct hash_desc *desc, struct scatterlist *sg,
			    int blen, int plen, char *out)
335 336 337
{
	unsigned long cycles = 0;
	int i, pcount;
338 339 340
	int ret;

	if (plen == blen)
341
		return test_hash_cycles_digest(desc, sg, blen, out);
342

343 344 345 346 347
	local_bh_disable();
	local_irq_disable();

	/* Warm-up run. */
	for (i = 0; i < 4; i++) {
348 349 350
		ret = crypto_hash_init(desc);
		if (ret)
			goto out;
351
		for (pcount = 0; pcount < blen; pcount += plen) {
352 353 354
			ret = crypto_hash_update(desc, sg, plen);
			if (ret)
				goto out;
355
		}
356
		ret = crypto_hash_final(desc, out);
357 358
		if (ret)
			goto out;
359 360 361 362 363 364 365 366
	}

	/* The real thing. */
	for (i = 0; i < 8; i++) {
		cycles_t start, end;

		start = get_cycles();

367 368 369
		ret = crypto_hash_init(desc);
		if (ret)
			goto out;
370
		for (pcount = 0; pcount < blen; pcount += plen) {
371 372 373
			ret = crypto_hash_update(desc, sg, plen);
			if (ret)
				goto out;
374
		}
375 376 377
		ret = crypto_hash_final(desc, out);
		if (ret)
			goto out;
378 379 380 381 382 383

		end = get_cycles();

		cycles += end - start;
	}

384
out:
385 386 387
	local_irq_enable();
	local_bh_enable();

388 389 390
	if (ret)
		return ret;

391 392 393
	printk("%6lu cycles/operation, %4lu cycles/byte\n",
	       cycles / 8, cycles / (8 * blen));

394
	return 0;
395 396
}

397 398
static void test_hash_speed(const char *algo, unsigned int sec,
			    struct hash_speed *speed)
399
{
400
	struct scatterlist sg[TVMEMSIZE];
401 402
	struct crypto_hash *tfm;
	struct hash_desc desc;
403
	static char output[1024];
404
	int i;
405
	int ret;
406

407
	printk(KERN_INFO "\ntesting speed of %s\n", algo);
408

409
	tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC);
410

411
	if (IS_ERR(tfm)) {
412
		printk(KERN_ERR "failed to load transform for %s: %ld\n", algo,
413
		       PTR_ERR(tfm));
414 415 416
		return;
	}

417 418 419 420
	desc.tfm = tfm;
	desc.flags = 0;

	if (crypto_hash_digestsize(tfm) > sizeof(output)) {
421
		printk(KERN_ERR "digestsize(%u) > outputbuffer(%zu)\n",
422
		       crypto_hash_digestsize(tfm), sizeof(output));
423 424 425
		goto out;
	}

426 427 428 429 430 431
	sg_init_table(sg, TVMEMSIZE);
	for (i = 0; i < TVMEMSIZE; i++) {
		sg_set_buf(sg + i, tvmem[i], PAGE_SIZE);
		memset(tvmem[i], 0xff, PAGE_SIZE);
	}

432
	for (i = 0; speed[i].blen != 0; i++) {
433
		if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) {
434 435
			printk(KERN_ERR
			       "template (%u) too big for tvmem (%lu)\n",
436
			       speed[i].blen, TVMEMSIZE * PAGE_SIZE);
437 438 439
			goto out;
		}

440 441 442
		if (speed[i].klen)
			crypto_hash_setkey(tfm, tvmem[0], speed[i].klen);

443 444
		printk(KERN_INFO "test%3u "
		       "(%5u byte blocks,%5u bytes per update,%4u updates): ",
445 446 447
		       i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);

		if (sec)
448
			ret = test_hash_jiffies(&desc, sg, speed[i].blen,
449
						speed[i].plen, output, sec);
450
		else
451
			ret = test_hash_cycles(&desc, sg, speed[i].blen,
452 453 454
					       speed[i].plen, output);

		if (ret) {
455
			printk(KERN_ERR "hashing failed ret=%d\n", ret);
456 457
			break;
		}
458 459 460
	}

out:
461
	crypto_free_hash(tfm);
462 463
}

464
static void test_available(void)
L
Linus Torvalds 已提交
465 466
{
	char **name = check;
467

L
Linus Torvalds 已提交
468 469
	while (*name) {
		printk("alg %s ", *name);
470
		printk(crypto_has_alg(*name, 0, 0) ?
471
		       "found\n" : "not found\n");
L
Linus Torvalds 已提交
472
		name++;
473
	}
L
Linus Torvalds 已提交
474 475
}

476 477
static inline int tcrypt_test(const char *alg)
{
478 479 480 481 482 483 484
	int ret;

	ret = alg_test(alg, alg, 0, 0);
	/* non-fips algs return -EINVAL in fips mode */
	if (fips_enabled && ret == -EINVAL)
		ret = 0;
	return ret;
485 486
}

487
static int do_test(int m)
488 489
{
	int i;
490
	int ret = 0;
491 492

	switch (m) {
L
Linus Torvalds 已提交
493
	case 0:
494
		for (i = 1; i < 200; i++)
495
			ret += do_test(i);
L
Linus Torvalds 已提交
496 497 498
		break;

	case 1:
499
		ret += tcrypt_test("md5");
L
Linus Torvalds 已提交
500 501 502
		break;

	case 2:
503
		ret += tcrypt_test("sha1");
L
Linus Torvalds 已提交
504 505 506
		break;

	case 3:
507 508
		ret += tcrypt_test("ecb(des)");
		ret += tcrypt_test("cbc(des)");
L
Linus Torvalds 已提交
509 510 511
		break;

	case 4:
512 513
		ret += tcrypt_test("ecb(des3_ede)");
		ret += tcrypt_test("cbc(des3_ede)");
L
Linus Torvalds 已提交
514 515 516
		break;

	case 5:
517
		ret += tcrypt_test("md4");
L
Linus Torvalds 已提交
518
		break;
519

L
Linus Torvalds 已提交
520
	case 6:
521
		ret += tcrypt_test("sha256");
L
Linus Torvalds 已提交
522
		break;
523

L
Linus Torvalds 已提交
524
	case 7:
525 526
		ret += tcrypt_test("ecb(blowfish)");
		ret += tcrypt_test("cbc(blowfish)");
L
Linus Torvalds 已提交
527 528 529
		break;

	case 8:
530 531
		ret += tcrypt_test("ecb(twofish)");
		ret += tcrypt_test("cbc(twofish)");
L
Linus Torvalds 已提交
532
		break;
533

L
Linus Torvalds 已提交
534
	case 9:
535
		ret += tcrypt_test("ecb(serpent)");
L
Linus Torvalds 已提交
536 537 538
		break;

	case 10:
539 540 541 542 543 544
		ret += tcrypt_test("ecb(aes)");
		ret += tcrypt_test("cbc(aes)");
		ret += tcrypt_test("lrw(aes)");
		ret += tcrypt_test("xts(aes)");
		ret += tcrypt_test("ctr(aes)");
		ret += tcrypt_test("rfc3686(ctr(aes))");
L
Linus Torvalds 已提交
545 546 547
		break;

	case 11:
548
		ret += tcrypt_test("sha384");
L
Linus Torvalds 已提交
549
		break;
550

L
Linus Torvalds 已提交
551
	case 12:
552
		ret += tcrypt_test("sha512");
L
Linus Torvalds 已提交
553 554 555
		break;

	case 13:
556
		ret += tcrypt_test("deflate");
L
Linus Torvalds 已提交
557 558 559
		break;

	case 14:
560
		ret += tcrypt_test("ecb(cast5)");
L
Linus Torvalds 已提交
561 562 563
		break;

	case 15:
564
		ret += tcrypt_test("ecb(cast6)");
L
Linus Torvalds 已提交
565 566 567
		break;

	case 16:
568
		ret += tcrypt_test("ecb(arc4)");
L
Linus Torvalds 已提交
569 570 571
		break;

	case 17:
572
		ret += tcrypt_test("michael_mic");
L
Linus Torvalds 已提交
573 574 575
		break;

	case 18:
576
		ret += tcrypt_test("crc32c");
L
Linus Torvalds 已提交
577 578 579
		break;

	case 19:
580
		ret += tcrypt_test("ecb(tea)");
L
Linus Torvalds 已提交
581 582 583
		break;

	case 20:
584
		ret += tcrypt_test("ecb(xtea)");
L
Linus Torvalds 已提交
585 586 587
		break;

	case 21:
588
		ret += tcrypt_test("ecb(khazad)");
L
Linus Torvalds 已提交
589 590 591
		break;

	case 22:
592
		ret += tcrypt_test("wp512");
L
Linus Torvalds 已提交
593 594 595
		break;

	case 23:
596
		ret += tcrypt_test("wp384");
L
Linus Torvalds 已提交
597 598 599
		break;

	case 24:
600
		ret += tcrypt_test("wp256");
L
Linus Torvalds 已提交
601 602 603
		break;

	case 25:
604
		ret += tcrypt_test("ecb(tnepres)");
L
Linus Torvalds 已提交
605 606 607
		break;

	case 26:
608 609
		ret += tcrypt_test("ecb(anubis)");
		ret += tcrypt_test("cbc(anubis)");
L
Linus Torvalds 已提交
610 611 612
		break;

	case 27:
613
		ret += tcrypt_test("tgr192");
L
Linus Torvalds 已提交
614 615 616 617
		break;

	case 28:

618
		ret += tcrypt_test("tgr160");
L
Linus Torvalds 已提交
619 620 621
		break;

	case 29:
622
		ret += tcrypt_test("tgr128");
L
Linus Torvalds 已提交
623
		break;
624

A
Aaron Grothe 已提交
625
	case 30:
626
		ret += tcrypt_test("ecb(xeta)");
A
Aaron Grothe 已提交
627
		break;
L
Linus Torvalds 已提交
628

629
	case 31:
630
		ret += tcrypt_test("pcbc(fcrypt)");
631 632
		break;

633
	case 32:
634 635
		ret += tcrypt_test("ecb(camellia)");
		ret += tcrypt_test("cbc(camellia)");
636
		break;
637
	case 33:
638
		ret += tcrypt_test("sha224");
639
		break;
640

641
	case 34:
642
		ret += tcrypt_test("salsa20");
643 644
		break;

645
	case 35:
646
		ret += tcrypt_test("gcm(aes)");
647 648
		break;

649
	case 36:
650
		ret += tcrypt_test("lzo");
651 652
		break;

J
Joy Latten 已提交
653
	case 37:
654
		ret += tcrypt_test("ccm(aes)");
J
Joy Latten 已提交
655 656
		break;

657
	case 38:
658
		ret += tcrypt_test("cts(cbc(aes))");
659 660
		break;

661
        case 39:
662
		ret += tcrypt_test("rmd128");
663 664 665
		break;

        case 40:
666
		ret += tcrypt_test("rmd160");
667 668
		break;

669
	case 41:
670
		ret += tcrypt_test("rmd256");
671 672 673
		break;

	case 42:
674
		ret += tcrypt_test("rmd320");
675 676 677
		break;

	case 43:
678
		ret += tcrypt_test("ecb(seed)");
679 680
		break;

681
	case 44:
682
		ret += tcrypt_test("zlib");
683 684
		break;

685
	case 45:
686
		ret += tcrypt_test("rfc4309(ccm(aes))");
687 688
		break;

L
Linus Torvalds 已提交
689
	case 100:
690
		ret += tcrypt_test("hmac(md5)");
L
Linus Torvalds 已提交
691
		break;
692

L
Linus Torvalds 已提交
693
	case 101:
694
		ret += tcrypt_test("hmac(sha1)");
L
Linus Torvalds 已提交
695
		break;
696

L
Linus Torvalds 已提交
697
	case 102:
698
		ret += tcrypt_test("hmac(sha256)");
L
Linus Torvalds 已提交
699 700
		break;

701
	case 103:
702
		ret += tcrypt_test("hmac(sha384)");
703 704 705
		break;

	case 104:
706
		ret += tcrypt_test("hmac(sha512)");
707
		break;
708

709
	case 105:
710
		ret += tcrypt_test("hmac(sha224)");
711
		break;
L
Linus Torvalds 已提交
712

713
	case 106:
714
		ret += tcrypt_test("xcbc(aes)");
715 716
		break;

717
	case 107:
718
		ret += tcrypt_test("hmac(rmd128)");
719 720 721
		break;

	case 108:
722
		ret += tcrypt_test("hmac(rmd160)");
723 724
		break;

725 726 727 728
	case 109:
		ret += tcrypt_test("vmac(aes)");
		break;

729
	case 150:
730
		ret += tcrypt_test("ansi_cprng");
731 732
		break;

H
Harald Welte 已提交
733
	case 200:
734
		test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
735
				speed_template_16_24_32);
736
		test_cipher_speed("ecb(aes)", DECRYPT, sec, NULL, 0,
737
				speed_template_16_24_32);
738
		test_cipher_speed("cbc(aes)", ENCRYPT, sec, NULL, 0,
739
				speed_template_16_24_32);
740
		test_cipher_speed("cbc(aes)", DECRYPT, sec, NULL, 0,
741
				speed_template_16_24_32);
R
Rik Snel 已提交
742
		test_cipher_speed("lrw(aes)", ENCRYPT, sec, NULL, 0,
743
				speed_template_32_40_48);
R
Rik Snel 已提交
744
		test_cipher_speed("lrw(aes)", DECRYPT, sec, NULL, 0,
745
				speed_template_32_40_48);
746
		test_cipher_speed("xts(aes)", ENCRYPT, sec, NULL, 0,
747
				speed_template_32_48_64);
748
		test_cipher_speed("xts(aes)", DECRYPT, sec, NULL, 0,
749
				speed_template_32_48_64);
H
Harald Welte 已提交
750 751 752
		break;

	case 201:
753
		test_cipher_speed("ecb(des3_ede)", ENCRYPT, sec,
754
				des3_speed_template, DES3_SPEED_VECTORS,
755
				speed_template_24);
756
		test_cipher_speed("ecb(des3_ede)", DECRYPT, sec,
757
				des3_speed_template, DES3_SPEED_VECTORS,
758
				speed_template_24);
759
		test_cipher_speed("cbc(des3_ede)", ENCRYPT, sec,
760
				des3_speed_template, DES3_SPEED_VECTORS,
761
				speed_template_24);
762
		test_cipher_speed("cbc(des3_ede)", DECRYPT, sec,
763
				des3_speed_template, DES3_SPEED_VECTORS,
764
				speed_template_24);
H
Harald Welte 已提交
765 766 767
		break;

	case 202:
768
		test_cipher_speed("ecb(twofish)", ENCRYPT, sec, NULL, 0,
769
				speed_template_16_24_32);
770
		test_cipher_speed("ecb(twofish)", DECRYPT, sec, NULL, 0,
771
				speed_template_16_24_32);
772
		test_cipher_speed("cbc(twofish)", ENCRYPT, sec, NULL, 0,
773
				speed_template_16_24_32);
774
		test_cipher_speed("cbc(twofish)", DECRYPT, sec, NULL, 0,
775
				speed_template_16_24_32);
H
Harald Welte 已提交
776 777 778
		break;

	case 203:
779
		test_cipher_speed("ecb(blowfish)", ENCRYPT, sec, NULL, 0,
780
				  speed_template_8_32);
781
		test_cipher_speed("ecb(blowfish)", DECRYPT, sec, NULL, 0,
782
				  speed_template_8_32);
783
		test_cipher_speed("cbc(blowfish)", ENCRYPT, sec, NULL, 0,
784
				  speed_template_8_32);
785
		test_cipher_speed("cbc(blowfish)", DECRYPT, sec, NULL, 0,
786
				  speed_template_8_32);
H
Harald Welte 已提交
787 788 789
		break;

	case 204:
790
		test_cipher_speed("ecb(des)", ENCRYPT, sec, NULL, 0,
791
				  speed_template_8);
792
		test_cipher_speed("ecb(des)", DECRYPT, sec, NULL, 0,
793
				  speed_template_8);
794
		test_cipher_speed("cbc(des)", ENCRYPT, sec, NULL, 0,
795
				  speed_template_8);
796
		test_cipher_speed("cbc(des)", DECRYPT, sec, NULL, 0,
797
				  speed_template_8);
H
Harald Welte 已提交
798 799
		break;

800 801
	case 205:
		test_cipher_speed("ecb(camellia)", ENCRYPT, sec, NULL, 0,
802
				speed_template_16_24_32);
803
		test_cipher_speed("ecb(camellia)", DECRYPT, sec, NULL, 0,
804
				speed_template_16_24_32);
805
		test_cipher_speed("cbc(camellia)", ENCRYPT, sec, NULL, 0,
806
				speed_template_16_24_32);
807
		test_cipher_speed("cbc(camellia)", DECRYPT, sec, NULL, 0,
808
				speed_template_16_24_32);
809 810
		break;

811 812
	case 206:
		test_cipher_speed("salsa20", ENCRYPT, sec, NULL, 0,
813
				  speed_template_16_32);
814 815
		break;

816 817 818 819
	case 300:
		/* fall through */

	case 301:
820
		test_hash_speed("md4", sec, generic_hash_speed_template);
821 822 823
		if (mode > 300 && mode < 400) break;

	case 302:
824
		test_hash_speed("md5", sec, generic_hash_speed_template);
825 826 827
		if (mode > 300 && mode < 400) break;

	case 303:
828
		test_hash_speed("sha1", sec, generic_hash_speed_template);
829 830 831
		if (mode > 300 && mode < 400) break;

	case 304:
832
		test_hash_speed("sha256", sec, generic_hash_speed_template);
833 834 835
		if (mode > 300 && mode < 400) break;

	case 305:
836
		test_hash_speed("sha384", sec, generic_hash_speed_template);
837 838 839
		if (mode > 300 && mode < 400) break;

	case 306:
840
		test_hash_speed("sha512", sec, generic_hash_speed_template);
841 842 843
		if (mode > 300 && mode < 400) break;

	case 307:
844
		test_hash_speed("wp256", sec, generic_hash_speed_template);
845 846 847
		if (mode > 300 && mode < 400) break;

	case 308:
848
		test_hash_speed("wp384", sec, generic_hash_speed_template);
849 850 851
		if (mode > 300 && mode < 400) break;

	case 309:
852
		test_hash_speed("wp512", sec, generic_hash_speed_template);
853 854 855
		if (mode > 300 && mode < 400) break;

	case 310:
856
		test_hash_speed("tgr128", sec, generic_hash_speed_template);
857 858 859
		if (mode > 300 && mode < 400) break;

	case 311:
860
		test_hash_speed("tgr160", sec, generic_hash_speed_template);
861 862 863
		if (mode > 300 && mode < 400) break;

	case 312:
864
		test_hash_speed("tgr192", sec, generic_hash_speed_template);
865 866
		if (mode > 300 && mode < 400) break;

867 868 869 870
	case 313:
		test_hash_speed("sha224", sec, generic_hash_speed_template);
		if (mode > 300 && mode < 400) break;

871 872 873 874 875 876 877 878
	case 314:
		test_hash_speed("rmd128", sec, generic_hash_speed_template);
		if (mode > 300 && mode < 400) break;

	case 315:
		test_hash_speed("rmd160", sec, generic_hash_speed_template);
		if (mode > 300 && mode < 400) break;

879 880 881 882 883 884 885 886
	case 316:
		test_hash_speed("rmd256", sec, generic_hash_speed_template);
		if (mode > 300 && mode < 400) break;

	case 317:
		test_hash_speed("rmd320", sec, generic_hash_speed_template);
		if (mode > 300 && mode < 400) break;

887 888 889 890
	case 318:
		test_hash_speed("ghash-generic", sec, hash_speed_template_16);
		if (mode > 300 && mode < 400) break;

891 892 893
	case 399:
		break;

L
Linus Torvalds 已提交
894 895 896 897
	case 1000:
		test_available();
		break;
	}
898 899

	return ret;
L
Linus Torvalds 已提交
900 901
}

H
Herbert Xu 已提交
902
static int do_alg_test(const char *alg, u32 type, u32 mask)
903
{
H
Herbert Xu 已提交
904 905
	return crypto_has_alg(alg, type, mask ?: CRYPTO_ALG_TYPE_MASK) ?
	       0 : -ENOENT;
906 907
}

908
static int __init tcrypt_mod_init(void)
L
Linus Torvalds 已提交
909
{
910
	int err = -ENOMEM;
911
	int i;
912

913 914 915 916 917
	for (i = 0; i < TVMEMSIZE; i++) {
		tvmem[i] = (void *)__get_free_page(GFP_KERNEL);
		if (!tvmem[i])
			goto err_free_tv;
	}
L
Linus Torvalds 已提交
918

919
	if (alg)
H
Herbert Xu 已提交
920
		err = do_alg_test(alg, type, mask);
921 922 923
	else
		err = do_test(mode);

924 925 926 927
	if (err) {
		printk(KERN_ERR "tcrypt: one or more tests failed!\n");
		goto err_free_tv;
	}
928

929 930 931 932
	/* We intentionaly return -EAGAIN to prevent keeping the module,
	 * unless we're running in fips mode. It does all its work from
	 * init() and doesn't offer any runtime functionality, but in
	 * the fips case, checking for a successful load is helpful.
933 934 935
	 * => we don't need it in the memory, do we?
	 *                                        -- mludvig
	 */
936 937
	if (!fips_enabled)
		err = -EAGAIN;
938

939 940 941
err_free_tv:
	for (i = 0; i < TVMEMSIZE && tvmem[i]; i++)
		free_page((unsigned long)tvmem[i]);
942 943

	return err;
L
Linus Torvalds 已提交
944 945 946 947 948 949
}

/*
 * If an init function is provided, an exit function must also be provided
 * to allow module unload.
 */
950
static void __exit tcrypt_mod_fini(void) { }
L
Linus Torvalds 已提交
951

952 953
module_init(tcrypt_mod_init);
module_exit(tcrypt_mod_fini);
L
Linus Torvalds 已提交
954

955 956
module_param(alg, charp, 0);
module_param(type, uint, 0);
H
Herbert Xu 已提交
957
module_param(mask, uint, 0);
L
Linus Torvalds 已提交
958
module_param(mode, int, 0);
H
Harald Welte 已提交
959
module_param(sec, uint, 0);
960 961
MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
		      "(defaults to zero which uses CPU cycles instead)");
L
Linus Torvalds 已提交
962 963 964 965

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Quick & dirty crypto testing module");
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");