Commit 53f52d7aecb4cb3772872c902b73e0c685a56901

Authored by Tim Chen
Committed by Herbert Xu
1 parent d764593af9

crypto: tcrypt - Added speed tests for AEAD crypto alogrithms in tcrypt test suite

Adding simple speed tests for a range of block sizes for AEAD crypto
algorithms.

Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Showing 2 changed files with 280 additions and 0 deletions Side-by-side Diff

... ... @@ -137,8 +137,273 @@
137 137 return ret;
138 138 }
139 139  
  140 +static int test_aead_jiffies(struct aead_request *req, int enc,
  141 + int blen, int sec)
  142 +{
  143 + unsigned long start, end;
  144 + int bcount;
  145 + int ret;
  146 +
  147 + for (start = jiffies, end = start + sec * HZ, bcount = 0;
  148 + time_before(jiffies, end); bcount++) {
  149 + if (enc)
  150 + ret = crypto_aead_encrypt(req);
  151 + else
  152 + ret = crypto_aead_decrypt(req);
  153 +
  154 + if (ret)
  155 + return ret;
  156 + }
  157 +
  158 + printk("%d operations in %d seconds (%ld bytes)\n",
  159 + bcount, sec, (long)bcount * blen);
  160 + return 0;
  161 +}
  162 +
  163 +static int test_aead_cycles(struct aead_request *req, int enc, int blen)
  164 +{
  165 + unsigned long cycles = 0;
  166 + int ret = 0;
  167 + int i;
  168 +
  169 + local_irq_disable();
  170 +
  171 + /* Warm-up run. */
  172 + for (i = 0; i < 4; i++) {
  173 + if (enc)
  174 + ret = crypto_aead_encrypt(req);
  175 + else
  176 + ret = crypto_aead_decrypt(req);
  177 +
  178 + if (ret)
  179 + goto out;
  180 + }
  181 +
  182 + /* The real thing. */
  183 + for (i = 0; i < 8; i++) {
  184 + cycles_t start, end;
  185 +
  186 + start = get_cycles();
  187 + if (enc)
  188 + ret = crypto_aead_encrypt(req);
  189 + else
  190 + ret = crypto_aead_decrypt(req);
  191 + end = get_cycles();
  192 +
  193 + if (ret)
  194 + goto out;
  195 +
  196 + cycles += end - start;
  197 + }
  198 +
  199 +out:
  200 + local_irq_enable();
  201 +
  202 + if (ret == 0)
  203 + printk("1 operation in %lu cycles (%d bytes)\n",
  204 + (cycles + 4) / 8, blen);
  205 +
  206 + return ret;
  207 +}
  208 +
140 209 static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 };
  210 +static u32 aead_sizes[] = { 16, 64, 256, 512, 1024, 2048, 4096, 8192, 0 };
141 211  
  212 +#define XBUFSIZE 8
  213 +#define MAX_IVLEN 32
  214 +
  215 +static int testmgr_alloc_buf(char *buf[XBUFSIZE])
  216 +{
  217 + int i;
  218 +
  219 + for (i = 0; i < XBUFSIZE; i++) {
  220 + buf[i] = (void *)__get_free_page(GFP_KERNEL);
  221 + if (!buf[i])
  222 + goto err_free_buf;
  223 + }
  224 +
  225 + return 0;
  226 +
  227 +err_free_buf:
  228 + while (i-- > 0)
  229 + free_page((unsigned long)buf[i]);
  230 +
  231 + return -ENOMEM;
  232 +}
  233 +
  234 +static void testmgr_free_buf(char *buf[XBUFSIZE])
  235 +{
  236 + int i;
  237 +
  238 + for (i = 0; i < XBUFSIZE; i++)
  239 + free_page((unsigned long)buf[i]);
  240 +}
  241 +
  242 +static void sg_init_aead(struct scatterlist *sg, char *xbuf[XBUFSIZE],
  243 + unsigned int buflen)
  244 +{
  245 + int np = (buflen + PAGE_SIZE - 1)/PAGE_SIZE;
  246 + int k, rem;
  247 +
  248 + np = (np > XBUFSIZE) ? XBUFSIZE : np;
  249 + rem = buflen % PAGE_SIZE;
  250 + if (np > XBUFSIZE) {
  251 + rem = PAGE_SIZE;
  252 + np = XBUFSIZE;
  253 + }
  254 + sg_init_table(sg, np);
  255 + for (k = 0; k < np; ++k) {
  256 + if (k == (np-1))
  257 + sg_set_buf(&sg[k], xbuf[k], rem);
  258 + else
  259 + sg_set_buf(&sg[k], xbuf[k], PAGE_SIZE);
  260 + }
  261 +}
  262 +
  263 +static void test_aead_speed(const char *algo, int enc, unsigned int sec,
  264 + struct aead_speed_template *template,
  265 + unsigned int tcount, u8 authsize,
  266 + unsigned int aad_size, u8 *keysize)
  267 +{
  268 + unsigned int i, j;
  269 + struct crypto_aead *tfm;
  270 + int ret = -ENOMEM;
  271 + const char *key;
  272 + struct aead_request *req;
  273 + struct scatterlist *sg;
  274 + struct scatterlist *asg;
  275 + struct scatterlist *sgout;
  276 + const char *e;
  277 + void *assoc;
  278 + char iv[MAX_IVLEN];
  279 + char *xbuf[XBUFSIZE];
  280 + char *xoutbuf[XBUFSIZE];
  281 + char *axbuf[XBUFSIZE];
  282 + unsigned int *b_size;
  283 + unsigned int iv_len;
  284 +
  285 + if (enc == ENCRYPT)
  286 + e = "encryption";
  287 + else
  288 + e = "decryption";
  289 +
  290 + if (testmgr_alloc_buf(xbuf))
  291 + goto out_noxbuf;
  292 + if (testmgr_alloc_buf(axbuf))
  293 + goto out_noaxbuf;
  294 + if (testmgr_alloc_buf(xoutbuf))
  295 + goto out_nooutbuf;
  296 +
  297 + sg = kmalloc(sizeof(*sg) * 8 * 3, GFP_KERNEL);
  298 + if (!sg)
  299 + goto out_nosg;
  300 + asg = &sg[8];
  301 + sgout = &asg[8];
  302 +
  303 +
  304 + printk(KERN_INFO "\ntesting speed of %s %s\n", algo, e);
  305 +
  306 + tfm = crypto_alloc_aead(algo, 0, 0);
  307 +
  308 + if (IS_ERR(tfm)) {
  309 + pr_err("alg: aead: Failed to load transform for %s: %ld\n", algo,
  310 + PTR_ERR(tfm));
  311 + return;
  312 + }
  313 +
  314 + req = aead_request_alloc(tfm, GFP_KERNEL);
  315 + if (!req) {
  316 + pr_err("alg: aead: Failed to allocate request for %s\n",
  317 + algo);
  318 + goto out;
  319 + }
  320 +
  321 + i = 0;
  322 + do {
  323 + b_size = aead_sizes;
  324 + do {
  325 + assoc = axbuf[0];
  326 +
  327 + if (aad_size < PAGE_SIZE)
  328 + memset(assoc, 0xff, aad_size);
  329 + else {
  330 + pr_err("associate data length (%u) too big\n",
  331 + aad_size);
  332 + goto out_nosg;
  333 + }
  334 + sg_init_one(&asg[0], assoc, aad_size);
  335 +
  336 + if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
  337 + pr_err("template (%u) too big for tvmem (%lu)\n",
  338 + *keysize + *b_size,
  339 + TVMEMSIZE * PAGE_SIZE);
  340 + goto out;
  341 + }
  342 +
  343 + key = tvmem[0];
  344 + for (j = 0; j < tcount; j++) {
  345 + if (template[j].klen == *keysize) {
  346 + key = template[j].key;
  347 + break;
  348 + }
  349 + }
  350 + ret = crypto_aead_setkey(tfm, key, *keysize);
  351 + ret = crypto_aead_setauthsize(tfm, authsize);
  352 +
  353 + iv_len = crypto_aead_ivsize(tfm);
  354 + if (iv_len)
  355 + memset(&iv, 0xff, iv_len);
  356 +
  357 + crypto_aead_clear_flags(tfm, ~0);
  358 + printk(KERN_INFO "test %u (%d bit key, %d byte blocks): ",
  359 + i, *keysize * 8, *b_size);
  360 +
  361 +
  362 + memset(tvmem[0], 0xff, PAGE_SIZE);
  363 +
  364 + if (ret) {
  365 + pr_err("setkey() failed flags=%x\n",
  366 + crypto_aead_get_flags(tfm));
  367 + goto out;
  368 + }
  369 +
  370 + sg_init_aead(&sg[0], xbuf,
  371 + *b_size + (enc ? authsize : 0));
  372 +
  373 + sg_init_aead(&sgout[0], xoutbuf,
  374 + *b_size + (enc ? authsize : 0));
  375 +
  376 + aead_request_set_crypt(req, sg, sgout, *b_size, iv);
  377 + aead_request_set_assoc(req, asg, aad_size);
  378 +
  379 + if (sec)
  380 + ret = test_aead_jiffies(req, enc, *b_size, sec);
  381 + else
  382 + ret = test_aead_cycles(req, enc, *b_size);
  383 +
  384 + if (ret) {
  385 + pr_err("%s() failed return code=%d\n", e, ret);
  386 + break;
  387 + }
  388 + b_size++;
  389 + i++;
  390 + } while (*b_size);
  391 + keysize++;
  392 + } while (*keysize);
  393 +
  394 +out:
  395 + crypto_free_aead(tfm);
  396 + kfree(sg);
  397 +out_nosg:
  398 + testmgr_free_buf(xoutbuf);
  399 +out_nooutbuf:
  400 + testmgr_free_buf(axbuf);
  401 +out_noaxbuf:
  402 + testmgr_free_buf(xbuf);
  403 +out_noxbuf:
  404 + return;
  405 +}
  406 +
142 407 static void test_cipher_speed(const char *algo, int enc, unsigned int sec,
143 408 struct cipher_speed_template *template,
144 409 unsigned int tcount, u8 *keysize)
... ... @@ -1425,6 +1690,11 @@
1425 1690 speed_template_32_64);
1426 1691 test_cipher_speed("xts(cast6)", DECRYPT, sec, NULL, 0,
1427 1692 speed_template_32_64);
  1693 + break;
  1694 +
  1695 + case 211:
  1696 + test_aead_speed("rfc4106(gcm(aes))", ENCRYPT, sec,
  1697 + NULL, 0, 16, 8, aead_speed_template_20);
1428 1698 break;
1429 1699  
1430 1700 case 300:
... ... @@ -22,6 +22,11 @@
22 22 unsigned int klen;
23 23 };
24 24  
  25 +struct aead_speed_template {
  26 + const char *key;
  27 + unsigned int klen;
  28 +};
  29 +
25 30 struct hash_speed {
26 31 unsigned int blen; /* buffer length */
27 32 unsigned int plen; /* per-update length */
... ... @@ -56,6 +61,11 @@
56 61 static u8 speed_template_32_48[] = {32, 48, 0};
57 62 static u8 speed_template_32_48_64[] = {32, 48, 64, 0};
58 63 static u8 speed_template_32_64[] = {32, 64, 0};
  64 +
  65 +/*
  66 + * AEAD speed tests
  67 + */
  68 +static u8 aead_speed_template_20[] = {20, 0};
59 69  
60 70 /*
61 71 * Digest speed tests