diff options
author | Stephan Mueller <smueller@chronox.de> | 2015-03-01 14:39:17 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-03-04 04:13:29 -0500 |
commit | 04bcbfcf7e28ba502383a8e19d99960ab8e347c8 (patch) | |
tree | 36fc2e3be9d626e4396305ece16a7bc8a203940d /crypto | |
parent | e8e5995372ac3fc63995915dcb351f38a3560018 (diff) |
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.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/drbg.c | 39 |
1 files changed, 16 insertions, 23 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c index d8ff16e5c322..c14274ac8d61 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c | |||
@@ -119,19 +119,19 @@ static const struct drbg_core drbg_cores[] = { | |||
119 | .statelen = 32, /* 256 bits as defined in 10.2.1 */ | 119 | .statelen = 32, /* 256 bits as defined in 10.2.1 */ |
120 | .blocklen_bytes = 16, | 120 | .blocklen_bytes = 16, |
121 | .cra_name = "ctr_aes128", | 121 | .cra_name = "ctr_aes128", |
122 | .backend_cra_name = "ecb(aes)", | 122 | .backend_cra_name = "aes", |
123 | }, { | 123 | }, { |
124 | .flags = DRBG_CTR | DRBG_STRENGTH192, | 124 | .flags = DRBG_CTR | DRBG_STRENGTH192, |
125 | .statelen = 40, /* 320 bits as defined in 10.2.1 */ | 125 | .statelen = 40, /* 320 bits as defined in 10.2.1 */ |
126 | .blocklen_bytes = 16, | 126 | .blocklen_bytes = 16, |
127 | .cra_name = "ctr_aes192", | 127 | .cra_name = "ctr_aes192", |
128 | .backend_cra_name = "ecb(aes)", | 128 | .backend_cra_name = "aes", |
129 | }, { | 129 | }, { |
130 | .flags = DRBG_CTR | DRBG_STRENGTH256, | 130 | .flags = DRBG_CTR | DRBG_STRENGTH256, |
131 | .statelen = 48, /* 384 bits as defined in 10.2.1 */ | 131 | .statelen = 48, /* 384 bits as defined in 10.2.1 */ |
132 | .blocklen_bytes = 16, | 132 | .blocklen_bytes = 16, |
133 | .cra_name = "ctr_aes256", | 133 | .cra_name = "ctr_aes256", |
134 | .backend_cra_name = "ecb(aes)", | 134 | .backend_cra_name = "aes", |
135 | }, | 135 | }, |
136 | #endif /* CONFIG_CRYPTO_DRBG_CTR */ | 136 | #endif /* CONFIG_CRYPTO_DRBG_CTR */ |
137 | #ifdef CONFIG_CRYPTO_DRBG_HASH | 137 | #ifdef CONFIG_CRYPTO_DRBG_HASH |
@@ -1644,24 +1644,24 @@ static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key, | |||
1644 | static int drbg_init_sym_kernel(struct drbg_state *drbg) | 1644 | static int drbg_init_sym_kernel(struct drbg_state *drbg) |
1645 | { | 1645 | { |
1646 | int ret = 0; | 1646 | int ret = 0; |
1647 | struct crypto_blkcipher *tfm; | 1647 | struct crypto_cipher *tfm; |
1648 | 1648 | ||
1649 | tfm = crypto_alloc_blkcipher(drbg->core->backend_cra_name, 0, 0); | 1649 | tfm = crypto_alloc_cipher(drbg->core->backend_cra_name, 0, 0); |
1650 | if (IS_ERR(tfm)) { | 1650 | if (IS_ERR(tfm)) { |
1651 | pr_info("DRBG: could not allocate cipher TFM handle\n"); | 1651 | pr_info("DRBG: could not allocate cipher TFM handle\n"); |
1652 | return PTR_ERR(tfm); | 1652 | return PTR_ERR(tfm); |
1653 | } | 1653 | } |
1654 | BUG_ON(drbg_blocklen(drbg) != crypto_blkcipher_blocksize(tfm)); | 1654 | BUG_ON(drbg_blocklen(drbg) != crypto_cipher_blocksize(tfm)); |
1655 | drbg->priv_data = tfm; | 1655 | drbg->priv_data = tfm; |
1656 | return ret; | 1656 | return ret; |
1657 | } | 1657 | } |
1658 | 1658 | ||
1659 | static int drbg_fini_sym_kernel(struct drbg_state *drbg) | 1659 | static int drbg_fini_sym_kernel(struct drbg_state *drbg) |
1660 | { | 1660 | { |
1661 | struct crypto_blkcipher *tfm = | 1661 | struct crypto_cipher *tfm = |
1662 | (struct crypto_blkcipher *)drbg->priv_data; | 1662 | (struct crypto_cipher *)drbg->priv_data; |
1663 | if (tfm) | 1663 | if (tfm) |
1664 | crypto_free_blkcipher(tfm); | 1664 | crypto_free_cipher(tfm); |
1665 | drbg->priv_data = NULL; | 1665 | drbg->priv_data = NULL; |
1666 | return 0; | 1666 | return 0; |
1667 | } | 1667 | } |
@@ -1669,21 +1669,14 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg) | |||
1669 | static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key, | 1669 | static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key, |
1670 | unsigned char *outval, const struct drbg_string *in) | 1670 | unsigned char *outval, const struct drbg_string *in) |
1671 | { | 1671 | { |
1672 | int ret = 0; | 1672 | struct crypto_cipher *tfm = |
1673 | struct scatterlist sg_in, sg_out; | 1673 | (struct crypto_cipher *)drbg->priv_data; |
1674 | struct blkcipher_desc desc; | ||
1675 | struct crypto_blkcipher *tfm = | ||
1676 | (struct crypto_blkcipher *)drbg->priv_data; | ||
1677 | |||
1678 | desc.tfm = tfm; | ||
1679 | desc.flags = 0; | ||
1680 | crypto_blkcipher_setkey(tfm, key, (drbg_keylen(drbg))); | ||
1681 | /* there is only component in *in */ | ||
1682 | sg_init_one(&sg_in, in->buf, in->len); | ||
1683 | sg_init_one(&sg_out, outval, drbg_blocklen(drbg)); | ||
1684 | ret = crypto_blkcipher_encrypt(&desc, &sg_out, &sg_in, in->len); | ||
1685 | 1674 | ||
1686 | return ret; | 1675 | crypto_cipher_setkey(tfm, key, (drbg_keylen(drbg))); |
1676 | /* there is only component in *in */ | ||
1677 | BUG_ON(in->len < drbg_blocklen(drbg)); | ||
1678 | crypto_cipher_encrypt_one(tfm, outval, in->buf); | ||
1679 | return 0; | ||
1687 | } | 1680 | } |
1688 | #endif /* CONFIG_CRYPTO_DRBG_CTR */ | 1681 | #endif /* CONFIG_CRYPTO_DRBG_CTR */ |
1689 | 1682 | ||