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