X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=crypto%2Ftcrypt.c;h=68639419c5bd0283697d60defb50f6cf109e8f5e;hb=49e31cbac5be2202f351626fd4fb33ad4d4819b8;hp=85a88a71ff5318936b42ebf44294025648356d47;hpb=3cc3816f93e3f94f88503da8e6090302fa986bd6;p=linux-2.6 diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 85a88a71ff..68639419c5 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -12,8 +12,9 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * 14 - 09 - 2003 - * Rewritten by Kartikey Mahendra Bhatt + * 2004-08-09 Added cipher speed tests (Reyk Floeter ) + * 2003-09-14 Rewritten by Kartikey Mahendra Bhatt + * */ #include @@ -25,12 +26,15 @@ #include #include #include +#include +#include +#include #include "tcrypt.h" /* * Need to kmalloc() memory for testing kmap(). */ -#define TVMEMSIZE 4096 +#define TVMEMSIZE 16384 #define XBUFSIZE 32768 /* @@ -55,6 +59,11 @@ static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; +/* + * Used by test_cipher_speed() + */ +static unsigned int sec; + static int mode; static char *xbuf; static char *tvmem; @@ -63,7 +72,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", - "khazad", "wp512", "wp384", "wp256", "tnepres", NULL + "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", NULL }; static void hexdump(unsigned char *buf, unsigned int len) @@ -419,6 +428,168 @@ out: crypto_free_tfm(tfm); } +static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p, + int blen, int sec) +{ + struct scatterlist sg[8]; + unsigned long start, end; + int bcount; + int ret; + + sg[0].page = virt_to_page(p); + sg[0].offset = offset_in_page(p); + sg[0].length = blen; + + for (start = jiffies, end = start + sec * HZ, bcount = 0; + time_before(jiffies, end); bcount++) { + if (enc) + ret = crypto_cipher_encrypt(tfm, sg, sg, blen); + else + ret = crypto_cipher_decrypt(tfm, sg, sg, blen); + + if (ret) + return ret; + } + + printk("%d operations in %d seconds (%ld bytes)\n", + bcount, sec, (long)bcount * blen); + return 0; +} + +static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p, + int blen) +{ + struct scatterlist sg[8]; + unsigned long cycles = 0; + int ret = 0; + int i; + + sg[0].page = virt_to_page(p); + sg[0].offset = offset_in_page(p); + sg[0].length = blen; + + local_bh_disable(); + local_irq_disable(); + + /* Warm-up run. */ + for (i = 0; i < 4; i++) { + if (enc) + ret = crypto_cipher_encrypt(tfm, sg, sg, blen); + else + ret = crypto_cipher_decrypt(tfm, sg, sg, blen); + + if (ret) + goto out; + } + + /* The real thing. */ + for (i = 0; i < 8; i++) { + cycles_t start, end; + + start = get_cycles(); + if (enc) + ret = crypto_cipher_encrypt(tfm, sg, sg, blen); + else + ret = crypto_cipher_decrypt(tfm, sg, sg, blen); + 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; +} + +static void test_cipher_speed(char *algo, int mode, int enc, unsigned int sec, + struct cipher_testvec *template, + unsigned int tcount, struct cipher_speed *speed) +{ + unsigned int ret, i, j, iv_len; + unsigned char *key, *p, iv[128]; + struct crypto_tfm *tfm; + const char *e, *m; + + if (enc == ENCRYPT) + e = "encryption"; + else + e = "decryption"; + if (mode == MODE_ECB) + m = "ECB"; + else + m = "CBC"; + + printk("\ntesting speed of %s %s %s\n", algo, m, e); + + if (mode) + tfm = crypto_alloc_tfm(algo, 0); + else + tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_CBC); + + if (tfm == NULL) { + printk("failed to load transform for %s %s\n", algo, m); + return; + } + + for (i = 0; speed[i].klen != 0; i++) { + if ((speed[i].blen + speed[i].klen) > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", + speed[i].blen + speed[i].klen, TVMEMSIZE); + goto out; + } + + printk("test %u (%d bit key, %d byte blocks): ", i, + speed[i].klen * 8, speed[i].blen); + + memset(tvmem, 0xff, speed[i].klen + speed[i].blen); + + /* set key, plain text and IV */ + key = (unsigned char *)tvmem; + for (j = 0; j < tcount; j++) { + if (template[j].klen == speed[i].klen) { + key = template[j].key; + break; + } + } + p = (unsigned char *)tvmem + speed[i].klen; + + ret = crypto_cipher_setkey(tfm, key, speed[i].klen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + if (!mode) { + iv_len = crypto_tfm_alg_ivsize(tfm); + memset(&iv, 0xff, iv_len); + crypto_cipher_set_iv(tfm, iv, iv_len); + } + + if (sec) + ret = test_cipher_jiffies(tfm, enc, p, speed[i].blen, + sec); + else + ret = test_cipher_cycles(tfm, enc, p, speed[i].blen); + + if (ret) { + printk("%s() failed flags=%x\n", e, tfm->crt_flags); + break; + } + } + +out: + crypto_free_tfm(tfm); +} + static void test_deflate(void) { unsigned int i; @@ -688,6 +859,10 @@ static void do_test(void) test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS); + //XETA + test_cipher ("xeta", MODE_ECB, ENCRYPT, xeta_enc_tv_template, XETA_ENC_TEST_VECTORS); + test_cipher ("xeta", MODE_ECB, DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS); + test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); @@ -845,6 +1020,11 @@ static void do_test(void) case 29: test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS); break; + + case 30: + test_cipher ("xeta", MODE_ECB, ENCRYPT, xeta_enc_tv_template, XETA_ENC_TEST_VECTORS); + test_cipher ("xeta", MODE_ECB, DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS); + break; #ifdef CONFIG_CRYPTO_HMAC case 100: @@ -861,6 +1041,69 @@ static void do_test(void) #endif + case 200: + test_cipher_speed("aes", MODE_ECB, ENCRYPT, sec, NULL, 0, + aes_speed_template); + test_cipher_speed("aes", MODE_ECB, DECRYPT, sec, NULL, 0, + aes_speed_template); + test_cipher_speed("aes", MODE_CBC, ENCRYPT, sec, NULL, 0, + aes_speed_template); + test_cipher_speed("aes", MODE_CBC, DECRYPT, sec, NULL, 0, + aes_speed_template); + break; + + case 201: + test_cipher_speed("des3_ede", MODE_ECB, ENCRYPT, sec, + des3_ede_enc_tv_template, + DES3_EDE_ENC_TEST_VECTORS, + des3_ede_speed_template); + test_cipher_speed("des3_ede", MODE_ECB, DECRYPT, sec, + des3_ede_dec_tv_template, + DES3_EDE_DEC_TEST_VECTORS, + des3_ede_speed_template); + test_cipher_speed("des3_ede", MODE_CBC, ENCRYPT, sec, + des3_ede_enc_tv_template, + DES3_EDE_ENC_TEST_VECTORS, + des3_ede_speed_template); + test_cipher_speed("des3_ede", MODE_CBC, DECRYPT, sec, + des3_ede_dec_tv_template, + DES3_EDE_DEC_TEST_VECTORS, + des3_ede_speed_template); + break; + + case 202: + test_cipher_speed("twofish", MODE_ECB, ENCRYPT, sec, NULL, 0, + twofish_speed_template); + test_cipher_speed("twofish", MODE_ECB, DECRYPT, sec, NULL, 0, + twofish_speed_template); + test_cipher_speed("twofish", MODE_CBC, ENCRYPT, sec, NULL, 0, + twofish_speed_template); + test_cipher_speed("twofish", MODE_CBC, DECRYPT, sec, NULL, 0, + twofish_speed_template); + break; + + case 203: + test_cipher_speed("blowfish", MODE_ECB, ENCRYPT, sec, NULL, 0, + blowfish_speed_template); + test_cipher_speed("blowfish", MODE_ECB, DECRYPT, sec, NULL, 0, + blowfish_speed_template); + test_cipher_speed("blowfish", MODE_CBC, ENCRYPT, sec, NULL, 0, + blowfish_speed_template); + test_cipher_speed("blowfish", MODE_CBC, DECRYPT, sec, NULL, 0, + blowfish_speed_template); + break; + + case 204: + test_cipher_speed("des", MODE_ECB, ENCRYPT, sec, NULL, 0, + des_speed_template); + test_cipher_speed("des", MODE_ECB, DECRYPT, sec, NULL, 0, + des_speed_template); + test_cipher_speed("des", MODE_CBC, ENCRYPT, sec, NULL, 0, + des_speed_template); + test_cipher_speed("des", MODE_CBC, DECRYPT, sec, NULL, 0, + des_speed_template); + break; + case 1000: test_available(); break; @@ -901,6 +1144,9 @@ module_init(init); module_exit(fini); module_param(mode, int, 0); +module_param(sec, uint, 0); +MODULE_PARM_DESC(sec, "Length in seconds of speed tests " + "(defaults to zero which uses CPU cycles instead)"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Quick & dirty crypto testing module");