The existing mode 200 performs ecb(aes), cbc(aes), ctr(aes), ecb(des), cbc(des)
ecb(des3_ede), cbc(des3_ede) for synchronous block cihper. For crypto hardware
drivers ablkcipher's are used and hence add new mode 500 and its variants to
perform the tests in asynchronous block cipher.

Signed-off-by: Arun Murthy <arun.mur...@stericsson.com>
Signed-off-by: Berne Hebark <berne.heb...@stericsson.com>
Acked-by: Srinidhi Kasagar <srinidhi.kasa...@stericsson.com>
Acked-by: Linus Walleij <linus.wall...@linaro.org>
---
 crypto/tcrypt.c |  265 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 249 insertions(+), 16 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 2222617..75f0747 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -67,6 +67,87 @@ static char *check[] = {
        "lzo", "cts", "zlib", NULL
 };
 
+struct tcrypt_result {
+       struct completion completion;
+       int err;
+};
+
+static int test_ablkcipher_jiffies(struct ablkcipher_request *req, int enc,
+                              int blen, int sec)
+{
+       unsigned long start, end;
+       int bcount;
+       int ret;
+
+       for (start = jiffies, end = start + sec * HZ, bcount = 0;
+            time_before(jiffies, end); bcount++) {
+               if (enc)
+                       ret = crypto_ablkcipher_encrypt(req);
+               else
+                       ret = crypto_ablkcipher_decrypt(req);
+
+               if (ret) {
+                       printk("\n [test_cipher_jiffies] "
+                               "crypto_ablkcipher_encrypt/decrypt: enc: %d, "
+                               "ret = %x \n", enc, ret);
+                       return ret;
+               }
+       }
+
+       printk("%d operations in %d seconds (%ld bytes)\n",
+              bcount, sec, (long)bcount * blen);
+       return 0;
+}
+
+static int test_ablkcipher_cycles(struct ablkcipher_request *req,
+                             int enc, int blen)
+{
+       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)
+                       ret = crypto_ablkcipher_encrypt(req);
+               else
+                       ret = crypto_ablkcipher_decrypt(req);
+
+               if (ret)
+                       goto out;
+       }
+
+       /* The real thing. */
+       for (i = 0; i < 8; i++) {
+               cycles_t start, end;
+
+               start = get_cycles();
+               if (enc)
+                       ret = crypto_ablkcipher_encrypt(req);
+               else
+                       ret = crypto_ablkcipher_decrypt(req);
+               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 int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
                               struct scatterlist *sg, int blen, int sec)
 {
@@ -139,8 +220,130 @@ out:
        return ret;
 }
 
+static u32 ablock_sizes[] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 
8192, 16384, 24576, 0 };
 static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 };
 
+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 void test_ablkcipher_speed(const char *algo, int enc, unsigned int sec,
+                               struct cipher_speed_template *template,
+                               unsigned int tcount, u8 *keysize)
+{
+       unsigned int ret, i, j, iv_len;
+       const char *key;
+       char iv[128];
+       const char *e;
+       u32 *b_size;
+       struct tcrypt_result result;
+       struct crypto_ablkcipher *tfm;
+       struct ablkcipher_request *req;
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       printk("\ntesting speed of %s %s\n", algo, e);
+       init_completion(&result.completion);
+
+       tfm = crypto_alloc_ablkcipher(algo, 0, 0);
+       if (IS_ERR(tfm)) {
+               printk("failed to load transform for %s: %ld\n", algo,
+                      PTR_ERR(tfm));
+               return;
+       }
+       req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
+       if (!req) {
+               printk(KERN_ERR "alg: cipher_speed: Failed to allocate request "
+                      "for %s\n", algo);
+               return;
+       }
+
+       ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+                                       tcrypt_complete, &result);
+
+       i = 0;
+       do {
+
+               b_size = ablock_sizes;
+               do {
+                       struct scatterlist sg[TVMEMSIZE];
+
+                       if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
+                               printk("template (%u) too big for "
+                                      "tvmem (%lu)\n", *keysize + *b_size,
+                                      TVMEMSIZE * PAGE_SIZE);
+                               goto out;
+                       }
+
+                       printk("test %u (%d bit key, %d byte blocks): ", i,
+                                       *keysize * 8, *b_size);
+
+                       memset(tvmem[0], 0xff, PAGE_SIZE);
+
+                       /* set key, plain text and IV */
+                       key = tvmem[0];
+                       for (j = 0; j < tcount; j++) {
+                               if (template[j].klen == *keysize) {
+                                       key = template[j].key;
+                                       break;
+                               }
+                       }
+                       ret = crypto_ablkcipher_setkey(tfm, key, *keysize);
+                       if (ret) {
+                               printk("setkey() failed flags=%x\n",
+                                               
crypto_ablkcipher_get_flags(tfm));
+                               goto out;
+                       }
+
+                       sg_init_table(sg, TVMEMSIZE);
+                       sg_set_buf(sg, tvmem[0] + *keysize,
+                                  (PAGE_SIZE - *keysize) -
+                                  ((PAGE_SIZE - *keysize)) % 16);
+                       for (j = 1; j < TVMEMSIZE; j++) {
+                               sg_set_buf(sg + j, tvmem[j], PAGE_SIZE);
+                               memset (tvmem[j], 0xff, PAGE_SIZE);
+                       }
+
+                       iv_len = crypto_ablkcipher_ivsize(tfm);
+                       if (iv_len) {
+                               memset(&iv, 0xff, iv_len);
+                       }
+                       ablkcipher_request_set_crypt(req, sg, sg,
+                                                    *b_size, iv);
+
+                       if (sec)
+                               ret = test_ablkcipher_jiffies(req, enc,
+                                                         *b_size, sec);
+                       else
+                               ret = test_ablkcipher_cycles(req, enc,
+                                                        *b_size);
+
+                       if (ret) {
+                               printk("%s() failed flags=%x\n", e,
+                                       crypto_ablkcipher_get_flags(tfm));
+                               break;
+                       }
+                       b_size++;
+                       i++;
+               } while (*b_size);
+               keysize++;
+       } while (*keysize);
+
+out:
+       ablkcipher_request_free(req);
+       crypto_free_ablkcipher(tfm);
+}
+
 static void test_cipher_speed(const char *algo, int enc, unsigned int sec,
                              struct cipher_speed_template *template,
                              unsigned int tcount, u8 *keysize)
@@ -475,22 +678,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) {
@@ -1230,7 +1417,53 @@ static int do_test(int m)
 
        case 499:
                break;
+       case 500:
+               test_ablkcipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_ablkcipher_speed("ecb(aes)", DECRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_ablkcipher_speed("cbc(aes)", ENCRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_ablkcipher_speed("cbc(aes)", DECRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_ablkcipher_speed("lrw(aes)", ENCRYPT, sec, NULL, 0,
+                               speed_template_32_40_48);
+               test_ablkcipher_speed("lrw(aes)", DECRYPT, sec, NULL, 0,
+                               speed_template_32_40_48);
+               test_ablkcipher_speed("xts(aes)", ENCRYPT, sec, NULL, 0,
+                               speed_template_32_48_64);
+               test_ablkcipher_speed("xts(aes)", DECRYPT, sec, NULL, 0,
+                               speed_template_32_48_64);
+               test_ablkcipher_speed("ctr(aes)", ENCRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_ablkcipher_speed("ctr(aes)", DECRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               break;
+       case 501:
+               test_ablkcipher_speed("ecb(des3_ede)", ENCRYPT, sec,
+                               des3_speed_template, DES3_SPEED_VECTORS,
+                               speed_template_24);
+               test_ablkcipher_speed("ecb(des3_ede)", DECRYPT, sec,
+                               des3_speed_template, DES3_SPEED_VECTORS,
+                               speed_template_24);
+               test_ablkcipher_speed("cbc(des3_ede)", ENCRYPT, sec,
+                               des3_speed_template, DES3_SPEED_VECTORS,
+                               speed_template_24);
+               test_ablkcipher_speed("cbc(des3_ede)", DECRYPT, sec,
+                               des3_speed_template, DES3_SPEED_VECTORS,
+                               speed_template_24);
+               break;
 
+       case 504:
+               test_ablkcipher_speed("ecb(des)", ENCRYPT, sec, NULL, 0,
+                                 speed_template_8);
+               test_ablkcipher_speed("ecb(des)", DECRYPT, sec, NULL, 0,
+                                 speed_template_8);
+               test_ablkcipher_speed("cbc(des)", ENCRYPT, sec, NULL, 0,
+                                 speed_template_8);
+               test_ablkcipher_speed("cbc(des)", DECRYPT, sec, NULL, 0,
+                                 speed_template_8);
+               break;
        case 1000:
                test_available();
                break;
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to