summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch')
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch315
1 files changed, 315 insertions, 0 deletions
diff --git a/recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch b/recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch
new file mode 100644
index 0000000..4745dc9
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch
@@ -0,0 +1,315 @@
1From f123f38532ae022e818312a9bc04cdb287e9623f Mon Sep 17 00:00:00 2001
2From: Cristian Stoica <cristian.stoica@nxp.com>
3Date: Thu, 17 Dec 2015 10:34:20 +0200
4Subject: [PATCH 35/38] use directly crypto API 'digest' operation for CIOCHASH
5
6Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
7---
8 crypto/cryptodev.h | 2 +-
9 cryptodev_int.h | 10 ++++
10 ioctl.c | 158 ++++++++++++++++++++++++++++++++++++++++++++---------
11 main.c | 39 ++++++++++++-
12 4 files changed, 179 insertions(+), 30 deletions(-)
13
14diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
15index c6083f7..9ade102 100644
16--- a/crypto/cryptodev.h
17+++ b/crypto/cryptodev.h
18@@ -169,7 +169,7 @@ struct crypt_auth_op {
19
20 /* data container for CIOCHASH operations */
21 struct hash_op_data {
22- __u32 ses; /* session identifier */
23+ struct csession *ses; /* session identifier */
24 __u32 mac_op; /* cryptodev_crypto_op_t */
25 __u8 *mackey;
26 __u32 mackeylen;
27diff --git a/cryptodev_int.h b/cryptodev_int.h
28index cb005d7..74c295a 100644
29--- a/cryptodev_int.h
30+++ b/cryptodev_int.h
31@@ -164,6 +164,15 @@ struct kernel_crypt_op {
32 struct mm_struct *mm;
33 };
34
35+struct kernel_hash_op {
36+ struct hash_op_data hash_op;
37+
38+ int digestsize;
39+ uint8_t hash_output[AALG_MAX_RESULT_LEN];
40+ struct task_struct *task;
41+ struct mm_struct *mm;
42+};
43+
44 struct kernel_crypt_auth_op {
45 struct crypt_auth_op caop;
46
47@@ -192,6 +201,7 @@ int kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
48 struct fcrypt *fcr, void __user *arg);
49 int crypto_auth_run(struct fcrypt *fcr, struct kernel_crypt_auth_op *kcaop);
50 int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop);
51+int hash_run(struct kernel_hash_op *khop);
52
53 #include <cryptlib.h>
54
55diff --git a/ioctl.c b/ioctl.c
56index 3763954..a052614 100644
57--- a/ioctl.c
58+++ b/ioctl.c
59@@ -397,7 +397,128 @@ session_error:
60 return ret;
61 }
62
63-/* Everything that needs to be done when removing a session. */
64+static inline void hash_destroy_session(struct csession *ses_ptr)
65+{
66+ cryptodev_hash_deinit(&ses_ptr->hdata);
67+ kfree(ses_ptr->pages);
68+ kfree(ses_ptr->sg);
69+ kfree(ses_ptr);
70+}
71+
72+static int hash_create_session(struct hash_op_data *hash_op)
73+{
74+ struct csession *ses;
75+ int ret = 0;
76+ const char *hash_name;
77+ int hmac_mode = 1;
78+ uint8_t mkey[CRYPTO_HMAC_MAX_KEY_LEN];
79+
80+ switch (hash_op->mac_op) {
81+ case CRYPTO_MD5_HMAC:
82+ hash_name = "hmac(md5)";
83+ break;
84+ case CRYPTO_RIPEMD160_HMAC:
85+ hash_name = "hmac(rmd160)";
86+ break;
87+ case CRYPTO_SHA1_HMAC:
88+ hash_name = "hmac(sha1)";
89+ break;
90+ case CRYPTO_SHA2_224_HMAC:
91+ hash_name = "hmac(sha224)";
92+ break;
93+ case CRYPTO_SHA2_256_HMAC:
94+ hash_name = "hmac(sha256)";
95+ break;
96+ case CRYPTO_SHA2_384_HMAC:
97+ hash_name = "hmac(sha384)";
98+ break;
99+ case CRYPTO_SHA2_512_HMAC:
100+ hash_name = "hmac(sha512)";
101+ break;
102+ /* non-hmac cases */
103+ case CRYPTO_MD5:
104+ hash_name = "md5";
105+ hmac_mode = 0;
106+ break;
107+ case CRYPTO_RIPEMD160:
108+ hash_name = "rmd160";
109+ hmac_mode = 0;
110+ break;
111+ case CRYPTO_SHA1:
112+ hash_name = "sha1";
113+ hmac_mode = 0;
114+ break;
115+ case CRYPTO_SHA2_224:
116+ hash_name = "sha224";
117+ hmac_mode = 0;
118+ break;
119+ case CRYPTO_SHA2_256:
120+ hash_name = "sha256";
121+ hmac_mode = 0;
122+ break;
123+ case CRYPTO_SHA2_384:
124+ hash_name = "sha384";
125+ hmac_mode = 0;
126+ break;
127+ case CRYPTO_SHA2_512:
128+ hash_name = "sha512";
129+ hmac_mode = 0;
130+ break;
131+ default:
132+ ddebug(1, "bad mac: %d", hash_op->mac_op);
133+ return -EINVAL;
134+ }
135+
136+ ses = kzalloc(sizeof(*ses), GFP_KERNEL);
137+ if (!ses) {
138+ return -ENOMEM;
139+ }
140+
141+ if (unlikely(hash_op->mackeylen > CRYPTO_HMAC_MAX_KEY_LEN)) {
142+ ddebug(1, "Setting key failed for %s-%zu.", hash_name,
143+ (size_t)hash_op->mackeylen * 8);
144+ ret = -EINVAL;
145+ goto error_hash;
146+ }
147+
148+ if (hash_op->mackey &&
149+ unlikely(copy_from_user(mkey, hash_op->mackey, hash_op->mackeylen))) {
150+ ret = -EFAULT;
151+ goto error_hash;
152+ }
153+
154+ ret = cryptodev_hash_init(&ses->hdata, hash_name, hmac_mode,
155+ mkey, hash_op->mackeylen);
156+ if (ret != 0) {
157+ ddebug(1, "Failed to load hash for %s", hash_name);
158+ ret = -EINVAL;
159+ goto error_hash;
160+ }
161+
162+ ses->alignmask = ses->hdata.alignmask;
163+ ddebug(2, "got alignmask %d", ses->alignmask);
164+
165+ ses->array_size = DEFAULT_PREALLOC_PAGES;
166+ ddebug(2, "preallocating for %d user pages", ses->array_size);
167+
168+ ses->pages = kzalloc(ses->array_size * sizeof(struct page *), GFP_KERNEL);
169+ ses->sg = kzalloc(ses->array_size * sizeof(struct scatterlist), GFP_KERNEL);
170+ if (ses->sg == NULL || ses->pages == NULL) {
171+ ddebug(0, "Memory error");
172+ ret = -ENOMEM;
173+ goto error_hash;
174+ }
175+
176+ hash_op->ses = ses;
177+ return 0;
178+
179+error_hash:
180+ hash_destroy_session(ses);
181+ return ret;
182+}
183+
184+
185+/* Everything that needs to be done when remowing a session. */
186 static inline void
187 crypto_destroy_session(struct csession *ses_ptr)
188 {
189@@ -960,7 +1081,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
190 void __user *arg = (void __user *)arg_;
191 int __user *p = arg;
192 struct session_op sop;
193- struct hash_op_data hash_op;
194+ struct kernel_hash_op khop;
195 struct kernel_crypt_op kcop;
196 struct kernel_crypt_auth_op kcaop;
197 struct crypt_priv *pcr = filp->private_data;
198@@ -1051,52 +1172,35 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
199
200 return kcop_to_user(&kcop, fcr, arg);
201 case CIOCHASH:
202- /* get session */
203- if (unlikely(copy_from_user(&hash_op, arg, sizeof(struct hash_op_data)))) {
204+ if (unlikely(copy_from_user(&khop.hash_op, arg, sizeof(struct hash_op_data)))) {
205 pr_err("copy from user fault\n");
206 return -EFAULT;
207 }
208+ khop.task = current;
209+ khop.mm = current->mm;
210
211- sop.cipher = 0;
212- sop.mac = hash_op.mac_op;
213- sop.mackey = hash_op.mackey;
214- sop.mackeylen = hash_op.mackeylen;
215-
216- /* writes sop.ses as a side-effect */
217- ret = crypto_create_session(fcr, &sop);
218+ /* get session */
219+ ret = hash_create_session(&khop.hash_op);
220 if (unlikely(ret)) {
221 pr_err("can't get session\n");
222 return ret;
223 }
224
225 /* do hashing */
226- kcop.cop.ses = sop.ses;
227- kcop.cop.flags = hash_op.flags;
228- kcop.cop.len = hash_op.len;
229- kcop.cop.src = hash_op.src;
230- kcop.cop.mac = hash_op.mac_result;
231- kcop.cop.dst = 0;
232- kcop.cop.op = 0;
233- kcop.cop.iv = 0;
234- kcop.ivlen = 0;
235- kcop.digestsize = 0; /* will be updated during operation */
236- kcop.task = current;
237- kcop.mm = current->mm;
238-
239- ret = crypto_run(fcr, &kcop);
240+ ret = hash_run(&khop);
241 if (unlikely(ret)) {
242 dwarning(1, "Error in hash run");
243 return ret;
244 }
245
246- ret = copy_to_user(kcop.cop.mac, kcop.hash_output, kcop.digestsize);
247+ ret = copy_to_user(khop.hash_op.mac_result, khop.hash_output, khop.digestsize);
248 if (unlikely(ret)) {
249 dwarning(1, "Error in copy to user");
250 return ret;
251 }
252
253 /* put session */
254- ret = crypto_finish_session(fcr, sop.ses);
255+ hash_destroy_session(khop.hash_op.ses);
256 return 0;
257 case CIOCAUTHCRYPT:
258 if (unlikely(ret = kcaop_from_user(&kcaop, fcr, arg))) {
259diff --git a/main.c b/main.c
260index ec11129..095aea5 100644
261--- a/main.c
262+++ b/main.c
263@@ -159,8 +159,6 @@ __crypto_run_std(struct csession *ses_ptr, struct crypt_op *cop)
264 return ret;
265 }
266
267-
268-
269 /* This is the main crypto function - zero-copy edition */
270 static int
271 __crypto_run_zc(struct csession *ses_ptr, struct kernel_crypt_op *kcop)
272@@ -841,3 +839,40 @@ out_unlock:
273 crypto_put_session(ses_ptr);
274 return ret;
275 }
276+
277+int hash_run(struct kernel_hash_op *khop)
278+{
279+ struct hash_op_data *hash_op = &khop->hash_op;
280+ struct csession *ses_ptr = hash_op->ses;
281+ struct hash_data *hdata = &ses_ptr->hdata;
282+ int ret;
283+ struct scatterlist *src_sg;
284+ struct scatterlist *dst_sg; /* required by get_userbuf but not used */
285+
286+ if (hash_op->len == 0) {
287+ src_sg = NULL;
288+ } else {
289+ ret = get_userbuf(ses_ptr, hash_op->src, hash_op->len, NULL, 0,
290+ khop->task, khop->mm, &src_sg, &dst_sg);
291+ if (unlikely(ret)) {
292+ derr(1, "Error getting user pages");
293+ return ret;
294+ }
295+ }
296+
297+ ahash_request_set_crypt(hdata->async.request, src_sg, khop->hash_output, hash_op->len);
298+
299+ ret = crypto_ahash_digest(hdata->async.request);
300+ if (ret == -EINPROGRESS || ret == -EBUSY) {
301+ wait_for_completion(&hdata->async.result.completion);
302+ ret = hdata->async.result.err;
303+ if (ret != 0) {
304+ derr(0, "CryptoAPI failure: %d", ret);
305+ }
306+ }
307+
308+ khop->digestsize = ses_ptr->hdata.digestsize;
309+
310+ release_user_pages(ses_ptr);
311+ return ret;
312+}
313--
3142.7.0
315