1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * algif_aead: User-space interface for AEAD algorithms
5 * Copyright (C) 2014, Stephan Mueller <smueller@chronox.de>
7 * This file provides the user-space API for AEAD ciphers.
9 * The following concept of the memory management is used:
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 (maybe with
13 * MSG_SPLICE_PAGES). Filling up the TX SGL does not cause a crypto operation
14 * -- the data will only be tracked by the kernel. Upon receipt of one recvmsg
15 * call, the caller must provide a buffer which is tracked with the RX SGL.
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.
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
26 #include <crypto/internal/aead.h>
27 #include <crypto/scatterwalk.h>
28 #include <crypto/if_alg.h>
29 #include <crypto/skcipher.h>
30 #include <crypto/null.h>
31 #include <linux/init.h>
32 #include <linux/list.h>
33 #include <linux/kernel.h>
35 #include <linux/module.h>
36 #include <linux/net.h>
40 struct crypto_aead
*aead
;
41 struct crypto_sync_skcipher
*null_tfm
;
44 static inline bool aead_sufficient_data(struct sock
*sk
)
46 struct alg_sock
*ask
= alg_sk(sk
);
47 struct sock
*psk
= ask
->parent
;
48 struct alg_sock
*pask
= alg_sk(psk
);
49 struct af_alg_ctx
*ctx
= ask
->private;
50 struct aead_tfm
*aeadc
= pask
->private;
51 struct crypto_aead
*tfm
= aeadc
->aead
;
52 unsigned int as
= crypto_aead_authsize(tfm
);
55 * The minimum amount of memory needed for an AEAD cipher is
56 * the AAD and in case of decryption the tag.
58 return ctx
->used
>= ctx
->aead_assoclen
+ (ctx
->enc
? 0 : as
);
61 static int aead_sendmsg(struct socket
*sock
, struct msghdr
*msg
, size_t size
)
63 struct sock
*sk
= sock
->sk
;
64 struct alg_sock
*ask
= alg_sk(sk
);
65 struct sock
*psk
= ask
->parent
;
66 struct alg_sock
*pask
= alg_sk(psk
);
67 struct aead_tfm
*aeadc
= pask
->private;
68 struct crypto_aead
*tfm
= aeadc
->aead
;
69 unsigned int ivsize
= crypto_aead_ivsize(tfm
);
71 return af_alg_sendmsg(sock
, msg
, size
, ivsize
);
74 static int crypto_aead_copy_sgl(struct crypto_sync_skcipher
*null_tfm
,
75 struct scatterlist
*src
,
76 struct scatterlist
*dst
, unsigned int len
)
78 SYNC_SKCIPHER_REQUEST_ON_STACK(skreq
, null_tfm
);
80 skcipher_request_set_sync_tfm(skreq
, null_tfm
);
81 skcipher_request_set_callback(skreq
, CRYPTO_TFM_REQ_MAY_SLEEP
,
83 skcipher_request_set_crypt(skreq
, src
, dst
, len
, NULL
);
85 return crypto_skcipher_encrypt(skreq
);
88 static int _aead_recvmsg(struct socket
*sock
, struct msghdr
*msg
,
89 size_t ignored
, int flags
)
91 struct sock
*sk
= sock
->sk
;
92 struct alg_sock
*ask
= alg_sk(sk
);
93 struct sock
*psk
= ask
->parent
;
94 struct alg_sock
*pask
= alg_sk(psk
);
95 struct af_alg_ctx
*ctx
= ask
->private;
96 struct aead_tfm
*aeadc
= pask
->private;
97 struct crypto_aead
*tfm
= aeadc
->aead
;
98 struct crypto_sync_skcipher
*null_tfm
= aeadc
->null_tfm
;
99 unsigned int i
, as
= crypto_aead_authsize(tfm
);
100 struct af_alg_async_req
*areq
;
101 struct af_alg_tsgl
*tsgl
, *tmp
;
102 struct scatterlist
*rsgl_src
, *tsgl_src
= NULL
;
104 size_t used
= 0; /* [in] TX bufs to be en/decrypted */
105 size_t outlen
= 0; /* [out] RX bufs produced by kernel */
106 size_t usedpages
= 0; /* [in] RX bufs to be used from user */
107 size_t processed
= 0; /* [in] TX bufs to be consumed */
109 if (!ctx
->init
|| ctx
->more
) {
110 err
= af_alg_wait_for_data(sk
, flags
, 0);
116 * Data length provided by caller via sendmsg that has not yet been
122 * Make sure sufficient data is present -- note, the same check is also
123 * present in sendmsg. The checks in sendmsg shall provide an
124 * information to the data sender that something is wrong, but they are
125 * irrelevant to maintain the kernel integrity. We need this check
126 * here too in case user space decides to not honor the error message
127 * in sendmsg and still call recvmsg. This check here protects the
130 if (!aead_sufficient_data(sk
))
134 * Calculate the minimum output buffer size holding the result of the
135 * cipher operation. When encrypting data, the receiving buffer is
136 * larger by the tag length compared to the input buffer as the
137 * encryption operation generates the tag. For decryption, the input
138 * buffer provides the tag which is consumed resulting in only the
139 * plaintext without a buffer for the tag returned to the caller.
147 * The cipher operation input data is reduced by the associated data
148 * length as this data is processed separately later on.
150 used
-= ctx
->aead_assoclen
;
152 /* Allocate cipher request for current operation. */
153 areq
= af_alg_alloc_areq(sk
, sizeof(struct af_alg_async_req
) +
154 crypto_aead_reqsize(tfm
));
156 return PTR_ERR(areq
);
158 /* convert iovecs of output buffers into RX SGL */
159 err
= af_alg_get_rsgl(sk
, msg
, flags
, areq
, outlen
, &usedpages
);
164 * Ensure output buffer is sufficiently large. If the caller provides
165 * less buffer space, only use the relative required input size. This
166 * allows AIO operation where the caller sent all data to be processed
167 * and the AIO operation performs the operation on the different chunks
170 if (usedpages
< outlen
) {
171 size_t less
= outlen
- usedpages
;
181 processed
= used
+ ctx
->aead_assoclen
;
182 list_for_each_entry_safe(tsgl
, tmp
, &ctx
->tsgl_list
, list
) {
183 for (i
= 0; i
< tsgl
->cur
; i
++) {
184 struct scatterlist
*process_sg
= tsgl
->sg
+ i
;
186 if (!(process_sg
->length
) || !sg_page(process_sg
))
188 tsgl_src
= process_sg
;
194 if (processed
&& !tsgl_src
) {
200 * Copy of AAD from source to destination
202 * The AAD is copied to the destination buffer without change. Even
203 * when user space uses an in-place cipher operation, the kernel
204 * will copy the data as it does not see whether such in-place operation
207 * To ensure efficiency, the following implementation ensure that the
208 * ciphers are invoked to perform a crypto operation in-place. This
209 * is achieved by memory management specified as follows.
212 /* Use the RX SGL as source (and destination) for crypto op. */
213 rsgl_src
= areq
->first_rsgl
.sgl
.sgt
.sgl
;
217 * Encryption operation - The in-place cipher operation is
218 * achieved by the following operation:
224 * RX SGL: AAD || PT || Tag
226 err
= crypto_aead_copy_sgl(null_tfm
, tsgl_src
,
227 areq
->first_rsgl
.sgl
.sgt
.sgl
,
231 af_alg_pull_tsgl(sk
, processed
, NULL
, 0);
234 * Decryption operation - To achieve an in-place cipher
235 * operation, the following SGL structure is used:
237 * TX SGL: AAD || CT || Tag
239 * | copy | | Create SGL link.
241 * RX SGL: AAD || CT ----+
244 /* Copy AAD || CT to RX SGL buffer for in-place operation. */
245 err
= crypto_aead_copy_sgl(null_tfm
, tsgl_src
,
246 areq
->first_rsgl
.sgl
.sgt
.sgl
,
251 /* Create TX SGL for tag and chain it to RX SGL. */
252 areq
->tsgl_entries
= af_alg_count_tsgl(sk
, processed
,
254 if (!areq
->tsgl_entries
)
255 areq
->tsgl_entries
= 1;
256 areq
->tsgl
= sock_kmalloc(sk
, array_size(sizeof(*areq
->tsgl
),
263 sg_init_table(areq
->tsgl
, areq
->tsgl_entries
);
265 /* Release TX SGL, except for tag data and reassign tag data. */
266 af_alg_pull_tsgl(sk
, processed
, areq
->tsgl
, processed
- as
);
268 /* chain the areq TX SGL holding the tag with RX SGL */
271 struct af_alg_sgl
*sgl_prev
= &areq
->last_rsgl
->sgl
;
272 struct scatterlist
*sg
= sgl_prev
->sgt
.sgl
;
274 sg_unmark_end(sg
+ sgl_prev
->sgt
.nents
- 1);
275 sg_chain(sg
, sgl_prev
->sgt
.nents
+ 1, areq
->tsgl
);
277 /* no RX SGL present (e.g. authentication only) */
278 rsgl_src
= areq
->tsgl
;
281 /* Initialize the crypto operation */
282 aead_request_set_crypt(&areq
->cra_u
.aead_req
, rsgl_src
,
283 areq
->first_rsgl
.sgl
.sgt
.sgl
, used
, ctx
->iv
);
284 aead_request_set_ad(&areq
->cra_u
.aead_req
, ctx
->aead_assoclen
);
285 aead_request_set_tfm(&areq
->cra_u
.aead_req
, tfm
);
287 if (msg
->msg_iocb
&& !is_sync_kiocb(msg
->msg_iocb
)) {
290 areq
->iocb
= msg
->msg_iocb
;
292 /* Remember output size that will be generated. */
293 areq
->outlen
= outlen
;
295 aead_request_set_callback(&areq
->cra_u
.aead_req
,
296 CRYPTO_TFM_REQ_MAY_SLEEP
,
297 af_alg_async_cb
, areq
);
298 err
= ctx
->enc
? crypto_aead_encrypt(&areq
->cra_u
.aead_req
) :
299 crypto_aead_decrypt(&areq
->cra_u
.aead_req
);
301 /* AIO operation in progress */
302 if (err
== -EINPROGRESS
)
307 /* Synchronous operation */
308 aead_request_set_callback(&areq
->cra_u
.aead_req
,
309 CRYPTO_TFM_REQ_MAY_SLEEP
|
310 CRYPTO_TFM_REQ_MAY_BACKLOG
,
311 crypto_req_done
, &ctx
->wait
);
312 err
= crypto_wait_req(ctx
->enc
?
313 crypto_aead_encrypt(&areq
->cra_u
.aead_req
) :
314 crypto_aead_decrypt(&areq
->cra_u
.aead_req
),
320 af_alg_free_resources(areq
);
322 return err
? err
: outlen
;
325 static int aead_recvmsg(struct socket
*sock
, struct msghdr
*msg
,
326 size_t ignored
, int flags
)
328 struct sock
*sk
= sock
->sk
;
332 while (msg_data_left(msg
)) {
333 int err
= _aead_recvmsg(sock
, msg
, ignored
, flags
);
336 * This error covers -EIOCBQUEUED which implies that we can
337 * only handle one AIO request. If the caller wants to have
338 * multiple AIO requests in parallel, he must make multiple
339 * separate AIO calls.
341 * Also return the error if no data has been processed so far.
344 if (err
== -EIOCBQUEUED
|| err
== -EBADMSG
|| !ret
)
353 af_alg_wmem_wakeup(sk
);
358 static struct proto_ops algif_aead_ops
= {
361 .connect
= sock_no_connect
,
362 .socketpair
= sock_no_socketpair
,
363 .getname
= sock_no_getname
,
364 .ioctl
= sock_no_ioctl
,
365 .listen
= sock_no_listen
,
366 .shutdown
= sock_no_shutdown
,
367 .mmap
= sock_no_mmap
,
368 .bind
= sock_no_bind
,
369 .accept
= sock_no_accept
,
371 .release
= af_alg_release
,
372 .sendmsg
= aead_sendmsg
,
373 .recvmsg
= aead_recvmsg
,
377 static int aead_check_key(struct socket
*sock
)
381 struct alg_sock
*pask
;
382 struct aead_tfm
*tfm
;
383 struct sock
*sk
= sock
->sk
;
384 struct alg_sock
*ask
= alg_sk(sk
);
387 if (!atomic_read(&ask
->nokey_refcnt
))
391 pask
= alg_sk(ask
->parent
);
395 lock_sock_nested(psk
, SINGLE_DEPTH_NESTING
);
396 if (crypto_aead_get_flags(tfm
->aead
) & CRYPTO_TFM_NEED_KEY
)
399 atomic_dec(&pask
->nokey_refcnt
);
400 atomic_set(&ask
->nokey_refcnt
, 0);
412 static int aead_sendmsg_nokey(struct socket
*sock
, struct msghdr
*msg
,
417 err
= aead_check_key(sock
);
421 return aead_sendmsg(sock
, msg
, size
);
424 static int aead_recvmsg_nokey(struct socket
*sock
, struct msghdr
*msg
,
425 size_t ignored
, int flags
)
429 err
= aead_check_key(sock
);
433 return aead_recvmsg(sock
, msg
, ignored
, flags
);
436 static struct proto_ops algif_aead_ops_nokey
= {
439 .connect
= sock_no_connect
,
440 .socketpair
= sock_no_socketpair
,
441 .getname
= sock_no_getname
,
442 .ioctl
= sock_no_ioctl
,
443 .listen
= sock_no_listen
,
444 .shutdown
= sock_no_shutdown
,
445 .mmap
= sock_no_mmap
,
446 .bind
= sock_no_bind
,
447 .accept
= sock_no_accept
,
449 .release
= af_alg_release
,
450 .sendmsg
= aead_sendmsg_nokey
,
451 .recvmsg
= aead_recvmsg_nokey
,
455 static void *aead_bind(const char *name
, u32 type
, u32 mask
)
457 struct aead_tfm
*tfm
;
458 struct crypto_aead
*aead
;
459 struct crypto_sync_skcipher
*null_tfm
;
461 tfm
= kzalloc(sizeof(*tfm
), GFP_KERNEL
);
463 return ERR_PTR(-ENOMEM
);
465 aead
= crypto_alloc_aead(name
, type
, mask
);
468 return ERR_CAST(aead
);
471 null_tfm
= crypto_get_default_null_skcipher();
472 if (IS_ERR(null_tfm
)) {
473 crypto_free_aead(aead
);
475 return ERR_CAST(null_tfm
);
479 tfm
->null_tfm
= null_tfm
;
484 static void aead_release(void *private)
486 struct aead_tfm
*tfm
= private;
488 crypto_free_aead(tfm
->aead
);
489 crypto_put_default_null_skcipher();
493 static int aead_setauthsize(void *private, unsigned int authsize
)
495 struct aead_tfm
*tfm
= private;
497 return crypto_aead_setauthsize(tfm
->aead
, authsize
);
500 static int aead_setkey(void *private, const u8
*key
, unsigned int keylen
)
502 struct aead_tfm
*tfm
= private;
504 return crypto_aead_setkey(tfm
->aead
, key
, keylen
);
507 static void aead_sock_destruct(struct sock
*sk
)
509 struct alg_sock
*ask
= alg_sk(sk
);
510 struct af_alg_ctx
*ctx
= ask
->private;
511 struct sock
*psk
= ask
->parent
;
512 struct alg_sock
*pask
= alg_sk(psk
);
513 struct aead_tfm
*aeadc
= pask
->private;
514 struct crypto_aead
*tfm
= aeadc
->aead
;
515 unsigned int ivlen
= crypto_aead_ivsize(tfm
);
517 af_alg_pull_tsgl(sk
, ctx
->used
, NULL
, 0);
518 sock_kzfree_s(sk
, ctx
->iv
, ivlen
);
519 sock_kfree_s(sk
, ctx
, ctx
->len
);
520 af_alg_release_parent(sk
);
523 static int aead_accept_parent_nokey(void *private, struct sock
*sk
)
525 struct af_alg_ctx
*ctx
;
526 struct alg_sock
*ask
= alg_sk(sk
);
527 struct aead_tfm
*tfm
= private;
528 struct crypto_aead
*aead
= tfm
->aead
;
529 unsigned int len
= sizeof(*ctx
);
530 unsigned int ivlen
= crypto_aead_ivsize(aead
);
532 ctx
= sock_kmalloc(sk
, len
, GFP_KERNEL
);
537 ctx
->iv
= sock_kmalloc(sk
, ivlen
, GFP_KERNEL
);
539 sock_kfree_s(sk
, ctx
, len
);
542 memset(ctx
->iv
, 0, ivlen
);
544 INIT_LIST_HEAD(&ctx
->tsgl_list
);
546 crypto_init_wait(&ctx
->wait
);
550 sk
->sk_destruct
= aead_sock_destruct
;
555 static int aead_accept_parent(void *private, struct sock
*sk
)
557 struct aead_tfm
*tfm
= private;
559 if (crypto_aead_get_flags(tfm
->aead
) & CRYPTO_TFM_NEED_KEY
)
562 return aead_accept_parent_nokey(private, sk
);
565 static const struct af_alg_type algif_type_aead
= {
567 .release
= aead_release
,
568 .setkey
= aead_setkey
,
569 .setauthsize
= aead_setauthsize
,
570 .accept
= aead_accept_parent
,
571 .accept_nokey
= aead_accept_parent_nokey
,
572 .ops
= &algif_aead_ops
,
573 .ops_nokey
= &algif_aead_ops_nokey
,
578 static int __init
algif_aead_init(void)
580 return af_alg_register_type(&algif_type_aead
);
583 static void __exit
algif_aead_exit(void)
585 int err
= af_alg_unregister_type(&algif_type_aead
);
589 module_init(algif_aead_init
);
590 module_exit(algif_aead_exit
);
591 MODULE_LICENSE("GPL");
592 MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
593 MODULE_DESCRIPTION("AEAD kernel crypto API user space interface");