linux/crypto/algif_skcipher.c
<<
>>
Prefs
   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 sendpage/sendmsg. Filling
  13 * up the TX SGL does not cause a crypto operation -- the data will only be
  14 * tracked by the kernel. Upon receipt of one recvmsg call, the caller must
  15 * provide a 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
  37static 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(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
  50static 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(psk);
  57        struct af_alg_ctx *ctx = ask->private;
  58        struct crypto_skcipher *tfm = pask->private;
  59        unsigned int bs = crypto_skcipher_blocksize(tfm);
  60        struct af_alg_async_req *areq;
  61        int err = 0;
  62        size_t len = 0;
  63
  64        if (!ctx->used) {
  65                err = af_alg_wait_for_data(sk, flags);
  66                if (err)
  67                        return err;
  68        }
  69
  70        /* Allocate cipher request for current operation. */
  71        areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
  72                                     crypto_skcipher_reqsize(tfm));
  73        if (IS_ERR(areq))
  74                return PTR_ERR(areq);
  75
  76        /* convert iovecs of output buffers into RX SGL */
  77        err = af_alg_get_rsgl(sk, msg, flags, areq, -1, &len);
  78        if (err)
  79                goto free;
  80
  81        /* Process only as much RX buffers for which we have TX data */
  82        if (len > ctx->used)
  83                len = ctx->used;
  84
  85        /*
  86         * If more buffers are to be expected to be processed, process only
  87         * full block size buffers.
  88         */
  89        if (ctx->more || len < ctx->used)
  90                len -= len % bs;
  91
  92        /*
  93         * Create a per request TX SGL for this request which tracks the
  94         * SG entries from the global TX SGL.
  95         */
  96        areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0);
  97        if (!areq->tsgl_entries)
  98                areq->tsgl_entries = 1;
  99        areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
 100                                                 areq->tsgl_entries),
 101                                  GFP_KERNEL);
 102        if (!areq->tsgl) {
 103                err = -ENOMEM;
 104                goto free;
 105        }
 106        sg_init_table(areq->tsgl, areq->tsgl_entries);
 107        af_alg_pull_tsgl(sk, len, areq->tsgl, 0);
 108
 109        /* Initialize the crypto operation */
 110        skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm);
 111        skcipher_request_set_crypt(&areq->cra_u.skcipher_req, areq->tsgl,
 112                                   areq->first_rsgl.sgl.sg, len, ctx->iv);
 113
 114        if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) {
 115                /* AIO operation */
 116                sock_hold(sk);
 117                areq->iocb = msg->msg_iocb;
 118
 119                /* Remember output size that will be generated. */
 120                areq->outlen = len;
 121
 122                skcipher_request_set_callback(&areq->cra_u.skcipher_req,
 123                                              CRYPTO_TFM_REQ_MAY_SLEEP,
 124                                              af_alg_async_cb, areq);
 125                err = ctx->enc ?
 126                        crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
 127                        crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
 128
 129                /* AIO operation in progress */
 130                if (err == -EINPROGRESS || err == -EBUSY)
 131                        return -EIOCBQUEUED;
 132
 133                sock_put(sk);
 134        } else {
 135                /* Synchronous operation */
 136                skcipher_request_set_callback(&areq->cra_u.skcipher_req,
 137                                              CRYPTO_TFM_REQ_MAY_SLEEP |
 138                                              CRYPTO_TFM_REQ_MAY_BACKLOG,
 139                                              crypto_req_done, &ctx->wait);
 140                err = crypto_wait_req(ctx->enc ?
 141                        crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
 142                        crypto_skcipher_decrypt(&areq->cra_u.skcipher_req),
 143                                                 &ctx->wait);
 144        }
 145
 146
 147free:
 148        af_alg_free_resources(areq);
 149
 150        return err ? err : len;
 151}
 152
 153static int skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
 154                            size_t ignored, int flags)
 155{
 156        struct sock *sk = sock->sk;
 157        int ret = 0;
 158
 159        lock_sock(sk);
 160        while (msg_data_left(msg)) {
 161                int err = _skcipher_recvmsg(sock, msg, ignored, flags);
 162
 163                /*
 164                 * This error covers -EIOCBQUEUED which implies that we can
 165                 * only handle one AIO request. If the caller wants to have
 166                 * multiple AIO requests in parallel, he must make multiple
 167                 * separate AIO calls.
 168                 *
 169                 * Also return the error if no data has been processed so far.
 170                 */
 171                if (err <= 0) {
 172                        if (err == -EIOCBQUEUED || !ret)
 173                                ret = err;
 174                        goto out;
 175                }
 176
 177                ret += err;
 178        }
 179
 180out:
 181        af_alg_wmem_wakeup(sk);
 182        release_sock(sk);
 183        return ret;
 184}
 185
 186static struct proto_ops algif_skcipher_ops = {
 187        .family         =       PF_ALG,
 188
 189        .connect        =       sock_no_connect,
 190        .socketpair     =       sock_no_socketpair,
 191        .getname        =       sock_no_getname,
 192        .ioctl          =       sock_no_ioctl,
 193        .listen         =       sock_no_listen,
 194        .shutdown       =       sock_no_shutdown,
 195        .getsockopt     =       sock_no_getsockopt,
 196        .mmap           =       sock_no_mmap,
 197        .bind           =       sock_no_bind,
 198        .accept         =       sock_no_accept,
 199        .setsockopt     =       sock_no_setsockopt,
 200
 201        .release        =       af_alg_release,
 202        .sendmsg        =       skcipher_sendmsg,
 203        .sendpage       =       af_alg_sendpage,
 204        .recvmsg        =       skcipher_recvmsg,
 205        .poll           =       af_alg_poll,
 206};
 207
 208static int skcipher_check_key(struct socket *sock)
 209{
 210        int err = 0;
 211        struct sock *psk;
 212        struct alg_sock *pask;
 213        struct crypto_skcipher *tfm;
 214        struct sock *sk = sock->sk;
 215        struct alg_sock *ask = alg_sk(sk);
 216
 217        lock_sock(sk);
 218        if (ask->refcnt)
 219                goto unlock_child;
 220
 221        psk = ask->parent;
 222        pask = alg_sk(ask->parent);
 223        tfm = pask->private;
 224
 225        err = -ENOKEY;
 226        lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
 227        if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
 228                goto unlock;
 229
 230        if (!pask->refcnt++)
 231                sock_hold(psk);
 232
 233        ask->refcnt = 1;
 234        sock_put(psk);
 235
 236        err = 0;
 237
 238unlock:
 239        release_sock(psk);
 240unlock_child:
 241        release_sock(sk);
 242
 243        return err;
 244}
 245
 246static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
 247                                  size_t size)
 248{
 249        int err;
 250
 251        err = skcipher_check_key(sock);
 252        if (err)
 253                return err;
 254
 255        return skcipher_sendmsg(sock, msg, size);
 256}
 257
 258static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
 259                                       int offset, size_t size, int flags)
 260{
 261        int err;
 262
 263        err = skcipher_check_key(sock);
 264        if (err)
 265                return err;
 266
 267        return af_alg_sendpage(sock, page, offset, size, flags);
 268}
 269
 270static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
 271                                  size_t ignored, int flags)
 272{
 273        int err;
 274
 275        err = skcipher_check_key(sock);
 276        if (err)
 277                return err;
 278
 279        return skcipher_recvmsg(sock, msg, ignored, flags);
 280}
 281
 282static struct proto_ops algif_skcipher_ops_nokey = {
 283        .family         =       PF_ALG,
 284
 285        .connect        =       sock_no_connect,
 286        .socketpair     =       sock_no_socketpair,
 287        .getname        =       sock_no_getname,
 288        .ioctl          =       sock_no_ioctl,
 289        .listen         =       sock_no_listen,
 290        .shutdown       =       sock_no_shutdown,
 291        .getsockopt     =       sock_no_getsockopt,
 292        .mmap           =       sock_no_mmap,
 293        .bind           =       sock_no_bind,
 294        .accept         =       sock_no_accept,
 295        .setsockopt     =       sock_no_setsockopt,
 296
 297        .release        =       af_alg_release,
 298        .sendmsg        =       skcipher_sendmsg_nokey,
 299        .sendpage       =       skcipher_sendpage_nokey,
 300        .recvmsg        =       skcipher_recvmsg_nokey,
 301        .poll           =       af_alg_poll,
 302};
 303
 304static void *skcipher_bind(const char *name, u32 type, u32 mask)
 305{
 306        return crypto_alloc_skcipher(name, type, mask);
 307}
 308
 309static void skcipher_release(void *private)
 310{
 311        crypto_free_skcipher(private);
 312}
 313
 314static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
 315{
 316        return crypto_skcipher_setkey(private, key, keylen);
 317}
 318
 319static void skcipher_sock_destruct(struct sock *sk)
 320{
 321        struct alg_sock *ask = alg_sk(sk);
 322        struct af_alg_ctx *ctx = ask->private;
 323        struct sock *psk = ask->parent;
 324        struct alg_sock *pask = alg_sk(psk);
 325        struct crypto_skcipher *tfm = pask->private;
 326
 327        af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
 328        sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
 329        sock_kfree_s(sk, ctx, ctx->len);
 330        af_alg_release_parent(sk);
 331}
 332
 333static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
 334{
 335        struct af_alg_ctx *ctx;
 336        struct alg_sock *ask = alg_sk(sk);
 337        struct crypto_skcipher *tfm = private;
 338        unsigned int len = sizeof(*ctx);
 339
 340        ctx = sock_kmalloc(sk, len, GFP_KERNEL);
 341        if (!ctx)
 342                return -ENOMEM;
 343
 344        ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(tfm),
 345                               GFP_KERNEL);
 346        if (!ctx->iv) {
 347                sock_kfree_s(sk, ctx, len);
 348                return -ENOMEM;
 349        }
 350
 351        memset(ctx->iv, 0, crypto_skcipher_ivsize(tfm));
 352
 353        INIT_LIST_HEAD(&ctx->tsgl_list);
 354        ctx->len = len;
 355        ctx->used = 0;
 356        atomic_set(&ctx->rcvused, 0);
 357        ctx->more = 0;
 358        ctx->merge = 0;
 359        ctx->enc = 0;
 360        crypto_init_wait(&ctx->wait);
 361
 362        ask->private = ctx;
 363
 364        sk->sk_destruct = skcipher_sock_destruct;
 365
 366        return 0;
 367}
 368
 369static int skcipher_accept_parent(void *private, struct sock *sk)
 370{
 371        struct crypto_skcipher *tfm = private;
 372
 373        if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
 374                return -ENOKEY;
 375
 376        return skcipher_accept_parent_nokey(private, sk);
 377}
 378
 379static const struct af_alg_type algif_type_skcipher = {
 380        .bind           =       skcipher_bind,
 381        .release        =       skcipher_release,
 382        .setkey         =       skcipher_setkey,
 383        .accept         =       skcipher_accept_parent,
 384        .accept_nokey   =       skcipher_accept_parent_nokey,
 385        .ops            =       &algif_skcipher_ops,
 386        .ops_nokey      =       &algif_skcipher_ops_nokey,
 387        .name           =       "skcipher",
 388        .owner          =       THIS_MODULE
 389};
 390
 391static int __init algif_skcipher_init(void)
 392{
 393        return af_alg_register_type(&algif_type_skcipher);
 394}
 395
 396static void __exit algif_skcipher_exit(void)
 397{
 398        int err = af_alg_unregister_type(&algif_type_skcipher);
 399        BUG_ON(err);
 400}
 401
 402module_init(algif_skcipher_init);
 403module_exit(algif_skcipher_exit);
 404MODULE_LICENSE("GPL");
 405