Lines Matching refs:walk

43 static int skcipher_walk_next(struct skcipher_walk *walk);
45 static inline void skcipher_unmap(struct scatter_walk *walk, void *vaddr) in skcipher_unmap() argument
47 if (PageHighMem(scatterwalk_page(walk))) in skcipher_unmap()
51 static inline void *skcipher_map(struct scatter_walk *walk) in skcipher_map() argument
53 struct page *page = scatterwalk_page(walk); in skcipher_map()
56 offset_in_page(walk->offset); in skcipher_map()
59 static inline void skcipher_map_src(struct skcipher_walk *walk) in skcipher_map_src() argument
61 walk->src.virt.addr = skcipher_map(&walk->in); in skcipher_map_src()
64 static inline void skcipher_map_dst(struct skcipher_walk *walk) in skcipher_map_dst() argument
66 walk->dst.virt.addr = skcipher_map(&walk->out); in skcipher_map_dst()
69 static inline void skcipher_unmap_src(struct skcipher_walk *walk) in skcipher_unmap_src() argument
71 skcipher_unmap(&walk->in, walk->src.virt.addr); in skcipher_unmap_src()
74 static inline void skcipher_unmap_dst(struct skcipher_walk *walk) in skcipher_unmap_dst() argument
76 skcipher_unmap(&walk->out, walk->dst.virt.addr); in skcipher_unmap_dst()
79 static inline gfp_t skcipher_walk_gfp(struct skcipher_walk *walk) in skcipher_walk_gfp() argument
81 return walk->flags & SKCIPHER_WALK_SLEEP ? GFP_KERNEL : GFP_ATOMIC; in skcipher_walk_gfp()
94 static int skcipher_done_slow(struct skcipher_walk *walk, unsigned int bsize) in skcipher_done_slow() argument
98 addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1); in skcipher_done_slow()
100 scatterwalk_copychunks(addr, &walk->out, bsize, in skcipher_done_slow()
101 (walk->flags & SKCIPHER_WALK_PHYS) ? 2 : 1); in skcipher_done_slow()
105 int skcipher_walk_done(struct skcipher_walk *walk, int err) in skcipher_walk_done() argument
107 unsigned int n = walk->nbytes; in skcipher_walk_done()
115 nbytes = walk->total - n; in skcipher_walk_done()
118 if (likely(!(walk->flags & (SKCIPHER_WALK_PHYS | in skcipher_walk_done()
123 skcipher_unmap_src(walk); in skcipher_walk_done()
124 } else if (walk->flags & SKCIPHER_WALK_DIFF) { in skcipher_walk_done()
125 skcipher_unmap_dst(walk); in skcipher_walk_done()
127 } else if (walk->flags & SKCIPHER_WALK_COPY) { in skcipher_walk_done()
128 skcipher_map_dst(walk); in skcipher_walk_done()
129 memcpy(walk->dst.virt.addr, walk->page, n); in skcipher_walk_done()
130 skcipher_unmap_dst(walk); in skcipher_walk_done()
131 } else if (unlikely(walk->flags & SKCIPHER_WALK_SLOW)) { in skcipher_walk_done()
142 n = skcipher_done_slow(walk, n); in skcipher_walk_done()
148 walk->total = nbytes; in skcipher_walk_done()
149 walk->nbytes = 0; in skcipher_walk_done()
151 scatterwalk_advance(&walk->in, n); in skcipher_walk_done()
152 scatterwalk_advance(&walk->out, n); in skcipher_walk_done()
153 scatterwalk_done(&walk->in, 0, nbytes); in skcipher_walk_done()
154 scatterwalk_done(&walk->out, 1, nbytes); in skcipher_walk_done()
157 crypto_yield(walk->flags & SKCIPHER_WALK_SLEEP ? in skcipher_walk_done()
159 return skcipher_walk_next(walk); in skcipher_walk_done()
164 if (!((unsigned long)walk->buffer | (unsigned long)walk->page)) in skcipher_walk_done()
167 if (walk->flags & SKCIPHER_WALK_PHYS) in skcipher_walk_done()
170 if (walk->iv != walk->oiv) in skcipher_walk_done()
171 memcpy(walk->oiv, walk->iv, walk->ivsize); in skcipher_walk_done()
172 if (walk->buffer != walk->page) in skcipher_walk_done()
173 kfree(walk->buffer); in skcipher_walk_done()
174 if (walk->page) in skcipher_walk_done()
175 free_page((unsigned long)walk->page); in skcipher_walk_done()
182 void skcipher_walk_complete(struct skcipher_walk *walk, int err) in skcipher_walk_complete() argument
186 list_for_each_entry_safe(p, tmp, &walk->buffers, entry) { in skcipher_walk_complete()
194 data = PTR_ALIGN(&p->buffer[0], walk->alignmask + 1); in skcipher_walk_complete()
195 data = skcipher_get_spot(data, walk->stride); in skcipher_walk_complete()
200 if (offset_in_page(p->data) + p->len + walk->stride > in skcipher_walk_complete()
209 if (!err && walk->iv != walk->oiv) in skcipher_walk_complete()
210 memcpy(walk->oiv, walk->iv, walk->ivsize); in skcipher_walk_complete()
211 if (walk->buffer != walk->page) in skcipher_walk_complete()
212 kfree(walk->buffer); in skcipher_walk_complete()
213 if (walk->page) in skcipher_walk_complete()
214 free_page((unsigned long)walk->page); in skcipher_walk_complete()
218 static void skcipher_queue_write(struct skcipher_walk *walk, in skcipher_queue_write() argument
221 p->dst = walk->out; in skcipher_queue_write()
222 list_add_tail(&p->entry, &walk->buffers); in skcipher_queue_write()
225 static int skcipher_next_slow(struct skcipher_walk *walk, unsigned int bsize) in skcipher_next_slow() argument
227 bool phys = walk->flags & SKCIPHER_WALK_PHYS; in skcipher_next_slow()
228 unsigned alignmask = walk->alignmask; in skcipher_next_slow()
236 if (!walk->buffer) in skcipher_next_slow()
237 walk->buffer = walk->page; in skcipher_next_slow()
238 buffer = walk->buffer; in skcipher_next_slow()
259 v = kzalloc(n, skcipher_walk_gfp(walk)); in skcipher_next_slow()
261 return skcipher_walk_done(walk, -ENOMEM); in skcipher_next_slow()
266 skcipher_queue_write(walk, p); in skcipher_next_slow()
269 walk->buffer = v; in skcipher_next_slow()
274 walk->dst.virt.addr = PTR_ALIGN(buffer, alignmask + 1); in skcipher_next_slow()
275 walk->dst.virt.addr = skcipher_get_spot(walk->dst.virt.addr, bsize); in skcipher_next_slow()
276 walk->src.virt.addr = walk->dst.virt.addr; in skcipher_next_slow()
278 scatterwalk_copychunks(walk->src.virt.addr, &walk->in, bsize, 0); in skcipher_next_slow()
280 walk->nbytes = bsize; in skcipher_next_slow()
281 walk->flags |= SKCIPHER_WALK_SLOW; in skcipher_next_slow()
286 static int skcipher_next_copy(struct skcipher_walk *walk) in skcipher_next_copy() argument
289 u8 *tmp = walk->page; in skcipher_next_copy()
291 skcipher_map_src(walk); in skcipher_next_copy()
292 memcpy(tmp, walk->src.virt.addr, walk->nbytes); in skcipher_next_copy()
293 skcipher_unmap_src(walk); in skcipher_next_copy()
295 walk->src.virt.addr = tmp; in skcipher_next_copy()
296 walk->dst.virt.addr = tmp; in skcipher_next_copy()
298 if (!(walk->flags & SKCIPHER_WALK_PHYS)) in skcipher_next_copy()
301 p = kmalloc(sizeof(*p), skcipher_walk_gfp(walk)); in skcipher_next_copy()
305 p->data = walk->page; in skcipher_next_copy()
306 p->len = walk->nbytes; in skcipher_next_copy()
307 skcipher_queue_write(walk, p); in skcipher_next_copy()
309 if (offset_in_page(walk->page) + walk->nbytes + walk->stride > in skcipher_next_copy()
311 walk->page = NULL; in skcipher_next_copy()
313 walk->page += walk->nbytes; in skcipher_next_copy()
318 static int skcipher_next_fast(struct skcipher_walk *walk) in skcipher_next_fast() argument
322 walk->src.phys.page = scatterwalk_page(&walk->in); in skcipher_next_fast()
323 walk->src.phys.offset = offset_in_page(walk->in.offset); in skcipher_next_fast()
324 walk->dst.phys.page = scatterwalk_page(&walk->out); in skcipher_next_fast()
325 walk->dst.phys.offset = offset_in_page(walk->out.offset); in skcipher_next_fast()
327 if (walk->flags & SKCIPHER_WALK_PHYS) in skcipher_next_fast()
330 diff = walk->src.phys.offset - walk->dst.phys.offset; in skcipher_next_fast()
331 diff |= walk->src.virt.page - walk->dst.virt.page; in skcipher_next_fast()
333 skcipher_map_src(walk); in skcipher_next_fast()
334 walk->dst.virt.addr = walk->src.virt.addr; in skcipher_next_fast()
337 walk->flags |= SKCIPHER_WALK_DIFF; in skcipher_next_fast()
338 skcipher_map_dst(walk); in skcipher_next_fast()
344 static int skcipher_walk_next(struct skcipher_walk *walk) in skcipher_walk_next() argument
350 walk->flags &= ~(SKCIPHER_WALK_SLOW | SKCIPHER_WALK_COPY | in skcipher_walk_next()
353 n = walk->total; in skcipher_walk_next()
354 bsize = min(walk->stride, max(n, walk->blocksize)); in skcipher_walk_next()
355 n = scatterwalk_clamp(&walk->in, n); in skcipher_walk_next()
356 n = scatterwalk_clamp(&walk->out, n); in skcipher_walk_next()
359 if (unlikely(walk->total < walk->blocksize)) in skcipher_walk_next()
360 return skcipher_walk_done(walk, -EINVAL); in skcipher_walk_next()
363 err = skcipher_next_slow(walk, bsize); in skcipher_walk_next()
367 if (unlikely((walk->in.offset | walk->out.offset) & walk->alignmask)) { in skcipher_walk_next()
368 if (!walk->page) { in skcipher_walk_next()
369 gfp_t gfp = skcipher_walk_gfp(walk); in skcipher_walk_next()
371 walk->page = (void *)__get_free_page(gfp); in skcipher_walk_next()
372 if (!walk->page) in skcipher_walk_next()
376 walk->nbytes = min_t(unsigned, n, in skcipher_walk_next()
377 PAGE_SIZE - offset_in_page(walk->page)); in skcipher_walk_next()
378 walk->flags |= SKCIPHER_WALK_COPY; in skcipher_walk_next()
379 err = skcipher_next_copy(walk); in skcipher_walk_next()
383 walk->nbytes = n; in skcipher_walk_next()
385 return skcipher_next_fast(walk); in skcipher_walk_next()
388 if (!err && (walk->flags & SKCIPHER_WALK_PHYS)) { in skcipher_walk_next()
389 walk->src.phys.page = virt_to_page(walk->src.virt.addr); in skcipher_walk_next()
390 walk->dst.phys.page = virt_to_page(walk->dst.virt.addr); in skcipher_walk_next()
391 walk->src.phys.offset &= PAGE_SIZE - 1; in skcipher_walk_next()
392 walk->dst.phys.offset &= PAGE_SIZE - 1; in skcipher_walk_next()
397 static int skcipher_copy_iv(struct skcipher_walk *walk) in skcipher_copy_iv() argument
400 unsigned alignmask = walk->alignmask; in skcipher_copy_iv()
401 unsigned ivsize = walk->ivsize; in skcipher_copy_iv()
402 unsigned bs = walk->stride; in skcipher_copy_iv()
412 if (walk->flags & SKCIPHER_WALK_PHYS) in skcipher_copy_iv()
421 walk->buffer = kmalloc(size, skcipher_walk_gfp(walk)); in skcipher_copy_iv()
422 if (!walk->buffer) in skcipher_copy_iv()
425 iv = PTR_ALIGN(walk->buffer, alignmask + 1); in skcipher_copy_iv()
428 walk->iv = memcpy(iv, walk->iv, walk->ivsize); in skcipher_copy_iv()
432 static int skcipher_walk_first(struct skcipher_walk *walk) in skcipher_walk_first() argument
437 walk->buffer = NULL; in skcipher_walk_first()
438 if (unlikely(((unsigned long)walk->iv & walk->alignmask))) { in skcipher_walk_first()
439 int err = skcipher_copy_iv(walk); in skcipher_walk_first()
444 walk->page = NULL; in skcipher_walk_first()
446 return skcipher_walk_next(walk); in skcipher_walk_first()
449 static int skcipher_walk_skcipher(struct skcipher_walk *walk, in skcipher_walk_skcipher() argument
454 walk->total = req->cryptlen; in skcipher_walk_skcipher()
455 walk->nbytes = 0; in skcipher_walk_skcipher()
456 walk->iv = req->iv; in skcipher_walk_skcipher()
457 walk->oiv = req->iv; in skcipher_walk_skcipher()
459 if (unlikely(!walk->total)) in skcipher_walk_skcipher()
462 scatterwalk_start(&walk->in, req->src); in skcipher_walk_skcipher()
463 scatterwalk_start(&walk->out, req->dst); in skcipher_walk_skcipher()
465 walk->flags &= ~SKCIPHER_WALK_SLEEP; in skcipher_walk_skcipher()
466 walk->flags |= req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? in skcipher_walk_skcipher()
469 walk->blocksize = crypto_skcipher_blocksize(tfm); in skcipher_walk_skcipher()
470 walk->stride = crypto_skcipher_walksize(tfm); in skcipher_walk_skcipher()
471 walk->ivsize = crypto_skcipher_ivsize(tfm); in skcipher_walk_skcipher()
472 walk->alignmask = crypto_skcipher_alignmask(tfm); in skcipher_walk_skcipher()
474 return skcipher_walk_first(walk); in skcipher_walk_skcipher()
477 int skcipher_walk_virt(struct skcipher_walk *walk, in skcipher_walk_virt() argument
484 walk->flags &= ~SKCIPHER_WALK_PHYS; in skcipher_walk_virt()
486 err = skcipher_walk_skcipher(walk, req); in skcipher_walk_virt()
488 walk->flags &= atomic ? ~SKCIPHER_WALK_SLEEP : ~0; in skcipher_walk_virt()
494 int skcipher_walk_async(struct skcipher_walk *walk, in skcipher_walk_async() argument
497 walk->flags |= SKCIPHER_WALK_PHYS; in skcipher_walk_async()
499 INIT_LIST_HEAD(&walk->buffers); in skcipher_walk_async()
501 return skcipher_walk_skcipher(walk, req); in skcipher_walk_async()
505 static int skcipher_walk_aead_common(struct skcipher_walk *walk, in skcipher_walk_aead_common() argument
511 walk->nbytes = 0; in skcipher_walk_aead_common()
512 walk->iv = req->iv; in skcipher_walk_aead_common()
513 walk->oiv = req->iv; in skcipher_walk_aead_common()
515 if (unlikely(!walk->total)) in skcipher_walk_aead_common()
518 walk->flags &= ~SKCIPHER_WALK_PHYS; in skcipher_walk_aead_common()
520 scatterwalk_start(&walk->in, req->src); in skcipher_walk_aead_common()
521 scatterwalk_start(&walk->out, req->dst); in skcipher_walk_aead_common()
523 scatterwalk_copychunks(NULL, &walk->in, req->assoclen, 2); in skcipher_walk_aead_common()
524 scatterwalk_copychunks(NULL, &walk->out, req->assoclen, 2); in skcipher_walk_aead_common()
526 scatterwalk_done(&walk->in, 0, walk->total); in skcipher_walk_aead_common()
527 scatterwalk_done(&walk->out, 0, walk->total); in skcipher_walk_aead_common()
530 walk->flags |= SKCIPHER_WALK_SLEEP; in skcipher_walk_aead_common()
532 walk->flags &= ~SKCIPHER_WALK_SLEEP; in skcipher_walk_aead_common()
534 walk->blocksize = crypto_aead_blocksize(tfm); in skcipher_walk_aead_common()
535 walk->stride = crypto_aead_chunksize(tfm); in skcipher_walk_aead_common()
536 walk->ivsize = crypto_aead_ivsize(tfm); in skcipher_walk_aead_common()
537 walk->alignmask = crypto_aead_alignmask(tfm); in skcipher_walk_aead_common()
539 err = skcipher_walk_first(walk); in skcipher_walk_aead_common()
542 walk->flags &= ~SKCIPHER_WALK_SLEEP; in skcipher_walk_aead_common()
547 int skcipher_walk_aead_encrypt(struct skcipher_walk *walk, in skcipher_walk_aead_encrypt() argument
550 walk->total = req->cryptlen; in skcipher_walk_aead_encrypt()
552 return skcipher_walk_aead_common(walk, req, atomic); in skcipher_walk_aead_encrypt()
556 int skcipher_walk_aead_decrypt(struct skcipher_walk *walk, in skcipher_walk_aead_decrypt() argument
561 walk->total = req->cryptlen - crypto_aead_authsize(tfm); in skcipher_walk_aead_decrypt()
563 return skcipher_walk_aead_common(walk, req, atomic); in skcipher_walk_aead_decrypt()