Branch data Line data Source code
1 : : /*
2 : : * Cryptographic scatter and gather helpers.
3 : : *
4 : : * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 : : * Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
6 : : * Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
7 : : * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
8 : : *
9 : : * This program is free software; you can redistribute it and/or modify it
10 : : * under the terms of the GNU General Public License as published by the Free
11 : : * Software Foundation; either version 2 of the License, or (at your option)
12 : : * any later version.
13 : : *
14 : : */
15 : :
16 : : #ifndef _CRYPTO_SCATTERWALK_H
17 : : #define _CRYPTO_SCATTERWALK_H
18 : :
19 : : #include <asm/kmap_types.h>
20 : : #include <crypto/algapi.h>
21 : : #include <linux/hardirq.h>
22 : : #include <linux/highmem.h>
23 : : #include <linux/kernel.h>
24 : : #include <linux/mm.h>
25 : : #include <linux/scatterlist.h>
26 : : #include <linux/sched.h>
27 : :
28 : : static inline void crypto_yield(u32 flags)
29 : : {
30 [ # # ][ # # ]: 0 : if (flags & CRYPTO_TFM_REQ_MAY_SLEEP)
[ # # ]
31 : 0 : cond_resched();
32 : : }
33 : :
34 : : static inline void scatterwalk_sg_chain(struct scatterlist *sg1, int num,
35 : : struct scatterlist *sg2)
36 : : {
37 : : sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0);
38 : 0 : sg1[num - 1].page_link &= ~0x02;
39 : 0 : sg1[num - 1].page_link |= 0x01;
40 : : }
41 : :
42 : : static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
43 : : {
44 [ # # ][ # # ]: 0 : if (sg_is_last(sg))
[ # # ]
45 : : return NULL;
46 : :
47 [ # # ][ # # ]: 0 : return (++sg)->length ? sg : sg_chain_ptr(sg);
[ # # ]
48 : : }
49 : :
50 : : static inline void scatterwalk_crypto_chain(struct scatterlist *head,
51 : : struct scatterlist *sg,
52 : : int chain, int num)
53 : : {
54 [ # # ][ # # ]: 0 : if (chain) {
55 : 0 : head->length += sg->length;
56 : : sg = scatterwalk_sg_next(sg);
57 : : }
58 : :
59 [ # # ][ # # ]: 0 : if (sg)
60 : : scatterwalk_sg_chain(head, num, sg);
61 : : else
62 : : sg_mark_end(head);
63 : : }
64 : :
65 : : static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
66 : : struct scatter_walk *walk_out)
67 : : {
68 : : return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
69 : : (int)(walk_in->offset - walk_out->offset));
70 : : }
71 : :
72 : : static inline unsigned int scatterwalk_pagelen(struct scatter_walk *walk)
73 : : {
74 : 0 : unsigned int len = walk->sg->offset + walk->sg->length - walk->offset;
75 : 0 : unsigned int len_this_page = offset_in_page(~walk->offset) + 1;
76 : 0 : return len_this_page > len ? len : len_this_page;
77 : : }
78 : :
79 : : static inline unsigned int scatterwalk_clamp(struct scatter_walk *walk,
80 : : unsigned int nbytes)
81 : : {
82 : : unsigned int len_this_page = scatterwalk_pagelen(walk);
83 : 0 : return nbytes > len_this_page ? len_this_page : nbytes;
84 : : }
85 : :
86 : : static inline void scatterwalk_advance(struct scatter_walk *walk,
87 : : unsigned int nbytes)
88 : : {
89 : 0 : walk->offset += nbytes;
90 : : }
91 : :
92 : : static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
93 : : unsigned int alignmask)
94 : : {
95 : 0 : return !(walk->offset & alignmask);
96 : : }
97 : :
98 : : static inline struct page *scatterwalk_page(struct scatter_walk *walk)
99 : : {
100 : 0 : return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
101 : : }
102 : :
103 : : static inline void scatterwalk_unmap(void *vaddr)
104 : : {
105 : 0 : kunmap_atomic(vaddr);
106 : : }
107 : :
108 : : void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
109 : : void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
110 : : size_t nbytes, int out);
111 : : void *scatterwalk_map(struct scatter_walk *walk);
112 : : void scatterwalk_done(struct scatter_walk *walk, int out, int more);
113 : :
114 : : void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
115 : : unsigned int start, unsigned int nbytes, int out);
116 : :
117 : : int scatterwalk_bytes_sglen(struct scatterlist *sg, int num_bytes);
118 : :
119 : : #endif /* _CRYPTO_SCATTERWALK_H */
|