1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * algif_skcipher: User-space interface for skcipher algorithms |
4 | * |
5 | * This file provides the user-space API for symmetric key ciphers. |
6 | * |
7 | * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> |
8 | * |
9 | * The following concept of the memory management is used: |
10 | * |
11 | * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is |
12 | * filled by user space with the data submitted via sendmsg. Filling up the TX |
13 | * SGL does not cause a crypto operation -- the data will only be tracked by |
14 | * the kernel. Upon receipt of one recvmsg call, the caller must provide a |
15 | * buffer which is tracked with the RX SGL. |
16 | * |
17 | * During the processing of the recvmsg operation, the cipher request is |
18 | * allocated and prepared. As part of the recvmsg operation, the processed |
19 | * TX buffers are extracted from the TX SGL into a separate SGL. |
20 | * |
21 | * After the completion of the crypto operation, the RX SGL and the cipher |
22 | * request is released. The extracted TX SGL parts are released together with |
23 | * the RX SGL release. |
24 | */ |
25 | |
26 | #include <crypto/scatterwalk.h> |
27 | #include <crypto/skcipher.h> |
28 | #include <crypto/if_alg.h> |
29 | #include <linux/init.h> |
30 | #include <linux/list.h> |
31 | #include <linux/kernel.h> |
32 | #include <linux/mm.h> |
33 | #include <linux/module.h> |
34 | #include <linux/net.h> |
35 | #include <net/sock.h> |
36 | |
37 | static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg, |
38 | size_t size) |
39 | { |
40 | struct sock *sk = sock->sk; |
41 | struct alg_sock *ask = alg_sk(sk); |
42 | struct sock *psk = ask->parent; |
43 | struct alg_sock *pask = alg_sk(sk: psk); |
44 | struct crypto_skcipher *tfm = pask->private; |
45 | unsigned ivsize = crypto_skcipher_ivsize(tfm); |
46 | |
47 | return af_alg_sendmsg(sock, msg, size, ivsize); |
48 | } |
49 | |
50 | static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, |
51 | size_t ignored, int flags) |
52 | { |
53 | struct sock *sk = sock->sk; |
54 | struct alg_sock *ask = alg_sk(sk); |
55 | struct sock *psk = ask->parent; |
56 | struct alg_sock *pask = alg_sk(sk: psk); |
57 | struct af_alg_ctx *ctx = ask->private; |
58 | struct crypto_skcipher *tfm = pask->private; |
59 | unsigned int bs = crypto_skcipher_chunksize(tfm); |
60 | struct af_alg_async_req *areq; |
61 | int err = 0; |
62 | size_t len = 0; |
63 | |
64 | if (!ctx->init || (ctx->more && ctx->used < bs)) { |
65 | err = af_alg_wait_for_data(sk, flags, min: bs); |
66 | if (err) |
67 | return err; |
68 | } |
69 | |
70 | /* Allocate cipher request for current operation. */ |
71 | areq = af_alg_alloc_areq(sk, areqlen: sizeof(struct af_alg_async_req) + |
72 | crypto_skcipher_reqsize(tfm)); |
73 | if (IS_ERR(ptr: areq)) |
74 | return PTR_ERR(ptr: areq); |
75 | |
76 | /* convert iovecs of output buffers into RX SGL */ |
77 | err = af_alg_get_rsgl(sk, msg, flags, areq, maxsize: ctx->used, outlen: &len); |
78 | if (err) |
79 | goto free; |
80 | |
81 | /* |
82 | * If more buffers are to be expected to be processed, process only |
83 | * full block size buffers. |
84 | */ |
85 | if (ctx->more || len < ctx->used) |
86 | len -= len % bs; |
87 | |
88 | /* |
89 | * Create a per request TX SGL for this request which tracks the |
90 | * SG entries from the global TX SGL. |
91 | */ |
92 | areq->tsgl_entries = af_alg_count_tsgl(sk, bytes: len, offset: 0); |
93 | if (!areq->tsgl_entries) |
94 | areq->tsgl_entries = 1; |
95 | areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl), |
96 | areq->tsgl_entries), |
97 | GFP_KERNEL); |
98 | if (!areq->tsgl) { |
99 | err = -ENOMEM; |
100 | goto free; |
101 | } |
102 | sg_init_table(areq->tsgl, areq->tsgl_entries); |
103 | af_alg_pull_tsgl(sk, used: len, dst: areq->tsgl, dst_offset: 0); |
104 | |
105 | /* Initialize the crypto operation */ |
106 | skcipher_request_set_tfm(req: &areq->cra_u.skcipher_req, tfm); |
107 | skcipher_request_set_crypt(req: &areq->cra_u.skcipher_req, src: areq->tsgl, |
108 | dst: areq->first_rsgl.sgl.sgt.sgl, cryptlen: len, iv: ctx->iv); |
109 | |
110 | if (msg->msg_iocb && !is_sync_kiocb(kiocb: msg->msg_iocb)) { |
111 | /* AIO operation */ |
112 | sock_hold(sk); |
113 | areq->iocb = msg->msg_iocb; |
114 | |
115 | /* Remember output size that will be generated. */ |
116 | areq->outlen = len; |
117 | |
118 | skcipher_request_set_callback(req: &areq->cra_u.skcipher_req, |
119 | CRYPTO_TFM_REQ_MAY_SLEEP, |
120 | compl: af_alg_async_cb, data: areq); |
121 | err = ctx->enc ? |
122 | crypto_skcipher_encrypt(req: &areq->cra_u.skcipher_req) : |
123 | crypto_skcipher_decrypt(req: &areq->cra_u.skcipher_req); |
124 | |
125 | /* AIO operation in progress */ |
126 | if (err == -EINPROGRESS) |
127 | return -EIOCBQUEUED; |
128 | |
129 | sock_put(sk); |
130 | } else { |
131 | /* Synchronous operation */ |
132 | skcipher_request_set_callback(req: &areq->cra_u.skcipher_req, |
133 | CRYPTO_TFM_REQ_MAY_SLEEP | |
134 | CRYPTO_TFM_REQ_MAY_BACKLOG, |
135 | compl: crypto_req_done, data: &ctx->wait); |
136 | err = crypto_wait_req(err: ctx->enc ? |
137 | crypto_skcipher_encrypt(req: &areq->cra_u.skcipher_req) : |
138 | crypto_skcipher_decrypt(req: &areq->cra_u.skcipher_req), |
139 | wait: &ctx->wait); |
140 | } |
141 | |
142 | |
143 | free: |
144 | af_alg_free_resources(areq); |
145 | |
146 | return err ? err : len; |
147 | } |
148 | |
149 | static int skcipher_recvmsg(struct socket *sock, struct msghdr *msg, |
150 | size_t ignored, int flags) |
151 | { |
152 | struct sock *sk = sock->sk; |
153 | int ret = 0; |
154 | |
155 | lock_sock(sk); |
156 | while (msg_data_left(msg)) { |
157 | int err = _skcipher_recvmsg(sock, msg, ignored, flags); |
158 | |
159 | /* |
160 | * This error covers -EIOCBQUEUED which implies that we can |
161 | * only handle one AIO request. If the caller wants to have |
162 | * multiple AIO requests in parallel, he must make multiple |
163 | * separate AIO calls. |
164 | * |
165 | * Also return the error if no data has been processed so far. |
166 | */ |
167 | if (err <= 0) { |
168 | if (err == -EIOCBQUEUED || !ret) |
169 | ret = err; |
170 | goto out; |
171 | } |
172 | |
173 | ret += err; |
174 | } |
175 | |
176 | out: |
177 | af_alg_wmem_wakeup(sk); |
178 | release_sock(sk); |
179 | return ret; |
180 | } |
181 | |
182 | static struct proto_ops algif_skcipher_ops = { |
183 | .family = PF_ALG, |
184 | |
185 | .connect = sock_no_connect, |
186 | .socketpair = sock_no_socketpair, |
187 | .getname = sock_no_getname, |
188 | .ioctl = sock_no_ioctl, |
189 | .listen = sock_no_listen, |
190 | .shutdown = sock_no_shutdown, |
191 | .mmap = sock_no_mmap, |
192 | .bind = sock_no_bind, |
193 | .accept = sock_no_accept, |
194 | |
195 | .release = af_alg_release, |
196 | .sendmsg = skcipher_sendmsg, |
197 | .recvmsg = skcipher_recvmsg, |
198 | .poll = af_alg_poll, |
199 | }; |
200 | |
201 | static int skcipher_check_key(struct socket *sock) |
202 | { |
203 | int err = 0; |
204 | struct sock *psk; |
205 | struct alg_sock *pask; |
206 | struct crypto_skcipher *tfm; |
207 | struct sock *sk = sock->sk; |
208 | struct alg_sock *ask = alg_sk(sk); |
209 | |
210 | lock_sock(sk); |
211 | if (!atomic_read(v: &ask->nokey_refcnt)) |
212 | goto unlock_child; |
213 | |
214 | psk = ask->parent; |
215 | pask = alg_sk(sk: ask->parent); |
216 | tfm = pask->private; |
217 | |
218 | err = -ENOKEY; |
219 | lock_sock_nested(sk: psk, SINGLE_DEPTH_NESTING); |
220 | if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) |
221 | goto unlock; |
222 | |
223 | atomic_dec(v: &pask->nokey_refcnt); |
224 | atomic_set(v: &ask->nokey_refcnt, i: 0); |
225 | |
226 | err = 0; |
227 | |
228 | unlock: |
229 | release_sock(sk: psk); |
230 | unlock_child: |
231 | release_sock(sk); |
232 | |
233 | return err; |
234 | } |
235 | |
236 | static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg, |
237 | size_t size) |
238 | { |
239 | int err; |
240 | |
241 | err = skcipher_check_key(sock); |
242 | if (err) |
243 | return err; |
244 | |
245 | return skcipher_sendmsg(sock, msg, size); |
246 | } |
247 | |
248 | static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg, |
249 | size_t ignored, int flags) |
250 | { |
251 | int err; |
252 | |
253 | err = skcipher_check_key(sock); |
254 | if (err) |
255 | return err; |
256 | |
257 | return skcipher_recvmsg(sock, msg, ignored, flags); |
258 | } |
259 | |
260 | static struct proto_ops algif_skcipher_ops_nokey = { |
261 | .family = PF_ALG, |
262 | |
263 | .connect = sock_no_connect, |
264 | .socketpair = sock_no_socketpair, |
265 | .getname = sock_no_getname, |
266 | .ioctl = sock_no_ioctl, |
267 | .listen = sock_no_listen, |
268 | .shutdown = sock_no_shutdown, |
269 | .mmap = sock_no_mmap, |
270 | .bind = sock_no_bind, |
271 | .accept = sock_no_accept, |
272 | |
273 | .release = af_alg_release, |
274 | .sendmsg = skcipher_sendmsg_nokey, |
275 | .recvmsg = skcipher_recvmsg_nokey, |
276 | .poll = af_alg_poll, |
277 | }; |
278 | |
279 | static void *skcipher_bind(const char *name, u32 type, u32 mask) |
280 | { |
281 | return crypto_alloc_skcipher(alg_name: name, type, mask); |
282 | } |
283 | |
284 | static void skcipher_release(void *private) |
285 | { |
286 | crypto_free_skcipher(tfm: private); |
287 | } |
288 | |
289 | static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) |
290 | { |
291 | return crypto_skcipher_setkey(tfm: private, key, keylen); |
292 | } |
293 | |
294 | static void skcipher_sock_destruct(struct sock *sk) |
295 | { |
296 | struct alg_sock *ask = alg_sk(sk); |
297 | struct af_alg_ctx *ctx = ask->private; |
298 | struct sock *psk = ask->parent; |
299 | struct alg_sock *pask = alg_sk(sk: psk); |
300 | struct crypto_skcipher *tfm = pask->private; |
301 | |
302 | af_alg_pull_tsgl(sk, used: ctx->used, NULL, dst_offset: 0); |
303 | sock_kzfree_s(sk, mem: ctx->iv, size: crypto_skcipher_ivsize(tfm)); |
304 | sock_kfree_s(sk, mem: ctx, size: ctx->len); |
305 | af_alg_release_parent(sk); |
306 | } |
307 | |
308 | static int skcipher_accept_parent_nokey(void *private, struct sock *sk) |
309 | { |
310 | struct af_alg_ctx *ctx; |
311 | struct alg_sock *ask = alg_sk(sk); |
312 | struct crypto_skcipher *tfm = private; |
313 | unsigned int len = sizeof(*ctx); |
314 | |
315 | ctx = sock_kmalloc(sk, size: len, GFP_KERNEL); |
316 | if (!ctx) |
317 | return -ENOMEM; |
318 | memset(ctx, 0, len); |
319 | |
320 | ctx->iv = sock_kmalloc(sk, size: crypto_skcipher_ivsize(tfm), |
321 | GFP_KERNEL); |
322 | if (!ctx->iv) { |
323 | sock_kfree_s(sk, mem: ctx, size: len); |
324 | return -ENOMEM; |
325 | } |
326 | memset(ctx->iv, 0, crypto_skcipher_ivsize(tfm)); |
327 | |
328 | INIT_LIST_HEAD(list: &ctx->tsgl_list); |
329 | ctx->len = len; |
330 | crypto_init_wait(wait: &ctx->wait); |
331 | |
332 | ask->private = ctx; |
333 | |
334 | sk->sk_destruct = skcipher_sock_destruct; |
335 | |
336 | return 0; |
337 | } |
338 | |
339 | static int skcipher_accept_parent(void *private, struct sock *sk) |
340 | { |
341 | struct crypto_skcipher *tfm = private; |
342 | |
343 | if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) |
344 | return -ENOKEY; |
345 | |
346 | return skcipher_accept_parent_nokey(private, sk); |
347 | } |
348 | |
349 | static const struct af_alg_type algif_type_skcipher = { |
350 | .bind = skcipher_bind, |
351 | .release = skcipher_release, |
352 | .setkey = skcipher_setkey, |
353 | .accept = skcipher_accept_parent, |
354 | .accept_nokey = skcipher_accept_parent_nokey, |
355 | .ops = &algif_skcipher_ops, |
356 | .ops_nokey = &algif_skcipher_ops_nokey, |
357 | .name = "skcipher" , |
358 | .owner = THIS_MODULE |
359 | }; |
360 | |
361 | static int __init algif_skcipher_init(void) |
362 | { |
363 | return af_alg_register_type(type: &algif_type_skcipher); |
364 | } |
365 | |
366 | static void __exit algif_skcipher_exit(void) |
367 | { |
368 | int err = af_alg_unregister_type(type: &algif_type_skcipher); |
369 | BUG_ON(err); |
370 | } |
371 | |
372 | module_init(algif_skcipher_init); |
373 | module_exit(algif_skcipher_exit); |
374 | MODULE_LICENSE("GPL" ); |
375 | |