Skip to content

Commit

Permalink
crypto: skcipher - Use RNG interface instead of get_random_bytes
Browse files Browse the repository at this point in the history
This patch makes the IV generators use the new RNG interface so
that the user can pick an RNG other than the default get_random_bytes.

Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
herbertx committed Aug 29, 2008
1 parent 17f0f4a commit a0f000e
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 13 deletions.
2 changes: 2 additions & 0 deletions crypto/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ config CRYPTO_AEAD
config CRYPTO_BLKCIPHER
tristate
select CRYPTO_ALGAPI
select CRYPTO_RNG

config CRYPTO_HASH
tristate
Expand Down Expand Up @@ -125,6 +126,7 @@ config CRYPTO_SEQIV
tristate "Sequence Number IV Generator"
select CRYPTO_AEAD
select CRYPTO_BLKCIPHER
select CRYPTO_RNG
help
This IV generator generates an IV based on a sequence number by
xoring it with a salt. This algorithm is mainly useful for CTR
Expand Down
34 changes: 29 additions & 5 deletions crypto/chainiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
*/

#include <crypto/internal/skcipher.h>
#include <crypto/rng.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/workqueue.h>
Expand Down Expand Up @@ -83,18 +83,23 @@ static int chainiv_givencrypt_first(struct skcipher_givcrypt_request *req)
{
struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
struct chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
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;
get_random_bytes(ctx->iv, crypto_ablkcipher_ivsize(geniv));
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);
}

Expand Down Expand Up @@ -203,6 +208,7 @@ 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;
Expand All @@ -212,11 +218,15 @@ static int async_chainiv_givencrypt_first(struct skcipher_givcrypt_request *req)
goto unlock;

crypto_ablkcipher_crt(geniv)->givencrypt = async_chainiv_givencrypt;
get_random_bytes(ctx->iv, crypto_ablkcipher_ivsize(geniv));
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);
}
Expand Down Expand Up @@ -284,9 +294,13 @@ static struct crypto_instance *chainiv_alloc(struct rtattr **tb)
if (IS_ERR(algt))
return ERR_PTR(err);

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 out;
goto put_rng;

inst->alg.cra_ablkcipher.givencrypt = chainiv_givencrypt_first;

Expand All @@ -311,12 +325,22 @@ 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 = skcipher_geniv_free,
.free = chainiv_free,
.module = THIS_MODULE,
};

Expand Down
25 changes: 21 additions & 4 deletions crypto/eseqiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
*/

#include <crypto/internal/skcipher.h>
#include <crypto/rng.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/scatterlist.h>
#include <linux/spinlock.h>
#include <linux/string.h>
Expand Down Expand Up @@ -163,17 +163,22 @@ static int eseqiv_givencrypt_first(struct skcipher_givcrypt_request *req)
{
struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
struct eseqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
int err = 0;

spin_lock_bh(&ctx->lock);
if (crypto_ablkcipher_crt(geniv)->givencrypt != eseqiv_givencrypt_first)
goto unlock;

crypto_ablkcipher_crt(geniv)->givencrypt = eseqiv_givencrypt;
get_random_bytes(ctx->salt, crypto_ablkcipher_ivsize(geniv));
err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
crypto_ablkcipher_ivsize(geniv));

unlock:
spin_unlock_bh(&ctx->lock);

if (err)
return err;

return eseqiv_givencrypt(req);
}

Expand Down Expand Up @@ -216,9 +221,13 @@ static struct crypto_instance *eseqiv_alloc(struct rtattr **tb)
struct crypto_instance *inst;
int err;

err = crypto_get_default_rng();
if (err)
return ERR_PTR(err);

inst = skcipher_geniv_alloc(&eseqiv_tmpl, tb, 0, 0);
if (IS_ERR(inst))
goto out;
goto put_rng;

err = -EINVAL;
if (inst->alg.cra_ablkcipher.ivsize != inst->alg.cra_blocksize)
Expand All @@ -238,13 +247,21 @@ static struct crypto_instance *eseqiv_alloc(struct rtattr **tb)
free_inst:
skcipher_geniv_free(inst);
inst = ERR_PTR(err);
put_rng:
crypto_put_default_rng();
goto out;
}

static void eseqiv_free(struct crypto_instance *inst)
{
skcipher_geniv_free(inst);
crypto_put_default_rng();
}

static struct crypto_template eseqiv_tmpl = {
.name = "eseqiv",
.alloc = eseqiv_alloc,
.free = skcipher_geniv_free,
.free = eseqiv_free,
.module = THIS_MODULE,
};

Expand Down
27 changes: 23 additions & 4 deletions crypto/seqiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@

#include <crypto/internal/aead.h>
#include <crypto/internal/skcipher.h>
#include <crypto/rng.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/spinlock.h>
#include <linux/string.h>

Expand Down Expand Up @@ -189,35 +189,45 @@ static int seqiv_givencrypt_first(struct skcipher_givcrypt_request *req)
{
struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
int err = 0;

spin_lock_bh(&ctx->lock);
if (crypto_ablkcipher_crt(geniv)->givencrypt != seqiv_givencrypt_first)
goto unlock;

crypto_ablkcipher_crt(geniv)->givencrypt = seqiv_givencrypt;
get_random_bytes(ctx->salt, crypto_ablkcipher_ivsize(geniv));
err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
crypto_ablkcipher_ivsize(geniv));

unlock:
spin_unlock_bh(&ctx->lock);

if (err)
return err;

return seqiv_givencrypt(req);
}

static int seqiv_aead_givencrypt_first(struct aead_givcrypt_request *req)
{
struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
int err = 0;

spin_lock_bh(&ctx->lock);
if (crypto_aead_crt(geniv)->givencrypt != seqiv_aead_givencrypt_first)
goto unlock;

crypto_aead_crt(geniv)->givencrypt = seqiv_aead_givencrypt;
get_random_bytes(ctx->salt, crypto_aead_ivsize(geniv));
err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
crypto_aead_ivsize(geniv));

unlock:
spin_unlock_bh(&ctx->lock);

if (err)
return err;

return seqiv_aead_givencrypt(req);
}

Expand Down Expand Up @@ -298,19 +308,27 @@ static struct crypto_instance *seqiv_alloc(struct rtattr **tb)
if (IS_ERR(algt))
return ERR_PTR(err);

err = crypto_get_default_rng();
if (err)
return ERR_PTR(err);

if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
inst = seqiv_ablkcipher_alloc(tb);
else
inst = seqiv_aead_alloc(tb);

if (IS_ERR(inst))
goto out;
goto put_rng;

inst->alg.cra_alignmask |= __alignof__(u32) - 1;
inst->alg.cra_ctxsize += sizeof(struct seqiv_ctx);

out:
return inst;

put_rng:
crypto_put_default_rng();
goto out;
}

static void seqiv_free(struct crypto_instance *inst)
Expand All @@ -319,6 +337,7 @@ static void seqiv_free(struct crypto_instance *inst)
skcipher_geniv_free(inst);
else
aead_geniv_free(inst);
crypto_put_default_rng();
}

static struct crypto_template seqiv_tmpl = {
Expand Down

0 comments on commit a0f000e

Please sign in to comment.