summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-06-21 19:11:49 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2015-06-22 15:49:28 +0800
commiteeee12aa34d840c6c99051f0ff85a9ffa1badd07 (patch)
treeecb6931eb545524be8bdfacbaed8a8bf8d7908db /crypto
parent055906d1e7f94f459a0e80228f15656bf5871311 (diff)
downloadlinux-eeee12aa34d840c6c99051f0ff85a9ffa1badd07.tar.gz
linux-eeee12aa34d840c6c99051f0ff85a9ffa1badd07.tar.bz2
linux-eeee12aa34d840c6c99051f0ff85a9ffa1badd07.zip
crypto: seqiv - Add compatibility support without RNG
When seqiv is used in compatibility mode, this patch allows it to function even when an RNG Is not available. It also changes the RNG allocation for the new explicit seqiv interface so that we only hold a reference to the RNG during initialisation. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/seqiv.c50
1 files changed, 25 insertions, 25 deletions
diff --git a/crypto/seqiv.c b/crypto/seqiv.c
index 42e4ee532d35..122c56e3491b 100644
--- a/crypto/seqiv.c
+++ b/crypto/seqiv.c
@@ -478,29 +478,42 @@ static int seqiv_init(struct crypto_tfm *tfm)
{
struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm);
struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+ int err;
spin_lock_init(&ctx->lock);
tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request);
- return crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
- crypto_ablkcipher_ivsize(geniv)) ?:
- skcipher_geniv_init(tfm);
+ err = 0;
+ if (!crypto_get_default_rng()) {
+ crypto_ablkcipher_crt(geniv)->givencrypt = seqiv_givencrypt;
+ err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
+ crypto_ablkcipher_ivsize(geniv));
+ crypto_put_default_rng();
+ }
+
+ return err ?: skcipher_geniv_init(tfm);
}
static int seqiv_old_aead_init(struct crypto_tfm *tfm)
{
struct crypto_aead *geniv = __crypto_aead_cast(tfm);
struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
+ int err;
spin_lock_init(&ctx->lock);
crypto_aead_set_reqsize(__crypto_aead_cast(tfm),
sizeof(struct aead_request));
+ err = 0;
+ if (!crypto_get_default_rng()) {
+ geniv->givencrypt = seqiv_aead_givencrypt;
+ err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
+ crypto_aead_ivsize(geniv));
+ crypto_put_default_rng();
+ }
- return crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
- crypto_aead_ivsize(geniv)) ?:
- aead_geniv_init(tfm);
+ return err ?: aead_geniv_init(tfm);
}
static int seqiv_aead_init_common(struct crypto_tfm *tfm, unsigned int reqsize)
@@ -513,8 +526,13 @@ static int seqiv_aead_init_common(struct crypto_tfm *tfm, unsigned int reqsize)
crypto_aead_set_reqsize(geniv, sizeof(struct aead_request));
+ err = crypto_get_default_rng();
+ if (err)
+ goto out;
+
err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
crypto_aead_ivsize(geniv));
+ crypto_put_default_rng();
if (err)
goto out;
@@ -571,8 +589,6 @@ static int seqiv_ablkcipher_create(struct crypto_template *tmpl,
if (inst->alg.cra_ablkcipher.ivsize < sizeof(u64))
goto free_inst;
- inst->alg.cra_ablkcipher.givencrypt = seqiv_givencrypt;
-
inst->alg.cra_init = seqiv_init;
inst->alg.cra_exit = skcipher_geniv_exit;
@@ -602,8 +618,6 @@ static int seqiv_old_aead_create(struct crypto_template *tmpl,
if (inst->alg.cra_aead.ivsize < sizeof(u64))
goto free_inst;
- inst->alg.cra_aead.givencrypt = seqiv_aead_givencrypt;
-
inst->alg.cra_init = seqiv_old_aead_init;
inst->alg.cra_exit = aead_geniv_exit;
@@ -680,18 +694,11 @@ static int seqiv_create(struct crypto_template *tmpl, struct rtattr **tb)
if (IS_ERR(algt))
return PTR_ERR(algt);
- err = crypto_get_default_rng();
- if (err)
- return err;
-
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
err = seqiv_ablkcipher_create(tmpl, tb);
else
err = seqiv_aead_create(tmpl, tb);
- if (err)
- crypto_put_default_rng();
-
return err;
}
@@ -702,14 +709,10 @@ static int seqniv_create(struct crypto_template *tmpl, struct rtattr **tb)
struct aead_alg *alg;
int err;
- err = crypto_get_default_rng();
- if (err)
- return err;
-
inst = aead_geniv_alloc(tmpl, tb, 0, 0);
err = PTR_ERR(inst);
if (IS_ERR(inst))
- goto put_rng;
+ goto out;
spawn = aead_instance_ctx(inst);
alg = crypto_spawn_aead_alg(spawn);
@@ -741,8 +744,6 @@ out:
free_inst:
aead_geniv_free(inst);
-put_rng:
- crypto_put_default_rng();
goto out;
}
@@ -752,7 +753,6 @@ static void seqiv_free(struct crypto_instance *inst)
skcipher_geniv_free(inst);
else
aead_geniv_free(aead_instance(inst));
- crypto_put_default_rng();
}
static struct crypto_template seqiv_tmpl = {