diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-22 21:04:48 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-22 21:04:48 -0700 |
commit | 44d21c3f3a2ef2f58b18bda64c52c99e723f3f4a (patch) | |
tree | 5146cf96cb0dbd7121176d484417ab942c92dcd4 /crypto/chainiv.c | |
parent | efdfce2b7ff3205ba0fba10270b92b80bbc6187d (diff) | |
parent | fe55dfdcdfabf160ab0c14617725c57c7a1facfc (diff) | |
download | linux-44d21c3f3a2ef2f58b18bda64c52c99e723f3f4a.tar.bz2 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto update from Herbert Xu:
"Here is the crypto update for 4.2:
API:
- Convert RNG interface to new style.
- New AEAD interface with one SG list for AD and plain/cipher text.
All external AEAD users have been converted.
- New asymmetric key interface (akcipher).
Algorithms:
- Chacha20, Poly1305 and RFC7539 support.
- New RSA implementation.
- Jitter RNG.
- DRBG is now seeded with both /dev/random and Jitter RNG. If kernel
pool isn't ready then DRBG will be reseeded when it is.
- DRBG is now the default crypto API RNG, replacing krng.
- 842 compression (previously part of powerpc nx driver).
Drivers:
- Accelerated SHA-512 for arm64.
- New Marvell CESA driver that supports DMA and more algorithms.
- Updated powerpc nx 842 support.
- Added support for SEC1 hardware to talitos"
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (292 commits)
crypto: marvell/cesa - remove COMPILE_TEST dependency
crypto: algif_aead - Temporarily disable all AEAD algorithms
crypto: af_alg - Forbid the use internal algorithms
crypto: echainiv - Only hold RNG during initialisation
crypto: seqiv - Add compatibility support without RNG
crypto: eseqiv - Offer normal cipher functionality without RNG
crypto: chainiv - Offer normal cipher functionality without RNG
crypto: user - Add CRYPTO_MSG_DELRNG
crypto: user - Move cryptouser.h to uapi
crypto: rng - Do not free default RNG when it becomes unused
crypto: skcipher - Allow givencrypt to be NULL
crypto: sahara - propagate the error on clk_disable_unprepare() failure
crypto: rsa - fix invalid select for AKCIPHER
crypto: picoxcell - Update to the current clk API
crypto: nx - Check for bogus firmware properties
crypto: marvell/cesa - add DT bindings documentation
crypto: marvell/cesa - add support for Kirkwood and Dove SoCs
crypto: marvell/cesa - add support for Orion SoCs
crypto: marvell/cesa - add allhwsupport module parameter
crypto: marvell/cesa - add support for all armada SoCs
...
Diffstat (limited to 'crypto/chainiv.c')
-rw-r--r-- | crypto/chainiv.c | 105 |
1 files changed, 30 insertions, 75 deletions
diff --git a/crypto/chainiv.c b/crypto/chainiv.c index 63c17d5992f7..b4340018c8d4 100644 --- a/crypto/chainiv.c +++ b/crypto/chainiv.c @@ -80,44 +80,37 @@ unlock: return err; } -static int chainiv_givencrypt_first(struct skcipher_givcrypt_request *req) +static int chainiv_init_common(struct crypto_tfm *tfm, char iv[]) { - struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req); - struct chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv); + struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm); int err = 0; - spin_lock_bh(&ctx->lock); - if (crypto_ablkcipher_crt(geniv)->givencrypt != - chainiv_givencrypt_first) - goto unlock; - - crypto_ablkcipher_crt(geniv)->givencrypt = chainiv_givencrypt; - err = crypto_rng_get_bytes(crypto_default_rng, ctx->iv, - crypto_ablkcipher_ivsize(geniv)); - -unlock: - spin_unlock_bh(&ctx->lock); - - if (err) - return err; - - return chainiv_givencrypt(req); -} - -static int chainiv_init_common(struct crypto_tfm *tfm) -{ tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request); - return skcipher_geniv_init(tfm); + if (iv) { + err = crypto_rng_get_bytes(crypto_default_rng, iv, + crypto_ablkcipher_ivsize(geniv)); + crypto_put_default_rng(); + } + + return err ?: skcipher_geniv_init(tfm); } static int chainiv_init(struct crypto_tfm *tfm) { + struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm); struct chainiv_ctx *ctx = crypto_tfm_ctx(tfm); + char *iv; spin_lock_init(&ctx->lock); - return chainiv_init_common(tfm); + iv = NULL; + if (!crypto_get_default_rng()) { + crypto_ablkcipher_crt(geniv)->givencrypt = chainiv_givencrypt; + iv = ctx->iv; + } + + return chainiv_init_common(tfm, iv); } static int async_chainiv_schedule_work(struct async_chainiv_ctx *ctx) @@ -205,33 +198,6 @@ postpone: return async_chainiv_postpone_request(req); } -static int async_chainiv_givencrypt_first(struct skcipher_givcrypt_request *req) -{ - struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req); - struct async_chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv); - int err = 0; - - if (test_and_set_bit(CHAINIV_STATE_INUSE, &ctx->state)) - goto out; - - if (crypto_ablkcipher_crt(geniv)->givencrypt != - async_chainiv_givencrypt_first) - goto unlock; - - crypto_ablkcipher_crt(geniv)->givencrypt = async_chainiv_givencrypt; - err = crypto_rng_get_bytes(crypto_default_rng, ctx->iv, - crypto_ablkcipher_ivsize(geniv)); - -unlock: - clear_bit(CHAINIV_STATE_INUSE, &ctx->state); - - if (err) - return err; - -out: - return async_chainiv_givencrypt(req); -} - static void async_chainiv_do_postponed(struct work_struct *work) { struct async_chainiv_ctx *ctx = container_of(work, @@ -263,14 +229,23 @@ static void async_chainiv_do_postponed(struct work_struct *work) static int async_chainiv_init(struct crypto_tfm *tfm) { + struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm); struct async_chainiv_ctx *ctx = crypto_tfm_ctx(tfm); + char *iv; spin_lock_init(&ctx->lock); crypto_init_queue(&ctx->queue, 100); INIT_WORK(&ctx->postponed, async_chainiv_do_postponed); - return chainiv_init_common(tfm); + iv = NULL; + if (!crypto_get_default_rng()) { + crypto_ablkcipher_crt(geniv)->givencrypt = + async_chainiv_givencrypt; + iv = ctx->iv; + } + + return chainiv_init_common(tfm, iv); } static void async_chainiv_exit(struct crypto_tfm *tfm) @@ -288,21 +263,14 @@ static struct crypto_instance *chainiv_alloc(struct rtattr **tb) { struct crypto_attr_type *algt; struct crypto_instance *inst; - int err; algt = crypto_get_attr_type(tb); if (IS_ERR(algt)) return ERR_CAST(algt); - err = crypto_get_default_rng(); - if (err) - return ERR_PTR(err); - inst = skcipher_geniv_alloc(&chainiv_tmpl, tb, 0, 0); if (IS_ERR(inst)) - goto put_rng; - - inst->alg.cra_ablkcipher.givencrypt = chainiv_givencrypt_first; + goto out; inst->alg.cra_init = chainiv_init; inst->alg.cra_exit = skcipher_geniv_exit; @@ -312,9 +280,6 @@ static struct crypto_instance *chainiv_alloc(struct rtattr **tb) if (!crypto_requires_sync(algt->type, algt->mask)) { inst->alg.cra_flags |= CRYPTO_ALG_ASYNC; - inst->alg.cra_ablkcipher.givencrypt = - async_chainiv_givencrypt_first; - inst->alg.cra_init = async_chainiv_init; inst->alg.cra_exit = async_chainiv_exit; @@ -325,22 +290,12 @@ static struct crypto_instance *chainiv_alloc(struct rtattr **tb) out: return inst; - -put_rng: - crypto_put_default_rng(); - goto out; -} - -static void chainiv_free(struct crypto_instance *inst) -{ - skcipher_geniv_free(inst); - crypto_put_default_rng(); } static struct crypto_template chainiv_tmpl = { .name = "chainiv", .alloc = chainiv_alloc, - .free = chainiv_free, + .free = skcipher_geniv_free, .module = THIS_MODULE, }; |