aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/mv_cesa.c
diff options
context:
space:
mode:
authorUri Simchoni <uri@jdland.co.il>2010-04-08 12:27:02 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2010-04-13 04:50:47 -0400
commit15d4dd3594221f11a7730fcf2d5f9942b96cdd7e (patch)
tree6a907ecf99f7ac734db64af03778f63456f660de /drivers/crypto/mv_cesa.c
parentf565e67ec1b8f4a95d21550f9b879fe86b4132e0 (diff)
crypto: mv_cesa - Fix situations where the src sglist spans more data than the request asks for
Fix for situations where the source scatterlist spans more data than the request nbytes Signed-off-by: Uri Simchoni <uri@jdland.co.il> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/mv_cesa.c')
-rw-r--r--drivers/crypto/mv_cesa.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index 018a95ce0c9b..096f9ff6578a 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -143,27 +143,45 @@ static int mv_setkey_aes(struct crypto_ablkcipher *cipher, const u8 *key,
143 return 0; 143 return 0;
144} 144}
145 145
146static void setup_data_in(struct ablkcipher_request *req) 146static void copy_src_to_buf(struct req_progress *p, char *dbuf, int len)
147{ 147{
148 int ret; 148 int ret;
149 void *buf; 149 void *sbuf;
150 150 int copied = 0;
151 if (!cpg->p.sg_src_left) {
152 ret = sg_miter_next(&cpg->p.src_sg_it);
153 BUG_ON(!ret);
154 cpg->p.sg_src_left = cpg->p.src_sg_it.length;
155 cpg->p.src_start = 0;
156 }
157 151
158 cpg->p.crypt_len = min(cpg->p.sg_src_left, cpg->max_req_size); 152 while (1) {
159 153 if (!p->sg_src_left) {
160 buf = cpg->p.src_sg_it.addr; 154 ret = sg_miter_next(&p->src_sg_it);
161 buf += cpg->p.src_start; 155 BUG_ON(!ret);
156 p->sg_src_left = p->src_sg_it.length;
157 p->src_start = 0;
158 }
162 159
163 memcpy(cpg->sram + SRAM_DATA_IN_START, buf, cpg->p.crypt_len); 160 sbuf = p->src_sg_it.addr + p->src_start;
161
162 if (p->sg_src_left <= len - copied) {
163 memcpy(dbuf + copied, sbuf, p->sg_src_left);
164 copied += p->sg_src_left;
165 p->sg_src_left = 0;
166 if (copied >= len)
167 break;
168 } else {
169 int copy_len = len - copied;
170 memcpy(dbuf + copied, sbuf, copy_len);
171 p->src_start += copy_len;
172 p->sg_src_left -= copy_len;
173 break;
174 }
175 }
176}
164 177
165 cpg->p.sg_src_left -= cpg->p.crypt_len; 178static void setup_data_in(struct ablkcipher_request *req)
166 cpg->p.src_start += cpg->p.crypt_len; 179{
180 struct req_progress *p = &cpg->p;
181 p->crypt_len =
182 min((int)req->nbytes - p->total_req_bytes, cpg->max_req_size);
183 copy_src_to_buf(p, cpg->sram + SRAM_DATA_IN_START,
184 p->crypt_len);
167} 185}
168 186
169static void mv_process_current_q(int first_block) 187static void mv_process_current_q(int first_block)
@@ -289,12 +307,16 @@ static void dequeue_complete_req(void)
289static int count_sgs(struct scatterlist *sl, unsigned int total_bytes) 307static int count_sgs(struct scatterlist *sl, unsigned int total_bytes)
290{ 308{
291 int i = 0; 309 int i = 0;
292 310 size_t cur_len;
293 do { 311
294 total_bytes -= sl[i].length; 312 while (1) {
295 i++; 313 cur_len = sl[i].length;
296 314 ++i;
297 } while (total_bytes > 0); 315 if (total_bytes > cur_len)
316 total_bytes -= cur_len;
317 else
318 break;
319 }
298 320
299 return i; 321 return i;
300} 322}