[PATCH] crypto: tcrypt - Add mode 500 for ablkcipher test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.murthy@xxxxxxxxxxxxxx>
Signed-off-by: Berne Hebark <berne.hebark@xxxxxxxxxxxxxx>
Acked-by: Srinidhi Kasagar <srinidhi.kasagar@xxxxxxxxxxxxxx>
Acked-by: Linus Walleij <linus.walleij@xxxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux