diff options
Diffstat (limited to 'crypto/gcm.c')
-rw-r--r-- | crypto/gcm.c | 114 |
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 | ||
41 | struct crypto_rfc4106_req_ctx { | ||
42 | struct scatterlist src[3]; | ||
43 | struct scatterlist dst[3]; | ||
44 | struct aead_request subreq; | ||
45 | }; | ||
46 | |||
41 | struct crypto_rfc4543_instance_ctx { | 47 | struct 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 | ||
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 | |||
604 | static int crypto_gcm_create_common(struct crypto_template *tmpl, | 619 | static 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 | ||
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 | |||
740 | static struct crypto_template crypto_gcm_tmpl = { | 750 | static 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, | |||
770 | static struct crypto_template crypto_gcm_base_tmpl = { | 779 | static 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 | ||
817 | static struct aead_request *crypto_rfc4106_crypt(struct aead_request *req) | 825 | static 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 | ||
838 | static int crypto_rfc4106_encrypt(struct aead_request *req) | 866 | static 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 | ||
845 | static int crypto_rfc4106_decrypt(struct aead_request *req) | 876 | static 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 | ||
918 | static void crypto_rfc4106_free(struct aead_instance *inst) | ||
919 | { | ||
920 | crypto_drop_aead(aead_instance_ctx(inst)); | ||
921 | kfree(inst); | ||
922 | } | ||
923 | |||
884 | static int crypto_rfc4106_create(struct crypto_template *tmpl, | 924 | static 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 | ||
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 | |||
975 | static struct crypto_template crypto_rfc4106_tmpl = { | 1013 | static 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 | ||
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 | |||
1117 | static int crypto_rfc4543_create(struct crypto_template *tmpl, | 1163 | static 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 | ||
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 | |||
1213 | static struct crypto_template crypto_rfc4543_tmpl = { | 1254 | static 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 | ||