18ff59090SHerbert Xu /* 28ff59090SHerbert Xu * algif_skcipher: User-space interface for skcipher algorithms 38ff59090SHerbert Xu * 48ff59090SHerbert Xu * This file provides the user-space API for symmetric key ciphers. 58ff59090SHerbert Xu * 68ff59090SHerbert Xu * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 78ff59090SHerbert Xu * 88ff59090SHerbert Xu * This program is free software; you can redistribute it and/or modify it 98ff59090SHerbert Xu * under the terms of the GNU General Public License as published by the Free 108ff59090SHerbert Xu * Software Foundation; either version 2 of the License, or (at your option) 118ff59090SHerbert Xu * any later version. 128ff59090SHerbert Xu * 13*e870456dSStephan Mueller * The following concept of the memory management is used: 14*e870456dSStephan Mueller * 15*e870456dSStephan Mueller * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is 16*e870456dSStephan Mueller * filled by user space with the data submitted via sendpage/sendmsg. Filling 17*e870456dSStephan Mueller * up the TX SGL does not cause a crypto operation -- the data will only be 18*e870456dSStephan Mueller * tracked by the kernel. Upon receipt of one recvmsg call, the caller must 19*e870456dSStephan Mueller * provide a buffer which is tracked with the RX SGL. 20*e870456dSStephan Mueller * 21*e870456dSStephan Mueller * During the processing of the recvmsg operation, the cipher request is 22*e870456dSStephan Mueller * allocated and prepared. As part of the recvmsg operation, the processed 23*e870456dSStephan Mueller * TX buffers are extracted from the TX SGL into a separate SGL. 24*e870456dSStephan Mueller * 25*e870456dSStephan Mueller * After the completion of the crypto operation, the RX SGL and the cipher 26*e870456dSStephan Mueller * request is released. The extracted TX SGL parts are released together with 27*e870456dSStephan Mueller * the RX SGL release. 288ff59090SHerbert Xu */ 298ff59090SHerbert Xu 308ff59090SHerbert Xu #include <crypto/scatterwalk.h> 318ff59090SHerbert Xu #include <crypto/skcipher.h> 328ff59090SHerbert Xu #include <crypto/if_alg.h> 338ff59090SHerbert Xu #include <linux/init.h> 348ff59090SHerbert Xu #include <linux/list.h> 358ff59090SHerbert Xu #include <linux/kernel.h> 36174cd4b1SIngo Molnar #include <linux/sched/signal.h> 378ff59090SHerbert Xu #include <linux/mm.h> 388ff59090SHerbert Xu #include <linux/module.h> 398ff59090SHerbert Xu #include <linux/net.h> 408ff59090SHerbert Xu #include <net/sock.h> 418ff59090SHerbert Xu 42*e870456dSStephan Mueller struct skcipher_tsgl { 438ff59090SHerbert Xu struct list_head list; 448ff59090SHerbert Xu int cur; 458ff59090SHerbert Xu struct scatterlist sg[0]; 468ff59090SHerbert Xu }; 478ff59090SHerbert Xu 48*e870456dSStephan Mueller struct skcipher_rsgl { 49*e870456dSStephan Mueller struct af_alg_sgl sgl; 50*e870456dSStephan Mueller struct list_head list; 51*e870456dSStephan Mueller size_t sg_num_bytes; 52*e870456dSStephan Mueller }; 53*e870456dSStephan Mueller 54*e870456dSStephan Mueller struct skcipher_async_req { 55*e870456dSStephan Mueller struct kiocb *iocb; 56*e870456dSStephan Mueller struct sock *sk; 57*e870456dSStephan Mueller 58*e870456dSStephan Mueller struct skcipher_rsgl first_sgl; 59*e870456dSStephan Mueller struct list_head rsgl_list; 60*e870456dSStephan Mueller 61*e870456dSStephan Mueller struct scatterlist *tsgl; 62*e870456dSStephan Mueller unsigned int tsgl_entries; 63*e870456dSStephan Mueller 64*e870456dSStephan Mueller unsigned int areqlen; 65*e870456dSStephan Mueller struct skcipher_request req; 66*e870456dSStephan Mueller }; 67*e870456dSStephan Mueller 68dd504589SHerbert Xu struct skcipher_tfm { 69dd504589SHerbert Xu struct crypto_skcipher *skcipher; 70dd504589SHerbert Xu bool has_key; 71dd504589SHerbert Xu }; 72dd504589SHerbert Xu 738ff59090SHerbert Xu struct skcipher_ctx { 74*e870456dSStephan Mueller struct list_head tsgl_list; 758ff59090SHerbert Xu 768ff59090SHerbert Xu void *iv; 778ff59090SHerbert Xu 788ff59090SHerbert Xu struct af_alg_completion completion; 798ff59090SHerbert Xu 80652d5b8aSLABBE Corentin size_t used; 81*e870456dSStephan Mueller size_t rcvused; 828ff59090SHerbert Xu 838ff59090SHerbert Xu bool more; 848ff59090SHerbert Xu bool merge; 858ff59090SHerbert Xu bool enc; 868ff59090SHerbert Xu 87*e870456dSStephan Mueller unsigned int len; 888ff59090SHerbert Xu }; 898ff59090SHerbert Xu 90*e870456dSStephan Mueller #define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_tsgl)) / \ 918ff59090SHerbert Xu sizeof(struct scatterlist) - 1) 928ff59090SHerbert Xu 930f6bb83cSHerbert Xu static inline int skcipher_sndbuf(struct sock *sk) 948ff59090SHerbert Xu { 958ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 968ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 978ff59090SHerbert Xu 980f6bb83cSHerbert Xu return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) - 990f6bb83cSHerbert Xu ctx->used, 0); 1000f6bb83cSHerbert Xu } 1010f6bb83cSHerbert Xu 1020f6bb83cSHerbert Xu static inline bool skcipher_writable(struct sock *sk) 1030f6bb83cSHerbert Xu { 1040f6bb83cSHerbert Xu return PAGE_SIZE <= skcipher_sndbuf(sk); 1058ff59090SHerbert Xu } 1068ff59090SHerbert Xu 107*e870456dSStephan Mueller static inline int skcipher_rcvbuf(struct sock *sk) 1088ff59090SHerbert Xu { 1098ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 1108ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 111*e870456dSStephan Mueller 112*e870456dSStephan Mueller return max_t(int, max_t(int, sk->sk_rcvbuf & PAGE_MASK, PAGE_SIZE) - 113*e870456dSStephan Mueller ctx->rcvused, 0); 114*e870456dSStephan Mueller } 115*e870456dSStephan Mueller 116*e870456dSStephan Mueller static inline bool skcipher_readable(struct sock *sk) 117*e870456dSStephan Mueller { 118*e870456dSStephan Mueller return PAGE_SIZE <= skcipher_rcvbuf(sk); 119*e870456dSStephan Mueller } 120*e870456dSStephan Mueller 121*e870456dSStephan Mueller static int skcipher_alloc_tsgl(struct sock *sk) 122*e870456dSStephan Mueller { 123*e870456dSStephan Mueller struct alg_sock *ask = alg_sk(sk); 124*e870456dSStephan Mueller struct skcipher_ctx *ctx = ask->private; 125*e870456dSStephan Mueller struct skcipher_tsgl *sgl; 1268ff59090SHerbert Xu struct scatterlist *sg = NULL; 1278ff59090SHerbert Xu 128*e870456dSStephan Mueller sgl = list_entry(ctx->tsgl_list.prev, struct skcipher_tsgl, list); 129*e870456dSStephan Mueller if (!list_empty(&ctx->tsgl_list)) 1308ff59090SHerbert Xu sg = sgl->sg; 1318ff59090SHerbert Xu 1328ff59090SHerbert Xu if (!sg || sgl->cur >= MAX_SGL_ENTS) { 1338ff59090SHerbert Xu sgl = sock_kmalloc(sk, sizeof(*sgl) + 1348ff59090SHerbert Xu sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1), 1358ff59090SHerbert Xu GFP_KERNEL); 1368ff59090SHerbert Xu if (!sgl) 1378ff59090SHerbert Xu return -ENOMEM; 1388ff59090SHerbert Xu 1398ff59090SHerbert Xu sg_init_table(sgl->sg, MAX_SGL_ENTS + 1); 1408ff59090SHerbert Xu sgl->cur = 0; 1418ff59090SHerbert Xu 1428ff59090SHerbert Xu if (sg) 143c56f6d12SDan Williams sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg); 1448ff59090SHerbert Xu 145*e870456dSStephan Mueller list_add_tail(&sgl->list, &ctx->tsgl_list); 1468ff59090SHerbert Xu } 1478ff59090SHerbert Xu 1488ff59090SHerbert Xu return 0; 1498ff59090SHerbert Xu } 1508ff59090SHerbert Xu 151*e870456dSStephan Mueller static unsigned int skcipher_count_tsgl(struct sock *sk, size_t bytes) 1528ff59090SHerbert Xu { 1538ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 1548ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 155*e870456dSStephan Mueller struct skcipher_tsgl *sgl, *tmp; 156*e870456dSStephan Mueller unsigned int i; 157*e870456dSStephan Mueller unsigned int sgl_count = 0; 1588ff59090SHerbert Xu 159*e870456dSStephan Mueller if (!bytes) 160*e870456dSStephan Mueller return 0; 161*e870456dSStephan Mueller 162*e870456dSStephan Mueller list_for_each_entry_safe(sgl, tmp, &ctx->tsgl_list, list) { 163*e870456dSStephan Mueller struct scatterlist *sg = sgl->sg; 164*e870456dSStephan Mueller 165*e870456dSStephan Mueller for (i = 0; i < sgl->cur; i++) { 166*e870456dSStephan Mueller sgl_count++; 167*e870456dSStephan Mueller if (sg[i].length >= bytes) 168*e870456dSStephan Mueller return sgl_count; 169*e870456dSStephan Mueller 170*e870456dSStephan Mueller bytes -= sg[i].length; 171*e870456dSStephan Mueller } 172*e870456dSStephan Mueller } 173*e870456dSStephan Mueller 174*e870456dSStephan Mueller return sgl_count; 175*e870456dSStephan Mueller } 176*e870456dSStephan Mueller 177*e870456dSStephan Mueller static void skcipher_pull_tsgl(struct sock *sk, size_t used, 178*e870456dSStephan Mueller struct scatterlist *dst) 179*e870456dSStephan Mueller { 180*e870456dSStephan Mueller struct alg_sock *ask = alg_sk(sk); 181*e870456dSStephan Mueller struct skcipher_ctx *ctx = ask->private; 182*e870456dSStephan Mueller struct skcipher_tsgl *sgl; 183*e870456dSStephan Mueller struct scatterlist *sg; 184*e870456dSStephan Mueller unsigned int i; 185*e870456dSStephan Mueller 186*e870456dSStephan Mueller while (!list_empty(&ctx->tsgl_list)) { 187*e870456dSStephan Mueller sgl = list_first_entry(&ctx->tsgl_list, struct skcipher_tsgl, 1888ff59090SHerbert Xu list); 1898ff59090SHerbert Xu sg = sgl->sg; 1908ff59090SHerbert Xu 1918ff59090SHerbert Xu for (i = 0; i < sgl->cur; i++) { 192652d5b8aSLABBE Corentin size_t plen = min_t(size_t, used, sg[i].length); 193*e870456dSStephan Mueller struct page *page = sg_page(sg + i); 1948ff59090SHerbert Xu 195*e870456dSStephan Mueller if (!page) 1968ff59090SHerbert Xu continue; 1978ff59090SHerbert Xu 198*e870456dSStephan Mueller /* 199*e870456dSStephan Mueller * Assumption: caller created skcipher_count_tsgl(len) 200*e870456dSStephan Mueller * SG entries in dst. 201*e870456dSStephan Mueller */ 202*e870456dSStephan Mueller if (dst) 203*e870456dSStephan Mueller sg_set_page(dst + i, page, plen, sg[i].offset); 204*e870456dSStephan Mueller 2058ff59090SHerbert Xu sg[i].length -= plen; 2068ff59090SHerbert Xu sg[i].offset += plen; 2078ff59090SHerbert Xu 2088ff59090SHerbert Xu used -= plen; 2098ff59090SHerbert Xu ctx->used -= plen; 2108ff59090SHerbert Xu 2118ff59090SHerbert Xu if (sg[i].length) 2128ff59090SHerbert Xu return; 213*e870456dSStephan Mueller 214*e870456dSStephan Mueller if (!dst) 215*e870456dSStephan Mueller put_page(page); 2168ff59090SHerbert Xu sg_assign_page(sg + i, NULL); 2178ff59090SHerbert Xu } 2188ff59090SHerbert Xu 2198ff59090SHerbert Xu list_del(&sgl->list); 220*e870456dSStephan Mueller sock_kfree_s(sk, sgl, sizeof(*sgl) + sizeof(sgl->sg[0]) * 2218ff59090SHerbert Xu (MAX_SGL_ENTS + 1)); 2228ff59090SHerbert Xu } 2238ff59090SHerbert Xu 2248ff59090SHerbert Xu if (!ctx->used) 2258ff59090SHerbert Xu ctx->merge = 0; 2268ff59090SHerbert Xu } 2278ff59090SHerbert Xu 228*e870456dSStephan Mueller static void skcipher_free_areq_sgls(struct skcipher_async_req *areq) 2298ff59090SHerbert Xu { 230*e870456dSStephan Mueller struct sock *sk = areq->sk; 2318ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 2328ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 233*e870456dSStephan Mueller struct skcipher_rsgl *rsgl, *tmp; 234*e870456dSStephan Mueller struct scatterlist *tsgl; 235*e870456dSStephan Mueller struct scatterlist *sg; 236*e870456dSStephan Mueller unsigned int i; 2378ff59090SHerbert Xu 238*e870456dSStephan Mueller list_for_each_entry_safe(rsgl, tmp, &areq->rsgl_list, list) { 239*e870456dSStephan Mueller ctx->rcvused -= rsgl->sg_num_bytes; 240*e870456dSStephan Mueller af_alg_free_sg(&rsgl->sgl); 241*e870456dSStephan Mueller list_del(&rsgl->list); 242*e870456dSStephan Mueller if (rsgl != &areq->first_sgl) 243*e870456dSStephan Mueller sock_kfree_s(sk, rsgl, sizeof(*rsgl)); 244*e870456dSStephan Mueller } 245*e870456dSStephan Mueller 246*e870456dSStephan Mueller tsgl = areq->tsgl; 247*e870456dSStephan Mueller for_each_sg(tsgl, sg, areq->tsgl_entries, i) { 248*e870456dSStephan Mueller if (!sg_page(sg)) 249*e870456dSStephan Mueller continue; 250*e870456dSStephan Mueller put_page(sg_page(sg)); 251*e870456dSStephan Mueller } 252*e870456dSStephan Mueller 253*e870456dSStephan Mueller if (areq->tsgl && areq->tsgl_entries) 254*e870456dSStephan Mueller sock_kfree_s(sk, tsgl, areq->tsgl_entries * sizeof(*tsgl)); 2558ff59090SHerbert Xu } 2568ff59090SHerbert Xu 2578ff59090SHerbert Xu static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags) 2588ff59090SHerbert Xu { 259d9dc8b0fSWANG Cong DEFINE_WAIT_FUNC(wait, woken_wake_function); 2608ff59090SHerbert Xu int err = -ERESTARTSYS; 261d9dc8b0fSWANG Cong long timeout; 2628ff59090SHerbert Xu 2638ff59090SHerbert Xu if (flags & MSG_DONTWAIT) 2648ff59090SHerbert Xu return -EAGAIN; 2658ff59090SHerbert Xu 2669cd3e072SEric Dumazet sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); 2678ff59090SHerbert Xu 268d9dc8b0fSWANG Cong add_wait_queue(sk_sleep(sk), &wait); 2698ff59090SHerbert Xu for (;;) { 2708ff59090SHerbert Xu if (signal_pending(current)) 2718ff59090SHerbert Xu break; 2728ff59090SHerbert Xu timeout = MAX_SCHEDULE_TIMEOUT; 273d9dc8b0fSWANG Cong if (sk_wait_event(sk, &timeout, skcipher_writable(sk), &wait)) { 2748ff59090SHerbert Xu err = 0; 2758ff59090SHerbert Xu break; 2768ff59090SHerbert Xu } 2778ff59090SHerbert Xu } 278d9dc8b0fSWANG Cong remove_wait_queue(sk_sleep(sk), &wait); 2798ff59090SHerbert Xu 2808ff59090SHerbert Xu return err; 2818ff59090SHerbert Xu } 2828ff59090SHerbert Xu 2838ff59090SHerbert Xu static void skcipher_wmem_wakeup(struct sock *sk) 2848ff59090SHerbert Xu { 2858ff59090SHerbert Xu struct socket_wq *wq; 2868ff59090SHerbert Xu 2878ff59090SHerbert Xu if (!skcipher_writable(sk)) 2888ff59090SHerbert Xu return; 2898ff59090SHerbert Xu 2908ff59090SHerbert Xu rcu_read_lock(); 2918ff59090SHerbert Xu wq = rcu_dereference(sk->sk_wq); 2921ce0bf50SHerbert Xu if (skwq_has_sleeper(wq)) 2938ff59090SHerbert Xu wake_up_interruptible_sync_poll(&wq->wait, POLLIN | 2948ff59090SHerbert Xu POLLRDNORM | 2958ff59090SHerbert Xu POLLRDBAND); 2968ff59090SHerbert Xu sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); 2978ff59090SHerbert Xu rcu_read_unlock(); 2988ff59090SHerbert Xu } 2998ff59090SHerbert Xu 3008ff59090SHerbert Xu static int skcipher_wait_for_data(struct sock *sk, unsigned flags) 3018ff59090SHerbert Xu { 302d9dc8b0fSWANG Cong DEFINE_WAIT_FUNC(wait, woken_wake_function); 3038ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 3048ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 3058ff59090SHerbert Xu long timeout; 3068ff59090SHerbert Xu int err = -ERESTARTSYS; 3078ff59090SHerbert Xu 3088ff59090SHerbert Xu if (flags & MSG_DONTWAIT) { 3098ff59090SHerbert Xu return -EAGAIN; 3108ff59090SHerbert Xu } 3118ff59090SHerbert Xu 3129cd3e072SEric Dumazet sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); 3138ff59090SHerbert Xu 314d9dc8b0fSWANG Cong add_wait_queue(sk_sleep(sk), &wait); 3158ff59090SHerbert Xu for (;;) { 3168ff59090SHerbert Xu if (signal_pending(current)) 3178ff59090SHerbert Xu break; 3188ff59090SHerbert Xu timeout = MAX_SCHEDULE_TIMEOUT; 319d9dc8b0fSWANG Cong if (sk_wait_event(sk, &timeout, ctx->used, &wait)) { 3208ff59090SHerbert Xu err = 0; 3218ff59090SHerbert Xu break; 3228ff59090SHerbert Xu } 3238ff59090SHerbert Xu } 324d9dc8b0fSWANG Cong remove_wait_queue(sk_sleep(sk), &wait); 3258ff59090SHerbert Xu 3269cd3e072SEric Dumazet sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); 3278ff59090SHerbert Xu 3288ff59090SHerbert Xu return err; 3298ff59090SHerbert Xu } 3308ff59090SHerbert Xu 3318ff59090SHerbert Xu static void skcipher_data_wakeup(struct sock *sk) 3328ff59090SHerbert Xu { 3338ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 3348ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 3358ff59090SHerbert Xu struct socket_wq *wq; 3368ff59090SHerbert Xu 3378ff59090SHerbert Xu if (!ctx->used) 3388ff59090SHerbert Xu return; 3398ff59090SHerbert Xu 3408ff59090SHerbert Xu rcu_read_lock(); 3418ff59090SHerbert Xu wq = rcu_dereference(sk->sk_wq); 3421ce0bf50SHerbert Xu if (skwq_has_sleeper(wq)) 3438ff59090SHerbert Xu wake_up_interruptible_sync_poll(&wq->wait, POLLOUT | 3448ff59090SHerbert Xu POLLRDNORM | 3458ff59090SHerbert Xu POLLRDBAND); 3468ff59090SHerbert Xu sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); 3478ff59090SHerbert Xu rcu_read_unlock(); 3488ff59090SHerbert Xu } 3498ff59090SHerbert Xu 3501b784140SYing Xue static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg, 3511b784140SYing Xue size_t size) 3528ff59090SHerbert Xu { 3538ff59090SHerbert Xu struct sock *sk = sock->sk; 3548ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 3556454c2b8SHerbert Xu struct sock *psk = ask->parent; 3566454c2b8SHerbert Xu struct alg_sock *pask = alg_sk(psk); 3578ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 3586454c2b8SHerbert Xu struct skcipher_tfm *skc = pask->private; 3596454c2b8SHerbert Xu struct crypto_skcipher *tfm = skc->skcipher; 3600d96e4baSHerbert Xu unsigned ivsize = crypto_skcipher_ivsize(tfm); 361*e870456dSStephan Mueller struct skcipher_tsgl *sgl; 3628ff59090SHerbert Xu struct af_alg_control con = {}; 3638ff59090SHerbert Xu long copied = 0; 3648ff59090SHerbert Xu bool enc = 0; 365f26b7b80SStephan Mueller bool init = 0; 3668ff59090SHerbert Xu int err; 3678ff59090SHerbert Xu int i; 3688ff59090SHerbert Xu 3698ff59090SHerbert Xu if (msg->msg_controllen) { 3708ff59090SHerbert Xu err = af_alg_cmsg_send(msg, &con); 3718ff59090SHerbert Xu if (err) 3728ff59090SHerbert Xu return err; 3738ff59090SHerbert Xu 374f26b7b80SStephan Mueller init = 1; 3758ff59090SHerbert Xu switch (con.op) { 3768ff59090SHerbert Xu case ALG_OP_ENCRYPT: 3778ff59090SHerbert Xu enc = 1; 3788ff59090SHerbert Xu break; 3798ff59090SHerbert Xu case ALG_OP_DECRYPT: 3808ff59090SHerbert Xu enc = 0; 3818ff59090SHerbert Xu break; 3828ff59090SHerbert Xu default: 3838ff59090SHerbert Xu return -EINVAL; 3848ff59090SHerbert Xu } 3858ff59090SHerbert Xu 3868ff59090SHerbert Xu if (con.iv && con.iv->ivlen != ivsize) 3878ff59090SHerbert Xu return -EINVAL; 3888ff59090SHerbert Xu } 3898ff59090SHerbert Xu 3908ff59090SHerbert Xu err = -EINVAL; 3918ff59090SHerbert Xu 3928ff59090SHerbert Xu lock_sock(sk); 3938ff59090SHerbert Xu if (!ctx->more && ctx->used) 3948ff59090SHerbert Xu goto unlock; 3958ff59090SHerbert Xu 396f26b7b80SStephan Mueller if (init) { 3978ff59090SHerbert Xu ctx->enc = enc; 3988ff59090SHerbert Xu if (con.iv) 3998ff59090SHerbert Xu memcpy(ctx->iv, con.iv->iv, ivsize); 4008ff59090SHerbert Xu } 4018ff59090SHerbert Xu 4028ff59090SHerbert Xu while (size) { 4038ff59090SHerbert Xu struct scatterlist *sg; 4048ff59090SHerbert Xu unsigned long len = size; 405652d5b8aSLABBE Corentin size_t plen; 4068ff59090SHerbert Xu 4078ff59090SHerbert Xu if (ctx->merge) { 408*e870456dSStephan Mueller sgl = list_entry(ctx->tsgl_list.prev, 409*e870456dSStephan Mueller struct skcipher_tsgl, list); 4108ff59090SHerbert Xu sg = sgl->sg + sgl->cur - 1; 4118ff59090SHerbert Xu len = min_t(unsigned long, len, 4128ff59090SHerbert Xu PAGE_SIZE - sg->offset - sg->length); 4138ff59090SHerbert Xu 4146ce8e9ceSAl Viro err = memcpy_from_msg(page_address(sg_page(sg)) + 4158ff59090SHerbert Xu sg->offset + sg->length, 4166ce8e9ceSAl Viro msg, len); 4178ff59090SHerbert Xu if (err) 4188ff59090SHerbert Xu goto unlock; 4198ff59090SHerbert Xu 4208ff59090SHerbert Xu sg->length += len; 4218ff59090SHerbert Xu ctx->merge = (sg->offset + sg->length) & 4228ff59090SHerbert Xu (PAGE_SIZE - 1); 4238ff59090SHerbert Xu 4248ff59090SHerbert Xu ctx->used += len; 4258ff59090SHerbert Xu copied += len; 4268ff59090SHerbert Xu size -= len; 4278ff59090SHerbert Xu continue; 4288ff59090SHerbert Xu } 4298ff59090SHerbert Xu 4300f6bb83cSHerbert Xu if (!skcipher_writable(sk)) { 4318ff59090SHerbert Xu err = skcipher_wait_for_wmem(sk, msg->msg_flags); 4328ff59090SHerbert Xu if (err) 4338ff59090SHerbert Xu goto unlock; 4348ff59090SHerbert Xu } 4358ff59090SHerbert Xu 4360f6bb83cSHerbert Xu len = min_t(unsigned long, len, skcipher_sndbuf(sk)); 4378ff59090SHerbert Xu 438*e870456dSStephan Mueller err = skcipher_alloc_tsgl(sk); 4398ff59090SHerbert Xu if (err) 4408ff59090SHerbert Xu goto unlock; 4418ff59090SHerbert Xu 442*e870456dSStephan Mueller sgl = list_entry(ctx->tsgl_list.prev, struct skcipher_tsgl, 443*e870456dSStephan Mueller list); 4448ff59090SHerbert Xu sg = sgl->sg; 445202736d9SHerbert Xu if (sgl->cur) 446202736d9SHerbert Xu sg_unmark_end(sg + sgl->cur - 1); 4478ff59090SHerbert Xu do { 4488ff59090SHerbert Xu i = sgl->cur; 449652d5b8aSLABBE Corentin plen = min_t(size_t, len, PAGE_SIZE); 4508ff59090SHerbert Xu 4518ff59090SHerbert Xu sg_assign_page(sg + i, alloc_page(GFP_KERNEL)); 4528ff59090SHerbert Xu err = -ENOMEM; 4538ff59090SHerbert Xu if (!sg_page(sg + i)) 4548ff59090SHerbert Xu goto unlock; 4558ff59090SHerbert Xu 4566ce8e9ceSAl Viro err = memcpy_from_msg(page_address(sg_page(sg + i)), 4576ce8e9ceSAl Viro msg, plen); 4588ff59090SHerbert Xu if (err) { 4598ff59090SHerbert Xu __free_page(sg_page(sg + i)); 4608ff59090SHerbert Xu sg_assign_page(sg + i, NULL); 4618ff59090SHerbert Xu goto unlock; 4628ff59090SHerbert Xu } 4638ff59090SHerbert Xu 4648ff59090SHerbert Xu sg[i].length = plen; 4658ff59090SHerbert Xu len -= plen; 4668ff59090SHerbert Xu ctx->used += plen; 4678ff59090SHerbert Xu copied += plen; 4688ff59090SHerbert Xu size -= plen; 4698ff59090SHerbert Xu sgl->cur++; 4708ff59090SHerbert Xu } while (len && sgl->cur < MAX_SGL_ENTS); 4718ff59090SHerbert Xu 4720f477b65STadeusz Struk if (!size) 4730f477b65STadeusz Struk sg_mark_end(sg + sgl->cur - 1); 4740f477b65STadeusz Struk 4758ff59090SHerbert Xu ctx->merge = plen & (PAGE_SIZE - 1); 4768ff59090SHerbert Xu } 4778ff59090SHerbert Xu 4788ff59090SHerbert Xu err = 0; 4798ff59090SHerbert Xu 4808ff59090SHerbert Xu ctx->more = msg->msg_flags & MSG_MORE; 4818ff59090SHerbert Xu 4828ff59090SHerbert Xu unlock: 4838ff59090SHerbert Xu skcipher_data_wakeup(sk); 4848ff59090SHerbert Xu release_sock(sk); 4858ff59090SHerbert Xu 4868ff59090SHerbert Xu return copied ?: err; 4878ff59090SHerbert Xu } 4888ff59090SHerbert Xu 4898ff59090SHerbert Xu static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, 4908ff59090SHerbert Xu int offset, size_t size, int flags) 4918ff59090SHerbert Xu { 4928ff59090SHerbert Xu struct sock *sk = sock->sk; 4938ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 4948ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 495*e870456dSStephan Mueller struct skcipher_tsgl *sgl; 4968ff59090SHerbert Xu int err = -EINVAL; 4978ff59090SHerbert Xu 498d3f7d56aSShawn Landden if (flags & MSG_SENDPAGE_NOTLAST) 499d3f7d56aSShawn Landden flags |= MSG_MORE; 500d3f7d56aSShawn Landden 5018ff59090SHerbert Xu lock_sock(sk); 5028ff59090SHerbert Xu if (!ctx->more && ctx->used) 5038ff59090SHerbert Xu goto unlock; 5048ff59090SHerbert Xu 5058ff59090SHerbert Xu if (!size) 5068ff59090SHerbert Xu goto done; 5078ff59090SHerbert Xu 5080f6bb83cSHerbert Xu if (!skcipher_writable(sk)) { 5098ff59090SHerbert Xu err = skcipher_wait_for_wmem(sk, flags); 5108ff59090SHerbert Xu if (err) 5118ff59090SHerbert Xu goto unlock; 5128ff59090SHerbert Xu } 5138ff59090SHerbert Xu 514*e870456dSStephan Mueller err = skcipher_alloc_tsgl(sk); 5158ff59090SHerbert Xu if (err) 5168ff59090SHerbert Xu goto unlock; 5178ff59090SHerbert Xu 5188ff59090SHerbert Xu ctx->merge = 0; 519*e870456dSStephan Mueller sgl = list_entry(ctx->tsgl_list.prev, struct skcipher_tsgl, list); 5208ff59090SHerbert Xu 5210f477b65STadeusz Struk if (sgl->cur) 5220f477b65STadeusz Struk sg_unmark_end(sgl->sg + sgl->cur - 1); 5230f477b65STadeusz Struk 5240f477b65STadeusz Struk sg_mark_end(sgl->sg + sgl->cur); 5258ff59090SHerbert Xu get_page(page); 5268ff59090SHerbert Xu sg_set_page(sgl->sg + sgl->cur, page, size, offset); 5278ff59090SHerbert Xu sgl->cur++; 5288ff59090SHerbert Xu ctx->used += size; 5298ff59090SHerbert Xu 5308ff59090SHerbert Xu done: 5318ff59090SHerbert Xu ctx->more = flags & MSG_MORE; 5328ff59090SHerbert Xu 5338ff59090SHerbert Xu unlock: 5348ff59090SHerbert Xu skcipher_data_wakeup(sk); 5358ff59090SHerbert Xu release_sock(sk); 5368ff59090SHerbert Xu 5378ff59090SHerbert Xu return err ?: size; 5388ff59090SHerbert Xu } 5398ff59090SHerbert Xu 540*e870456dSStephan Mueller static void skcipher_async_cb(struct crypto_async_request *req, int err) 541a596999bSTadeusz Struk { 542*e870456dSStephan Mueller struct skcipher_async_req *areq = req->data; 543*e870456dSStephan Mueller struct sock *sk = areq->sk; 544*e870456dSStephan Mueller struct kiocb *iocb = areq->iocb; 545*e870456dSStephan Mueller unsigned int resultlen; 546a596999bSTadeusz Struk 547*e870456dSStephan Mueller lock_sock(sk); 548a596999bSTadeusz Struk 549*e870456dSStephan Mueller /* Buffer size written by crypto operation. */ 550*e870456dSStephan Mueller resultlen = areq->req.cryptlen; 551a596999bSTadeusz Struk 552*e870456dSStephan Mueller skcipher_free_areq_sgls(areq); 553*e870456dSStephan Mueller sock_kfree_s(sk, areq, areq->areqlen); 554*e870456dSStephan Mueller __sock_put(sk); 555*e870456dSStephan Mueller 556*e870456dSStephan Mueller iocb->ki_complete(iocb, err ? err : resultlen, 0); 557*e870456dSStephan Mueller 558*e870456dSStephan Mueller release_sock(sk); 559a596999bSTadeusz Struk } 560a596999bSTadeusz Struk 561*e870456dSStephan Mueller static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, 562*e870456dSStephan Mueller size_t ignored, int flags) 563a596999bSTadeusz Struk { 564a596999bSTadeusz Struk struct sock *sk = sock->sk; 565a596999bSTadeusz Struk struct alg_sock *ask = alg_sk(sk); 566ec69bbfbSHerbert Xu struct sock *psk = ask->parent; 567ec69bbfbSHerbert Xu struct alg_sock *pask = alg_sk(psk); 568a596999bSTadeusz Struk struct skcipher_ctx *ctx = ask->private; 569ec69bbfbSHerbert Xu struct skcipher_tfm *skc = pask->private; 570ec69bbfbSHerbert Xu struct crypto_skcipher *tfm = skc->skcipher; 571*e870456dSStephan Mueller unsigned int bs = crypto_skcipher_blocksize(tfm); 572*e870456dSStephan Mueller unsigned int areqlen = sizeof(struct skcipher_async_req) + 573*e870456dSStephan Mueller crypto_skcipher_reqsize(tfm); 574*e870456dSStephan Mueller struct skcipher_async_req *areq; 575*e870456dSStephan Mueller struct skcipher_rsgl *last_rsgl = NULL; 576*e870456dSStephan Mueller int err = 0; 577*e870456dSStephan Mueller size_t len = 0; 578ec69bbfbSHerbert Xu 579*e870456dSStephan Mueller /* Allocate cipher request for current operation. */ 580*e870456dSStephan Mueller areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); 581*e870456dSStephan Mueller if (unlikely(!areq)) 582*e870456dSStephan Mueller return -ENOMEM; 583*e870456dSStephan Mueller areq->areqlen = areqlen; 584*e870456dSStephan Mueller areq->sk = sk; 585*e870456dSStephan Mueller INIT_LIST_HEAD(&areq->rsgl_list); 586*e870456dSStephan Mueller areq->tsgl = NULL; 587*e870456dSStephan Mueller areq->tsgl_entries = 0; 588ec69bbfbSHerbert Xu 589*e870456dSStephan Mueller /* convert iovecs of output buffers into RX SGL */ 590*e870456dSStephan Mueller while (msg_data_left(msg)) { 591*e870456dSStephan Mueller struct skcipher_rsgl *rsgl; 592*e870456dSStephan Mueller size_t seglen; 593a596999bSTadeusz Struk 594*e870456dSStephan Mueller /* limit the amount of readable buffers */ 595*e870456dSStephan Mueller if (!skcipher_readable(sk)) 596*e870456dSStephan Mueller break; 597a596999bSTadeusz Struk 598a596999bSTadeusz Struk if (!ctx->used) { 599a596999bSTadeusz Struk err = skcipher_wait_for_data(sk, flags); 600a596999bSTadeusz Struk if (err) 601a596999bSTadeusz Struk goto free; 602a596999bSTadeusz Struk } 603a596999bSTadeusz Struk 604*e870456dSStephan Mueller seglen = min_t(size_t, ctx->used, msg_data_left(msg)); 605a596999bSTadeusz Struk 606*e870456dSStephan Mueller if (list_empty(&areq->rsgl_list)) { 607*e870456dSStephan Mueller rsgl = &areq->first_sgl; 608a596999bSTadeusz Struk } else { 609*e870456dSStephan Mueller rsgl = sock_kmalloc(sk, sizeof(*rsgl), GFP_KERNEL); 610a596999bSTadeusz Struk if (!rsgl) { 611a596999bSTadeusz Struk err = -ENOMEM; 612a596999bSTadeusz Struk goto free; 613a596999bSTadeusz Struk } 614a596999bSTadeusz Struk } 615a596999bSTadeusz Struk 616*e870456dSStephan Mueller rsgl->sgl.npages = 0; 617*e870456dSStephan Mueller list_add_tail(&rsgl->list, &areq->rsgl_list); 618*e870456dSStephan Mueller 619*e870456dSStephan Mueller /* make one iovec available as scatterlist */ 620*e870456dSStephan Mueller err = af_alg_make_sg(&rsgl->sgl, &msg->msg_iter, seglen); 621*e870456dSStephan Mueller if (err < 0) 622a596999bSTadeusz Struk goto free; 623*e870456dSStephan Mueller 624*e870456dSStephan Mueller /* chain the new scatterlist with previous one */ 625a596999bSTadeusz Struk if (last_rsgl) 626a596999bSTadeusz Struk af_alg_link_sg(&last_rsgl->sgl, &rsgl->sgl); 627a596999bSTadeusz Struk 628a596999bSTadeusz Struk last_rsgl = rsgl; 629*e870456dSStephan Mueller len += err; 630*e870456dSStephan Mueller ctx->rcvused += err; 631*e870456dSStephan Mueller rsgl->sg_num_bytes = err; 632*e870456dSStephan Mueller iov_iter_advance(&msg->msg_iter, err); 633a596999bSTadeusz Struk } 634a596999bSTadeusz Struk 635*e870456dSStephan Mueller /* Process only as much RX buffers for which we have TX data */ 636*e870456dSStephan Mueller if (len > ctx->used) 637*e870456dSStephan Mueller len = ctx->used; 638033f46b3Stadeusz.struk@intel.com 639*e870456dSStephan Mueller /* 640*e870456dSStephan Mueller * If more buffers are to be expected to be processed, process only 641*e870456dSStephan Mueller * full block size buffers. 642*e870456dSStephan Mueller */ 643*e870456dSStephan Mueller if (ctx->more || len < ctx->used) 644*e870456dSStephan Mueller len -= len % bs; 645a596999bSTadeusz Struk 646*e870456dSStephan Mueller /* 647*e870456dSStephan Mueller * Create a per request TX SGL for this request which tracks the 648*e870456dSStephan Mueller * SG entries from the global TX SGL. 649*e870456dSStephan Mueller */ 650*e870456dSStephan Mueller areq->tsgl_entries = skcipher_count_tsgl(sk, len); 651*e870456dSStephan Mueller if (!areq->tsgl_entries) 652*e870456dSStephan Mueller areq->tsgl_entries = 1; 653*e870456dSStephan Mueller areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * areq->tsgl_entries, 654*e870456dSStephan Mueller GFP_KERNEL); 655*e870456dSStephan Mueller if (!areq->tsgl) { 656*e870456dSStephan Mueller err = -ENOMEM; 657bc97e57eSHerbert Xu goto free; 658*e870456dSStephan Mueller } 659*e870456dSStephan Mueller sg_init_table(areq->tsgl, areq->tsgl_entries); 660*e870456dSStephan Mueller skcipher_pull_tsgl(sk, len, areq->tsgl); 6618ff59090SHerbert Xu 662*e870456dSStephan Mueller /* Initialize the crypto operation */ 663*e870456dSStephan Mueller skcipher_request_set_tfm(&areq->req, tfm); 664*e870456dSStephan Mueller skcipher_request_set_crypt(&areq->req, areq->tsgl, 665*e870456dSStephan Mueller areq->first_sgl.sgl.sg, len, ctx->iv); 6664f0414e5SHerbert Xu 667*e870456dSStephan Mueller if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) { 668*e870456dSStephan Mueller /* AIO operation */ 669*e870456dSStephan Mueller areq->iocb = msg->msg_iocb; 670*e870456dSStephan Mueller skcipher_request_set_callback(&areq->req, 671*e870456dSStephan Mueller CRYPTO_TFM_REQ_MAY_SLEEP, 672*e870456dSStephan Mueller skcipher_async_cb, areq); 673*e870456dSStephan Mueller err = ctx->enc ? crypto_skcipher_encrypt(&areq->req) : 674*e870456dSStephan Mueller crypto_skcipher_decrypt(&areq->req); 675*e870456dSStephan Mueller } else { 676*e870456dSStephan Mueller /* Synchronous operation */ 677*e870456dSStephan Mueller skcipher_request_set_callback(&areq->req, 678*e870456dSStephan Mueller CRYPTO_TFM_REQ_MAY_SLEEP | 679*e870456dSStephan Mueller CRYPTO_TFM_REQ_MAY_BACKLOG, 680*e870456dSStephan Mueller af_alg_complete, 6818ff59090SHerbert Xu &ctx->completion); 682*e870456dSStephan Mueller err = af_alg_wait_for_completion(ctx->enc ? 683*e870456dSStephan Mueller crypto_skcipher_encrypt(&areq->req) : 684*e870456dSStephan Mueller crypto_skcipher_decrypt(&areq->req), 685*e870456dSStephan Mueller &ctx->completion); 6868ff59090SHerbert Xu } 6878ff59090SHerbert Xu 688*e870456dSStephan Mueller /* AIO operation in progress */ 689*e870456dSStephan Mueller if (err == -EINPROGRESS) { 690*e870456dSStephan Mueller sock_hold(sk); 691*e870456dSStephan Mueller return -EIOCBQUEUED; 692*e870456dSStephan Mueller } 6938ff59090SHerbert Xu 694*e870456dSStephan Mueller free: 695*e870456dSStephan Mueller skcipher_free_areq_sgls(areq); 696*e870456dSStephan Mueller if (areq) 697*e870456dSStephan Mueller sock_kfree_s(sk, areq, areqlen); 6988ff59090SHerbert Xu 699*e870456dSStephan Mueller return err ? err : len; 7008ff59090SHerbert Xu } 7018ff59090SHerbert Xu 702a596999bSTadeusz Struk static int skcipher_recvmsg(struct socket *sock, struct msghdr *msg, 703a596999bSTadeusz Struk size_t ignored, int flags) 704a596999bSTadeusz Struk { 705*e870456dSStephan Mueller struct sock *sk = sock->sk; 706*e870456dSStephan Mueller int ret = 0; 707*e870456dSStephan Mueller 708*e870456dSStephan Mueller lock_sock(sk); 709*e870456dSStephan Mueller while (msg_data_left(msg)) { 710*e870456dSStephan Mueller int err = _skcipher_recvmsg(sock, msg, ignored, flags); 711*e870456dSStephan Mueller 712*e870456dSStephan Mueller /* 713*e870456dSStephan Mueller * This error covers -EIOCBQUEUED which implies that we can 714*e870456dSStephan Mueller * only handle one AIO request. If the caller wants to have 715*e870456dSStephan Mueller * multiple AIO requests in parallel, he must make multiple 716*e870456dSStephan Mueller * separate AIO calls. 717*e870456dSStephan Mueller */ 718*e870456dSStephan Mueller if (err <= 0) { 719*e870456dSStephan Mueller if (err == -EIOCBQUEUED) 720*e870456dSStephan Mueller ret = err; 721*e870456dSStephan Mueller goto out; 722*e870456dSStephan Mueller } 723*e870456dSStephan Mueller 724*e870456dSStephan Mueller ret += err; 725*e870456dSStephan Mueller } 726*e870456dSStephan Mueller 727*e870456dSStephan Mueller out: 728*e870456dSStephan Mueller skcipher_wmem_wakeup(sk); 729*e870456dSStephan Mueller release_sock(sk); 730*e870456dSStephan Mueller return ret; 731a596999bSTadeusz Struk } 7328ff59090SHerbert Xu 7338ff59090SHerbert Xu static unsigned int skcipher_poll(struct file *file, struct socket *sock, 7348ff59090SHerbert Xu poll_table *wait) 7358ff59090SHerbert Xu { 7368ff59090SHerbert Xu struct sock *sk = sock->sk; 7378ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 7388ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 7398ff59090SHerbert Xu unsigned int mask; 7408ff59090SHerbert Xu 7418ff59090SHerbert Xu sock_poll_wait(file, sk_sleep(sk), wait); 7428ff59090SHerbert Xu mask = 0; 7438ff59090SHerbert Xu 7448ff59090SHerbert Xu if (ctx->used) 7458ff59090SHerbert Xu mask |= POLLIN | POLLRDNORM; 7468ff59090SHerbert Xu 7478ff59090SHerbert Xu if (skcipher_writable(sk)) 7488ff59090SHerbert Xu mask |= POLLOUT | POLLWRNORM | POLLWRBAND; 7498ff59090SHerbert Xu 7508ff59090SHerbert Xu return mask; 7518ff59090SHerbert Xu } 7528ff59090SHerbert Xu 7538ff59090SHerbert Xu static struct proto_ops algif_skcipher_ops = { 7548ff59090SHerbert Xu .family = PF_ALG, 7558ff59090SHerbert Xu 7568ff59090SHerbert Xu .connect = sock_no_connect, 7578ff59090SHerbert Xu .socketpair = sock_no_socketpair, 7588ff59090SHerbert Xu .getname = sock_no_getname, 7598ff59090SHerbert Xu .ioctl = sock_no_ioctl, 7608ff59090SHerbert Xu .listen = sock_no_listen, 7618ff59090SHerbert Xu .shutdown = sock_no_shutdown, 7628ff59090SHerbert Xu .getsockopt = sock_no_getsockopt, 7638ff59090SHerbert Xu .mmap = sock_no_mmap, 7648ff59090SHerbert Xu .bind = sock_no_bind, 7658ff59090SHerbert Xu .accept = sock_no_accept, 7668ff59090SHerbert Xu .setsockopt = sock_no_setsockopt, 7678ff59090SHerbert Xu 7688ff59090SHerbert Xu .release = af_alg_release, 7698ff59090SHerbert Xu .sendmsg = skcipher_sendmsg, 7708ff59090SHerbert Xu .sendpage = skcipher_sendpage, 7718ff59090SHerbert Xu .recvmsg = skcipher_recvmsg, 7728ff59090SHerbert Xu .poll = skcipher_poll, 7738ff59090SHerbert Xu }; 7748ff59090SHerbert Xu 775a0fa2d03SHerbert Xu static int skcipher_check_key(struct socket *sock) 776a0fa2d03SHerbert Xu { 7771822793aSHerbert Xu int err = 0; 778a0fa2d03SHerbert Xu struct sock *psk; 779a0fa2d03SHerbert Xu struct alg_sock *pask; 780a0fa2d03SHerbert Xu struct skcipher_tfm *tfm; 781a0fa2d03SHerbert Xu struct sock *sk = sock->sk; 782a0fa2d03SHerbert Xu struct alg_sock *ask = alg_sk(sk); 783a0fa2d03SHerbert Xu 7841822793aSHerbert Xu lock_sock(sk); 785a0fa2d03SHerbert Xu if (ask->refcnt) 7861822793aSHerbert Xu goto unlock_child; 787a0fa2d03SHerbert Xu 788a0fa2d03SHerbert Xu psk = ask->parent; 789a0fa2d03SHerbert Xu pask = alg_sk(ask->parent); 790a0fa2d03SHerbert Xu tfm = pask->private; 791a0fa2d03SHerbert Xu 792a0fa2d03SHerbert Xu err = -ENOKEY; 7931822793aSHerbert Xu lock_sock_nested(psk, SINGLE_DEPTH_NESTING); 794a0fa2d03SHerbert Xu if (!tfm->has_key) 795a0fa2d03SHerbert Xu goto unlock; 796a0fa2d03SHerbert Xu 797a0fa2d03SHerbert Xu if (!pask->refcnt++) 798a0fa2d03SHerbert Xu sock_hold(psk); 799a0fa2d03SHerbert Xu 800a0fa2d03SHerbert Xu ask->refcnt = 1; 801a0fa2d03SHerbert Xu sock_put(psk); 802a0fa2d03SHerbert Xu 803a0fa2d03SHerbert Xu err = 0; 804a0fa2d03SHerbert Xu 805a0fa2d03SHerbert Xu unlock: 806a0fa2d03SHerbert Xu release_sock(psk); 8071822793aSHerbert Xu unlock_child: 8081822793aSHerbert Xu release_sock(sk); 809a0fa2d03SHerbert Xu 810a0fa2d03SHerbert Xu return err; 811a0fa2d03SHerbert Xu } 812a0fa2d03SHerbert Xu 813a0fa2d03SHerbert Xu static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg, 814a0fa2d03SHerbert Xu size_t size) 815a0fa2d03SHerbert Xu { 816a0fa2d03SHerbert Xu int err; 817a0fa2d03SHerbert Xu 818a0fa2d03SHerbert Xu err = skcipher_check_key(sock); 819a0fa2d03SHerbert Xu if (err) 820a0fa2d03SHerbert Xu return err; 821a0fa2d03SHerbert Xu 822a0fa2d03SHerbert Xu return skcipher_sendmsg(sock, msg, size); 823a0fa2d03SHerbert Xu } 824a0fa2d03SHerbert Xu 825a0fa2d03SHerbert Xu static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page, 826a0fa2d03SHerbert Xu int offset, size_t size, int flags) 827a0fa2d03SHerbert Xu { 828a0fa2d03SHerbert Xu int err; 829a0fa2d03SHerbert Xu 830a0fa2d03SHerbert Xu err = skcipher_check_key(sock); 831a0fa2d03SHerbert Xu if (err) 832a0fa2d03SHerbert Xu return err; 833a0fa2d03SHerbert Xu 834a0fa2d03SHerbert Xu return skcipher_sendpage(sock, page, offset, size, flags); 835a0fa2d03SHerbert Xu } 836a0fa2d03SHerbert Xu 837a0fa2d03SHerbert Xu static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg, 838a0fa2d03SHerbert Xu size_t ignored, int flags) 839a0fa2d03SHerbert Xu { 840a0fa2d03SHerbert Xu int err; 841a0fa2d03SHerbert Xu 842a0fa2d03SHerbert Xu err = skcipher_check_key(sock); 843a0fa2d03SHerbert Xu if (err) 844a0fa2d03SHerbert Xu return err; 845a0fa2d03SHerbert Xu 846a0fa2d03SHerbert Xu return skcipher_recvmsg(sock, msg, ignored, flags); 847a0fa2d03SHerbert Xu } 848a0fa2d03SHerbert Xu 849a0fa2d03SHerbert Xu static struct proto_ops algif_skcipher_ops_nokey = { 850a0fa2d03SHerbert Xu .family = PF_ALG, 851a0fa2d03SHerbert Xu 852a0fa2d03SHerbert Xu .connect = sock_no_connect, 853a0fa2d03SHerbert Xu .socketpair = sock_no_socketpair, 854a0fa2d03SHerbert Xu .getname = sock_no_getname, 855a0fa2d03SHerbert Xu .ioctl = sock_no_ioctl, 856a0fa2d03SHerbert Xu .listen = sock_no_listen, 857a0fa2d03SHerbert Xu .shutdown = sock_no_shutdown, 858a0fa2d03SHerbert Xu .getsockopt = sock_no_getsockopt, 859a0fa2d03SHerbert Xu .mmap = sock_no_mmap, 860a0fa2d03SHerbert Xu .bind = sock_no_bind, 861a0fa2d03SHerbert Xu .accept = sock_no_accept, 862a0fa2d03SHerbert Xu .setsockopt = sock_no_setsockopt, 863a0fa2d03SHerbert Xu 864a0fa2d03SHerbert Xu .release = af_alg_release, 865a0fa2d03SHerbert Xu .sendmsg = skcipher_sendmsg_nokey, 866a0fa2d03SHerbert Xu .sendpage = skcipher_sendpage_nokey, 867a0fa2d03SHerbert Xu .recvmsg = skcipher_recvmsg_nokey, 868a0fa2d03SHerbert Xu .poll = skcipher_poll, 869a0fa2d03SHerbert Xu }; 870a0fa2d03SHerbert Xu 8718ff59090SHerbert Xu static void *skcipher_bind(const char *name, u32 type, u32 mask) 8728ff59090SHerbert Xu { 873dd504589SHerbert Xu struct skcipher_tfm *tfm; 874dd504589SHerbert Xu struct crypto_skcipher *skcipher; 875dd504589SHerbert Xu 876dd504589SHerbert Xu tfm = kzalloc(sizeof(*tfm), GFP_KERNEL); 877dd504589SHerbert Xu if (!tfm) 878dd504589SHerbert Xu return ERR_PTR(-ENOMEM); 879dd504589SHerbert Xu 880dd504589SHerbert Xu skcipher = crypto_alloc_skcipher(name, type, mask); 881dd504589SHerbert Xu if (IS_ERR(skcipher)) { 882dd504589SHerbert Xu kfree(tfm); 883dd504589SHerbert Xu return ERR_CAST(skcipher); 884dd504589SHerbert Xu } 885dd504589SHerbert Xu 886dd504589SHerbert Xu tfm->skcipher = skcipher; 887dd504589SHerbert Xu 888dd504589SHerbert Xu return tfm; 8898ff59090SHerbert Xu } 8908ff59090SHerbert Xu 8918ff59090SHerbert Xu static void skcipher_release(void *private) 8928ff59090SHerbert Xu { 893dd504589SHerbert Xu struct skcipher_tfm *tfm = private; 894dd504589SHerbert Xu 895dd504589SHerbert Xu crypto_free_skcipher(tfm->skcipher); 896dd504589SHerbert Xu kfree(tfm); 8978ff59090SHerbert Xu } 8988ff59090SHerbert Xu 8998ff59090SHerbert Xu static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) 9008ff59090SHerbert Xu { 901dd504589SHerbert Xu struct skcipher_tfm *tfm = private; 902dd504589SHerbert Xu int err; 903dd504589SHerbert Xu 904dd504589SHerbert Xu err = crypto_skcipher_setkey(tfm->skcipher, key, keylen); 905dd504589SHerbert Xu tfm->has_key = !err; 906dd504589SHerbert Xu 907dd504589SHerbert Xu return err; 9088ff59090SHerbert Xu } 9098ff59090SHerbert Xu 9108ff59090SHerbert Xu static void skcipher_sock_destruct(struct sock *sk) 9118ff59090SHerbert Xu { 9128ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 9138ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 914*e870456dSStephan Mueller struct sock *psk = ask->parent; 915*e870456dSStephan Mueller struct alg_sock *pask = alg_sk(psk); 916*e870456dSStephan Mueller struct skcipher_tfm *skc = pask->private; 917*e870456dSStephan Mueller struct crypto_skcipher *tfm = skc->skcipher; 9188ff59090SHerbert Xu 919*e870456dSStephan Mueller skcipher_pull_tsgl(sk, ctx->used, NULL); 9200d96e4baSHerbert Xu sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm)); 9218ff59090SHerbert Xu sock_kfree_s(sk, ctx, ctx->len); 9228ff59090SHerbert Xu af_alg_release_parent(sk); 9238ff59090SHerbert Xu } 9248ff59090SHerbert Xu 925d7b65aeeSHerbert Xu static int skcipher_accept_parent_nokey(void *private, struct sock *sk) 9268ff59090SHerbert Xu { 9278ff59090SHerbert Xu struct skcipher_ctx *ctx; 9288ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 929dd504589SHerbert Xu struct skcipher_tfm *tfm = private; 930dd504589SHerbert Xu struct crypto_skcipher *skcipher = tfm->skcipher; 931*e870456dSStephan Mueller unsigned int len = sizeof(*ctx); 9328ff59090SHerbert Xu 9338ff59090SHerbert Xu ctx = sock_kmalloc(sk, len, GFP_KERNEL); 9348ff59090SHerbert Xu if (!ctx) 9358ff59090SHerbert Xu return -ENOMEM; 9368ff59090SHerbert Xu 937dd504589SHerbert Xu ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher), 9388ff59090SHerbert Xu GFP_KERNEL); 9398ff59090SHerbert Xu if (!ctx->iv) { 9408ff59090SHerbert Xu sock_kfree_s(sk, ctx, len); 9418ff59090SHerbert Xu return -ENOMEM; 9428ff59090SHerbert Xu } 9438ff59090SHerbert Xu 944dd504589SHerbert Xu memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher)); 9458ff59090SHerbert Xu 946*e870456dSStephan Mueller INIT_LIST_HEAD(&ctx->tsgl_list); 9478ff59090SHerbert Xu ctx->len = len; 9488ff59090SHerbert Xu ctx->used = 0; 949*e870456dSStephan Mueller ctx->rcvused = 0; 9508ff59090SHerbert Xu ctx->more = 0; 9518ff59090SHerbert Xu ctx->merge = 0; 9528ff59090SHerbert Xu ctx->enc = 0; 9538ff59090SHerbert Xu af_alg_init_completion(&ctx->completion); 9548ff59090SHerbert Xu 9558ff59090SHerbert Xu ask->private = ctx; 9568ff59090SHerbert Xu 9578ff59090SHerbert Xu sk->sk_destruct = skcipher_sock_destruct; 9588ff59090SHerbert Xu 9598ff59090SHerbert Xu return 0; 9608ff59090SHerbert Xu } 9618ff59090SHerbert Xu 962a0fa2d03SHerbert Xu static int skcipher_accept_parent(void *private, struct sock *sk) 963a0fa2d03SHerbert Xu { 964a0fa2d03SHerbert Xu struct skcipher_tfm *tfm = private; 965a0fa2d03SHerbert Xu 9666e8d8ecfSHerbert Xu if (!tfm->has_key && crypto_skcipher_has_setkey(tfm->skcipher)) 967a0fa2d03SHerbert Xu return -ENOKEY; 968a0fa2d03SHerbert Xu 969d7b65aeeSHerbert Xu return skcipher_accept_parent_nokey(private, sk); 970a0fa2d03SHerbert Xu } 971a0fa2d03SHerbert Xu 9728ff59090SHerbert Xu static const struct af_alg_type algif_type_skcipher = { 9738ff59090SHerbert Xu .bind = skcipher_bind, 9748ff59090SHerbert Xu .release = skcipher_release, 9758ff59090SHerbert Xu .setkey = skcipher_setkey, 9768ff59090SHerbert Xu .accept = skcipher_accept_parent, 977a0fa2d03SHerbert Xu .accept_nokey = skcipher_accept_parent_nokey, 9788ff59090SHerbert Xu .ops = &algif_skcipher_ops, 979a0fa2d03SHerbert Xu .ops_nokey = &algif_skcipher_ops_nokey, 9808ff59090SHerbert Xu .name = "skcipher", 9818ff59090SHerbert Xu .owner = THIS_MODULE 9828ff59090SHerbert Xu }; 9838ff59090SHerbert Xu 9848ff59090SHerbert Xu static int __init algif_skcipher_init(void) 9858ff59090SHerbert Xu { 9868ff59090SHerbert Xu return af_alg_register_type(&algif_type_skcipher); 9878ff59090SHerbert Xu } 9888ff59090SHerbert Xu 9898ff59090SHerbert Xu static void __exit algif_skcipher_exit(void) 9908ff59090SHerbert Xu { 9918ff59090SHerbert Xu int err = af_alg_unregister_type(&algif_type_skcipher); 9928ff59090SHerbert Xu BUG_ON(err); 9938ff59090SHerbert Xu } 9948ff59090SHerbert Xu 9958ff59090SHerbert Xu module_init(algif_skcipher_init); 9968ff59090SHerbert Xu module_exit(algif_skcipher_exit); 9978ff59090SHerbert Xu MODULE_LICENSE("GPL"); 998