tcrypt.c 20.0 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
		printk(KERN_INFO "test%3u "
		       "(%5u byte blocks,%5u bytes per update,%4u updates): ",
442 443 444
		       i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);

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

		if (ret) {
452
			printk(KERN_ERR "hashing failed ret=%d\n", ret);
453 454
			break;
		}
455 456 457
	}

out:
458
	crypto_free_hash(tfm);
459 460
}

461
static void test_available(void)
L
Linus Torvalds 已提交
462 463
{
	char **name = check;
464

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

473 474
static inline int tcrypt_test(const char *alg)
{
475 476 477 478 479 480 481
	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;
482 483
}

484
static int do_test(int m)
485 486
{
	int i;
487
	int ret = 0;
488 489

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

	case 1:
496
		ret += tcrypt_test("md5");
L
Linus Torvalds 已提交
497 498 499
		break;

	case 2:
500
		ret += tcrypt_test("sha1");
L
Linus Torvalds 已提交
501 502 503
		break;

	case 3:
504 505
		ret += tcrypt_test("ecb(des)");
		ret += tcrypt_test("cbc(des)");
L
Linus Torvalds 已提交
506 507 508
		break;

	case 4:
509 510
		ret += tcrypt_test("ecb(des3_ede)");
		ret += tcrypt_test("cbc(des3_ede)");
L
Linus Torvalds 已提交
511 512 513
		break;

	case 5:
514
		ret += tcrypt_test("md4");
L
Linus Torvalds 已提交
515
		break;
516

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

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

	case 8:
527 528
		ret += tcrypt_test("ecb(twofish)");
		ret += tcrypt_test("cbc(twofish)");
L
Linus Torvalds 已提交
529
		break;
530

L
Linus Torvalds 已提交
531
	case 9:
532
		ret += tcrypt_test("ecb(serpent)");
L
Linus Torvalds 已提交
533 534 535
		break;

	case 10:
536 537 538 539 540 541
		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 已提交
542 543 544
		break;

	case 11:
545
		ret += tcrypt_test("sha384");
L
Linus Torvalds 已提交
546
		break;
547

L
Linus Torvalds 已提交
548
	case 12:
549
		ret += tcrypt_test("sha512");
L
Linus Torvalds 已提交
550 551 552
		break;

	case 13:
553
		ret += tcrypt_test("deflate");
L
Linus Torvalds 已提交
554 555 556
		break;

	case 14:
557
		ret += tcrypt_test("ecb(cast5)");
L
Linus Torvalds 已提交
558 559 560
		break;

	case 15:
561
		ret += tcrypt_test("ecb(cast6)");
L
Linus Torvalds 已提交
562 563 564
		break;

	case 16:
565
		ret += tcrypt_test("ecb(arc4)");
L
Linus Torvalds 已提交
566 567 568
		break;

	case 17:
569
		ret += tcrypt_test("michael_mic");
L
Linus Torvalds 已提交
570 571 572
		break;

	case 18:
573
		ret += tcrypt_test("crc32c");
L
Linus Torvalds 已提交
574 575 576
		break;

	case 19:
577
		ret += tcrypt_test("ecb(tea)");
L
Linus Torvalds 已提交
578 579 580
		break;

	case 20:
581
		ret += tcrypt_test("ecb(xtea)");
L
Linus Torvalds 已提交
582 583 584
		break;

	case 21:
585
		ret += tcrypt_test("ecb(khazad)");
L
Linus Torvalds 已提交
586 587 588
		break;

	case 22:
589
		ret += tcrypt_test("wp512");
L
Linus Torvalds 已提交
590 591 592
		break;

	case 23:
593
		ret += tcrypt_test("wp384");
L
Linus Torvalds 已提交
594 595 596
		break;

	case 24:
597
		ret += tcrypt_test("wp256");
L
Linus Torvalds 已提交
598 599 600
		break;

	case 25:
601
		ret += tcrypt_test("ecb(tnepres)");
L
Linus Torvalds 已提交
602 603 604
		break;

	case 26:
605 606
		ret += tcrypt_test("ecb(anubis)");
		ret += tcrypt_test("cbc(anubis)");
L
Linus Torvalds 已提交
607 608 609
		break;

	case 27:
610
		ret += tcrypt_test("tgr192");
L
Linus Torvalds 已提交
611 612 613 614
		break;

	case 28:

615
		ret += tcrypt_test("tgr160");
L
Linus Torvalds 已提交
616 617 618
		break;

	case 29:
619
		ret += tcrypt_test("tgr128");
L
Linus Torvalds 已提交
620
		break;
621

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

626
	case 31:
627
		ret += tcrypt_test("pcbc(fcrypt)");
628 629
		break;

630
	case 32:
631 632
		ret += tcrypt_test("ecb(camellia)");
		ret += tcrypt_test("cbc(camellia)");
633
		break;
634
	case 33:
635
		ret += tcrypt_test("sha224");
636
		break;
637

638
	case 34:
639
		ret += tcrypt_test("salsa20");
640 641
		break;

642
	case 35:
643
		ret += tcrypt_test("gcm(aes)");
644 645
		break;

646
	case 36:
647
		ret += tcrypt_test("lzo");
648 649
		break;

J
Joy Latten 已提交
650
	case 37:
651
		ret += tcrypt_test("ccm(aes)");
J
Joy Latten 已提交
652 653
		break;

654
	case 38:
655
		ret += tcrypt_test("cts(cbc(aes))");
656 657
		break;

658
        case 39:
659
		ret += tcrypt_test("rmd128");
660 661 662
		break;

        case 40:
663
		ret += tcrypt_test("rmd160");
664 665
		break;

666
	case 41:
667
		ret += tcrypt_test("rmd256");
668 669 670
		break;

	case 42:
671
		ret += tcrypt_test("rmd320");
672 673 674
		break;

	case 43:
675
		ret += tcrypt_test("ecb(seed)");
676 677
		break;

678
	case 44:
679
		ret += tcrypt_test("zlib");
680 681
		break;

682
	case 45:
683
		ret += tcrypt_test("rfc4309(ccm(aes))");
684 685
		break;

L
Linus Torvalds 已提交
686
	case 100:
687
		ret += tcrypt_test("hmac(md5)");
L
Linus Torvalds 已提交
688
		break;
689

L
Linus Torvalds 已提交
690
	case 101:
691
		ret += tcrypt_test("hmac(sha1)");
L
Linus Torvalds 已提交
692
		break;
693

L
Linus Torvalds 已提交
694
	case 102:
695
		ret += tcrypt_test("hmac(sha256)");
L
Linus Torvalds 已提交
696 697
		break;

698
	case 103:
699
		ret += tcrypt_test("hmac(sha384)");
700 701 702
		break;

	case 104:
703
		ret += tcrypt_test("hmac(sha512)");
704
		break;
705

706
	case 105:
707
		ret += tcrypt_test("hmac(sha224)");
708
		break;
L
Linus Torvalds 已提交
709

710
	case 106:
711
		ret += tcrypt_test("xcbc(aes)");
712 713
		break;

714
	case 107:
715
		ret += tcrypt_test("hmac(rmd128)");
716 717 718
		break;

	case 108:
719
		ret += tcrypt_test("hmac(rmd160)");
720 721
		break;

722 723 724 725
	case 109:
		ret += tcrypt_test("vmac(aes)");
		break;

726
	case 150:
727
		ret += tcrypt_test("ansi_cprng");
728 729
		break;

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

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

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

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

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

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

808 809
	case 206:
		test_cipher_speed("salsa20", ENCRYPT, sec, NULL, 0,
810
				  speed_template_16_32);
811 812
		break;

813 814 815 816
	case 300:
		/* fall through */

	case 301:
817
		test_hash_speed("md4", sec, generic_hash_speed_template);
818 819 820
		if (mode > 300 && mode < 400) break;

	case 302:
821
		test_hash_speed("md5", sec, generic_hash_speed_template);
822 823 824
		if (mode > 300 && mode < 400) break;

	case 303:
825
		test_hash_speed("sha1", sec, generic_hash_speed_template);
826 827 828
		if (mode > 300 && mode < 400) break;

	case 304:
829
		test_hash_speed("sha256", sec, generic_hash_speed_template);
830 831 832
		if (mode > 300 && mode < 400) break;

	case 305:
833
		test_hash_speed("sha384", sec, generic_hash_speed_template);
834 835 836
		if (mode > 300 && mode < 400) break;

	case 306:
837
		test_hash_speed("sha512", sec, generic_hash_speed_template);
838 839 840
		if (mode > 300 && mode < 400) break;

	case 307:
841
		test_hash_speed("wp256", sec, generic_hash_speed_template);
842 843 844
		if (mode > 300 && mode < 400) break;

	case 308:
845
		test_hash_speed("wp384", sec, generic_hash_speed_template);
846 847 848
		if (mode > 300 && mode < 400) break;

	case 309:
849
		test_hash_speed("wp512", sec, generic_hash_speed_template);
850 851 852
		if (mode > 300 && mode < 400) break;

	case 310:
853
		test_hash_speed("tgr128", sec, generic_hash_speed_template);
854 855 856
		if (mode > 300 && mode < 400) break;

	case 311:
857
		test_hash_speed("tgr160", sec, generic_hash_speed_template);
858 859 860
		if (mode > 300 && mode < 400) break;

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

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

868 869 870 871 872 873 874 875
	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;

876 877 878 879 880 881 882 883
	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;

884 885 886
	case 399:
		break;

L
Linus Torvalds 已提交
887 888 889 890
	case 1000:
		test_available();
		break;
	}
891 892

	return ret;
L
Linus Torvalds 已提交
893 894
}

H
Herbert Xu 已提交
895
static int do_alg_test(const char *alg, u32 type, u32 mask)
896
{
H
Herbert Xu 已提交
897 898
	return crypto_has_alg(alg, type, mask ?: CRYPTO_ALG_TYPE_MASK) ?
	       0 : -ENOENT;
899 900
}

901
static int __init tcrypt_mod_init(void)
L
Linus Torvalds 已提交
902
{
903
	int err = -ENOMEM;
904
	int i;
905

906 907 908 909 910
	for (i = 0; i < TVMEMSIZE; i++) {
		tvmem[i] = (void *)__get_free_page(GFP_KERNEL);
		if (!tvmem[i])
			goto err_free_tv;
	}
L
Linus Torvalds 已提交
911

912
	if (alg)
H
Herbert Xu 已提交
913
		err = do_alg_test(alg, type, mask);
914 915 916
	else
		err = do_test(mode);

917 918 919 920
	if (err) {
		printk(KERN_ERR "tcrypt: one or more tests failed!\n");
		goto err_free_tv;
	}
921

922 923 924 925
	/* 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.
926 927 928
	 * => we don't need it in the memory, do we?
	 *                                        -- mludvig
	 */
929 930
	if (!fips_enabled)
		err = -EAGAIN;
931

932 933 934
err_free_tv:
	for (i = 0; i < TVMEMSIZE && tvmem[i]; i++)
		free_page((unsigned long)tvmem[i]);
935 936

	return err;
L
Linus Torvalds 已提交
937 938 939 940 941 942
}

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

945 946
module_init(tcrypt_mod_init);
module_exit(tcrypt_mod_fini);
L
Linus Torvalds 已提交
947

948 949
module_param(alg, charp, 0);
module_param(type, uint, 0);
H
Herbert Xu 已提交
950
module_param(mask, uint, 0);
L
Linus Torvalds 已提交
951
module_param(mode, int, 0);
H
Harald Welte 已提交
952
module_param(sec, uint, 0);
953 954
MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
		      "(defaults to zero which uses CPU cycles instead)");
L
Linus Torvalds 已提交
955 956 957 958

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