aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilad Ben-Yossef <gilad@benyossef.com>2019-04-18 09:39:00 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2019-04-25 03:38:15 -0400
commitc776f7d37b6bf3663c838b2d2223f8ec1b523b12 (patch)
tree038c9be5ae4d39586b6dc0ecaea329f6a6e76728
parentda3cf67f1bcf25b069a54ff70fd108860242c8f7 (diff)
crypto: ccree - make AEAD sgl iterator well behaved
Fix some scatter list interation code was not handling scatter lists being shorter than expected in a graceful manner. Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/ccree/cc_buffer_mgr.c55
1 files changed, 17 insertions, 38 deletions
diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c
index 86e498bee0bb..fa625bdde3f9 100644
--- a/drivers/crypto/ccree/cc_buffer_mgr.c
+++ b/drivers/crypto/ccree/cc_buffer_mgr.c
@@ -659,11 +659,9 @@ static int cc_aead_chain_assoc(struct cc_drvdata *drvdata,
659{ 659{
660 struct aead_req_ctx *areq_ctx = aead_request_ctx(req); 660 struct aead_req_ctx *areq_ctx = aead_request_ctx(req);
661 int rc = 0; 661 int rc = 0;
662 u32 mapped_nents = 0; 662 int mapped_nents = 0;
663 struct scatterlist *current_sg = req->src;
664 struct crypto_aead *tfm = crypto_aead_reqtfm(req); 663 struct crypto_aead *tfm = crypto_aead_reqtfm(req);
665 unsigned int sg_index = 0; 664 unsigned int size_of_assoc = areq_ctx->assoclen;
666 u32 size_of_assoc = areq_ctx->assoclen;
667 struct device *dev = drvdata_to_dev(drvdata); 665 struct device *dev = drvdata_to_dev(drvdata);
668 666
669 if (areq_ctx->is_gcm4543) 667 if (areq_ctx->is_gcm4543)
@@ -684,26 +682,10 @@ static int cc_aead_chain_assoc(struct cc_drvdata *drvdata,
684 goto chain_assoc_exit; 682 goto chain_assoc_exit;
685 } 683 }
686 684
687 //iterate over the sgl to see how many entries are for associated data 685 mapped_nents = sg_nents_for_len(req->src, size_of_assoc);
688 //it is assumed that if we reach here , the sgl is already mapped 686 if (mapped_nents < 0)
689 sg_index = current_sg->length; 687 return mapped_nents;
690 //the first entry in the scatter list contains all the associated data 688
691 if (sg_index > size_of_assoc) {
692 mapped_nents++;
693 } else {
694 while (sg_index <= size_of_assoc) {
695 current_sg = sg_next(current_sg);
696 /* if have reached the end of the sgl, then this is
697 * unexpected
698 */
699 if (!current_sg) {
700 dev_err(dev, "reached end of sg list. unexpected\n");
701 return -EINVAL;
702 }
703 sg_index += current_sg->length;
704 mapped_nents++;
705 }
706 }
707 if (mapped_nents > LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES) { 689 if (mapped_nents > LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES) {
708 dev_err(dev, "Too many fragments. current %d max %d\n", 690 dev_err(dev, "Too many fragments. current %d max %d\n",
709 mapped_nents, LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES); 691 mapped_nents, LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES);
@@ -898,6 +880,7 @@ static int cc_aead_chain_data(struct cc_drvdata *drvdata,
898 u32 sg_index = 0; 880 u32 sg_index = 0;
899 bool is_gcm4543 = areq_ctx->is_gcm4543; 881 bool is_gcm4543 = areq_ctx->is_gcm4543;
900 u32 size_to_skip = areq_ctx->assoclen; 882 u32 size_to_skip = areq_ctx->assoclen;
883 struct scatterlist *sgl;
901 884
902 if (is_gcm4543) 885 if (is_gcm4543)
903 size_to_skip += crypto_aead_ivsize(tfm); 886 size_to_skip += crypto_aead_ivsize(tfm);
@@ -920,15 +903,13 @@ static int cc_aead_chain_data(struct cc_drvdata *drvdata,
920 sg_index = areq_ctx->src_sgl->length; 903 sg_index = areq_ctx->src_sgl->length;
921 //check where the data starts 904 //check where the data starts
922 while (sg_index <= size_to_skip) { 905 while (sg_index <= size_to_skip) {
906 src_mapped_nents--;
923 offset -= areq_ctx->src_sgl->length; 907 offset -= areq_ctx->src_sgl->length;
924 areq_ctx->src_sgl = sg_next(areq_ctx->src_sgl); 908 sgl = sg_next(areq_ctx->src_sgl);
925 //if have reached the end of the sgl, then this is unexpected 909 if (!sgl)
926 if (!areq_ctx->src_sgl) { 910 break;
927 dev_err(dev, "reached end of sg list. unexpected\n"); 911 areq_ctx->src_sgl = sgl;
928 return -EINVAL;
929 }
930 sg_index += areq_ctx->src_sgl->length; 912 sg_index += areq_ctx->src_sgl->length;
931 src_mapped_nents--;
932 } 913 }
933 if (src_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES) { 914 if (src_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES) {
934 dev_err(dev, "Too many fragments. current %d max %d\n", 915 dev_err(dev, "Too many fragments. current %d max %d\n",
@@ -962,15 +943,13 @@ static int cc_aead_chain_data(struct cc_drvdata *drvdata,
962 943
963 //check where the data starts 944 //check where the data starts
964 while (sg_index <= size_to_skip) { 945 while (sg_index <= size_to_skip) {
946 dst_mapped_nents--;
965 offset -= areq_ctx->dst_sgl->length; 947 offset -= areq_ctx->dst_sgl->length;
966 areq_ctx->dst_sgl = sg_next(areq_ctx->dst_sgl); 948 sgl = sg_next(areq_ctx->dst_sgl);
967 //if have reached the end of the sgl, then this is unexpected 949 if (!sgl)
968 if (!areq_ctx->dst_sgl) { 950 break;
969 dev_err(dev, "reached end of sg list. unexpected\n"); 951 areq_ctx->dst_sgl = sgl;
970 return -EINVAL;
971 }
972 sg_index += areq_ctx->dst_sgl->length; 952 sg_index += areq_ctx->dst_sgl->length;
973 dst_mapped_nents--;
974 } 953 }
975 if (dst_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES) { 954 if (dst_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES) {
976 dev_err(dev, "Too many fragments. current %d max %d\n", 955 dev_err(dev, "Too many fragments. current %d max %d\n",