Skip to content

Commit 7b05a37

Browse files
committed
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: Herbert Xu <[email protected]>
1 parent e9b8d2c commit 7b05a37

File tree

1 file changed

+77
-37
lines changed

1 file changed

+77
-37
lines changed

crypto/gcm.c

Lines changed: 77 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ struct crypto_rfc4106_ctx {
3838
u8 nonce[4];
3939
};
4040

41+
struct crypto_rfc4106_req_ctx {
42+
struct scatterlist src[3];
43+
struct scatterlist dst[3];
44+
struct aead_request subreq;
45+
};
46+
4147
struct crypto_rfc4543_instance_ctx {
4248
struct crypto_aead_spawn aead;
4349
};
@@ -601,6 +607,15 @@ static void crypto_gcm_exit_tfm(struct crypto_aead *tfm)
601607
crypto_free_ablkcipher(ctx->ctr);
602608
}
603609

610+
static void crypto_gcm_free(struct aead_instance *inst)
611+
{
612+
struct gcm_instance_ctx *ctx = aead_instance_ctx(inst);
613+
614+
crypto_drop_skcipher(&ctx->ctr);
615+
crypto_drop_ahash(&ctx->ghash);
616+
kfree(inst);
617+
}
618+
604619
static int crypto_gcm_create_common(struct crypto_template *tmpl,
605620
struct rtattr **tb,
606621
const char *full_name,
@@ -619,7 +634,8 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
619634
if (IS_ERR(algt))
620635
return PTR_ERR(algt);
621636

622-
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
637+
if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_AEAD_NEW)) &
638+
algt->mask)
623639
return -EINVAL;
624640

625641
ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type,
@@ -674,6 +690,7 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
674690

675691
inst->alg.base.cra_flags = (ghash->base.cra_flags | ctr->cra_flags) &
676692
CRYPTO_ALG_ASYNC;
693+
inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW;
677694
inst->alg.base.cra_priority = (ghash->base.cra_priority +
678695
ctr->cra_priority) / 2;
679696
inst->alg.base.cra_blocksize = 1;
@@ -689,6 +706,8 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
689706
inst->alg.encrypt = crypto_gcm_encrypt;
690707
inst->alg.decrypt = crypto_gcm_decrypt;
691708

709+
inst->free = crypto_gcm_free;
710+
692711
err = aead_register_instance(tmpl, inst);
693712
if (err)
694713
goto out_put_ctr;
@@ -728,19 +747,9 @@ static int crypto_gcm_create(struct crypto_template *tmpl, struct rtattr **tb)
728747
ctr_name, "ghash");
729748
}
730749

731-
static void crypto_gcm_free(struct crypto_instance *inst)
732-
{
733-
struct gcm_instance_ctx *ctx = crypto_instance_ctx(inst);
734-
735-
crypto_drop_skcipher(&ctx->ctr);
736-
crypto_drop_ahash(&ctx->ghash);
737-
kfree(aead_instance(inst));
738-
}
739-
740750
static struct crypto_template crypto_gcm_tmpl = {
741751
.name = "gcm",
742752
.create = crypto_gcm_create,
743-
.free = crypto_gcm_free,
744753
.module = THIS_MODULE,
745754
};
746755

@@ -770,7 +779,6 @@ static int crypto_gcm_base_create(struct crypto_template *tmpl,
770779
static struct crypto_template crypto_gcm_base_tmpl = {
771780
.name = "gcm_base",
772781
.create = crypto_gcm_base_create,
773-
.free = crypto_gcm_free,
774782
.module = THIS_MODULE,
775783
};
776784

@@ -816,34 +824,60 @@ static int crypto_rfc4106_setauthsize(struct crypto_aead *parent,
816824

817825
static struct aead_request *crypto_rfc4106_crypt(struct aead_request *req)
818826
{
819-
struct aead_request *subreq = aead_request_ctx(req);
827+
struct crypto_rfc4106_req_ctx *rctx = aead_request_ctx(req);
820828
struct crypto_aead *aead = crypto_aead_reqtfm(req);
821829
struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(aead);
830+
struct aead_request *subreq = &rctx->subreq;
822831
struct crypto_aead *child = ctx->child;
832+
struct scatterlist *sg;
823833
u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child),
824834
crypto_aead_alignmask(child) + 1);
825835

836+
scatterwalk_map_and_copy(iv + 12, req->src, 0, req->assoclen - 8, 0);
837+
826838
memcpy(iv, ctx->nonce, 4);
827839
memcpy(iv + 4, req->iv, 8);
828840

841+
sg_init_table(rctx->src, 3);
842+
sg_set_buf(rctx->src, iv + 12, req->assoclen - 8);
843+
sg = scatterwalk_ffwd(rctx->src + 1, req->src, req->assoclen);
844+
if (sg != rctx->src + 1)
845+
sg_chain(rctx->src, 2, sg);
846+
847+
if (req->src != req->dst) {
848+
sg_init_table(rctx->dst, 3);
849+
sg_set_buf(rctx->dst, iv + 12, req->assoclen - 8);
850+
sg = scatterwalk_ffwd(rctx->dst + 1, req->dst, req->assoclen);
851+
if (sg != rctx->dst + 1)
852+
sg_chain(rctx->dst, 2, sg);
853+
}
854+
829855
aead_request_set_tfm(subreq, child);
830856
aead_request_set_callback(subreq, req->base.flags, req->base.complete,
831857
req->base.data);
832-
aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, iv);
833-
aead_request_set_ad(subreq, req->assoclen);
858+
aead_request_set_crypt(subreq, rctx->src,
859+
req->src == req->dst ? rctx->src : rctx->dst,
860+
req->cryptlen, iv);
861+
aead_request_set_ad(subreq, req->assoclen - 8);
834862

835863
return subreq;
836864
}
837865

838866
static int crypto_rfc4106_encrypt(struct aead_request *req)
839867
{
868+
if (req->assoclen != 16 && req->assoclen != 20)
869+
return -EINVAL;
870+
840871
req = crypto_rfc4106_crypt(req);
841872

842873
return crypto_aead_encrypt(req);
843874
}
844875

845876
static int crypto_rfc4106_decrypt(struct aead_request *req)
846877
{
878+
if (req->assoclen != 16 && req->assoclen != 20)
879+
return -EINVAL;
880+
847881
req = crypto_rfc4106_crypt(req);
848882

849883
return crypto_aead_decrypt(req);
@@ -867,9 +901,9 @@ static int crypto_rfc4106_init_tfm(struct crypto_aead *tfm)
867901
align &= ~(crypto_tfm_ctx_alignment() - 1);
868902
crypto_aead_set_reqsize(
869903
tfm,
870-
sizeof(struct aead_request) +
904+
sizeof(struct crypto_rfc4106_req_ctx) +
871905
ALIGN(crypto_aead_reqsize(aead), crypto_tfm_ctx_alignment()) +
872-
align + 12);
906+
align + 24);
873907

874908
return 0;
875909
}
@@ -881,6 +915,12 @@ static void crypto_rfc4106_exit_tfm(struct crypto_aead *tfm)
881915
crypto_free_aead(ctx->child);
882916
}
883917

918+
static void crypto_rfc4106_free(struct aead_instance *inst)
919+
{
920+
crypto_drop_aead(aead_instance_ctx(inst));
921+
kfree(inst);
922+
}
923+
884924
static int crypto_rfc4106_create(struct crypto_template *tmpl,
885925
struct rtattr **tb)
886926
{
@@ -895,7 +935,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
895935
if (IS_ERR(algt))
896936
return PTR_ERR(algt);
897937

898-
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
938+
if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_AEAD_NEW)) &
939+
algt->mask)
899940
return -EINVAL;
900941

901942
ccm_name = crypto_attr_alg_name(tb[1]);
@@ -934,7 +975,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
934975
CRYPTO_MAX_ALG_NAME)
935976
goto out_drop_alg;
936977

937-
inst->alg.base.cra_flags |= alg->base.cra_flags & CRYPTO_ALG_ASYNC;
978+
inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
979+
inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW;
938980
inst->alg.base.cra_priority = alg->base.cra_priority;
939981
inst->alg.base.cra_blocksize = 1;
940982
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
@@ -952,6 +994,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
952994
inst->alg.encrypt = crypto_rfc4106_encrypt;
953995
inst->alg.decrypt = crypto_rfc4106_decrypt;
954996

997+
inst->free = crypto_rfc4106_free;
998+
955999
err = aead_register_instance(tmpl, inst);
9561000
if (err)
9571001
goto out_drop_alg;
@@ -966,16 +1010,9 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
9661010
goto out;
9671011
}
9681012

969-
static void crypto_rfc4106_free(struct crypto_instance *inst)
970-
{
971-
crypto_drop_aead(crypto_instance_ctx(inst));
972-
kfree(aead_instance(inst));
973-
}
974-
9751013
static struct crypto_template crypto_rfc4106_tmpl = {
9761014
.name = "rfc4106",
9771015
.create = crypto_rfc4106_create,
978-
.free = crypto_rfc4106_free,
9791016
.module = THIS_MODULE,
9801017
};
9811018

@@ -1114,6 +1151,15 @@ static void crypto_rfc4543_exit_tfm(struct crypto_aead *tfm)
11141151
crypto_put_default_null_skcipher();
11151152
}
11161153

1154+
static void crypto_rfc4543_free(struct aead_instance *inst)
1155+
{
1156+
struct crypto_rfc4543_instance_ctx *ctx = aead_instance_ctx(inst);
1157+
1158+
crypto_drop_aead(&ctx->aead);
1159+
1160+
kfree(inst);
1161+
}
1162+
11171163
static int crypto_rfc4543_create(struct crypto_template *tmpl,
11181164
struct rtattr **tb)
11191165
{
@@ -1129,7 +1175,8 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
11291175
if (IS_ERR(algt))
11301176
return PTR_ERR(algt);
11311177

1132-
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
1178+
if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_AEAD_NEW)) &
1179+
algt->mask)
11331180
return -EINVAL;
11341181

11351182
ccm_name = crypto_attr_alg_name(tb[1]);
@@ -1170,6 +1217,7 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
11701217
goto out_drop_alg;
11711218

11721219
inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
1220+
inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW;
11731221
inst->alg.base.cra_priority = alg->base.cra_priority;
11741222
inst->alg.base.cra_blocksize = 1;
11751223
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
@@ -1187,6 +1235,8 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
11871235
inst->alg.encrypt = crypto_rfc4543_encrypt;
11881236
inst->alg.decrypt = crypto_rfc4543_decrypt;
11891237

1238+
inst->free = crypto_rfc4543_free,
1239+
11901240
err = aead_register_instance(tmpl, inst);
11911241
if (err)
11921242
goto out_drop_alg;
@@ -1201,19 +1251,9 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
12011251
goto out;
12021252
}
12031253

1204-
static void crypto_rfc4543_free(struct crypto_instance *inst)
1205-
{
1206-
struct crypto_rfc4543_instance_ctx *ctx = crypto_instance_ctx(inst);
1207-
1208-
crypto_drop_aead(&ctx->aead);
1209-
1210-
kfree(aead_instance(inst));
1211-
}
1212-
12131254
static struct crypto_template crypto_rfc4543_tmpl = {
12141255
.name = "rfc4543",
12151256
.create = crypto_rfc4543_create,
1216-
.free = crypto_rfc4543_free,
12171257
.module = THIS_MODULE,
12181258
};
12191259

0 commit comments

Comments
 (0)