Commit 7b05a373 authored by Herbert Xu's avatar Herbert Xu

crypto: gcm - Use new IV convention

This patch converts rfc4106 to the new calling convention where
the IV is now part of the AD and needs to be skipped.  This patch
also makes use of the new type-safe way of freeing instances.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent e9b8d2c2
...@@ -38,6 +38,12 @@ struct crypto_rfc4106_ctx { ...@@ -38,6 +38,12 @@ struct crypto_rfc4106_ctx {
u8 nonce[4]; u8 nonce[4];
}; };
struct crypto_rfc4106_req_ctx {
struct scatterlist src[3];
struct scatterlist dst[3];
struct aead_request subreq;
};
struct crypto_rfc4543_instance_ctx { struct crypto_rfc4543_instance_ctx {
struct crypto_aead_spawn aead; struct crypto_aead_spawn aead;
}; };
...@@ -601,6 +607,15 @@ static void crypto_gcm_exit_tfm(struct crypto_aead *tfm) ...@@ -601,6 +607,15 @@ static void crypto_gcm_exit_tfm(struct crypto_aead *tfm)
crypto_free_ablkcipher(ctx->ctr); crypto_free_ablkcipher(ctx->ctr);
} }
static void crypto_gcm_free(struct aead_instance *inst)
{
struct gcm_instance_ctx *ctx = aead_instance_ctx(inst);
crypto_drop_skcipher(&ctx->ctr);
crypto_drop_ahash(&ctx->ghash);
kfree(inst);
}
static int crypto_gcm_create_common(struct crypto_template *tmpl, static int crypto_gcm_create_common(struct crypto_template *tmpl,
struct rtattr **tb, struct rtattr **tb,
const char *full_name, const char *full_name,
...@@ -619,7 +634,8 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl, ...@@ -619,7 +634,8 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
if (IS_ERR(algt)) if (IS_ERR(algt))
return PTR_ERR(algt); return PTR_ERR(algt);
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_AEAD_NEW)) &
algt->mask)
return -EINVAL; return -EINVAL;
ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type, ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type,
...@@ -674,6 +690,7 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl, ...@@ -674,6 +690,7 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
inst->alg.base.cra_flags = (ghash->base.cra_flags | ctr->cra_flags) & inst->alg.base.cra_flags = (ghash->base.cra_flags | ctr->cra_flags) &
CRYPTO_ALG_ASYNC; CRYPTO_ALG_ASYNC;
inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW;
inst->alg.base.cra_priority = (ghash->base.cra_priority + inst->alg.base.cra_priority = (ghash->base.cra_priority +
ctr->cra_priority) / 2; ctr->cra_priority) / 2;
inst->alg.base.cra_blocksize = 1; inst->alg.base.cra_blocksize = 1;
...@@ -689,6 +706,8 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl, ...@@ -689,6 +706,8 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
inst->alg.encrypt = crypto_gcm_encrypt; inst->alg.encrypt = crypto_gcm_encrypt;
inst->alg.decrypt = crypto_gcm_decrypt; inst->alg.decrypt = crypto_gcm_decrypt;
inst->free = crypto_gcm_free;
err = aead_register_instance(tmpl, inst); err = aead_register_instance(tmpl, inst);
if (err) if (err)
goto out_put_ctr; goto out_put_ctr;
...@@ -728,19 +747,9 @@ static int crypto_gcm_create(struct crypto_template *tmpl, struct rtattr **tb) ...@@ -728,19 +747,9 @@ static int crypto_gcm_create(struct crypto_template *tmpl, struct rtattr **tb)
ctr_name, "ghash"); ctr_name, "ghash");
} }
static void crypto_gcm_free(struct crypto_instance *inst)
{
struct gcm_instance_ctx *ctx = crypto_instance_ctx(inst);
crypto_drop_skcipher(&ctx->ctr);
crypto_drop_ahash(&ctx->ghash);
kfree(aead_instance(inst));
}
static struct crypto_template crypto_gcm_tmpl = { static struct crypto_template crypto_gcm_tmpl = {
.name = "gcm", .name = "gcm",
.create = crypto_gcm_create, .create = crypto_gcm_create,
.free = crypto_gcm_free,
.module = THIS_MODULE, .module = THIS_MODULE,
}; };
...@@ -770,7 +779,6 @@ static int crypto_gcm_base_create(struct crypto_template *tmpl, ...@@ -770,7 +779,6 @@ static int crypto_gcm_base_create(struct crypto_template *tmpl,
static struct crypto_template crypto_gcm_base_tmpl = { static struct crypto_template crypto_gcm_base_tmpl = {
.name = "gcm_base", .name = "gcm_base",
.create = crypto_gcm_base_create, .create = crypto_gcm_base_create,
.free = crypto_gcm_free,
.module = THIS_MODULE, .module = THIS_MODULE,
}; };
...@@ -816,27 +824,50 @@ static int crypto_rfc4106_setauthsize(struct crypto_aead *parent, ...@@ -816,27 +824,50 @@ static int crypto_rfc4106_setauthsize(struct crypto_aead *parent,
static struct aead_request *crypto_rfc4106_crypt(struct aead_request *req) static struct aead_request *crypto_rfc4106_crypt(struct aead_request *req)
{ {
struct aead_request *subreq = aead_request_ctx(req); struct crypto_rfc4106_req_ctx *rctx = aead_request_ctx(req);
struct crypto_aead *aead = crypto_aead_reqtfm(req); struct crypto_aead *aead = crypto_aead_reqtfm(req);
struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(aead); struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(aead);
struct aead_request *subreq = &rctx->subreq;
struct crypto_aead *child = ctx->child; struct crypto_aead *child = ctx->child;
struct scatterlist *sg;
u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child), u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child),
crypto_aead_alignmask(child) + 1); crypto_aead_alignmask(child) + 1);
scatterwalk_map_and_copy(iv + 12, req->src, 0, req->assoclen - 8, 0);
memcpy(iv, ctx->nonce, 4); memcpy(iv, ctx->nonce, 4);
memcpy(iv + 4, req->iv, 8); memcpy(iv + 4, req->iv, 8);
sg_init_table(rctx->src, 3);
sg_set_buf(rctx->src, iv + 12, req->assoclen - 8);
sg = scatterwalk_ffwd(rctx->src + 1, req->src, req->assoclen);
if (sg != rctx->src + 1)
sg_chain(rctx->src, 2, sg);
if (req->src != req->dst) {
sg_init_table(rctx->dst, 3);
sg_set_buf(rctx->dst, iv + 12, req->assoclen - 8);
sg = scatterwalk_ffwd(rctx->dst + 1, req->dst, req->assoclen);
if (sg != rctx->dst + 1)
sg_chain(rctx->dst, 2, sg);
}
aead_request_set_tfm(subreq, child); aead_request_set_tfm(subreq, child);
aead_request_set_callback(subreq, req->base.flags, req->base.complete, aead_request_set_callback(subreq, req->base.flags, req->base.complete,
req->base.data); req->base.data);
aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, iv); aead_request_set_crypt(subreq, rctx->src,
aead_request_set_ad(subreq, req->assoclen); req->src == req->dst ? rctx->src : rctx->dst,
req->cryptlen, iv);
aead_request_set_ad(subreq, req->assoclen - 8);
return subreq; return subreq;
} }
static int crypto_rfc4106_encrypt(struct aead_request *req) static int crypto_rfc4106_encrypt(struct aead_request *req)
{ {
if (req->assoclen != 16 && req->assoclen != 20)
return -EINVAL;
req = crypto_rfc4106_crypt(req); req = crypto_rfc4106_crypt(req);
return crypto_aead_encrypt(req); return crypto_aead_encrypt(req);
...@@ -844,6 +875,9 @@ static int crypto_rfc4106_encrypt(struct aead_request *req) ...@@ -844,6 +875,9 @@ static int crypto_rfc4106_encrypt(struct aead_request *req)
static int crypto_rfc4106_decrypt(struct aead_request *req) static int crypto_rfc4106_decrypt(struct aead_request *req)
{ {
if (req->assoclen != 16 && req->assoclen != 20)
return -EINVAL;
req = crypto_rfc4106_crypt(req); req = crypto_rfc4106_crypt(req);
return crypto_aead_decrypt(req); return crypto_aead_decrypt(req);
...@@ -867,9 +901,9 @@ static int crypto_rfc4106_init_tfm(struct crypto_aead *tfm) ...@@ -867,9 +901,9 @@ static int crypto_rfc4106_init_tfm(struct crypto_aead *tfm)
align &= ~(crypto_tfm_ctx_alignment() - 1); align &= ~(crypto_tfm_ctx_alignment() - 1);
crypto_aead_set_reqsize( crypto_aead_set_reqsize(
tfm, tfm,
sizeof(struct aead_request) + sizeof(struct crypto_rfc4106_req_ctx) +
ALIGN(crypto_aead_reqsize(aead), crypto_tfm_ctx_alignment()) + ALIGN(crypto_aead_reqsize(aead), crypto_tfm_ctx_alignment()) +
align + 12); align + 24);
return 0; return 0;
} }
...@@ -881,6 +915,12 @@ static void crypto_rfc4106_exit_tfm(struct crypto_aead *tfm) ...@@ -881,6 +915,12 @@ static void crypto_rfc4106_exit_tfm(struct crypto_aead *tfm)
crypto_free_aead(ctx->child); crypto_free_aead(ctx->child);
} }
static void crypto_rfc4106_free(struct aead_instance *inst)
{
crypto_drop_aead(aead_instance_ctx(inst));
kfree(inst);
}
static int crypto_rfc4106_create(struct crypto_template *tmpl, static int crypto_rfc4106_create(struct crypto_template *tmpl,
struct rtattr **tb) struct rtattr **tb)
{ {
...@@ -895,7 +935,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl, ...@@ -895,7 +935,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
if (IS_ERR(algt)) if (IS_ERR(algt))
return PTR_ERR(algt); return PTR_ERR(algt);
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_AEAD_NEW)) &
algt->mask)
return -EINVAL; return -EINVAL;
ccm_name = crypto_attr_alg_name(tb[1]); ccm_name = crypto_attr_alg_name(tb[1]);
...@@ -934,7 +975,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl, ...@@ -934,7 +975,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
CRYPTO_MAX_ALG_NAME) CRYPTO_MAX_ALG_NAME)
goto out_drop_alg; goto out_drop_alg;
inst->alg.base.cra_flags |= alg->base.cra_flags & CRYPTO_ALG_ASYNC; inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW;
inst->alg.base.cra_priority = alg->base.cra_priority; inst->alg.base.cra_priority = alg->base.cra_priority;
inst->alg.base.cra_blocksize = 1; inst->alg.base.cra_blocksize = 1;
inst->alg.base.cra_alignmask = alg->base.cra_alignmask; inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
...@@ -952,6 +994,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl, ...@@ -952,6 +994,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
inst->alg.encrypt = crypto_rfc4106_encrypt; inst->alg.encrypt = crypto_rfc4106_encrypt;
inst->alg.decrypt = crypto_rfc4106_decrypt; inst->alg.decrypt = crypto_rfc4106_decrypt;
inst->free = crypto_rfc4106_free;
err = aead_register_instance(tmpl, inst); err = aead_register_instance(tmpl, inst);
if (err) if (err)
goto out_drop_alg; goto out_drop_alg;
...@@ -966,16 +1010,9 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl, ...@@ -966,16 +1010,9 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
goto out; goto out;
} }
static void crypto_rfc4106_free(struct crypto_instance *inst)
{
crypto_drop_aead(crypto_instance_ctx(inst));
kfree(aead_instance(inst));
}
static struct crypto_template crypto_rfc4106_tmpl = { static struct crypto_template crypto_rfc4106_tmpl = {
.name = "rfc4106", .name = "rfc4106",
.create = crypto_rfc4106_create, .create = crypto_rfc4106_create,
.free = crypto_rfc4106_free,
.module = THIS_MODULE, .module = THIS_MODULE,
}; };
...@@ -1114,6 +1151,15 @@ static void crypto_rfc4543_exit_tfm(struct crypto_aead *tfm) ...@@ -1114,6 +1151,15 @@ static void crypto_rfc4543_exit_tfm(struct crypto_aead *tfm)
crypto_put_default_null_skcipher(); crypto_put_default_null_skcipher();
} }
static void crypto_rfc4543_free(struct aead_instance *inst)
{
struct crypto_rfc4543_instance_ctx *ctx = aead_instance_ctx(inst);
crypto_drop_aead(&ctx->aead);
kfree(inst);
}
static int crypto_rfc4543_create(struct crypto_template *tmpl, static int crypto_rfc4543_create(struct crypto_template *tmpl,
struct rtattr **tb) struct rtattr **tb)
{ {
...@@ -1129,7 +1175,8 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl, ...@@ -1129,7 +1175,8 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
if (IS_ERR(algt)) if (IS_ERR(algt))
return PTR_ERR(algt); return PTR_ERR(algt);
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_AEAD_NEW)) &
algt->mask)
return -EINVAL; return -EINVAL;
ccm_name = crypto_attr_alg_name(tb[1]); ccm_name = crypto_attr_alg_name(tb[1]);
...@@ -1170,6 +1217,7 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl, ...@@ -1170,6 +1217,7 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
goto out_drop_alg; goto out_drop_alg;
inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC; inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW;
inst->alg.base.cra_priority = alg->base.cra_priority; inst->alg.base.cra_priority = alg->base.cra_priority;
inst->alg.base.cra_blocksize = 1; inst->alg.base.cra_blocksize = 1;
inst->alg.base.cra_alignmask = alg->base.cra_alignmask; inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
...@@ -1187,6 +1235,8 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl, ...@@ -1187,6 +1235,8 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
inst->alg.encrypt = crypto_rfc4543_encrypt; inst->alg.encrypt = crypto_rfc4543_encrypt;
inst->alg.decrypt = crypto_rfc4543_decrypt; inst->alg.decrypt = crypto_rfc4543_decrypt;
inst->free = crypto_rfc4543_free,
err = aead_register_instance(tmpl, inst); err = aead_register_instance(tmpl, inst);
if (err) if (err)
goto out_drop_alg; goto out_drop_alg;
...@@ -1201,19 +1251,9 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl, ...@@ -1201,19 +1251,9 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
goto out; goto out;
} }
static void crypto_rfc4543_free(struct crypto_instance *inst)
{
struct crypto_rfc4543_instance_ctx *ctx = crypto_instance_ctx(inst);
crypto_drop_aead(&ctx->aead);
kfree(aead_instance(inst));
}
static struct crypto_template crypto_rfc4543_tmpl = { static struct crypto_template crypto_rfc4543_tmpl = {
.name = "rfc4543", .name = "rfc4543",
.create = crypto_rfc4543_create, .create = crypto_rfc4543_create,
.free = crypto_rfc4543_free,
.module = THIS_MODULE, .module = THIS_MODULE,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment