Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/crypto/scatterwalk.c

  1 /*
  2  * Cryptographic API.
  3  *
  4  * Cipher operations.
  5  *
  6  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  7  *               2002 Adam J. Richter <adam@yggdrasil.com>
  8  *               2004 Jean-Luc Cooke <jlcooke@certainkey.com>
  9  *
 10  * This program is free software; you can redistribute it and/or modify it
 11  * under the terms of the GNU General Public License as published by the Free
 12  * Software Foundation; either version 2 of the License, or (at your option)
 13  * any later version.
 14  *
 15  */
 16 
 17 #include <crypto/scatterwalk.h>
 18 #include <linux/kernel.h>
 19 #include <linux/mm.h>
 20 #include <linux/module.h>
 21 #include <linux/scatterlist.h>
 22 
 23 static inline void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
 24 {
 25         void *src = out ? buf : sgdata;
 26         void *dst = out ? sgdata : buf;
 27 
 28         memcpy(dst, src, nbytes);
 29 }
 30 
 31 void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
 32                             size_t nbytes, int out)
 33 {
 34         for (;;) {
 35                 unsigned int len_this_page = scatterwalk_pagelen(walk);
 36                 u8 *vaddr;
 37 
 38                 if (len_this_page > nbytes)
 39                         len_this_page = nbytes;
 40 
 41                 if (out != 2) {
 42                         vaddr = scatterwalk_map(walk);
 43                         memcpy_dir(buf, vaddr, len_this_page, out);
 44                         scatterwalk_unmap(vaddr);
 45                 }
 46 
 47                 scatterwalk_advance(walk, len_this_page);
 48 
 49                 if (nbytes == len_this_page)
 50                         break;
 51 
 52                 buf += len_this_page;
 53                 nbytes -= len_this_page;
 54 
 55                 scatterwalk_pagedone(walk, out & 1, 1);
 56         }
 57 }
 58 EXPORT_SYMBOL_GPL(scatterwalk_copychunks);
 59 
 60 void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
 61                               unsigned int start, unsigned int nbytes, int out)
 62 {
 63         struct scatter_walk walk;
 64         struct scatterlist tmp[2];
 65 
 66         if (!nbytes)
 67                 return;
 68 
 69         sg = scatterwalk_ffwd(tmp, sg, start);
 70 
 71         scatterwalk_start(&walk, sg);
 72         scatterwalk_copychunks(buf, &walk, nbytes, out);
 73         scatterwalk_done(&walk, out, 0);
 74 }
 75 EXPORT_SYMBOL_GPL(scatterwalk_map_and_copy);
 76 
 77 struct scatterlist *scatterwalk_ffwd(struct scatterlist dst[2],
 78                                      struct scatterlist *src,
 79                                      unsigned int len)
 80 {
 81         for (;;) {
 82                 if (!len)
 83                         return src;
 84 
 85                 if (src->length > len)
 86                         break;
 87 
 88                 len -= src->length;
 89                 src = sg_next(src);
 90         }
 91 
 92         sg_init_table(dst, 2);
 93         sg_set_page(dst, sg_page(src), src->length - len, src->offset + len);
 94         scatterwalk_crypto_chain(dst, sg_next(src), 0, 2);
 95 
 96         return dst;
 97 }
 98 EXPORT_SYMBOL_GPL(scatterwalk_ffwd);
 99 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us