1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef _CRYPTO_IF_ALG_H
14#define _CRYPTO_IF_ALG_H
15
16#include <linux/compiler.h>
17#include <linux/completion.h>
18#include <linux/if_alg.h>
19#include <linux/scatterlist.h>
20#include <linux/types.h>
21#include <linux/atomic.h>
22#include <net/sock.h>
23
24#include <crypto/aead.h>
25#include <crypto/skcipher.h>
26
27#define ALG_MAX_PAGES 16
28
29struct crypto_async_request;
30
31struct alg_sock {
32
33 struct sock sk;
34
35 struct sock *parent;
36
37 unsigned int refcnt;
38 unsigned int nokey_refcnt;
39
40 const struct af_alg_type *type;
41 void *private;
42};
43
44struct af_alg_control {
45 struct af_alg_iv *iv;
46 int op;
47 unsigned int aead_assoclen;
48};
49
50struct af_alg_type {
51 void *(*bind)(const char *name, u32 type, u32 mask);
52 void (*release)(void *private);
53 int (*setkey)(void *private, const u8 *key, unsigned int keylen);
54 int (*accept)(void *private, struct sock *sk);
55 int (*accept_nokey)(void *private, struct sock *sk);
56 int (*setauthsize)(void *private, unsigned int authsize);
57
58 struct proto_ops *ops;
59 struct proto_ops *ops_nokey;
60 struct module *owner;
61 char name[14];
62};
63
64struct af_alg_sgl {
65 struct scatterlist sg[ALG_MAX_PAGES + 1];
66 struct page *pages[ALG_MAX_PAGES];
67 unsigned int npages;
68};
69
70
71struct af_alg_tsgl {
72 struct list_head list;
73 unsigned int cur;
74 struct scatterlist sg[0];
75};
76
77#define MAX_SGL_ENTS ((4096 - sizeof(struct af_alg_tsgl)) / \
78 sizeof(struct scatterlist) - 1)
79
80
81struct af_alg_rsgl {
82 struct af_alg_sgl sgl;
83 struct list_head list;
84 size_t sg_num_bytes;
85};
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100struct af_alg_async_req {
101 struct kiocb *iocb;
102 struct sock *sk;
103
104 struct af_alg_rsgl first_rsgl;
105 struct af_alg_rsgl *last_rsgl;
106 struct list_head rsgl_list;
107
108 struct scatterlist *tsgl;
109 unsigned int tsgl_entries;
110
111 unsigned int outlen;
112 unsigned int areqlen;
113
114 union {
115 struct aead_request aead_req;
116 struct skcipher_request skcipher_req;
117 } cra_u;
118
119
120};
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145struct af_alg_ctx {
146 struct list_head tsgl_list;
147
148 void *iv;
149 size_t aead_assoclen;
150
151 struct crypto_wait wait;
152
153 size_t used;
154 atomic_t rcvused;
155
156 bool more;
157 bool merge;
158 bool enc;
159
160 unsigned int len;
161};
162
163int af_alg_register_type(const struct af_alg_type *type);
164int af_alg_unregister_type(const struct af_alg_type *type);
165
166int af_alg_release(struct socket *sock);
167void af_alg_release_parent(struct sock *sk);
168int af_alg_accept(struct sock *sk, struct socket *newsock, bool kern);
169
170int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len);
171void af_alg_free_sg(struct af_alg_sgl *sgl);
172void af_alg_link_sg(struct af_alg_sgl *sgl_prev, struct af_alg_sgl *sgl_new);
173
174int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con);
175
176static inline struct alg_sock *alg_sk(struct sock *sk)
177{
178 return (struct alg_sock *)sk;
179}
180
181
182
183
184
185
186
187static inline int af_alg_sndbuf(struct sock *sk)
188{
189 struct alg_sock *ask = alg_sk(sk);
190 struct af_alg_ctx *ctx = ask->private;
191
192 return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) -
193 ctx->used, 0);
194}
195
196
197
198
199
200
201
202static inline bool af_alg_writable(struct sock *sk)
203{
204 return PAGE_SIZE <= af_alg_sndbuf(sk);
205}
206
207
208
209
210
211
212
213static inline int af_alg_rcvbuf(struct sock *sk)
214{
215 struct alg_sock *ask = alg_sk(sk);
216 struct af_alg_ctx *ctx = ask->private;
217
218 return max_t(int, max_t(int, sk->sk_rcvbuf & PAGE_MASK, PAGE_SIZE) -
219 atomic_read(&ctx->rcvused), 0);
220}
221
222
223
224
225
226
227
228static inline bool af_alg_readable(struct sock *sk)
229{
230 return PAGE_SIZE <= af_alg_rcvbuf(sk);
231}
232
233int af_alg_alloc_tsgl(struct sock *sk);
234unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset);
235void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
236 size_t dst_offset);
237void af_alg_free_areq_sgls(struct af_alg_async_req *areq);
238int af_alg_wait_for_wmem(struct sock *sk, unsigned int flags);
239void af_alg_wmem_wakeup(struct sock *sk);
240int af_alg_wait_for_data(struct sock *sk, unsigned flags);
241void af_alg_data_wakeup(struct sock *sk);
242int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
243 unsigned int ivsize);
244ssize_t af_alg_sendpage(struct socket *sock, struct page *page,
245 int offset, size_t size, int flags);
246void af_alg_free_resources(struct af_alg_async_req *areq);
247void af_alg_async_cb(struct crypto_async_request *_req, int err);
248__poll_t af_alg_poll(struct file *file, struct socket *sock,
249 poll_table *wait);
250struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk,
251 unsigned int areqlen);
252int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
253 struct af_alg_async_req *areq, size_t maxsize,
254 size_t *outlen);
255
256#endif
257