Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * if_alg: User-space algorithm interface
0004  *
0005  * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
0006  */
0007 
0008 #ifndef _CRYPTO_IF_ALG_H
0009 #define _CRYPTO_IF_ALG_H
0010 
0011 #include <linux/compiler.h>
0012 #include <linux/completion.h>
0013 #include <linux/if_alg.h>
0014 #include <linux/scatterlist.h>
0015 #include <linux/types.h>
0016 #include <linux/atomic.h>
0017 #include <net/sock.h>
0018 
0019 #include <crypto/aead.h>
0020 #include <crypto/skcipher.h>
0021 
0022 #define ALG_MAX_PAGES           16
0023 
0024 struct crypto_async_request;
0025 
0026 struct alg_sock {
0027     /* struct sock must be the first member of struct alg_sock */
0028     struct sock sk;
0029 
0030     struct sock *parent;
0031 
0032     atomic_t refcnt;
0033     atomic_t nokey_refcnt;
0034 
0035     const struct af_alg_type *type;
0036     void *private;
0037 };
0038 
0039 struct af_alg_control {
0040     struct af_alg_iv *iv;
0041     int op;
0042     unsigned int aead_assoclen;
0043 };
0044 
0045 struct af_alg_type {
0046     void *(*bind)(const char *name, u32 type, u32 mask);
0047     void (*release)(void *private);
0048     int (*setkey)(void *private, const u8 *key, unsigned int keylen);
0049     int (*setentropy)(void *private, sockptr_t entropy, unsigned int len);
0050     int (*accept)(void *private, struct sock *sk);
0051     int (*accept_nokey)(void *private, struct sock *sk);
0052     int (*setauthsize)(void *private, unsigned int authsize);
0053 
0054     struct proto_ops *ops;
0055     struct proto_ops *ops_nokey;
0056     struct module *owner;
0057     char name[14];
0058 };
0059 
0060 struct af_alg_sgl {
0061     struct scatterlist sg[ALG_MAX_PAGES + 1];
0062     struct page *pages[ALG_MAX_PAGES];
0063     unsigned int npages;
0064 };
0065 
0066 /* TX SGL entry */
0067 struct af_alg_tsgl {
0068     struct list_head list;
0069     unsigned int cur;       /* Last processed SG entry */
0070     struct scatterlist sg[];    /* Array of SGs forming the SGL */
0071 };
0072 
0073 #define MAX_SGL_ENTS ((4096 - sizeof(struct af_alg_tsgl)) / \
0074               sizeof(struct scatterlist) - 1)
0075 
0076 /* RX SGL entry */
0077 struct af_alg_rsgl {
0078     struct af_alg_sgl sgl;
0079     struct list_head list;
0080     size_t sg_num_bytes;        /* Bytes of data in that SGL */
0081 };
0082 
0083 /**
0084  * struct af_alg_async_req - definition of crypto request
0085  * @iocb:       IOCB for AIO operations
0086  * @sk:         Socket the request is associated with
0087  * @first_rsgl:     First RX SG
0088  * @last_rsgl:      Pointer to last RX SG
0089  * @rsgl_list:      Track RX SGs
0090  * @tsgl:       Private, per request TX SGL of buffers to process
0091  * @tsgl_entries:   Number of entries in priv. TX SGL
0092  * @outlen:     Number of output bytes generated by crypto op
0093  * @areqlen:        Length of this data structure
0094  * @cra_u:      Cipher request
0095  */
0096 struct af_alg_async_req {
0097     struct kiocb *iocb;
0098     struct sock *sk;
0099 
0100     struct af_alg_rsgl first_rsgl;
0101     struct af_alg_rsgl *last_rsgl;
0102     struct list_head rsgl_list;
0103 
0104     struct scatterlist *tsgl;
0105     unsigned int tsgl_entries;
0106 
0107     unsigned int outlen;
0108     unsigned int areqlen;
0109 
0110     union {
0111         struct aead_request aead_req;
0112         struct skcipher_request skcipher_req;
0113     } cra_u;
0114 
0115     /* req ctx trails this struct */
0116 };
0117 
0118 /**
0119  * struct af_alg_ctx - definition of the crypto context
0120  *
0121  * The crypto context tracks the input data during the lifetime of an AF_ALG
0122  * socket.
0123  *
0124  * @tsgl_list:      Link to TX SGL
0125  * @iv:         IV for cipher operation
0126  * @aead_assoclen:  Length of AAD for AEAD cipher operations
0127  * @completion:     Work queue for synchronous operation
0128  * @used:       TX bytes sent to kernel. This variable is used to
0129  *          ensure that user space cannot cause the kernel
0130  *          to allocate too much memory in sendmsg operation.
0131  * @rcvused:        Total RX bytes to be filled by kernel. This variable
0132  *          is used to ensure user space cannot cause the kernel
0133  *          to allocate too much memory in a recvmsg operation.
0134  * @more:       More data to be expected from user space?
0135  * @merge:      Shall new data from user space be merged into existing
0136  *          SG?
0137  * @enc:        Cryptographic operation to be performed when
0138  *          recvmsg is invoked.
0139  * @init:       True if metadata has been sent.
0140  * @len:        Length of memory allocated for this data structure.
0141  */
0142 struct af_alg_ctx {
0143     struct list_head tsgl_list;
0144 
0145     void *iv;
0146     size_t aead_assoclen;
0147 
0148     struct crypto_wait wait;
0149 
0150     size_t used;
0151     atomic_t rcvused;
0152 
0153     bool more;
0154     bool merge;
0155     bool enc;
0156     bool init;
0157 
0158     unsigned int len;
0159 };
0160 
0161 int af_alg_register_type(const struct af_alg_type *type);
0162 int af_alg_unregister_type(const struct af_alg_type *type);
0163 
0164 int af_alg_release(struct socket *sock);
0165 void af_alg_release_parent(struct sock *sk);
0166 int af_alg_accept(struct sock *sk, struct socket *newsock, bool kern);
0167 
0168 int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len);
0169 void af_alg_free_sg(struct af_alg_sgl *sgl);
0170 
0171 static inline struct alg_sock *alg_sk(struct sock *sk)
0172 {
0173     return (struct alg_sock *)sk;
0174 }
0175 
0176 /**
0177  * Size of available buffer for sending data from user space to kernel.
0178  *
0179  * @sk socket of connection to user space
0180  * @return number of bytes still available
0181  */
0182 static inline int af_alg_sndbuf(struct sock *sk)
0183 {
0184     struct alg_sock *ask = alg_sk(sk);
0185     struct af_alg_ctx *ctx = ask->private;
0186 
0187     return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) -
0188               ctx->used, 0);
0189 }
0190 
0191 /**
0192  * Can the send buffer still be written to?
0193  *
0194  * @sk socket of connection to user space
0195  * @return true => writable, false => not writable
0196  */
0197 static inline bool af_alg_writable(struct sock *sk)
0198 {
0199     return PAGE_SIZE <= af_alg_sndbuf(sk);
0200 }
0201 
0202 /**
0203  * Size of available buffer used by kernel for the RX user space operation.
0204  *
0205  * @sk socket of connection to user space
0206  * @return number of bytes still available
0207  */
0208 static inline int af_alg_rcvbuf(struct sock *sk)
0209 {
0210     struct alg_sock *ask = alg_sk(sk);
0211     struct af_alg_ctx *ctx = ask->private;
0212 
0213     return max_t(int, max_t(int, sk->sk_rcvbuf & PAGE_MASK, PAGE_SIZE) -
0214              atomic_read(&ctx->rcvused), 0);
0215 }
0216 
0217 /**
0218  * Can the RX buffer still be written to?
0219  *
0220  * @sk socket of connection to user space
0221  * @return true => writable, false => not writable
0222  */
0223 static inline bool af_alg_readable(struct sock *sk)
0224 {
0225     return PAGE_SIZE <= af_alg_rcvbuf(sk);
0226 }
0227 
0228 unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset);
0229 void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
0230               size_t dst_offset);
0231 void af_alg_wmem_wakeup(struct sock *sk);
0232 int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min);
0233 int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
0234            unsigned int ivsize);
0235 ssize_t af_alg_sendpage(struct socket *sock, struct page *page,
0236             int offset, size_t size, int flags);
0237 void af_alg_free_resources(struct af_alg_async_req *areq);
0238 void af_alg_async_cb(struct crypto_async_request *_req, int err);
0239 __poll_t af_alg_poll(struct file *file, struct socket *sock,
0240              poll_table *wait);
0241 struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk,
0242                        unsigned int areqlen);
0243 int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
0244             struct af_alg_async_req *areq, size_t maxsize,
0245             size_t *outlen);
0246 
0247 #endif  /* _CRYPTO_IF_ALG_H */