Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * algif_skcipher: User-space interface for skcipher algorithms
0004  *
0005  * This file provides the user-space API for symmetric key ciphers.
0006  *
0007  * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
0008  *
0009  * The following concept of the memory management is used:
0010  *
0011  * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is
0012  * filled by user space with the data submitted via sendpage/sendmsg. Filling
0013  * up the TX SGL does not cause a crypto operation -- the data will only be
0014  * tracked by the kernel. Upon receipt of one recvmsg call, the caller must
0015  * provide a buffer which is tracked with the RX SGL.
0016  *
0017  * During the processing of the recvmsg operation, the cipher request is
0018  * allocated and prepared. As part of the recvmsg operation, the processed
0019  * TX buffers are extracted from the TX SGL into a separate SGL.
0020  *
0021  * After the completion of the crypto operation, the RX SGL and the cipher
0022  * request is released. The extracted TX SGL parts are released together with
0023  * the RX SGL release.
0024  */
0025 
0026 #include <crypto/scatterwalk.h>
0027 #include <crypto/skcipher.h>
0028 #include <crypto/if_alg.h>
0029 #include <linux/init.h>
0030 #include <linux/list.h>
0031 #include <linux/kernel.h>
0032 #include <linux/mm.h>
0033 #include <linux/module.h>
0034 #include <linux/net.h>
0035 #include <net/sock.h>
0036 
0037 static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
0038                 size_t size)
0039 {
0040     struct sock *sk = sock->sk;
0041     struct alg_sock *ask = alg_sk(sk);
0042     struct sock *psk = ask->parent;
0043     struct alg_sock *pask = alg_sk(psk);
0044     struct crypto_skcipher *tfm = pask->private;
0045     unsigned ivsize = crypto_skcipher_ivsize(tfm);
0046 
0047     return af_alg_sendmsg(sock, msg, size, ivsize);
0048 }
0049 
0050 static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
0051                  size_t ignored, int flags)
0052 {
0053     struct sock *sk = sock->sk;
0054     struct alg_sock *ask = alg_sk(sk);
0055     struct sock *psk = ask->parent;
0056     struct alg_sock *pask = alg_sk(psk);
0057     struct af_alg_ctx *ctx = ask->private;
0058     struct crypto_skcipher *tfm = pask->private;
0059     unsigned int bs = crypto_skcipher_chunksize(tfm);
0060     struct af_alg_async_req *areq;
0061     int err = 0;
0062     size_t len = 0;
0063 
0064     if (!ctx->init || (ctx->more && ctx->used < bs)) {
0065         err = af_alg_wait_for_data(sk, flags, bs);
0066         if (err)
0067             return err;
0068     }
0069 
0070     /* Allocate cipher request for current operation. */
0071     areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
0072                      crypto_skcipher_reqsize(tfm));
0073     if (IS_ERR(areq))
0074         return PTR_ERR(areq);
0075 
0076     /* convert iovecs of output buffers into RX SGL */
0077     err = af_alg_get_rsgl(sk, msg, flags, areq, ctx->used, &len);
0078     if (err)
0079         goto free;
0080 
0081     /*
0082      * If more buffers are to be expected to be processed, process only
0083      * full block size buffers.
0084      */
0085     if (ctx->more || len < ctx->used)
0086         len -= len % bs;
0087 
0088     /*
0089      * Create a per request TX SGL for this request which tracks the
0090      * SG entries from the global TX SGL.
0091      */
0092     areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0);
0093     if (!areq->tsgl_entries)
0094         areq->tsgl_entries = 1;
0095     areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
0096                          areq->tsgl_entries),
0097                   GFP_KERNEL);
0098     if (!areq->tsgl) {
0099         err = -ENOMEM;
0100         goto free;
0101     }
0102     sg_init_table(areq->tsgl, areq->tsgl_entries);
0103     af_alg_pull_tsgl(sk, len, areq->tsgl, 0);
0104 
0105     /* Initialize the crypto operation */
0106     skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm);
0107     skcipher_request_set_crypt(&areq->cra_u.skcipher_req, areq->tsgl,
0108                    areq->first_rsgl.sgl.sg, len, ctx->iv);
0109 
0110     if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) {
0111         /* AIO operation */
0112         sock_hold(sk);
0113         areq->iocb = msg->msg_iocb;
0114 
0115         /* Remember output size that will be generated. */
0116         areq->outlen = len;
0117 
0118         skcipher_request_set_callback(&areq->cra_u.skcipher_req,
0119                           CRYPTO_TFM_REQ_MAY_SLEEP,
0120                           af_alg_async_cb, areq);
0121         err = ctx->enc ?
0122             crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
0123             crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
0124 
0125         /* AIO operation in progress */
0126         if (err == -EINPROGRESS)
0127             return -EIOCBQUEUED;
0128 
0129         sock_put(sk);
0130     } else {
0131         /* Synchronous operation */
0132         skcipher_request_set_callback(&areq->cra_u.skcipher_req,
0133                           CRYPTO_TFM_REQ_MAY_SLEEP |
0134                           CRYPTO_TFM_REQ_MAY_BACKLOG,
0135                           crypto_req_done, &ctx->wait);
0136         err = crypto_wait_req(ctx->enc ?
0137             crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
0138             crypto_skcipher_decrypt(&areq->cra_u.skcipher_req),
0139                          &ctx->wait);
0140     }
0141 
0142 
0143 free:
0144     af_alg_free_resources(areq);
0145 
0146     return err ? err : len;
0147 }
0148 
0149 static int skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
0150                 size_t ignored, int flags)
0151 {
0152     struct sock *sk = sock->sk;
0153     int ret = 0;
0154 
0155     lock_sock(sk);
0156     while (msg_data_left(msg)) {
0157         int err = _skcipher_recvmsg(sock, msg, ignored, flags);
0158 
0159         /*
0160          * This error covers -EIOCBQUEUED which implies that we can
0161          * only handle one AIO request. If the caller wants to have
0162          * multiple AIO requests in parallel, he must make multiple
0163          * separate AIO calls.
0164          *
0165          * Also return the error if no data has been processed so far.
0166          */
0167         if (err <= 0) {
0168             if (err == -EIOCBQUEUED || !ret)
0169                 ret = err;
0170             goto out;
0171         }
0172 
0173         ret += err;
0174     }
0175 
0176 out:
0177     af_alg_wmem_wakeup(sk);
0178     release_sock(sk);
0179     return ret;
0180 }
0181 
0182 static struct proto_ops algif_skcipher_ops = {
0183     .family     =   PF_ALG,
0184 
0185     .connect    =   sock_no_connect,
0186     .socketpair =   sock_no_socketpair,
0187     .getname    =   sock_no_getname,
0188     .ioctl      =   sock_no_ioctl,
0189     .listen     =   sock_no_listen,
0190     .shutdown   =   sock_no_shutdown,
0191     .mmap       =   sock_no_mmap,
0192     .bind       =   sock_no_bind,
0193     .accept     =   sock_no_accept,
0194 
0195     .release    =   af_alg_release,
0196     .sendmsg    =   skcipher_sendmsg,
0197     .sendpage   =   af_alg_sendpage,
0198     .recvmsg    =   skcipher_recvmsg,
0199     .poll       =   af_alg_poll,
0200 };
0201 
0202 static int skcipher_check_key(struct socket *sock)
0203 {
0204     int err = 0;
0205     struct sock *psk;
0206     struct alg_sock *pask;
0207     struct crypto_skcipher *tfm;
0208     struct sock *sk = sock->sk;
0209     struct alg_sock *ask = alg_sk(sk);
0210 
0211     lock_sock(sk);
0212     if (!atomic_read(&ask->nokey_refcnt))
0213         goto unlock_child;
0214 
0215     psk = ask->parent;
0216     pask = alg_sk(ask->parent);
0217     tfm = pask->private;
0218 
0219     err = -ENOKEY;
0220     lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
0221     if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
0222         goto unlock;
0223 
0224     atomic_dec(&pask->nokey_refcnt);
0225     atomic_set(&ask->nokey_refcnt, 0);
0226 
0227     err = 0;
0228 
0229 unlock:
0230     release_sock(psk);
0231 unlock_child:
0232     release_sock(sk);
0233 
0234     return err;
0235 }
0236 
0237 static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
0238                   size_t size)
0239 {
0240     int err;
0241 
0242     err = skcipher_check_key(sock);
0243     if (err)
0244         return err;
0245 
0246     return skcipher_sendmsg(sock, msg, size);
0247 }
0248 
0249 static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
0250                        int offset, size_t size, int flags)
0251 {
0252     int err;
0253 
0254     err = skcipher_check_key(sock);
0255     if (err)
0256         return err;
0257 
0258     return af_alg_sendpage(sock, page, offset, size, flags);
0259 }
0260 
0261 static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
0262                   size_t ignored, int flags)
0263 {
0264     int err;
0265 
0266     err = skcipher_check_key(sock);
0267     if (err)
0268         return err;
0269 
0270     return skcipher_recvmsg(sock, msg, ignored, flags);
0271 }
0272 
0273 static struct proto_ops algif_skcipher_ops_nokey = {
0274     .family     =   PF_ALG,
0275 
0276     .connect    =   sock_no_connect,
0277     .socketpair =   sock_no_socketpair,
0278     .getname    =   sock_no_getname,
0279     .ioctl      =   sock_no_ioctl,
0280     .listen     =   sock_no_listen,
0281     .shutdown   =   sock_no_shutdown,
0282     .mmap       =   sock_no_mmap,
0283     .bind       =   sock_no_bind,
0284     .accept     =   sock_no_accept,
0285 
0286     .release    =   af_alg_release,
0287     .sendmsg    =   skcipher_sendmsg_nokey,
0288     .sendpage   =   skcipher_sendpage_nokey,
0289     .recvmsg    =   skcipher_recvmsg_nokey,
0290     .poll       =   af_alg_poll,
0291 };
0292 
0293 static void *skcipher_bind(const char *name, u32 type, u32 mask)
0294 {
0295     return crypto_alloc_skcipher(name, type, mask);
0296 }
0297 
0298 static void skcipher_release(void *private)
0299 {
0300     crypto_free_skcipher(private);
0301 }
0302 
0303 static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
0304 {
0305     return crypto_skcipher_setkey(private, key, keylen);
0306 }
0307 
0308 static void skcipher_sock_destruct(struct sock *sk)
0309 {
0310     struct alg_sock *ask = alg_sk(sk);
0311     struct af_alg_ctx *ctx = ask->private;
0312     struct sock *psk = ask->parent;
0313     struct alg_sock *pask = alg_sk(psk);
0314     struct crypto_skcipher *tfm = pask->private;
0315 
0316     af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
0317     sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
0318     sock_kfree_s(sk, ctx, ctx->len);
0319     af_alg_release_parent(sk);
0320 }
0321 
0322 static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
0323 {
0324     struct af_alg_ctx *ctx;
0325     struct alg_sock *ask = alg_sk(sk);
0326     struct crypto_skcipher *tfm = private;
0327     unsigned int len = sizeof(*ctx);
0328 
0329     ctx = sock_kmalloc(sk, len, GFP_KERNEL);
0330     if (!ctx)
0331         return -ENOMEM;
0332     memset(ctx, 0, len);
0333 
0334     ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(tfm),
0335                    GFP_KERNEL);
0336     if (!ctx->iv) {
0337         sock_kfree_s(sk, ctx, len);
0338         return -ENOMEM;
0339     }
0340     memset(ctx->iv, 0, crypto_skcipher_ivsize(tfm));
0341 
0342     INIT_LIST_HEAD(&ctx->tsgl_list);
0343     ctx->len = len;
0344     crypto_init_wait(&ctx->wait);
0345 
0346     ask->private = ctx;
0347 
0348     sk->sk_destruct = skcipher_sock_destruct;
0349 
0350     return 0;
0351 }
0352 
0353 static int skcipher_accept_parent(void *private, struct sock *sk)
0354 {
0355     struct crypto_skcipher *tfm = private;
0356 
0357     if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
0358         return -ENOKEY;
0359 
0360     return skcipher_accept_parent_nokey(private, sk);
0361 }
0362 
0363 static const struct af_alg_type algif_type_skcipher = {
0364     .bind       =   skcipher_bind,
0365     .release    =   skcipher_release,
0366     .setkey     =   skcipher_setkey,
0367     .accept     =   skcipher_accept_parent,
0368     .accept_nokey   =   skcipher_accept_parent_nokey,
0369     .ops        =   &algif_skcipher_ops,
0370     .ops_nokey  =   &algif_skcipher_ops_nokey,
0371     .name       =   "skcipher",
0372     .owner      =   THIS_MODULE
0373 };
0374 
0375 static int __init algif_skcipher_init(void)
0376 {
0377     return af_alg_register_type(&algif_type_skcipher);
0378 }
0379 
0380 static void __exit algif_skcipher_exit(void)
0381 {
0382     int err = af_alg_unregister_type(&algif_type_skcipher);
0383     BUG_ON(err);
0384 }
0385 
0386 module_init(algif_skcipher_init);
0387 module_exit(algif_skcipher_exit);
0388 MODULE_LICENSE("GPL");