Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * algif_hash: User-space interface for hash algorithms
0004  *
0005  * This file provides the user-space API for hash algorithms.
0006  *
0007  * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
0008  */
0009 
0010 #include <crypto/hash.h>
0011 #include <crypto/if_alg.h>
0012 #include <linux/init.h>
0013 #include <linux/kernel.h>
0014 #include <linux/mm.h>
0015 #include <linux/module.h>
0016 #include <linux/net.h>
0017 #include <net/sock.h>
0018 
0019 struct hash_ctx {
0020     struct af_alg_sgl sgl;
0021 
0022     u8 *result;
0023 
0024     struct crypto_wait wait;
0025 
0026     unsigned int len;
0027     bool more;
0028 
0029     struct ahash_request req;
0030 };
0031 
0032 static int hash_alloc_result(struct sock *sk, struct hash_ctx *ctx)
0033 {
0034     unsigned ds;
0035 
0036     if (ctx->result)
0037         return 0;
0038 
0039     ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req));
0040 
0041     ctx->result = sock_kmalloc(sk, ds, GFP_KERNEL);
0042     if (!ctx->result)
0043         return -ENOMEM;
0044 
0045     memset(ctx->result, 0, ds);
0046 
0047     return 0;
0048 }
0049 
0050 static void hash_free_result(struct sock *sk, struct hash_ctx *ctx)
0051 {
0052     unsigned ds;
0053 
0054     if (!ctx->result)
0055         return;
0056 
0057     ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req));
0058 
0059     sock_kzfree_s(sk, ctx->result, ds);
0060     ctx->result = NULL;
0061 }
0062 
0063 static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
0064             size_t ignored)
0065 {
0066     int limit = ALG_MAX_PAGES * PAGE_SIZE;
0067     struct sock *sk = sock->sk;
0068     struct alg_sock *ask = alg_sk(sk);
0069     struct hash_ctx *ctx = ask->private;
0070     long copied = 0;
0071     int err;
0072 
0073     if (limit > sk->sk_sndbuf)
0074         limit = sk->sk_sndbuf;
0075 
0076     lock_sock(sk);
0077     if (!ctx->more) {
0078         if ((msg->msg_flags & MSG_MORE))
0079             hash_free_result(sk, ctx);
0080 
0081         err = crypto_wait_req(crypto_ahash_init(&ctx->req), &ctx->wait);
0082         if (err)
0083             goto unlock;
0084     }
0085 
0086     ctx->more = false;
0087 
0088     while (msg_data_left(msg)) {
0089         int len = msg_data_left(msg);
0090 
0091         if (len > limit)
0092             len = limit;
0093 
0094         len = af_alg_make_sg(&ctx->sgl, &msg->msg_iter, len);
0095         if (len < 0) {
0096             err = copied ? 0 : len;
0097             goto unlock;
0098         }
0099 
0100         ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, NULL, len);
0101 
0102         err = crypto_wait_req(crypto_ahash_update(&ctx->req),
0103                       &ctx->wait);
0104         af_alg_free_sg(&ctx->sgl);
0105         if (err) {
0106             iov_iter_revert(&msg->msg_iter, len);
0107             goto unlock;
0108         }
0109 
0110         copied += len;
0111     }
0112 
0113     err = 0;
0114 
0115     ctx->more = msg->msg_flags & MSG_MORE;
0116     if (!ctx->more) {
0117         err = hash_alloc_result(sk, ctx);
0118         if (err)
0119             goto unlock;
0120 
0121         ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
0122         err = crypto_wait_req(crypto_ahash_final(&ctx->req),
0123                       &ctx->wait);
0124     }
0125 
0126 unlock:
0127     release_sock(sk);
0128 
0129     return err ?: copied;
0130 }
0131 
0132 static ssize_t hash_sendpage(struct socket *sock, struct page *page,
0133                  int offset, size_t size, int flags)
0134 {
0135     struct sock *sk = sock->sk;
0136     struct alg_sock *ask = alg_sk(sk);
0137     struct hash_ctx *ctx = ask->private;
0138     int err;
0139 
0140     if (flags & MSG_SENDPAGE_NOTLAST)
0141         flags |= MSG_MORE;
0142 
0143     lock_sock(sk);
0144     sg_init_table(ctx->sgl.sg, 1);
0145     sg_set_page(ctx->sgl.sg, page, size, offset);
0146 
0147     if (!(flags & MSG_MORE)) {
0148         err = hash_alloc_result(sk, ctx);
0149         if (err)
0150             goto unlock;
0151     } else if (!ctx->more)
0152         hash_free_result(sk, ctx);
0153 
0154     ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, ctx->result, size);
0155 
0156     if (!(flags & MSG_MORE)) {
0157         if (ctx->more)
0158             err = crypto_ahash_finup(&ctx->req);
0159         else
0160             err = crypto_ahash_digest(&ctx->req);
0161     } else {
0162         if (!ctx->more) {
0163             err = crypto_ahash_init(&ctx->req);
0164             err = crypto_wait_req(err, &ctx->wait);
0165             if (err)
0166                 goto unlock;
0167         }
0168 
0169         err = crypto_ahash_update(&ctx->req);
0170     }
0171 
0172     err = crypto_wait_req(err, &ctx->wait);
0173     if (err)
0174         goto unlock;
0175 
0176     ctx->more = flags & MSG_MORE;
0177 
0178 unlock:
0179     release_sock(sk);
0180 
0181     return err ?: size;
0182 }
0183 
0184 static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
0185             int flags)
0186 {
0187     struct sock *sk = sock->sk;
0188     struct alg_sock *ask = alg_sk(sk);
0189     struct hash_ctx *ctx = ask->private;
0190     unsigned ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req));
0191     bool result;
0192     int err;
0193 
0194     if (len > ds)
0195         len = ds;
0196     else if (len < ds)
0197         msg->msg_flags |= MSG_TRUNC;
0198 
0199     lock_sock(sk);
0200     result = ctx->result;
0201     err = hash_alloc_result(sk, ctx);
0202     if (err)
0203         goto unlock;
0204 
0205     ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
0206 
0207     if (!result && !ctx->more) {
0208         err = crypto_wait_req(crypto_ahash_init(&ctx->req),
0209                       &ctx->wait);
0210         if (err)
0211             goto unlock;
0212     }
0213 
0214     if (!result || ctx->more) {
0215         ctx->more = false;
0216         err = crypto_wait_req(crypto_ahash_final(&ctx->req),
0217                       &ctx->wait);
0218         if (err)
0219             goto unlock;
0220     }
0221 
0222     err = memcpy_to_msg(msg, ctx->result, len);
0223 
0224 unlock:
0225     hash_free_result(sk, ctx);
0226     release_sock(sk);
0227 
0228     return err ?: len;
0229 }
0230 
0231 static int hash_accept(struct socket *sock, struct socket *newsock, int flags,
0232                bool kern)
0233 {
0234     struct sock *sk = sock->sk;
0235     struct alg_sock *ask = alg_sk(sk);
0236     struct hash_ctx *ctx = ask->private;
0237     struct ahash_request *req = &ctx->req;
0238     char state[HASH_MAX_STATESIZE];
0239     struct sock *sk2;
0240     struct alg_sock *ask2;
0241     struct hash_ctx *ctx2;
0242     bool more;
0243     int err;
0244 
0245     lock_sock(sk);
0246     more = ctx->more;
0247     err = more ? crypto_ahash_export(req, state) : 0;
0248     release_sock(sk);
0249 
0250     if (err)
0251         return err;
0252 
0253     err = af_alg_accept(ask->parent, newsock, kern);
0254     if (err)
0255         return err;
0256 
0257     sk2 = newsock->sk;
0258     ask2 = alg_sk(sk2);
0259     ctx2 = ask2->private;
0260     ctx2->more = more;
0261 
0262     if (!more)
0263         return err;
0264 
0265     err = crypto_ahash_import(&ctx2->req, state);
0266     if (err) {
0267         sock_orphan(sk2);
0268         sock_put(sk2);
0269     }
0270 
0271     return err;
0272 }
0273 
0274 static struct proto_ops algif_hash_ops = {
0275     .family     =   PF_ALG,
0276 
0277     .connect    =   sock_no_connect,
0278     .socketpair =   sock_no_socketpair,
0279     .getname    =   sock_no_getname,
0280     .ioctl      =   sock_no_ioctl,
0281     .listen     =   sock_no_listen,
0282     .shutdown   =   sock_no_shutdown,
0283     .mmap       =   sock_no_mmap,
0284     .bind       =   sock_no_bind,
0285 
0286     .release    =   af_alg_release,
0287     .sendmsg    =   hash_sendmsg,
0288     .sendpage   =   hash_sendpage,
0289     .recvmsg    =   hash_recvmsg,
0290     .accept     =   hash_accept,
0291 };
0292 
0293 static int hash_check_key(struct socket *sock)
0294 {
0295     int err = 0;
0296     struct sock *psk;
0297     struct alg_sock *pask;
0298     struct crypto_ahash *tfm;
0299     struct sock *sk = sock->sk;
0300     struct alg_sock *ask = alg_sk(sk);
0301 
0302     lock_sock(sk);
0303     if (!atomic_read(&ask->nokey_refcnt))
0304         goto unlock_child;
0305 
0306     psk = ask->parent;
0307     pask = alg_sk(ask->parent);
0308     tfm = pask->private;
0309 
0310     err = -ENOKEY;
0311     lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
0312     if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
0313         goto unlock;
0314 
0315     atomic_dec(&pask->nokey_refcnt);
0316     atomic_set(&ask->nokey_refcnt, 0);
0317 
0318     err = 0;
0319 
0320 unlock:
0321     release_sock(psk);
0322 unlock_child:
0323     release_sock(sk);
0324 
0325     return err;
0326 }
0327 
0328 static int hash_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
0329                   size_t size)
0330 {
0331     int err;
0332 
0333     err = hash_check_key(sock);
0334     if (err)
0335         return err;
0336 
0337     return hash_sendmsg(sock, msg, size);
0338 }
0339 
0340 static ssize_t hash_sendpage_nokey(struct socket *sock, struct page *page,
0341                    int offset, size_t size, int flags)
0342 {
0343     int err;
0344 
0345     err = hash_check_key(sock);
0346     if (err)
0347         return err;
0348 
0349     return hash_sendpage(sock, page, offset, size, flags);
0350 }
0351 
0352 static int hash_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
0353                   size_t ignored, int flags)
0354 {
0355     int err;
0356 
0357     err = hash_check_key(sock);
0358     if (err)
0359         return err;
0360 
0361     return hash_recvmsg(sock, msg, ignored, flags);
0362 }
0363 
0364 static int hash_accept_nokey(struct socket *sock, struct socket *newsock,
0365                  int flags, bool kern)
0366 {
0367     int err;
0368 
0369     err = hash_check_key(sock);
0370     if (err)
0371         return err;
0372 
0373     return hash_accept(sock, newsock, flags, kern);
0374 }
0375 
0376 static struct proto_ops algif_hash_ops_nokey = {
0377     .family     =   PF_ALG,
0378 
0379     .connect    =   sock_no_connect,
0380     .socketpair =   sock_no_socketpair,
0381     .getname    =   sock_no_getname,
0382     .ioctl      =   sock_no_ioctl,
0383     .listen     =   sock_no_listen,
0384     .shutdown   =   sock_no_shutdown,
0385     .mmap       =   sock_no_mmap,
0386     .bind       =   sock_no_bind,
0387 
0388     .release    =   af_alg_release,
0389     .sendmsg    =   hash_sendmsg_nokey,
0390     .sendpage   =   hash_sendpage_nokey,
0391     .recvmsg    =   hash_recvmsg_nokey,
0392     .accept     =   hash_accept_nokey,
0393 };
0394 
0395 static void *hash_bind(const char *name, u32 type, u32 mask)
0396 {
0397     return crypto_alloc_ahash(name, type, mask);
0398 }
0399 
0400 static void hash_release(void *private)
0401 {
0402     crypto_free_ahash(private);
0403 }
0404 
0405 static int hash_setkey(void *private, const u8 *key, unsigned int keylen)
0406 {
0407     return crypto_ahash_setkey(private, key, keylen);
0408 }
0409 
0410 static void hash_sock_destruct(struct sock *sk)
0411 {
0412     struct alg_sock *ask = alg_sk(sk);
0413     struct hash_ctx *ctx = ask->private;
0414 
0415     hash_free_result(sk, ctx);
0416     sock_kfree_s(sk, ctx, ctx->len);
0417     af_alg_release_parent(sk);
0418 }
0419 
0420 static int hash_accept_parent_nokey(void *private, struct sock *sk)
0421 {
0422     struct crypto_ahash *tfm = private;
0423     struct alg_sock *ask = alg_sk(sk);
0424     struct hash_ctx *ctx;
0425     unsigned int len = sizeof(*ctx) + crypto_ahash_reqsize(tfm);
0426 
0427     ctx = sock_kmalloc(sk, len, GFP_KERNEL);
0428     if (!ctx)
0429         return -ENOMEM;
0430 
0431     ctx->result = NULL;
0432     ctx->len = len;
0433     ctx->more = false;
0434     crypto_init_wait(&ctx->wait);
0435 
0436     ask->private = ctx;
0437 
0438     ahash_request_set_tfm(&ctx->req, tfm);
0439     ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
0440                    crypto_req_done, &ctx->wait);
0441 
0442     sk->sk_destruct = hash_sock_destruct;
0443 
0444     return 0;
0445 }
0446 
0447 static int hash_accept_parent(void *private, struct sock *sk)
0448 {
0449     struct crypto_ahash *tfm = private;
0450 
0451     if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
0452         return -ENOKEY;
0453 
0454     return hash_accept_parent_nokey(private, sk);
0455 }
0456 
0457 static const struct af_alg_type algif_type_hash = {
0458     .bind       =   hash_bind,
0459     .release    =   hash_release,
0460     .setkey     =   hash_setkey,
0461     .accept     =   hash_accept_parent,
0462     .accept_nokey   =   hash_accept_parent_nokey,
0463     .ops        =   &algif_hash_ops,
0464     .ops_nokey  =   &algif_hash_ops_nokey,
0465     .name       =   "hash",
0466     .owner      =   THIS_MODULE
0467 };
0468 
0469 static int __init algif_hash_init(void)
0470 {
0471     return af_alg_register_type(&algif_type_hash);
0472 }
0473 
0474 static void __exit algif_hash_exit(void)
0475 {
0476     int err = af_alg_unregister_type(&algif_type_hash);
0477     BUG_ON(err);
0478 }
0479 
0480 module_init(algif_hash_init);
0481 module_exit(algif_hash_exit);
0482 MODULE_LICENSE("GPL");