aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2016-05-31 07:11:57 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2016-06-02 06:39:01 -0400
commited494d4fa234443a005489afb6b9583415ad89ff (patch)
treef638837277d65abd82370e7749b3aecac569df99
parent5318c53d5b4bbf097ccba2e74831d67e4d63b1a1 (diff)
crypto: drbg - reduce number of setkey calls
The CTR DRBG code always set the key for each sym cipher invocation even though the key has not been changed. The patch ensures that the setkey is only invoked when a new key is generated by the DRBG. With this patch, the CTR DRBG performance increases by more than 150%. Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/drbg.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 0a3538f6cf22..0aca2b908c76 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -252,8 +252,10 @@ MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes192");
252MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes128"); 252MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes128");
253MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes128"); 253MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes128");
254 254
255static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key, 255static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
256 unsigned char *outval, const struct drbg_string *in); 256 const unsigned char *key);
257static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
258 const struct drbg_string *in);
257static int drbg_init_sym_kernel(struct drbg_state *drbg); 259static int drbg_init_sym_kernel(struct drbg_state *drbg);
258static int drbg_fini_sym_kernel(struct drbg_state *drbg); 260static int drbg_fini_sym_kernel(struct drbg_state *drbg);
259 261
@@ -270,6 +272,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
270 drbg_string_fill(&data, out, drbg_blocklen(drbg)); 272 drbg_string_fill(&data, out, drbg_blocklen(drbg));
271 273
272 /* 10.4.3 step 2 / 4 */ 274 /* 10.4.3 step 2 / 4 */
275 drbg_kcapi_symsetkey(drbg, key);
273 list_for_each_entry(curr, in, list) { 276 list_for_each_entry(curr, in, list) {
274 const unsigned char *pos = curr->buf; 277 const unsigned char *pos = curr->buf;
275 size_t len = curr->len; 278 size_t len = curr->len;
@@ -278,7 +281,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
278 /* 10.4.3 step 4.2 */ 281 /* 10.4.3 step 4.2 */
279 if (drbg_blocklen(drbg) == cnt) { 282 if (drbg_blocklen(drbg) == cnt) {
280 cnt = 0; 283 cnt = 0;
281 ret = drbg_kcapi_sym(drbg, key, out, &data); 284 ret = drbg_kcapi_sym(drbg, out, &data);
282 if (ret) 285 if (ret)
283 return ret; 286 return ret;
284 } 287 }
@@ -290,7 +293,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
290 } 293 }
291 /* 10.4.3 step 4.2 for last block */ 294 /* 10.4.3 step 4.2 for last block */
292 if (cnt) 295 if (cnt)
293 ret = drbg_kcapi_sym(drbg, key, out, &data); 296 ret = drbg_kcapi_sym(drbg, out, &data);
294 297
295 return ret; 298 return ret;
296} 299}
@@ -425,6 +428,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
425 /* 10.4.2 step 12: overwriting of outval is implemented in next step */ 428 /* 10.4.2 step 12: overwriting of outval is implemented in next step */
426 429
427 /* 10.4.2 step 13 */ 430 /* 10.4.2 step 13 */
431 drbg_kcapi_symsetkey(drbg, temp);
428 while (generated_len < bytes_to_return) { 432 while (generated_len < bytes_to_return) {
429 short blocklen = 0; 433 short blocklen = 0;
430 /* 434 /*
@@ -432,7 +436,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
432 * implicit as the key is only drbg_blocklen in size based on 436 * implicit as the key is only drbg_blocklen in size based on
433 * the implementation of the cipher function callback 437 * the implementation of the cipher function callback
434 */ 438 */
435 ret = drbg_kcapi_sym(drbg, temp, X, &cipherin); 439 ret = drbg_kcapi_sym(drbg, X, &cipherin);
436 if (ret) 440 if (ret)
437 goto out; 441 goto out;
438 blocklen = (drbg_blocklen(drbg) < 442 blocklen = (drbg_blocklen(drbg) <
@@ -488,6 +492,7 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
488 ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed); 492 ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed);
489 if (ret) 493 if (ret)
490 goto out; 494 goto out;
495 drbg_kcapi_symsetkey(drbg, drbg->C);
491 } 496 }
492 497
493 drbg_string_fill(&cipherin, drbg->V, drbg_blocklen(drbg)); 498 drbg_string_fill(&cipherin, drbg->V, drbg_blocklen(drbg));
@@ -500,7 +505,7 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
500 crypto_inc(drbg->V, drbg_blocklen(drbg)); 505 crypto_inc(drbg->V, drbg_blocklen(drbg));
501 /* 506 /*
502 * 10.2.1.2 step 2.2 */ 507 * 10.2.1.2 step 2.2 */
503 ret = drbg_kcapi_sym(drbg, drbg->C, temp + len, &cipherin); 508 ret = drbg_kcapi_sym(drbg, temp + len, &cipherin);
504 if (ret) 509 if (ret)
505 goto out; 510 goto out;
506 /* 10.2.1.2 step 2.3 and 3 */ 511 /* 10.2.1.2 step 2.3 and 3 */
@@ -517,6 +522,7 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
517 522
518 /* 10.2.1.2 step 5 */ 523 /* 10.2.1.2 step 5 */
519 memcpy(drbg->C, temp, drbg_keylen(drbg)); 524 memcpy(drbg->C, temp, drbg_keylen(drbg));
525 drbg_kcapi_symsetkey(drbg, drbg->C);
520 /* 10.2.1.2 step 6 */ 526 /* 10.2.1.2 step 6 */
521 memcpy(drbg->V, temp + drbg_keylen(drbg), drbg_blocklen(drbg)); 527 memcpy(drbg->V, temp + drbg_keylen(drbg), drbg_blocklen(drbg));
522 ret = 0; 528 ret = 0;
@@ -546,6 +552,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg,
546 ret = drbg_ctr_update(drbg, addtl, 2); 552 ret = drbg_ctr_update(drbg, addtl, 2);
547 if (ret) 553 if (ret)
548 return 0; 554 return 0;
555 drbg_kcapi_symsetkey(drbg, drbg->C);
549 } 556 }
550 557
551 /* 10.2.1.5.2 step 4.1 */ 558 /* 10.2.1.5.2 step 4.1 */
@@ -554,7 +561,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg,
554 while (len < buflen) { 561 while (len < buflen) {
555 int outlen = 0; 562 int outlen = 0;
556 /* 10.2.1.5.2 step 4.2 */ 563 /* 10.2.1.5.2 step 4.2 */
557 ret = drbg_kcapi_sym(drbg, drbg->C, drbg->scratchpad, &data); 564 ret = drbg_kcapi_sym(drbg, drbg->scratchpad, &data);
558 if (ret) { 565 if (ret) {
559 len = ret; 566 len = ret;
560 goto out; 567 goto out;
@@ -1653,13 +1660,21 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
1653 return 0; 1660 return 0;
1654} 1661}
1655 1662
1656static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key, 1663static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
1657 unsigned char *outval, const struct drbg_string *in) 1664 const unsigned char *key)
1658{ 1665{
1659 struct crypto_cipher *tfm = 1666 struct crypto_cipher *tfm =
1660 (struct crypto_cipher *)drbg->priv_data; 1667 (struct crypto_cipher *)drbg->priv_data;
1661 1668
1662 crypto_cipher_setkey(tfm, key, (drbg_keylen(drbg))); 1669 crypto_cipher_setkey(tfm, key, (drbg_keylen(drbg)));
1670}
1671
1672static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
1673 const struct drbg_string *in)
1674{
1675 struct crypto_cipher *tfm =
1676 (struct crypto_cipher *)drbg->priv_data;
1677
1663 /* there is only component in *in */ 1678 /* there is only component in *in */
1664 BUG_ON(in->len < drbg_blocklen(drbg)); 1679 BUG_ON(in->len < drbg_blocklen(drbg));
1665 crypto_cipher_encrypt_one(tfm, outval, in->buf); 1680 crypto_cipher_encrypt_one(tfm, outval, in->buf);