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 <linux/string.h>
36 #include <net/sock.h>
37
38 static const struct af_alg_allowlist_entry skcipher_allowlist[] = {
39 { "adiantum(xchacha12,aes)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
40 { "adiantum(xchacha20,aes)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
41 { "cbc(aes)" }, /* iwd */
42 { "cbc(des)" }, /* iwd */
43 { "cbc(des3_ede)" }, /* iwd */
44 { "cbc(paes)" }, /* caam and others */
45 { "ctr(aes)" }, /* iwd */
46 { "ecb(aes)" }, /* iwd, bluez */
47 { "ecb(des)" }, /* iwd */
48 { "hctr2(aes)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
49 { "xts(aes)", AF_ALG_UNPRIVILEGED }, /* cryptsetup benchmark */
50 { "xts(camellia)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
51 { "xts(serpent)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
52 { "xts(twofish)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
53 {},
54 };
55
skcipher_sendmsg(struct socket * sock,struct msghdr * msg,size_t size)56 static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
57 size_t size)
58 {
59 struct sock *sk = sock->sk;
60 struct alg_sock *ask = alg_sk(sk);
61 struct sock *psk = ask->parent;
62 struct alg_sock *pask = alg_sk(psk);
63 struct crypto_skcipher *tfm = pask->private;
64 unsigned ivsize = crypto_skcipher_ivsize(tfm);
65
66 return af_alg_sendmsg(sock, msg, size, ivsize);
67 }
68
algif_skcipher_export(struct sock * sk,struct skcipher_request * req)69 static int algif_skcipher_export(struct sock *sk, struct skcipher_request *req)
70 {
71 struct alg_sock *ask = alg_sk(sk);
72 struct crypto_skcipher *tfm;
73 struct af_alg_ctx *ctx;
74 struct alg_sock *pask;
75 unsigned statesize;
76 struct sock *psk;
77 int err;
78
79 if (!(req->base.flags & CRYPTO_SKCIPHER_REQ_NOTFINAL))
80 return 0;
81
82 ctx = ask->private;
83 psk = ask->parent;
84 pask = alg_sk(psk);
85 tfm = pask->private;
86
87 statesize = crypto_skcipher_statesize(tfm);
88 ctx->state = sock_kmalloc(sk, statesize, GFP_ATOMIC);
89 if (!ctx->state)
90 return -ENOMEM;
91
92 err = crypto_skcipher_export(req, ctx->state);
93 if (err) {
94 sock_kzfree_s(sk, ctx->state, statesize);
95 ctx->state = NULL;
96 }
97
98 return err;
99 }
100
_skcipher_recvmsg(struct socket * sock,struct msghdr * msg,size_t ignored,int flags)101 static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
102 size_t ignored, int flags)
103 {
104 struct sock *sk = sock->sk;
105 struct alg_sock *ask = alg_sk(sk);
106 struct sock *psk = ask->parent;
107 struct alg_sock *pask = alg_sk(psk);
108 struct af_alg_ctx *ctx = ask->private;
109 struct crypto_skcipher *tfm = pask->private;
110 unsigned int bs = crypto_skcipher_chunksize(tfm);
111 struct af_alg_async_req *areq;
112 unsigned cflags = 0;
113 int err = 0;
114 size_t len = 0;
115
116 if (!ctx->init || (ctx->more && ctx->used < bs)) {
117 err = af_alg_wait_for_data(sk, flags, bs);
118 if (err)
119 return err;
120 }
121
122 /* Allocate cipher request for current operation. */
123 areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
124 crypto_skcipher_reqsize(tfm));
125 if (IS_ERR(areq))
126 return PTR_ERR(areq);
127
128 /* convert iovecs of output buffers into RX SGL */
129 err = af_alg_get_rsgl(sk, msg, flags, areq, ctx->used, &len);
130 if (err)
131 goto free;
132
133 /*
134 * If more buffers are to be expected to be processed, process only
135 * full block size buffers.
136 */
137 if (ctx->more || len < ctx->used) {
138 if (len < bs) {
139 err = -EINVAL;
140 goto free;
141 }
142
143 len -= len % bs;
144 cflags |= CRYPTO_SKCIPHER_REQ_NOTFINAL;
145 }
146
147 /*
148 * Create a per request TX SGL for this request which tracks the
149 * SG entries from the global TX SGL.
150 */
151 areq->tsgl_entries = af_alg_count_tsgl(sk, len);
152 if (!areq->tsgl_entries)
153 areq->tsgl_entries = 1;
154 areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
155 areq->tsgl_entries),
156 GFP_KERNEL);
157 if (!areq->tsgl) {
158 err = -ENOMEM;
159 goto free;
160 }
161 sg_init_table(areq->tsgl, areq->tsgl_entries);
162 af_alg_pull_tsgl(sk, len, areq->tsgl);
163
164 /* Initialize the crypto operation */
165 skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm);
166 skcipher_request_set_crypt(&areq->cra_u.skcipher_req, areq->tsgl,
167 areq->first_rsgl.sgl.sgt.sgl, len, ctx->iv);
168
169 if (ctx->state) {
170 err = crypto_skcipher_import(&areq->cra_u.skcipher_req,
171 ctx->state);
172 sock_kzfree_s(sk, ctx->state, crypto_skcipher_statesize(tfm));
173 ctx->state = NULL;
174 if (err)
175 goto free;
176 cflags |= CRYPTO_SKCIPHER_REQ_CONT;
177 }
178
179 skcipher_request_set_callback(&areq->cra_u.skcipher_req,
180 cflags |
181 CRYPTO_TFM_REQ_MAY_SLEEP |
182 CRYPTO_TFM_REQ_MAY_BACKLOG,
183 crypto_req_done, &ctx->wait);
184 err = crypto_wait_req(ctx->enc ?
185 crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
186 crypto_skcipher_decrypt(&areq->cra_u.skcipher_req),
187 &ctx->wait);
188
189 if (!err)
190 err = algif_skcipher_export(
191 sk, &areq->cra_u.skcipher_req);
192
193 free:
194 af_alg_free_resources(areq);
195
196 return err ? err : len;
197 }
198
skcipher_recvmsg(struct socket * sock,struct msghdr * msg,size_t ignored,int flags)199 static int skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
200 size_t ignored, int flags)
201 {
202 struct sock *sk = sock->sk;
203 int ret = 0;
204
205 lock_sock(sk);
206 while (msg_data_left(msg)) {
207 int err = _skcipher_recvmsg(sock, msg, ignored, flags);
208
209 /*
210 * This error covers -EIOCBQUEUED which implies that we can
211 * only handle one AIO request. If the caller wants to have
212 * multiple AIO requests in parallel, he must make multiple
213 * separate AIO calls.
214 *
215 * Also return the error if no data has been processed so far.
216 */
217 if (err <= 0) {
218 if (err == -EIOCBQUEUED || !ret)
219 ret = err;
220 goto out;
221 }
222
223 ret += err;
224 }
225
226 out:
227 af_alg_wmem_wakeup(sk);
228 release_sock(sk);
229 return ret;
230 }
231
232 static struct proto_ops algif_skcipher_ops = {
233 .family = PF_ALG,
234
235 .connect = sock_no_connect,
236 .socketpair = sock_no_socketpair,
237 .getname = sock_no_getname,
238 .ioctl = sock_no_ioctl,
239 .listen = sock_no_listen,
240 .shutdown = sock_no_shutdown,
241 .mmap = sock_no_mmap,
242 .bind = sock_no_bind,
243 .accept = sock_no_accept,
244
245 .release = af_alg_release,
246 .sendmsg = skcipher_sendmsg,
247 .recvmsg = skcipher_recvmsg,
248 .poll = af_alg_poll,
249 };
250
skcipher_check_key(struct socket * sock)251 static int skcipher_check_key(struct socket *sock)
252 {
253 int err = 0;
254 struct sock *psk;
255 struct alg_sock *pask;
256 struct crypto_skcipher *tfm;
257 struct sock *sk = sock->sk;
258 struct alg_sock *ask = alg_sk(sk);
259
260 lock_sock(sk);
261 if (!atomic_read(&ask->nokey_refcnt))
262 goto unlock_child;
263
264 psk = ask->parent;
265 pask = alg_sk(ask->parent);
266 tfm = pask->private;
267
268 err = -ENOKEY;
269 lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
270 if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
271 goto unlock;
272
273 atomic_dec(&pask->nokey_refcnt);
274 atomic_set(&ask->nokey_refcnt, 0);
275
276 err = 0;
277
278 unlock:
279 release_sock(psk);
280 unlock_child:
281 release_sock(sk);
282
283 return err;
284 }
285
skcipher_sendmsg_nokey(struct socket * sock,struct msghdr * msg,size_t size)286 static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
287 size_t size)
288 {
289 int err;
290
291 err = skcipher_check_key(sock);
292 if (err)
293 return err;
294
295 return skcipher_sendmsg(sock, msg, size);
296 }
297
skcipher_recvmsg_nokey(struct socket * sock,struct msghdr * msg,size_t ignored,int flags)298 static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
299 size_t ignored, int flags)
300 {
301 int err;
302
303 err = skcipher_check_key(sock);
304 if (err)
305 return err;
306
307 return skcipher_recvmsg(sock, msg, ignored, flags);
308 }
309
310 static struct proto_ops algif_skcipher_ops_nokey = {
311 .family = PF_ALG,
312
313 .connect = sock_no_connect,
314 .socketpair = sock_no_socketpair,
315 .getname = sock_no_getname,
316 .ioctl = sock_no_ioctl,
317 .listen = sock_no_listen,
318 .shutdown = sock_no_shutdown,
319 .mmap = sock_no_mmap,
320 .bind = sock_no_bind,
321 .accept = sock_no_accept,
322
323 .release = af_alg_release,
324 .sendmsg = skcipher_sendmsg_nokey,
325 .recvmsg = skcipher_recvmsg_nokey,
326 .poll = af_alg_poll,
327 };
328
skcipher_bind(const char * name)329 static void *skcipher_bind(const char *name)
330 {
331 u32 mask = AF_ALG_CRYPTOAPI_MASK;
332 int err;
333
334 err = af_alg_check_restriction(name, skcipher_allowlist);
335 if (err)
336 return ERR_PTR(err);
337
338 if (strcmp(name, "cbc(paes)") == 0)
339 mask = 0;
340
341 return crypto_alloc_skcipher(name, 0, mask);
342 }
343
skcipher_release(void * private)344 static void skcipher_release(void *private)
345 {
346 crypto_free_skcipher(private);
347 }
348
skcipher_setkey(void * private,const u8 * key,unsigned int keylen)349 static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
350 {
351 return crypto_skcipher_setkey(private, key, keylen);
352 }
353
skcipher_sock_destruct(struct sock * sk)354 static void skcipher_sock_destruct(struct sock *sk)
355 {
356 struct alg_sock *ask = alg_sk(sk);
357 struct af_alg_ctx *ctx = ask->private;
358 struct sock *psk = ask->parent;
359 struct alg_sock *pask = alg_sk(psk);
360 struct crypto_skcipher *tfm = pask->private;
361
362 af_alg_pull_tsgl(sk, ctx->used, NULL);
363 sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
364 if (ctx->state)
365 sock_kzfree_s(sk, ctx->state, crypto_skcipher_statesize(tfm));
366 sock_kfree_s(sk, ctx, ctx->len);
367 af_alg_release_parent(sk);
368 }
369
skcipher_accept_parent_nokey(void * private,struct sock * sk)370 static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
371 {
372 struct af_alg_ctx *ctx;
373 struct alg_sock *ask = alg_sk(sk);
374 struct crypto_skcipher *tfm = private;
375 unsigned int len = sizeof(*ctx);
376
377 ctx = sock_kmalloc(sk, len, GFP_KERNEL);
378 if (!ctx)
379 return -ENOMEM;
380 memset(ctx, 0, len);
381
382 ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(tfm),
383 GFP_KERNEL);
384 if (!ctx->iv) {
385 sock_kfree_s(sk, ctx, len);
386 return -ENOMEM;
387 }
388 memset(ctx->iv, 0, crypto_skcipher_ivsize(tfm));
389
390 INIT_LIST_HEAD(&ctx->tsgl_list);
391 ctx->len = len;
392 crypto_init_wait(&ctx->wait);
393
394 ask->private = ctx;
395
396 sk->sk_destruct = skcipher_sock_destruct;
397
398 return 0;
399 }
400
skcipher_accept_parent(void * private,struct sock * sk)401 static int skcipher_accept_parent(void *private, struct sock *sk)
402 {
403 struct crypto_skcipher *tfm = private;
404
405 if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
406 return -ENOKEY;
407
408 return skcipher_accept_parent_nokey(private, sk);
409 }
410
411 static const struct af_alg_type algif_type_skcipher = {
412 .bind = skcipher_bind,
413 .release = skcipher_release,
414 .setkey = skcipher_setkey,
415 .accept = skcipher_accept_parent,
416 .accept_nokey = skcipher_accept_parent_nokey,
417 .ops = &algif_skcipher_ops,
418 .ops_nokey = &algif_skcipher_ops_nokey,
419 .name = "skcipher",
420 .owner = THIS_MODULE
421 };
422
algif_skcipher_init(void)423 static int __init algif_skcipher_init(void)
424 {
425 return af_alg_register_type(&algif_type_skcipher);
426 }
427
algif_skcipher_exit(void)428 static void __exit algif_skcipher_exit(void)
429 {
430 int err = af_alg_unregister_type(&algif_type_skcipher);
431 BUG_ON(err);
432 }
433
434 module_init(algif_skcipher_init);
435 module_exit(algif_skcipher_exit);
436 MODULE_DESCRIPTION("Userspace interface for skcipher algorithms");
437 MODULE_LICENSE("GPL");
438