xref: /openbmc/linux/crypto/algif_skcipher.c (revision e870456d8e7c8d57c059ea479b5aadbb55ff4c3a)
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