diff options
author | Gilad Ben-Yossef <gilad@benyossef.com> | 2019-04-18 09:39:00 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2019-04-25 03:38:15 -0400 |
commit | c776f7d37b6bf3663c838b2d2223f8ec1b523b12 (patch) | |
tree | 038c9be5ae4d39586b6dc0ecaea329f6a6e76728 | |
parent | da3cf67f1bcf25b069a54ff70fd108860242c8f7 (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.c | 55 |
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", |