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
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
10 Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
12 authenc.c | 197 ++++++++++++++++++++++++++++++++++++++++----------------------
13 1 file changed, 126 insertions(+), 71 deletions(-)
15 diff --git a/authenc.c b/authenc.c
16 index 1bd7377..28eb0f9 100644
19 @@ -609,96 +609,151 @@ auth_n_crypt(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop,
23 -/* This is the main crypto function - zero-copy edition */
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)
28 - struct scatterlist *dst_sg, *auth_sg, *src_sg;
29 + struct scatterlist *dst_sg, *auth_sg;
30 struct crypt_auth_op *caop = &kcaop->caop;
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)");
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)");
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.");
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.");
58 - ret = srtp_auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
60 + ret = srtp_auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
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
68 - unsigned char *auth_buf = NULL;
69 - struct scatterlist tmp;
70 + release_user_pages(ses_ptr);
72 - if (unlikely(caop->auth_len > PAGE_SIZE)) {
73 - derr(1, "auth data len is excessive.");
79 - auth_buf = (char *)__get_free_page(GFP_KERNEL);
80 - if (unlikely(!auth_buf)) {
81 - derr(1, "unable to get a free page.");
84 +static int crypto_auth_zc_tls(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop)
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;
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.");
98 + if (unlikely(ses_ptr->cdata.aead != 0)) {
102 + if (unlikely(caop->auth_len > PAGE_SIZE)) {
103 + derr(1, "auth data len is excessive.");
107 + auth_buf = (char *)__get_free_page(GFP_KERNEL);
108 + if (unlikely(!auth_buf)) {
109 + derr(1, "unable to get a free page.");
113 - sg_init_one(&tmp, auth_buf, caop->auth_len);
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.");
121 + goto free_auth_buf;
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;
130 + sg_init_one(&tmp, auth_buf, caop->auth_len);
136 - ret = tls_auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
137 - dst_sg, caop->len);
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");
144 - goto free_auth_buf;
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;
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;
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);
163 + free_page((unsigned long)auth_buf);
167 +static int crypto_auth_zc_aead(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop)
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;
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");
183 + if (unlikely(caop->auth_len > PAGE_SIZE)) {
184 + derr(1, "auth data len is excessive.");
188 + auth_buf = (char *)__get_free_page(GFP_KERNEL);
189 + if (unlikely(!auth_buf)) {
190 + derr(1, "unable to get a free page.");
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.");
198 + goto free_auth_buf;
201 - release_user_pages(ses_ptr);
202 + sg_init_one(&tmp, auth_buf, caop->auth_len);
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;
215 + ret = auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
216 + src_sg, dst_sg, caop->len);
218 + release_user_pages(ses_ptr);
221 - free_page((unsigned long)auth_buf);
222 + free_page((unsigned long)auth_buf);
228 +__crypto_auth_run_zc(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcaop)
230 + struct crypt_auth_op *caop = &kcaop->caop;
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);
238 + ret = crypto_auth_zc_aead(ses_ptr, kcaop);