提交 ed494d4f 编写于 作者: S Stephan Mueller 提交者: Herbert Xu

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: NStephan Mueller <smueller@chronox.de>
Signed-off-by: NHerbert Xu <herbert@gondor.apana.org.au>
上级 5318c53d
...@@ -252,8 +252,10 @@ MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes192"); ...@@ -252,8 +252,10 @@ MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes192");
MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes128"); MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes128");
MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes128"); MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes128");
static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key, static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
unsigned char *outval, const struct drbg_string *in); const unsigned char *key);
static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
const struct drbg_string *in);
static int drbg_init_sym_kernel(struct drbg_state *drbg); static int drbg_init_sym_kernel(struct drbg_state *drbg);
static int drbg_fini_sym_kernel(struct drbg_state *drbg); static int drbg_fini_sym_kernel(struct drbg_state *drbg);
...@@ -270,6 +272,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg, ...@@ -270,6 +272,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
drbg_string_fill(&data, out, drbg_blocklen(drbg)); drbg_string_fill(&data, out, drbg_blocklen(drbg));
/* 10.4.3 step 2 / 4 */ /* 10.4.3 step 2 / 4 */
drbg_kcapi_symsetkey(drbg, key);
list_for_each_entry(curr, in, list) { list_for_each_entry(curr, in, list) {
const unsigned char *pos = curr->buf; const unsigned char *pos = curr->buf;
size_t len = curr->len; size_t len = curr->len;
...@@ -278,7 +281,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg, ...@@ -278,7 +281,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
/* 10.4.3 step 4.2 */ /* 10.4.3 step 4.2 */
if (drbg_blocklen(drbg) == cnt) { if (drbg_blocklen(drbg) == cnt) {
cnt = 0; cnt = 0;
ret = drbg_kcapi_sym(drbg, key, out, &data); ret = drbg_kcapi_sym(drbg, out, &data);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -290,7 +293,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg, ...@@ -290,7 +293,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
} }
/* 10.4.3 step 4.2 for last block */ /* 10.4.3 step 4.2 for last block */
if (cnt) if (cnt)
ret = drbg_kcapi_sym(drbg, key, out, &data); ret = drbg_kcapi_sym(drbg, out, &data);
return ret; return ret;
} }
...@@ -425,6 +428,7 @@ static int drbg_ctr_df(struct drbg_state *drbg, ...@@ -425,6 +428,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
/* 10.4.2 step 12: overwriting of outval is implemented in next step */ /* 10.4.2 step 12: overwriting of outval is implemented in next step */
/* 10.4.2 step 13 */ /* 10.4.2 step 13 */
drbg_kcapi_symsetkey(drbg, temp);
while (generated_len < bytes_to_return) { while (generated_len < bytes_to_return) {
short blocklen = 0; short blocklen = 0;
/* /*
...@@ -432,7 +436,7 @@ static int drbg_ctr_df(struct drbg_state *drbg, ...@@ -432,7 +436,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
* implicit as the key is only drbg_blocklen in size based on * implicit as the key is only drbg_blocklen in size based on
* the implementation of the cipher function callback * the implementation of the cipher function callback
*/ */
ret = drbg_kcapi_sym(drbg, temp, X, &cipherin); ret = drbg_kcapi_sym(drbg, X, &cipherin);
if (ret) if (ret)
goto out; goto out;
blocklen = (drbg_blocklen(drbg) < blocklen = (drbg_blocklen(drbg) <
...@@ -488,6 +492,7 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, ...@@ -488,6 +492,7 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed); ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed);
if (ret) if (ret)
goto out; goto out;
drbg_kcapi_symsetkey(drbg, drbg->C);
} }
drbg_string_fill(&cipherin, drbg->V, drbg_blocklen(drbg)); 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,7 +505,7 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
crypto_inc(drbg->V, drbg_blocklen(drbg)); crypto_inc(drbg->V, drbg_blocklen(drbg));
/* /*
* 10.2.1.2 step 2.2 */ * 10.2.1.2 step 2.2 */
ret = drbg_kcapi_sym(drbg, drbg->C, temp + len, &cipherin); ret = drbg_kcapi_sym(drbg, temp + len, &cipherin);
if (ret) if (ret)
goto out; goto out;
/* 10.2.1.2 step 2.3 and 3 */ /* 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,6 +522,7 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
/* 10.2.1.2 step 5 */ /* 10.2.1.2 step 5 */
memcpy(drbg->C, temp, drbg_keylen(drbg)); memcpy(drbg->C, temp, drbg_keylen(drbg));
drbg_kcapi_symsetkey(drbg, drbg->C);
/* 10.2.1.2 step 6 */ /* 10.2.1.2 step 6 */
memcpy(drbg->V, temp + drbg_keylen(drbg), drbg_blocklen(drbg)); memcpy(drbg->V, temp + drbg_keylen(drbg), drbg_blocklen(drbg));
ret = 0; ret = 0;
...@@ -546,6 +552,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg, ...@@ -546,6 +552,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg,
ret = drbg_ctr_update(drbg, addtl, 2); ret = drbg_ctr_update(drbg, addtl, 2);
if (ret) if (ret)
return 0; return 0;
drbg_kcapi_symsetkey(drbg, drbg->C);
} }
/* 10.2.1.5.2 step 4.1 */ /* 10.2.1.5.2 step 4.1 */
...@@ -554,7 +561,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg, ...@@ -554,7 +561,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg,
while (len < buflen) { while (len < buflen) {
int outlen = 0; int outlen = 0;
/* 10.2.1.5.2 step 4.2 */ /* 10.2.1.5.2 step 4.2 */
ret = drbg_kcapi_sym(drbg, drbg->C, drbg->scratchpad, &data); ret = drbg_kcapi_sym(drbg, drbg->scratchpad, &data);
if (ret) { if (ret) {
len = ret; len = ret;
goto out; goto out;
...@@ -1653,13 +1660,21 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg) ...@@ -1653,13 +1660,21 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
return 0; return 0;
} }
static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key, static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
unsigned char *outval, const struct drbg_string *in) const unsigned char *key)
{ {
struct crypto_cipher *tfm = struct crypto_cipher *tfm =
(struct crypto_cipher *)drbg->priv_data; (struct crypto_cipher *)drbg->priv_data;
crypto_cipher_setkey(tfm, key, (drbg_keylen(drbg))); crypto_cipher_setkey(tfm, key, (drbg_keylen(drbg)));
}
static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
const struct drbg_string *in)
{
struct crypto_cipher *tfm =
(struct crypto_cipher *)drbg->priv_data;
/* there is only component in *in */ /* there is only component in *in */
BUG_ON(in->len < drbg_blocklen(drbg)); BUG_ON(in->len < drbg_blocklen(drbg));
crypto_cipher_encrypt_one(tfm, outval, in->buf); crypto_cipher_encrypt_one(tfm, outval, in->buf);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册