blob: f557b5dff60cd2045d7758e3a4de2d6fbb8c8b38 [file] [log] [blame]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001From 20dcf071bc3076ee7db9d603cfbe6a06e86c7d5f Mon Sep 17 00:00:00 2001
2From: Cristian Stoica <cristian.stoica@nxp.com>
3Date: Thu, 4 May 2017 15:06:20 +0300
4Subject: [PATCH 1/3] refactoring: split big function to simplify maintainance
5
6The setup of auth_buf in tls and aead is now duplicated but this
7is temporary and allows necessary corrections for the aead case
8with v4.2+ kernels.
9
10Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
11
12Upstream-Status: Backport
13
14Commit ID: 20dcf071bc3076ee7db9d603c
15
16Signed-off-by: Hongzhi.Song <hongzhi.song@windriver.com>
17---
18 authenc.c | 197 ++++++++++++++++++++++++++++++++++++++++----------------------
19 1 file changed, 126 insertions(+), 71 deletions(-)
20
21diff --git a/authenc.c b/authenc.c
22index 1bd7377..28eb0f9 100644
23--- a/authenc.c
24+++ b/authenc.c
25@@ -609,96 +609,151 @@ auth_n_crypt(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop,
26 return 0;
27 }
28
29-/* This is the main crypto function - zero-copy edition */
30-static int
31-__crypto_auth_run_zc(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop)
32+static int crypto_auth_zc_srtp(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop)
33 {
34- struct scatterlist *dst_sg, *auth_sg, *src_sg;
35+ struct scatterlist *dst_sg, *auth_sg;
36 struct crypt_auth_op *caop = &kcaop->caop;
37- int ret = 0;
38+ int ret;
39
40- if (caop->flags & COP_FLAG_AEAD_SRTP_TYPE) {
41- if (unlikely(ses_ptr->cdata.init != 0 &&
42- (ses_ptr->cdata.stream == 0 ||
43- ses_ptr->cdata.aead != 0))) {
44- derr(0, "Only stream modes are allowed in SRTP mode (but not AEAD)");
45- return -EINVAL;
46- }
47+ if (unlikely(ses_ptr->cdata.init != 0 &&
48+ (ses_ptr->cdata.stream == 0 || ses_ptr->cdata.aead != 0))) {
49+ derr(0, "Only stream modes are allowed in SRTP mode (but not AEAD)");
50+ return -EINVAL;
51+ }
52
53- ret = get_userbuf_srtp(ses_ptr, kcaop, &auth_sg, &dst_sg);
54- if (unlikely(ret)) {
55- derr(1, "get_userbuf_srtp(): Error getting user pages.");
56- return ret;
57- }
58+ ret = get_userbuf_srtp(ses_ptr, kcaop, &auth_sg, &dst_sg);
59+ if (unlikely(ret)) {
60+ derr(1, "get_userbuf_srtp(): Error getting user pages.");
61+ return ret;
62+ }
63
64- ret = srtp_auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
65- dst_sg, caop->len);
66+ ret = srtp_auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
67+ dst_sg, caop->len);
68
69- release_user_pages(ses_ptr);
70- } else { /* TLS and normal cases. Here auth data are usually small
71- * so we just copy them to a free page, instead of trying
72- * to map them.
73- */
74- unsigned char *auth_buf = NULL;
75- struct scatterlist tmp;
76+ release_user_pages(ses_ptr);
77
78- if (unlikely(caop->auth_len > PAGE_SIZE)) {
79- derr(1, "auth data len is excessive.");
80- return -EINVAL;
81- }
82+ return ret;
83+}
84
85- auth_buf = (char *)__get_free_page(GFP_KERNEL);
86- if (unlikely(!auth_buf)) {
87- derr(1, "unable to get a free page.");
88- return -ENOMEM;
89- }
90+static int crypto_auth_zc_tls(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop)
91+{
92+ struct crypt_auth_op *caop = &kcaop->caop;
93+ struct scatterlist *dst_sg, *auth_sg;
94+ unsigned char *auth_buf = NULL;
95+ struct scatterlist tmp;
96+ int ret;
97
98- if (caop->auth_src && caop->auth_len > 0) {
99- if (unlikely(copy_from_user(auth_buf, caop->auth_src, caop->auth_len))) {
100- derr(1, "unable to copy auth data from userspace.");
101- ret = -EFAULT;
102- goto free_auth_buf;
103- }
104+ if (unlikely(ses_ptr->cdata.aead != 0)) {
105+ return -EINVAL;
106+ }
107+
108+ if (unlikely(caop->auth_len > PAGE_SIZE)) {
109+ derr(1, "auth data len is excessive.");
110+ return -EINVAL;
111+ }
112+
113+ auth_buf = (char *)__get_free_page(GFP_KERNEL);
114+ if (unlikely(!auth_buf)) {
115+ derr(1, "unable to get a free page.");
116+ return -ENOMEM;
117+ }
118
119- sg_init_one(&tmp, auth_buf, caop->auth_len);
120- auth_sg = &tmp;
121- } else {
122- auth_sg = NULL;
123+ if (caop->auth_src && caop->auth_len > 0) {
124+ if (unlikely(copy_from_user(auth_buf, caop->auth_src, caop->auth_len))) {
125+ derr(1, "unable to copy auth data from userspace.");
126+ ret = -EFAULT;
127+ goto free_auth_buf;
128 }
129
130- if (caop->flags & COP_FLAG_AEAD_TLS_TYPE && ses_ptr->cdata.aead == 0) {
131- ret = get_userbuf_tls(ses_ptr, kcaop, &dst_sg);
132- if (unlikely(ret)) {
133- derr(1, "get_userbuf_tls(): Error getting user pages.");
134- goto free_auth_buf;
135- }
136+ sg_init_one(&tmp, auth_buf, caop->auth_len);
137+ auth_sg = &tmp;
138+ } else {
139+ auth_sg = NULL;
140+ }
141
142- ret = tls_auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
143- dst_sg, caop->len);
144- } else {
145- if (unlikely(ses_ptr->cdata.init == 0 ||
146- (ses_ptr->cdata.stream == 0 &&
147- ses_ptr->cdata.aead == 0))) {
148- derr(0, "Only stream and AEAD ciphers are allowed for authenc");
149- ret = -EINVAL;
150- goto free_auth_buf;
151- }
152+ ret = get_userbuf_tls(ses_ptr, kcaop, &dst_sg);
153+ if (unlikely(ret)) {
154+ derr(1, "get_userbuf_tls(): Error getting user pages.");
155+ goto free_auth_buf;
156+ }
157
158- ret = get_userbuf(ses_ptr, caop->src, caop->len, caop->dst, kcaop->dst_len,
159- kcaop->task, kcaop->mm, &src_sg, &dst_sg);
160- if (unlikely(ret)) {
161- derr(1, "get_userbuf(): Error getting user pages.");
162- goto free_auth_buf;
163- }
164+ ret = tls_auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
165+ dst_sg, caop->len);
166+ release_user_pages(ses_ptr);
167+
168+free_auth_buf:
169+ free_page((unsigned long)auth_buf);
170+ return ret;
171+}
172+
173+static int crypto_auth_zc_aead(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop)
174+{
175+ struct scatterlist *dst_sg, *auth_sg, *src_sg;
176+ struct crypt_auth_op *caop = &kcaop->caop;
177+ unsigned char *auth_buf = NULL;
178+ struct scatterlist tmp;
179+ int ret;
180
181- ret = auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
182- src_sg, dst_sg, caop->len);
183+ if (unlikely(ses_ptr->cdata.init == 0 ||
184+ (ses_ptr->cdata.stream == 0 && ses_ptr->cdata.aead == 0))) {
185+ derr(0, "Only stream and AEAD ciphers are allowed for authenc");
186+ return -EINVAL;
187+ }
188+
189+ if (unlikely(caop->auth_len > PAGE_SIZE)) {
190+ derr(1, "auth data len is excessive.");
191+ return -EINVAL;
192+ }
193+
194+ auth_buf = (char *)__get_free_page(GFP_KERNEL);
195+ if (unlikely(!auth_buf)) {
196+ derr(1, "unable to get a free page.");
197+ return -ENOMEM;
198+ }
199+
200+ if (caop->auth_src && caop->auth_len > 0) {
201+ if (unlikely(copy_from_user(auth_buf, caop->auth_src, caop->auth_len))) {
202+ derr(1, "unable to copy auth data from userspace.");
203+ ret = -EFAULT;
204+ goto free_auth_buf;
205 }
206
207- release_user_pages(ses_ptr);
208+ sg_init_one(&tmp, auth_buf, caop->auth_len);
209+ auth_sg = &tmp;
210+ } else {
211+ auth_sg = NULL;
212+ }
213+
214+ ret = get_userbuf(ses_ptr, caop->src, caop->len, caop->dst, kcaop->dst_len,
215+ kcaop->task, kcaop->mm, &src_sg, &dst_sg);
216+ if (unlikely(ret)) {
217+ derr(1, "get_userbuf(): Error getting user pages.");
218+ goto free_auth_buf;
219+ }
220+
221+ ret = auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
222+ src_sg, dst_sg, caop->len);
223+
224+ release_user_pages(ses_ptr);
225
226 free_auth_buf:
227- free_page((unsigned long)auth_buf);
228+ free_page((unsigned long)auth_buf);
229+
230+ return ret;
231+}
232+
233+static int
234+__crypto_auth_run_zc(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop)
235+{
236+ struct crypt_auth_op *caop = &kcaop->caop;
237+ int ret;
238+
239+ if (caop->flags & COP_FLAG_AEAD_SRTP_TYPE) {
240+ ret = crypto_auth_zc_srtp(ses_ptr, kcaop);
241+ } else if (caop->flags & COP_FLAG_AEAD_TLS_TYPE) {
242+ ret = crypto_auth_zc_tls(ses_ptr, kcaop);
243+ } else {
244+ ret = crypto_auth_zc_aead(ses_ptr, kcaop);
245 }
246
247 return ret;
248--
2492.11.0
250