Hi Herbert, attached is a patch that adds speed testing for digest algorithms in a way similar to already existing cipher speed tests. Applies on top of the "tests by names" patch.
Michal -- * Personal homepage: http://www.logix.cz/michal
This patch adds speed tests (benchmarks) for digest algorithms. Tests are run with different buffer sizes (16 bytes, ... 8 kBytes) and with each buffer multiple tests are run with different update() sizes (e.g. hash 64 bytes buffer in four 16 byte updates). There is no correctness checking of the result and all tests and algorithms use the same input buffer. Signed-off-by: Michal Ludvig <[EMAIL PROTECTED]> Index: linux/crypto/tcrypt.c =================================================================== --- linux.orig/crypto/tcrypt.c +++ linux/crypto/tcrypt.c @@ -630,6 +630,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("% 8u opers/sec, % 8lu 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("%lu cycles/operation, %lu 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; @@ -1069,6 +1185,54 @@ static void do_test(void) des_speed_template); if (mode_speed != ALG_ALL) break; + case ALG_MD4: + test_digest_speed("md4", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_MD5: + test_digest_speed("md5", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_SHA1: + test_digest_speed("sha1", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_SHA256: + test_digest_speed("sha256", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_SHA384: + test_digest_speed("sha384", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_SHA512: + test_digest_speed("sha512", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_WP256: + test_digest_speed("wp256", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_WP384: + test_digest_speed("wp384", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_WP512: + test_digest_speed("wp512", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_TGR128: + test_digest_speed("tgr128", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_TGR160: + test_digest_speed("tgr160", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + + case ALG_TGR192: + test_digest_speed("tgr192", sec, generic_digest_speed_template); + if (mode_speed != ALG_ALL) break; + default: if (mode_speed != ALG_ALL) printk("Speed test for '%s' not implemented.\n", name_speed); Index: linux/crypto/tcrypt.h =================================================================== --- linux.orig/crypto/tcrypt.h +++ linux/crypto/tcrypt.h @@ -106,6 +106,11 @@ struct cipher_speed { unsigned int blen; }; +struct digest_speed { + unsigned int blen; /* buffer length */ + unsigned int plen; /* per-update length */ +}; + /* * MD4 test vectors from RFC1320 */ @@ -3016,4 +3021,35 @@ static struct cipher_speed des_speed_tem { .klen = 0, .blen = 0, } }; +/* + * Digest speed tests + */ +static struct digest_speed generic_digest_speed_template[] = { + { .blen = 16, .plen = 16, }, + { .blen = 64, .plen = 16, }, + { .blen = 64, .plen = 64, }, + { .blen = 256, .plen = 16, }, + { .blen = 256, .plen = 64, }, + { .blen = 256, .plen = 256, }, + { .blen = 1024, .plen = 16, }, + { .blen = 1024, .plen = 256, }, + { .blen = 1024, .plen = 1024, }, + { .blen = 2048, .plen = 16, }, + { .blen = 2048, .plen = 256, }, + { .blen = 2048, .plen = 1024, }, + { .blen = 2048, .plen = 2048, }, + { .blen = 4096, .plen = 16, }, + { .blen = 4096, .plen = 256, }, + { .blen = 4096, .plen = 1024, }, + { .blen = 4096, .plen = 4096, }, + { .blen = 8192, .plen = 16, }, + { .blen = 8192, .plen = 256, }, + { .blen = 8192, .plen = 1024, }, + { .blen = 8192, .plen = 4096, }, + { .blen = 8192, .plen = 8192, }, + + /* End marker */ + { .blen = 0, .plen = 0, } +}; + #endif /* _CRYPTO_TCRYPT_H */