X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=crypto%2Ftcrypt.c;h=e52f56c5bd5e44320f6f49b70e252680f014f222;hb=e620c4940002348417e8d317d65bc7b152646493;hp=68639419c5bd0283697d60defb50f6cf109e8f5e;hpb=5d54e69c68c05b162a56f9914cae72afd7e6f40a;p=linux-2.6 diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 68639419c5..e52f56c5bd 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -86,7 +86,6 @@ static void hexdump(unsigned char *buf, unsigned int len) static void test_hash(char *algo, struct hash_testvec *template, unsigned int tcount) { - char *p; unsigned int i, j, k, temp; struct scatterlist sg[8]; char result[64]; @@ -116,10 +115,7 @@ static void test_hash(char *algo, struct hash_testvec *template, printk("test %u:\n", i + 1); memset(result, 0, 64); - p = hash_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = offset_in_page(p); - sg[0].length = hash_tv[i].psize; + sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize); crypto_digest_init(tfm); if (tfm->crt_u.digest.dit_setkey) { @@ -154,10 +150,8 @@ static void test_hash(char *algo, struct hash_testvec *template, hash_tv[i].plaintext + temp, hash_tv[i].tap[k]); temp += hash_tv[i].tap[k]; - p = &xbuf[IDX[k]]; - sg[k].page = virt_to_page(p); - sg[k].offset = offset_in_page(p); - sg[k].length = hash_tv[i].tap[k]; + sg_set_buf(&sg[k], &xbuf[IDX[k]], + hash_tv[i].tap[k]); } crypto_digest_digest(tfm, sg, hash_tv[i].np, result); @@ -179,7 +173,6 @@ static void test_hash(char *algo, struct hash_testvec *template, static void test_hmac(char *algo, struct hmac_testvec *template, unsigned int tcount) { - char *p; unsigned int i, j, k, temp; struct scatterlist sg[8]; char result[64]; @@ -210,11 +203,8 @@ static void test_hmac(char *algo, struct hmac_testvec *template, printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); - p = hmac_tv[i].plaintext; klen = hmac_tv[i].ksize; - sg[0].page = virt_to_page(p); - sg[0].offset = offset_in_page(p); - sg[0].length = hmac_tv[i].psize; + sg_set_buf(&sg[0], hmac_tv[i].plaintext, hmac_tv[i].psize); crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result); @@ -243,10 +233,8 @@ static void test_hmac(char *algo, struct hmac_testvec *template, hmac_tv[i].plaintext + temp, hmac_tv[i].tap[k]); temp += hmac_tv[i].tap[k]; - p = &xbuf[IDX[k]]; - sg[k].page = virt_to_page(p); - sg[k].offset = offset_in_page(p); - sg[k].length = hmac_tv[i].tap[k]; + sg_set_buf(&sg[k], &xbuf[IDX[k]], + hmac_tv[i].tap[k]); } crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, @@ -270,7 +258,7 @@ static void test_cipher(char *algo, int mode, int enc, { unsigned int ret, i, j, k, temp; unsigned int tsize; - char *p, *q; + char *q; struct crypto_tfm *tfm; char *key; struct cipher_testvec *cipher_tv; @@ -330,10 +318,8 @@ static void test_cipher(char *algo, int mode, int enc, goto out; } - p = cipher_tv[i].input; - sg[0].page = virt_to_page(p); - sg[0].offset = offset_in_page(p); - sg[0].length = cipher_tv[i].ilen; + sg_set_buf(&sg[0], cipher_tv[i].input, + cipher_tv[i].ilen); if (!mode) { crypto_cipher_set_iv(tfm, cipher_tv[i].iv, @@ -389,10 +375,8 @@ static void test_cipher(char *algo, int mode, int enc, cipher_tv[i].input + temp, cipher_tv[i].tap[k]); temp += cipher_tv[i].tap[k]; - p = &xbuf[IDX[k]]; - sg[k].page = virt_to_page(p); - sg[k].offset = offset_in_page(p); - sg[k].length = cipher_tv[i].tap[k]; + sg_set_buf(&sg[k], &xbuf[IDX[k]], + cipher_tv[i].tap[k]); } if (!mode) { @@ -431,14 +415,12 @@ out: static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p, int blen, int sec) { - struct scatterlist sg[8]; + struct scatterlist sg[1]; 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; + sg_set_buf(sg, p, blen); for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { @@ -459,14 +441,12 @@ static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p, static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p, int blen) { - struct scatterlist sg[8]; + struct scatterlist sg[1]; 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; + sg_set_buf(sg, p, blen); local_bh_disable(); local_irq_disable(); @@ -590,6 +570,122 @@ out: crypto_free_tfm(tfm); } +static void test_digest_jiffies(struct crypto_tfm *tfm, char *p, int blen, + int plen, char *out, int sec) +{ + struct scatterlist sg[1]; + unsigned long start, end; + int bcount, pcount; + + for (start = jiffies, end = start + sec * HZ, bcount = 0; + time_before(jiffies, end); bcount++) { + crypto_digest_init(tfm); + for (pcount = 0; pcount < blen; pcount += plen) { + sg_set_buf(sg, p + pcount, plen); + crypto_digest_update(tfm, sg, 1); + } + /* we assume there is enough space in 'out' for the result */ + crypto_digest_final(tfm, out); + } + + printk("%6u opers/sec, %9lu bytes/sec\n", + bcount / sec, ((long)bcount * blen) / sec); + + return; +} + +static void test_digest_cycles(struct crypto_tfm *tfm, char *p, int blen, + int plen, char *out) +{ + struct scatterlist sg[1]; + unsigned long cycles = 0; + int i, pcount; + + local_bh_disable(); + local_irq_disable(); + + /* Warm-up run. */ + for (i = 0; i < 4; i++) { + crypto_digest_init(tfm); + for (pcount = 0; pcount < blen; pcount += plen) { + sg_set_buf(sg, p + pcount, plen); + crypto_digest_update(tfm, sg, 1); + } + crypto_digest_final(tfm, out); + } + + /* The real thing. */ + for (i = 0; i < 8; i++) { + cycles_t start, end; + + crypto_digest_init(tfm); + + start = get_cycles(); + + for (pcount = 0; pcount < blen; pcount += plen) { + sg_set_buf(sg, p + pcount, plen); + crypto_digest_update(tfm, sg, 1); + } + crypto_digest_final(tfm, out); + + end = get_cycles(); + + cycles += end - start; + } + + local_irq_enable(); + local_bh_enable(); + + printk("%6lu cycles/operation, %4lu cycles/byte\n", + cycles / 8, cycles / (8 * blen)); + + return; +} + +static void test_digest_speed(char *algo, unsigned int sec, + struct digest_speed *speed) +{ + struct crypto_tfm *tfm; + char output[1024]; + int i; + + printk("\ntesting speed of %s\n", algo); + + tfm = crypto_alloc_tfm(algo, 0); + + if (tfm == NULL) { + printk("failed to load transform for %s\n", algo); + return; + } + + if (crypto_tfm_alg_digestsize(tfm) > sizeof(output)) { + printk("digestsize(%u) > outputbuffer(%zu)\n", + crypto_tfm_alg_digestsize(tfm), sizeof(output)); + goto out; + } + + for (i = 0; speed[i].blen != 0; i++) { + if (speed[i].blen > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", + speed[i].blen, TVMEMSIZE); + goto out; + } + + printk("test%3u (%5u byte blocks,%5u bytes per update,%4u updates): ", + i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen); + + memset(tvmem, 0xff, speed[i].blen); + + if (sec) + test_digest_jiffies(tfm, tvmem, speed[i].blen, speed[i].plen, output, sec); + else + test_digest_cycles(tfm, tvmem, speed[i].blen, speed[i].plen, output); + } + +out: + crypto_free_tfm(tfm); +} + static void test_deflate(void) { unsigned int i; @@ -709,9 +805,7 @@ static void test_crc32c(void) for (i = 0; i < NUMVEC; i++) { for (j = 0; j < VECSIZE; j++) test_vec[i][j] = ++b; - sg[i].page = virt_to_page(test_vec[i]); - sg[i].offset = offset_in_page(test_vec[i]); - sg[i].length = VECSIZE; + sg_set_buf(&sg[i], test_vec[i], VECSIZE); } seed = SEEDTESTVAL; @@ -827,6 +921,8 @@ static void do_test(void) //AES test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS); test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS); + test_cipher ("aes", MODE_CBC, ENCRYPT, aes_cbc_enc_tv_template, AES_CBC_ENC_TEST_VECTORS); + test_cipher ("aes", MODE_CBC, DECRYPT, aes_cbc_dec_tv_template, AES_CBC_DEC_TEST_VECTORS); //CAST5 test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS); @@ -932,6 +1028,8 @@ static void do_test(void) case 10: test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS); test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS); + test_cipher ("aes", MODE_CBC, ENCRYPT, aes_cbc_enc_tv_template, AES_CBC_ENC_TEST_VECTORS); + test_cipher ("aes", MODE_CBC, DECRYPT, aes_cbc_dec_tv_template, AES_CBC_DEC_TEST_VECTORS); break; case 11: @@ -1104,6 +1202,60 @@ static void do_test(void) des_speed_template); break; + case 300: + /* fall through */ + + case 301: + test_digest_speed("md4", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 302: + test_digest_speed("md5", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 303: + test_digest_speed("sha1", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 304: + test_digest_speed("sha256", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 305: + test_digest_speed("sha384", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 306: + test_digest_speed("sha512", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 307: + test_digest_speed("wp256", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 308: + test_digest_speed("wp384", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 309: + test_digest_speed("wp512", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 310: + test_digest_speed("tgr128", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 311: + test_digest_speed("tgr160", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 312: + test_digest_speed("tgr192", sec, generic_digest_speed_template); + if (mode > 300 && mode < 400) break; + + case 399: + break; + case 1000: test_available(); break; @@ -1131,7 +1283,14 @@ static int __init init(void) kfree(xbuf); kfree(tvmem); - return 0; + + /* We intentionaly return -EAGAIN to prevent keeping + * the module. It does all its work from init() + * and doesn't offer any runtime functionality + * => we don't need it in the memory, do we? + * -- mludvig + */ + return -EAGAIN; } /*