diff options
Diffstat (limited to 'kernel/crypto/tcrypt.c')
-rw-r--r-- | kernel/crypto/tcrypt.c | 133 |
1 files changed, 92 insertions, 41 deletions
diff --git a/kernel/crypto/tcrypt.c b/kernel/crypto/tcrypt.c index 1a2800107..46a4a757d 100644 --- a/kernel/crypto/tcrypt.c +++ b/kernel/crypto/tcrypt.c @@ -22,8 +22,10 @@ * */ +#include <crypto/aead.h> #include <crypto/hash.h> #include <linux/err.h> +#include <linux/fips.h> #include <linux/init.h> #include <linux/gfp.h> #include <linux/module.h> @@ -34,7 +36,6 @@ #include <linux/timex.h> #include <linux/interrupt.h> #include "tcrypt.h" -#include "internal.h" /* * Need slab memory for testing (size in number of pages). @@ -47,6 +48,8 @@ #define ENCRYPT 1 #define DECRYPT 0 +#define MAX_DIGEST_SIZE 64 + /* * return a string with the driver name */ @@ -72,6 +75,22 @@ static char *check[] = { "lzo", "cts", "zlib", NULL }; +struct tcrypt_result { + struct completion completion; + int err; +}; + +static void tcrypt_complete(struct crypto_async_request *req, int err) +{ + struct tcrypt_result *res = req->data; + + if (err == -EINPROGRESS) + return; + + res->err = err; + complete(&res->completion); +} + static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, struct scatterlist *sg, int blen, int secs) { @@ -142,6 +161,20 @@ out: return ret; } +static inline int do_one_aead_op(struct aead_request *req, int ret) +{ + if (ret == -EINPROGRESS || ret == -EBUSY) { + struct tcrypt_result *tr = req->base.data; + + ret = wait_for_completion_interruptible(&tr->completion); + if (!ret) + ret = tr->err; + reinit_completion(&tr->completion); + } + + return ret; +} + static int test_aead_jiffies(struct aead_request *req, int enc, int blen, int secs) { @@ -152,9 +185,9 @@ static int test_aead_jiffies(struct aead_request *req, int enc, for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { if (enc) - ret = crypto_aead_encrypt(req); + ret = do_one_aead_op(req, crypto_aead_encrypt(req)); else - ret = crypto_aead_decrypt(req); + ret = do_one_aead_op(req, crypto_aead_decrypt(req)); if (ret) return ret; @@ -176,9 +209,9 @@ static int test_aead_cycles(struct aead_request *req, int enc, int blen) /* Warm-up run. */ for (i = 0; i < 4; i++) { if (enc) - ret = crypto_aead_encrypt(req); + ret = do_one_aead_op(req, crypto_aead_encrypt(req)); else - ret = crypto_aead_decrypt(req); + ret = do_one_aead_op(req, crypto_aead_decrypt(req)); if (ret) goto out; @@ -190,9 +223,9 @@ static int test_aead_cycles(struct aead_request *req, int enc, int blen) start = get_cycles(); if (enc) - ret = crypto_aead_encrypt(req); + ret = do_one_aead_op(req, crypto_aead_encrypt(req)); else - ret = crypto_aead_decrypt(req); + ret = do_one_aead_op(req, crypto_aead_decrypt(req)); end = get_cycles(); if (ret) @@ -257,12 +290,12 @@ static void sg_init_aead(struct scatterlist *sg, char *xbuf[XBUFSIZE], rem = buflen % PAGE_SIZE; } - sg_init_table(sg, np); + sg_init_table(sg, np + 1); np--; for (k = 0; k < np; k++) - sg_set_buf(&sg[k], xbuf[k], PAGE_SIZE); + sg_set_buf(&sg[k + 1], xbuf[k], PAGE_SIZE); - sg_set_buf(&sg[k], xbuf[k], rem); + sg_set_buf(&sg[k + 1], xbuf[k], rem); } static void test_aead_speed(const char *algo, int enc, unsigned int secs, @@ -276,7 +309,6 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, const char *key; struct aead_request *req; struct scatterlist *sg; - struct scatterlist *asg; struct scatterlist *sgout; const char *e; void *assoc; @@ -286,6 +318,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, char *axbuf[XBUFSIZE]; unsigned int *b_size; unsigned int iv_len; + struct tcrypt_result result; iv = kzalloc(MAX_IVLEN, GFP_KERNEL); if (!iv) @@ -308,11 +341,10 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, if (testmgr_alloc_buf(xoutbuf)) goto out_nooutbuf; - sg = kmalloc(sizeof(*sg) * 8 * 3, GFP_KERNEL); + sg = kmalloc(sizeof(*sg) * 9 * 2, GFP_KERNEL); if (!sg) goto out_nosg; - asg = &sg[8]; - sgout = &asg[8]; + sgout = &sg[9]; tfm = crypto_alloc_aead(algo, 0, 0); @@ -322,6 +354,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, goto out_notfm; } + init_completion(&result.completion); printk(KERN_INFO "\ntesting speed of %s (%s) %s\n", algo, get_driver_name(crypto_aead, tfm), e); @@ -332,13 +365,15 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, goto out_noreq; } + aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &result); + i = 0; do { b_size = aead_sizes; do { assoc = axbuf[0]; memset(assoc, 0xff, aad_size); - sg_init_one(&asg[0], assoc, aad_size); if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) { pr_err("template (%u) too big for tvmem (%lu)\n", @@ -374,14 +409,17 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, goto out; } - sg_init_aead(&sg[0], xbuf, + sg_init_aead(sg, xbuf, *b_size + (enc ? authsize : 0)); - sg_init_aead(&sgout[0], xoutbuf, + sg_init_aead(sgout, xoutbuf, *b_size + (enc ? authsize : 0)); + sg_set_buf(&sg[0], assoc, aad_size); + sg_set_buf(&sgout[0], assoc, aad_size); + aead_request_set_crypt(req, sg, sgout, *b_size, iv); - aead_request_set_assoc(req, asg, aad_size); + aead_request_set_ad(req, aad_size); if (secs) ret = test_aead_jiffies(req, enc, *b_size, @@ -748,22 +786,6 @@ out: crypto_free_hash(tfm); } -struct tcrypt_result { - struct completion completion; - int err; -}; - -static void tcrypt_complete(struct crypto_async_request *req, int err) -{ - struct tcrypt_result *res = req->data; - - if (err == -EINPROGRESS) - return; - - res->err = err; - complete(&res->completion); -} - static inline int do_one_ahash_op(struct ahash_request *req, int ret) { if (ret == -EINPROGRESS || ret == -EBUSY) { @@ -808,7 +830,7 @@ static int test_ahash_jiffies(struct ahash_request *req, int blen, for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { - ret = crypto_ahash_init(req); + ret = do_one_ahash_op(req, crypto_ahash_init(req)); if (ret) return ret; for (pcount = 0; pcount < blen; pcount += plen) { @@ -877,7 +899,7 @@ static int test_ahash_cycles(struct ahash_request *req, int blen, /* Warm-up run. */ for (i = 0; i < 4; i++) { - ret = crypto_ahash_init(req); + ret = do_one_ahash_op(req, crypto_ahash_init(req)); if (ret) goto out; for (pcount = 0; pcount < blen; pcount += plen) { @@ -896,7 +918,7 @@ static int test_ahash_cycles(struct ahash_request *req, int blen, start = get_cycles(); - ret = crypto_ahash_init(req); + ret = do_one_ahash_op(req, crypto_ahash_init(req)); if (ret) goto out; for (pcount = 0; pcount < blen; pcount += plen) { @@ -930,7 +952,7 @@ static void test_ahash_speed(const char *algo, unsigned int secs, struct tcrypt_result tresult; struct ahash_request *req; struct crypto_ahash *tfm; - static char output[1024]; + char *output; int i, ret; tfm = crypto_alloc_ahash(algo, 0, 0); @@ -943,9 +965,9 @@ static void test_ahash_speed(const char *algo, unsigned int secs, printk(KERN_INFO "\ntesting speed of async %s (%s)\n", algo, get_driver_name(crypto_ahash, tfm)); - if (crypto_ahash_digestsize(tfm) > sizeof(output)) { - pr_err("digestsize(%u) > outputbuffer(%zu)\n", - crypto_ahash_digestsize(tfm), sizeof(output)); + if (crypto_ahash_digestsize(tfm) > MAX_DIGEST_SIZE) { + pr_err("digestsize(%u) > %d\n", crypto_ahash_digestsize(tfm), + MAX_DIGEST_SIZE); goto out; } @@ -960,6 +982,10 @@ static void test_ahash_speed(const char *algo, unsigned int secs, ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, tcrypt_complete, &tresult); + output = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); + if (!output) + goto out_nomem; + for (i = 0; speed[i].blen != 0; i++) { if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) { pr_err("template (%u) too big for tvmem (%lu)\n", @@ -986,6 +1012,9 @@ static void test_ahash_speed(const char *algo, unsigned int secs, } } + kfree(output); + +out_nomem: ahash_request_free(req); out: @@ -1758,9 +1787,27 @@ static int do_test(const char *alg, u32 type, u32 mask, int m) case 211: test_aead_speed("rfc4106(gcm(aes))", ENCRYPT, sec, + NULL, 0, 16, 16, aead_speed_template_20); + test_aead_speed("gcm(aes)", ENCRYPT, sec, NULL, 0, 16, 8, aead_speed_template_20); break; + case 212: + test_aead_speed("rfc4309(ccm(aes))", ENCRYPT, sec, + NULL, 0, 16, 16, aead_speed_template_19); + break; + + case 213: + test_aead_speed("rfc7539esp(chacha20,poly1305)", ENCRYPT, sec, + NULL, 0, 16, 8, aead_speed_template_36); + break; + + case 214: + test_cipher_speed("chacha20", ENCRYPT, sec, NULL, 0, + speed_template_32); + break; + + case 300: if (alg) { test_hash_speed(alg, sec, generic_hash_speed_template); @@ -1849,6 +1896,10 @@ static int do_test(const char *alg, u32 type, u32 mask, int m) test_hash_speed("crct10dif", sec, generic_hash_speed_template); if (mode > 300 && mode < 400) break; + case 321: + test_hash_speed("poly1305", sec, poly1305_speed_template); + if (mode > 300 && mode < 400) break; + case 399: break; |