crypto: drbg: performance improvements
cover crypto: drbg: performance improvements
Hi,
The following patches increase the performance of the CTR DRBG and Hash DRBG.
The updates successfully pass the CAVS testing. for Hash DRBG and CTR DRBG.
Stephan Mueller (2):
crypto: drbg: use single block cipher API
crypto: drbg: remove superflowous memsets
crypto/drbg.c | 57 ++++++++++++++++----------------------------------------- 1 file changed, 16 insertions(+), 41 deletions(-)
Signature · 1 line
2.1.0
PATCH 1/2 crypto: drbg: use single block cipher API
The CTR DRBG only encrypts one single block at a time. Thus, use the single block crypto API to avoid additional overhead from the block chaining modes.
With the patch, the speed of the DRBG increases between 30% and 40%.
The DRBG still passes the CTR DRBG CAVS test.
--- crypto/drbg.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-)
crypto/drbg.c +16 -23
@@ -119,19 +119,19 @@ static const struct drbg_core drbg_cores[] = { .statelen = 32, /* 256 bits as defined in 10.2.1 */ .blocklen_bytes = 16, .cra_name = "ctr_aes128", - .backend_cra_name = "ecb(aes)", + .backend_cra_name = "aes", }, { .flags = DRBG_CTR | DRBG_STRENGTH192, .statelen = 40, /* 320 bits as defined in 10.2.1 */ .blocklen_bytes = 16, .cra_name = "ctr_aes192", - .backend_cra_name = "ecb(aes)", + .backend_cra_name = "aes", }, { .flags = DRBG_CTR | DRBG_STRENGTH256, .statelen = 48, /* 384 bits as defined in 10.2.1 */ .blocklen_bytes = 16, .cra_name = "ctr_aes256", - .backend_cra_name = "ecb(aes)", + .backend_cra_name = "aes", }, #endif /* CONFIG_CRYPTO_DRBG_CTR */ #ifdef CONFIG_CRYPTO_DRBG_HASH
@@ -1644,24 +1644,24 @@ static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key,static int drbg_init_sym_kernel (struct drbg_state *drbg) {int ret =0 ; -struct crypto_blkcipher *tfm; +struct crypto_cipher *tfm; - tfm =crypto_alloc_blkcipher (drbg->core->backend_cra_name,0 ,0 ); + tfm =crypto_alloc_cipher (drbg->core->backend_cra_name,0 ,0 );if (IS_ERR (tfm)) {pr_info ("DRBG: could not allocate cipher TFM handle\n" );return PTR_ERR (tfm); } -BUG_ON (drbg_blocklen (drbg) !=crypto_blkcipher_blocksize (tfm)); +BUG_ON (drbg_blocklen (drbg) !=crypto_cipher_blocksize (tfm)); drbg->priv_data = tfm;return ret; }static int drbg_fini_sym_kernel (struct drbg_state *drbg) { -struct crypto_blkcipher *tfm = - (struct crypto_blkcipher *)drbg->priv_data; +struct crypto_cipher *tfm = + (struct crypto_cipher *)drbg->priv_data;if (tfm) -crypto_free_blkcipher (tfm); +crypto_free_cipher (tfm); drbg->priv_data =NULL ;return 0 ; }
@@ -1669,21 +1669,14 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)static int drbg_kcapi_sym (struct drbg_state *drbg,const unsigned char *key,unsigned char *outval,const struct drbg_string *in) { -int ret =0 ; -struct scatterlist sg_in, sg_out; -struct blkcipher_desc desc; -struct crypto_blkcipher *tfm = - (struct crypto_blkcipher *)drbg->priv_data; - - desc.tfm = tfm; - desc.flags =0 ; -crypto_blkcipher_setkey (tfm, key, (drbg_keylen (drbg))); -/* there is only component in *in */ -sg_init_one (&sg_in, in->buf, in->len); -sg_init_one (&sg_out, outval,drbg_blocklen (drbg)); - ret =crypto_blkcipher_encrypt (&desc, &sg_out, &sg_in, in->len); +struct crypto_cipher *tfm = + (struct crypto_cipher *)drbg->priv_data; -return ret; +crypto_cipher_setkey (tfm, key, (drbg_keylen (drbg))); +/* there is only component in *in */ +BUG_ON (in->len <drbg_blocklen (drbg)); +crypto_cipher_encrypt_one (tfm, outval, in->buf); +return 0 ; }#endif /* CONFIG_CRYPTO_DRBG_CTR */
Signature · 1 line
2.1.0
PATCH 2/2 crypto: drbg: remove superflowous memsets
In reply to Stephan MuellerThe DRBG code contains memset(0) calls to initialize a varaible that are not necessary as the variable is always overwritten by the processing.
This patch increases the CTR and Hash DRBGs by about 5%.
--- crypto/drbg.c | 18 ------------------ 1 file changed, 18 deletions(-)
crypto/drbg.c +0 -18
@@ -308,9 +308,6 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,drbg_string_fill (&data, out,drbg_blocklen (drbg)); -/* 10.4.3 step 1 */ -memset (out,0 ,drbg_blocklen (drbg)); -/* 10.4.3 step 2 / 4 */ list_for_each_entry (curr, in, list) {const unsigned char *pos = curr->buf;
@@ -406,7 +403,6 @@ static int drbg_ctr_df(struct drbg_state *drbg,memset (pad,0 ,drbg_blocklen (drbg));memset (iv,0 ,drbg_blocklen (drbg)); -memset (temp,0 ,drbg_statelen (drbg));/* 10.4.2 step 1 is implicit as we work byte-wise */
@@ -523,7 +519,6 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,unsigned int len =0 ;struct drbg_string cipherin; -memset (temp,0 ,drbg_statelen (drbg) +drbg_blocklen (drbg));if (3 > reseed)memset (df_data,0 ,drbg_statelen (drbg));
@@ -585,8 +580,6 @@ static int drbg_ctr_generate(struct drbg_state *drbg,int ret =0 ;struct drbg_string data; -memset (drbg->scratchpad,0 ,drbg_blocklen (drbg)); -/* 10.2.1.5.2 step 2 */ if (addtl && !list_empty (addtl)) { ret =drbg_ctr_update (drbg, addtl,2 );
@@ -761,7 +754,6 @@ static struct drbg_state_ops drbg_hmac_ops = { .generate = drbg_hmac_generate, .crypto_init = drbg_init_hash_kernel, .crypto_fini = drbg_fini_hash_kernel, - };#endif /* CONFIG_CRYPTO_DRBG_HMAC */
@@ -838,8 +830,6 @@ static int drbg_hash_df(struct drbg_state *drbg,unsigned char *tmp = drbg->scratchpad +drbg_statelen (drbg);struct drbg_string data; -memset (tmp,0 ,drbg_blocklen (drbg)); -/* 10.4.1 step 3 */ input[0 ] =1 ;drbg_cpu_to_be32 ((outlen *8 ), &input[1 ]);
@@ -879,7 +869,6 @@ static int drbg_hash_update(struct drbg_state *drbg, struct list_head *seed,unsigned char *V = drbg->scratchpad;unsigned char prefix =DRBG_PREFIX1 ; -memset (drbg->scratchpad,0 ,drbg_statelen (drbg));if (!seed)return -EINVAL ;
@@ -921,9 +910,6 @@ static int drbg_hash_process_addtl(struct drbg_state *drbg,LIST_HEAD (datalist);unsigned char prefix =DRBG_PREFIX2 ; -/* this is value w as per documentation */ -memset (drbg->scratchpad,0 ,drbg_blocklen (drbg)); -/* 10.1.1.4 step 2 */ if (!addtl ||list_empty (addtl))return 0 ;
@@ -959,9 +945,6 @@ static int drbg_hash_hashgen(struct drbg_state *drbg,struct drbg_string data;LIST_HEAD (datalist); -memset (src,0 ,drbg_statelen (drbg)); -memset (dst,0 ,drbg_blocklen (drbg)); -/* 10.1.1.4 step hashgen 2 */ memcpy (src, drbg->V,drbg_statelen (drbg));
@@ -1018,7 +1001,6 @@ static int drbg_hash_generate(struct drbg_state *drbg, len =drbg_hash_hashgen (drbg, buf, buflen);/* this is the value H as documented in 10.1.1.4 */ -memset (drbg->scratchpad,0 ,drbg_blocklen (drbg));/* 10.1.1.4 step 4 */ drbg_string_fill (&data1, &prefix,1 );list_add_tail (&data1.list, &datalist);
Signature · 1 line
2.1.0
Herbert Xu
maintainerQuoted 11 lines · Stephan Mueller
Hi,
The following patches increase the performance of the CTR DRBG and Hash DRBG.
The updates successfully pass the CAVS testing. for Hash DRBG and CTR DRBG.
Stephan Mueller (2):
crypto: drbg: use single block cipher API
crypto: drbg: remove superflowous memsets
All applied.
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt