Commit 70c3c8a9 authored by Herbert Xu's avatar Herbert Xu

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: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent ecb479d0
...@@ -2713,10 +2713,8 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, ...@@ -2713,10 +2713,8 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
sec4_sg_index = 0; sec4_sg_index = 0;
if (!all_contig) { if (!all_contig) {
if (!is_gcm) { if (!is_gcm) {
sg_to_sec4_sg(req->assoc, sg_to_sec4_sg_len(req->assoc, req->assoclen,
assoc_nents, edesc->sec4_sg + sec4_sg_index);
edesc->sec4_sg +
sec4_sg_index, 0);
sec4_sg_index += assoc_nents; sec4_sg_index += assoc_nents;
} }
...@@ -2725,10 +2723,8 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, ...@@ -2725,10 +2723,8 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
sec4_sg_index += 1; sec4_sg_index += 1;
if (is_gcm) { if (is_gcm) {
sg_to_sec4_sg(req->assoc, sg_to_sec4_sg_len(req->assoc, req->assoclen,
assoc_nents, edesc->sec4_sg + sec4_sg_index);
edesc->sec4_sg +
sec4_sg_index, 0);
sec4_sg_index += assoc_nents; sec4_sg_index += assoc_nents;
} }
...@@ -2953,8 +2949,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request ...@@ -2953,8 +2949,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
sec4_sg_index = 0; sec4_sg_index = 0;
if (!(contig & GIV_SRC_CONTIG)) { if (!(contig & GIV_SRC_CONTIG)) {
if (!is_gcm) { if (!is_gcm) {
sg_to_sec4_sg(req->assoc, assoc_nents, sg_to_sec4_sg_len(req->assoc, req->assoclen,
edesc->sec4_sg + sec4_sg_index, 0); edesc->sec4_sg + sec4_sg_index);
sec4_sg_index += assoc_nents; sec4_sg_index += assoc_nents;
} }
...@@ -2963,8 +2959,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request ...@@ -2963,8 +2959,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
sec4_sg_index += 1; sec4_sg_index += 1;
if (is_gcm) { if (is_gcm) {
sg_to_sec4_sg(req->assoc, assoc_nents, sg_to_sec4_sg_len(req->assoc, req->assoclen,
edesc->sec4_sg + sec4_sg_index, 0); edesc->sec4_sg + sec4_sg_index);
sec4_sg_index += assoc_nents; sec4_sg_index += assoc_nents;
} }
......
...@@ -55,6 +55,21 @@ static inline void sg_to_sec4_sg_last(struct scatterlist *sg, int sg_count, ...@@ -55,6 +55,21 @@ static inline void sg_to_sec4_sg_last(struct scatterlist *sg, int sg_count,
sec4_sg_ptr->len |= SEC4_SG_LEN_FIN; sec4_sg_ptr->len |= SEC4_SG_LEN_FIN;
} }
static inline struct sec4_sg_entry *sg_to_sec4_sg_len(
struct scatterlist *sg, unsigned int total,
struct sec4_sg_entry *sec4_sg_ptr)
{
do {
unsigned int len = min(sg_dma_len(sg), total);
dma_to_sec4_sg_one(sec4_sg_ptr, sg_dma_address(sg), len, 0);
sec4_sg_ptr++;
sg = sg_next(sg);
total -= len;
} while (total);
return sec4_sg_ptr - 1;
}
/* count number of elements in scatterlist */ /* count number of elements in scatterlist */
static inline int __sg_count(struct scatterlist *sg_list, int nbytes, static inline int __sg_count(struct scatterlist *sg_list, int nbytes,
bool *chained) bool *chained)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment