diff options
author | Uri Simchoni <uri@jdland.co.il> | 2010-04-08 12:27:02 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2010-04-13 04:50:47 -0400 |
commit | 15d4dd3594221f11a7730fcf2d5f9942b96cdd7e (patch) | |
tree | 6a907ecf99f7ac734db64af03778f63456f660de /drivers/crypto/mv_cesa.c | |
parent | f565e67ec1b8f4a95d21550f9b879fe86b4132e0 (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.c | 66 |
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 | ||
146 | static void setup_data_in(struct ablkcipher_request *req) | 146 | static 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; | 178 | static 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 | ||
169 | static void mv_process_current_q(int first_block) | 187 | static void mv_process_current_q(int first_block) |
@@ -289,12 +307,16 @@ static void dequeue_complete_req(void) | |||
289 | static int count_sgs(struct scatterlist *sl, unsigned int total_bytes) | 307 | static 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 | } |