aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/gcm.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-07-08 19:17:30 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-07-14 02:56:47 -0400
commit7b05a373a7f8a69622006f3b1ffd06c2507d7990 (patch)
tree5f0a380a8062e6bc2a1adf6895ea67ff7543a842 /crypto/gcm.c
parente9b8d2c20a8749601f44c267590c954d222e9b3e (diff)
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 <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/gcm.c')
-rw-r--r--crypto/gcm.c114
1 files changed, 77 insertions, 37 deletions
diff --git a/crypto/gcm.c b/crypto/gcm.c
index 7d32d4720564..0c9e33bdce1a 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -38,6 +38,12 @@ struct crypto_rfc4106_ctx {
38 u8 nonce[4]; 38 u8 nonce[4];
39}; 39};
40 40
41struct crypto_rfc4106_req_ctx {
42 struct scatterlist src[3];
43 struct scatterlist dst[3];
44 struct aead_request subreq;
45};
46
41struct crypto_rfc4543_instance_ctx { 47struct crypto_rfc4543_instance_ctx {
42 struct crypto_aead_spawn aead; 48 struct crypto_aead_spawn aead;
43}; 49};
@@ -601,6 +607,15 @@ static void crypto_gcm_exit_tfm(struct crypto_aead *tfm)
601 crypto_free_ablkcipher(ctx->ctr); 607 crypto_free_ablkcipher(ctx->ctr);
602} 608}
603 609
610static 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
604static int crypto_gcm_create_common(struct crypto_template *tmpl, 619static int crypto_gcm_create_common(struct crypto_template *tmpl,
605 struct rtattr **tb, 620 struct rtattr **tb,
606 const char *full_name, 621 const char *full_name,
@@ -619,7 +634,8 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
619 if (IS_ERR(algt)) 634 if (IS_ERR(algt))
620 return PTR_ERR(algt); 635 return PTR_ERR(algt);
621 636
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)
623 return -EINVAL; 639 return -EINVAL;
624 640
625 ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type, 641 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 690
675 inst->alg.base.cra_flags = (ghash->base.cra_flags | ctr->cra_flags) & 691 inst->alg.base.cra_flags = (ghash->base.cra_flags | ctr->cra_flags) &
676 CRYPTO_ALG_ASYNC; 692 CRYPTO_ALG_ASYNC;
693 inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW;
677 inst->alg.base.cra_priority = (ghash->base.cra_priority + 694 inst->alg.base.cra_priority = (ghash->base.cra_priority +
678 ctr->cra_priority) / 2; 695 ctr->cra_priority) / 2;
679 inst->alg.base.cra_blocksize = 1; 696 inst->alg.base.cra_blocksize = 1;
@@ -689,6 +706,8 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
689 inst->alg.encrypt = crypto_gcm_encrypt; 706 inst->alg.encrypt = crypto_gcm_encrypt;
690 inst->alg.decrypt = crypto_gcm_decrypt; 707 inst->alg.decrypt = crypto_gcm_decrypt;
691 708
709 inst->free = crypto_gcm_free;
710
692 err = aead_register_instance(tmpl, inst); 711 err = aead_register_instance(tmpl, inst);
693 if (err) 712 if (err)
694 goto out_put_ctr; 713 goto out_put_ctr;
@@ -728,19 +747,9 @@ static int crypto_gcm_create(struct crypto_template *tmpl, struct rtattr **tb)
728 ctr_name, "ghash"); 747 ctr_name, "ghash");
729} 748}
730 749
731static 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
740static struct crypto_template crypto_gcm_tmpl = { 750static struct crypto_template crypto_gcm_tmpl = {
741 .name = "gcm", 751 .name = "gcm",
742 .create = crypto_gcm_create, 752 .create = crypto_gcm_create,
743 .free = crypto_gcm_free,
744 .module = THIS_MODULE, 753 .module = THIS_MODULE,
745}; 754};
746 755
@@ -770,7 +779,6 @@ static int crypto_gcm_base_create(struct crypto_template *tmpl,
770static struct crypto_template crypto_gcm_base_tmpl = { 779static struct crypto_template crypto_gcm_base_tmpl = {
771 .name = "gcm_base", 780 .name = "gcm_base",
772 .create = crypto_gcm_base_create, 781 .create = crypto_gcm_base_create,
773 .free = crypto_gcm_free,
774 .module = THIS_MODULE, 782 .module = THIS_MODULE,
775}; 783};
776 784
@@ -816,27 +824,50 @@ static int crypto_rfc4106_setauthsize(struct crypto_aead *parent,
816 824
817static struct aead_request *crypto_rfc4106_crypt(struct aead_request *req) 825static struct aead_request *crypto_rfc4106_crypt(struct aead_request *req)
818{ 826{
819 struct aead_request *subreq = aead_request_ctx(req); 827 struct crypto_rfc4106_req_ctx *rctx = aead_request_ctx(req);
820 struct crypto_aead *aead = crypto_aead_reqtfm(req); 828 struct crypto_aead *aead = crypto_aead_reqtfm(req);
821 struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(aead); 829 struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(aead);
830 struct aead_request *subreq = &rctx->subreq;
822 struct crypto_aead *child = ctx->child; 831 struct crypto_aead *child = ctx->child;
832 struct scatterlist *sg;
823 u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child), 833 u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child),
824 crypto_aead_alignmask(child) + 1); 834 crypto_aead_alignmask(child) + 1);
825 835
836 scatterwalk_map_and_copy(iv + 12, req->src, 0, req->assoclen - 8, 0);
837
826 memcpy(iv, ctx->nonce, 4); 838 memcpy(iv, ctx->nonce, 4);
827 memcpy(iv + 4, req->iv, 8); 839 memcpy(iv + 4, req->iv, 8);
828 840
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
829 aead_request_set_tfm(subreq, child); 855 aead_request_set_tfm(subreq, child);
830 aead_request_set_callback(subreq, req->base.flags, req->base.complete, 856 aead_request_set_callback(subreq, req->base.flags, req->base.complete,
831 req->base.data); 857 req->base.data);
832 aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, iv); 858 aead_request_set_crypt(subreq, rctx->src,
833 aead_request_set_ad(subreq, req->assoclen); 859 req->src == req->dst ? rctx->src : rctx->dst,
860 req->cryptlen, iv);
861 aead_request_set_ad(subreq, req->assoclen - 8);
834 862
835 return subreq; 863 return subreq;
836} 864}
837 865
838static int crypto_rfc4106_encrypt(struct aead_request *req) 866static int crypto_rfc4106_encrypt(struct aead_request *req)
839{ 867{
868 if (req->assoclen != 16 && req->assoclen != 20)
869 return -EINVAL;
870
840 req = crypto_rfc4106_crypt(req); 871 req = crypto_rfc4106_crypt(req);
841 872
842 return crypto_aead_encrypt(req); 873 return crypto_aead_encrypt(req);
@@ -844,6 +875,9 @@ static int crypto_rfc4106_encrypt(struct aead_request *req)
844 875
845static int crypto_rfc4106_decrypt(struct aead_request *req) 876static int crypto_rfc4106_decrypt(struct aead_request *req)
846{ 877{
878 if (req->assoclen != 16 && req->assoclen != 20)
879 return -EINVAL;
880
847 req = crypto_rfc4106_crypt(req); 881 req = crypto_rfc4106_crypt(req);
848 882
849 return crypto_aead_decrypt(req); 883 return crypto_aead_decrypt(req);
@@ -867,9 +901,9 @@ static int crypto_rfc4106_init_tfm(struct crypto_aead *tfm)
867 align &= ~(crypto_tfm_ctx_alignment() - 1); 901 align &= ~(crypto_tfm_ctx_alignment() - 1);
868 crypto_aead_set_reqsize( 902 crypto_aead_set_reqsize(
869 tfm, 903 tfm,
870 sizeof(struct aead_request) + 904 sizeof(struct crypto_rfc4106_req_ctx) +
871 ALIGN(crypto_aead_reqsize(aead), crypto_tfm_ctx_alignment()) + 905 ALIGN(crypto_aead_reqsize(aead), crypto_tfm_ctx_alignment()) +
872 align + 12); 906 align + 24);
873 907
874 return 0; 908 return 0;
875} 909}
@@ -881,6 +915,12 @@ static void crypto_rfc4106_exit_tfm(struct crypto_aead *tfm)
881 crypto_free_aead(ctx->child); 915 crypto_free_aead(ctx->child);
882} 916}
883 917
918static void crypto_rfc4106_free(struct aead_instance *inst)
919{
920 crypto_drop_aead(aead_instance_ctx(inst));
921 kfree(inst);
922}
923
884static int crypto_rfc4106_create(struct crypto_template *tmpl, 924static int crypto_rfc4106_create(struct crypto_template *tmpl,
885 struct rtattr **tb) 925 struct rtattr **tb)
886{ 926{
@@ -895,7 +935,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
895 if (IS_ERR(algt)) 935 if (IS_ERR(algt))
896 return PTR_ERR(algt); 936 return PTR_ERR(algt);
897 937
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)
899 return -EINVAL; 940 return -EINVAL;
900 941
901 ccm_name = crypto_attr_alg_name(tb[1]); 942 ccm_name = crypto_attr_alg_name(tb[1]);
@@ -934,7 +975,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
934 CRYPTO_MAX_ALG_NAME) 975 CRYPTO_MAX_ALG_NAME)
935 goto out_drop_alg; 976 goto out_drop_alg;
936 977
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;
938 inst->alg.base.cra_priority = alg->base.cra_priority; 980 inst->alg.base.cra_priority = alg->base.cra_priority;
939 inst->alg.base.cra_blocksize = 1; 981 inst->alg.base.cra_blocksize = 1;
940 inst->alg.base.cra_alignmask = alg->base.cra_alignmask; 982 inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
@@ -952,6 +994,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
952 inst->alg.encrypt = crypto_rfc4106_encrypt; 994 inst->alg.encrypt = crypto_rfc4106_encrypt;
953 inst->alg.decrypt = crypto_rfc4106_decrypt; 995 inst->alg.decrypt = crypto_rfc4106_decrypt;
954 996
997 inst->free = crypto_rfc4106_free;
998
955 err = aead_register_instance(tmpl, inst); 999 err = aead_register_instance(tmpl, inst);
956 if (err) 1000 if (err)
957 goto out_drop_alg; 1001 goto out_drop_alg;
@@ -966,16 +1010,9 @@ out_free_inst:
966 goto out; 1010 goto out;
967} 1011}
968 1012
969static void crypto_rfc4106_free(struct crypto_instance *inst)
970{
971 crypto_drop_aead(crypto_instance_ctx(inst));
972 kfree(aead_instance(inst));
973}
974
975static struct crypto_template crypto_rfc4106_tmpl = { 1013static struct crypto_template crypto_rfc4106_tmpl = {
976 .name = "rfc4106", 1014 .name = "rfc4106",
977 .create = crypto_rfc4106_create, 1015 .create = crypto_rfc4106_create,
978 .free = crypto_rfc4106_free,
979 .module = THIS_MODULE, 1016 .module = THIS_MODULE,
980}; 1017};
981 1018
@@ -1114,6 +1151,15 @@ static void crypto_rfc4543_exit_tfm(struct crypto_aead *tfm)
1114 crypto_put_default_null_skcipher(); 1151 crypto_put_default_null_skcipher();
1115} 1152}
1116 1153
1154static 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
1117static int crypto_rfc4543_create(struct crypto_template *tmpl, 1163static int crypto_rfc4543_create(struct crypto_template *tmpl,
1118 struct rtattr **tb) 1164 struct rtattr **tb)
1119{ 1165{
@@ -1129,7 +1175,8 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
1129 if (IS_ERR(algt)) 1175 if (IS_ERR(algt))
1130 return PTR_ERR(algt); 1176 return PTR_ERR(algt);
1131 1177
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)
1133 return -EINVAL; 1180 return -EINVAL;
1134 1181
1135 ccm_name = crypto_attr_alg_name(tb[1]); 1182 ccm_name = crypto_attr_alg_name(tb[1]);
@@ -1170,6 +1217,7 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
1170 goto out_drop_alg; 1217 goto out_drop_alg;
1171 1218
1172 inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC; 1219 inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
1220 inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW;
1173 inst->alg.base.cra_priority = alg->base.cra_priority; 1221 inst->alg.base.cra_priority = alg->base.cra_priority;
1174 inst->alg.base.cra_blocksize = 1; 1222 inst->alg.base.cra_blocksize = 1;
1175 inst->alg.base.cra_alignmask = alg->base.cra_alignmask; 1223 inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
@@ -1187,6 +1235,8 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
1187 inst->alg.encrypt = crypto_rfc4543_encrypt; 1235 inst->alg.encrypt = crypto_rfc4543_encrypt;
1188 inst->alg.decrypt = crypto_rfc4543_decrypt; 1236 inst->alg.decrypt = crypto_rfc4543_decrypt;
1189 1237
1238 inst->free = crypto_rfc4543_free,
1239
1190 err = aead_register_instance(tmpl, inst); 1240 err = aead_register_instance(tmpl, inst);
1191 if (err) 1241 if (err)
1192 goto out_drop_alg; 1242 goto out_drop_alg;
@@ -1201,19 +1251,9 @@ out_free_inst:
1201 goto out; 1251 goto out;
1202} 1252}
1203 1253
1204static 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
1213static struct crypto_template crypto_rfc4543_tmpl = { 1254static struct crypto_template crypto_rfc4543_tmpl = {
1214 .name = "rfc4543", 1255 .name = "rfc4543",
1215 .create = crypto_rfc4543_create, 1256 .create = crypto_rfc4543_create,
1216 .free = crypto_rfc4543_free,
1217 .module = THIS_MODULE, 1257 .module = THIS_MODULE,
1218}; 1258};
1219 1259