aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-06-08 04:38:24 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-06-09 10:25:58 -0400
commit70c3c8a96a85d333b3ff1f24df84c0e179261a8a (patch)
tree60dfee06ecc515fa9113c1fd98b46ece0b6a7845 /drivers/crypto
parentecb479d07a4e2db980965193511dbf2563d50db5 (diff)
crypto: caam - Clamp AEAD SG list by input length
Currently caam assumes that the SG list contains exactly the number of bytes required. This assumption is incorrect. Up until now this has been harmless. However with the new AEAD interface this now breaks as the AD SG list contains more bytes than just the AD. This patch fixes this by always clamping the AD SG list by the specified AD length. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/caam/caamalg.c20
-rw-r--r--drivers/crypto/caam/sg_sw_sec4.h15
2 files changed, 23 insertions, 12 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 3d850ab47c28..3c37fe63e598 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -2713,10 +2713,8 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
2713 sec4_sg_index = 0; 2713 sec4_sg_index = 0;
2714 if (!all_contig) { 2714 if (!all_contig) {
2715 if (!is_gcm) { 2715 if (!is_gcm) {
2716 sg_to_sec4_sg(req->assoc, 2716 sg_to_sec4_sg_len(req->assoc, req->assoclen,
2717 assoc_nents, 2717 edesc->sec4_sg + sec4_sg_index);
2718 edesc->sec4_sg +
2719 sec4_sg_index, 0);
2720 sec4_sg_index += assoc_nents; 2718 sec4_sg_index += assoc_nents;
2721 } 2719 }
2722 2720
@@ -2725,10 +2723,8 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
2725 sec4_sg_index += 1; 2723 sec4_sg_index += 1;
2726 2724
2727 if (is_gcm) { 2725 if (is_gcm) {
2728 sg_to_sec4_sg(req->assoc, 2726 sg_to_sec4_sg_len(req->assoc, req->assoclen,
2729 assoc_nents, 2727 edesc->sec4_sg + sec4_sg_index);
2730 edesc->sec4_sg +
2731 sec4_sg_index, 0);
2732 sec4_sg_index += assoc_nents; 2728 sec4_sg_index += assoc_nents;
2733 } 2729 }
2734 2730
@@ -2953,8 +2949,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
2953 sec4_sg_index = 0; 2949 sec4_sg_index = 0;
2954 if (!(contig & GIV_SRC_CONTIG)) { 2950 if (!(contig & GIV_SRC_CONTIG)) {
2955 if (!is_gcm) { 2951 if (!is_gcm) {
2956 sg_to_sec4_sg(req->assoc, assoc_nents, 2952 sg_to_sec4_sg_len(req->assoc, req->assoclen,
2957 edesc->sec4_sg + sec4_sg_index, 0); 2953 edesc->sec4_sg + sec4_sg_index);
2958 sec4_sg_index += assoc_nents; 2954 sec4_sg_index += assoc_nents;
2959 } 2955 }
2960 2956
@@ -2963,8 +2959,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
2963 sec4_sg_index += 1; 2959 sec4_sg_index += 1;
2964 2960
2965 if (is_gcm) { 2961 if (is_gcm) {
2966 sg_to_sec4_sg(req->assoc, assoc_nents, 2962 sg_to_sec4_sg_len(req->assoc, req->assoclen,
2967 edesc->sec4_sg + sec4_sg_index, 0); 2963 edesc->sec4_sg + sec4_sg_index);
2968 sec4_sg_index += assoc_nents; 2964 sec4_sg_index += assoc_nents;
2969 } 2965 }
2970 2966
diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h
index 3b918218aa4c..efbc1db8da53 100644
--- a/drivers/crypto/caam/sg_sw_sec4.h
+++ b/drivers/crypto/caam/sg_sw_sec4.h
@@ -55,6 +55,21 @@ static inline void sg_to_sec4_sg_last(struct scatterlist *sg, int sg_count,
55 sec4_sg_ptr->len |= SEC4_SG_LEN_FIN; 55 sec4_sg_ptr->len |= SEC4_SG_LEN_FIN;
56} 56}
57 57
58static inline struct sec4_sg_entry *sg_to_sec4_sg_len(
59 struct scatterlist *sg, unsigned int total,
60 struct sec4_sg_entry *sec4_sg_ptr)
61{
62 do {
63 unsigned int len = min(sg_dma_len(sg), total);
64
65 dma_to_sec4_sg_one(sec4_sg_ptr, sg_dma_address(sg), len, 0);
66 sec4_sg_ptr++;
67 sg = sg_next(sg);
68 total -= len;
69 } while (total);
70 return sec4_sg_ptr - 1;
71}
72
58/* count number of elements in scatterlist */ 73/* count number of elements in scatterlist */
59static inline int __sg_count(struct scatterlist *sg_list, int nbytes, 74static inline int __sg_count(struct scatterlist *sg_list, int nbytes,
60 bool *chained) 75 bool *chained)