summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/cryptodev
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/cryptodev')
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl.inc17
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch52
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0001-don-t-advertise-RSA-keygen.patch32
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch207
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0003-PKC-support-added-in-cryptodev-module.patch898
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0004-Compat-versions-of-PKC-IOCTLs.patch200
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0005-Asynchronous-interface-changes-in-cryptodev.patch213
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch212
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch238
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0008-Add-RSA-Key-generation-offloading.patch170
-rw-r--r--recipes-kernel/cryptodev/cryptodev-fsl/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch160
-rw-r--r--recipes-kernel/cryptodev/cryptodev-linux_1.6.bbappend2
-rw-r--r--recipes-kernel/cryptodev/cryptodev-module_1.6.bbappend12
13 files changed, 2413 insertions, 0 deletions
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl.inc b/recipes-kernel/cryptodev/cryptodev-fsl.inc
new file mode 100644
index 0000000..e32e350
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl.inc
@@ -0,0 +1,17 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/cryptodev-fsl:"
2
3SRC_URI_qoriq-ppc = "git://github.com/cryptodev-linux/cryptodev-linux.git \
4 file://0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch \
5 file://0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch \
6 file://0003-PKC-support-added-in-cryptodev-module.patch \
7 file://0004-Compat-versions-of-PKC-IOCTLs.patch \
8 file://0005-Asynchronous-interface-changes-in-cryptodev.patch \
9 file://0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch \
10 file://0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch \
11 file://0008-Add-RSA-Key-generation-offloading.patch \
12 file://0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch \
13"
14SRCREV_qoriq-ppc = "6aa62a2c320b04f55fdfe0ed015c3d9b48997239"
15
16S_qoriq-ppc = "${WORKDIR}/git"
17
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch
new file mode 100644
index 0000000..796e548
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch
@@ -0,0 +1,52 @@
1From 715ade8236f40cf811c39f9538dfd60803967fcd Mon Sep 17 00:00:00 2001
2From: Cristian Stoica <cristian.stoica@freescale.com>
3Date: Thu, 29 Aug 2013 16:52:30 +0300
4Subject: [PATCH 1/9] add support for composite TLS10(SHA1,AES) algorithm
5 offload
6
7This adds support for composite algorithm offload as a primitive
8crypto (cipher + hmac) operation.
9
10It requires kernel support for tls10(hmac(sha1),cbc(aes)) algorithm
11provided either in software or accelerated by hardware such as
12Freescale B*, P* and T* platforms.
13
14Change-Id: Ia1c605da3860e91e681295dfc8df7c09eb4006cf
15Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
16Reviewed-on: http://git.am.freescale.net:8181/17218
17---
18 crypto/cryptodev.h | 1 +
19 ioctl.c | 5 +++++
20 2 files changed, 6 insertions(+)
21
22diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
23index 7fb9c7d..c0e8cd4 100644
24--- a/crypto/cryptodev.h
25+++ b/crypto/cryptodev.h
26@@ -50,6 +50,7 @@ enum cryptodev_crypto_op_t {
27 CRYPTO_SHA2_384,
28 CRYPTO_SHA2_512,
29 CRYPTO_SHA2_224_HMAC,
30+ CRYPTO_TLS10_AES_CBC_HMAC_SHA1,
31 CRYPTO_ALGORITHM_ALL, /* Keep updated - see below */
32 };
33
34diff --git a/ioctl.c b/ioctl.c
35index 5a55a76..f9b9b2e 100644
36--- a/ioctl.c
37+++ b/ioctl.c
38@@ -159,6 +159,11 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
39 stream = 1;
40 aead = 1;
41 break;
42+ case CRYPTO_TLS10_AES_CBC_HMAC_SHA1:
43+ alg_name = "tls10(hmac(sha1),cbc(aes))";
44+ stream = 0;
45+ aead = 1;
46+ break;
47 case CRYPTO_NULL:
48 alg_name = "ecb(cipher_null)";
49 stream = 1;
50--
511.8.3.1
52
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0001-don-t-advertise-RSA-keygen.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0001-don-t-advertise-RSA-keygen.patch
new file mode 100644
index 0000000..3d7c608
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0001-don-t-advertise-RSA-keygen.patch
@@ -0,0 +1,32 @@
1From b6e2a3747e3cffdf3cc515b0ce35d6bcdcb051c5 Mon Sep 17 00:00:00 2001
2From: Cristian Stoica <cristian.stoica@freescale.com>
3Date: Tue, 9 Dec 2014 16:41:25 +0200
4Subject: [PATCH] don't advertise RSA keygen
5
6This is supposed to avoid RSA keygen operations when they are not
7available. Since no testing can be done, the patch should be applied
8selectively (for example when offloading through pkc driver on C293)
9
10Change-Id: I60765f46fd7a39053d42e075d2ec71b032b2ed8a
11Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
12---
13 ioctl.c | 3 +--
14 1 file changed, 1 insertion(+), 2 deletions(-)
15
16diff --git a/ioctl.c b/ioctl.c
17index e907167..3239093 100644
18--- a/ioctl.c
19+++ b/ioctl.c
20@@ -961,8 +961,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
21 case CIOCASYMFEAT:
22 return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_DSA_SIGN |
23 CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY |
24- CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY |
25- CRF_RSA_GENERATE_KEY, p);
26+ CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY, p);
27 case CRIOGET:
28 fd = clonefd(filp);
29 ret = put_user(fd, p);
30--
312.2.0
32
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch
new file mode 100644
index 0000000..086a97f
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch
@@ -0,0 +1,207 @@
1From 4b766c93e4ee19248dd66bbebb61fb5cc9c8a012 Mon Sep 17 00:00:00 2001
2From: Horia Geanta <horia.geanta@freescale.com>
3Date: Wed, 4 Dec 2013 15:43:41 +0200
4Subject: [PATCH 2/9] add support for COMPAT_CIOCAUTHCRYPT ioctl()
5
6Upstream-status: Pending
7
8Needed for 64b kernel with 32b user space.
9
10Change-Id: I44a999a4164e7ae7122dee6ed0716b2f25cadbc1
11Signed-off-by: Horia Geanta <horia.geanta@freescale.com>
12Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
13---
14 authenc.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15 cryptodev_int.h | 40 +++++++++++++++++++++++++++++
16 ioctl.c | 16 ++++++++++++
17 3 files changed, 134 insertions(+)
18
19diff --git a/authenc.c b/authenc.c
20index 1bd7377..ef0d3db 100644
21--- a/authenc.c
22+++ b/authenc.c
23@@ -272,6 +272,84 @@ static int fill_caop_from_kcaop(struct kernel_crypt_auth_op *kcaop, struct fcryp
24 return 0;
25 }
26
27+/* compatibility code for 32bit userlands */
28+#ifdef CONFIG_COMPAT
29+
30+static inline void
31+compat_to_crypt_auth_op(struct compat_crypt_auth_op *compat,
32+ struct crypt_auth_op *caop)
33+{
34+ caop->ses = compat->ses;
35+ caop->op = compat->op;
36+ caop->flags = compat->flags;
37+ caop->len = compat->len;
38+ caop->auth_len = compat->auth_len;
39+ caop->tag_len = compat->tag_len;
40+ caop->iv_len = compat->iv_len;
41+
42+ caop->auth_src = compat_ptr(compat->auth_src);
43+ caop->src = compat_ptr(compat->src);
44+ caop->dst = compat_ptr(compat->dst);
45+ caop->tag = compat_ptr(compat->tag);
46+ caop->iv = compat_ptr(compat->iv);
47+}
48+
49+static inline void
50+crypt_auth_op_to_compat(struct crypt_auth_op *caop,
51+ struct compat_crypt_auth_op *compat)
52+{
53+ compat->ses = caop->ses;
54+ compat->op = caop->op;
55+ compat->flags = caop->flags;
56+ compat->len = caop->len;
57+ compat->auth_len = caop->auth_len;
58+ compat->tag_len = caop->tag_len;
59+ compat->iv_len = caop->iv_len;
60+
61+ compat->auth_src = ptr_to_compat(caop->auth_src);
62+ compat->src = ptr_to_compat(caop->src);
63+ compat->dst = ptr_to_compat(caop->dst);
64+ compat->tag = ptr_to_compat(caop->tag);
65+ compat->iv = ptr_to_compat(caop->iv);
66+}
67+
68+int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
69+ struct fcrypt *fcr, void __user *arg)
70+{
71+ struct compat_crypt_auth_op compat_caop;
72+
73+ if (unlikely(copy_from_user(&compat_caop, arg, sizeof(compat_caop)))) {
74+ dprintk(1, KERN_ERR, "Error in copying from userspace\n");
75+ return -EFAULT;
76+ }
77+
78+ compat_to_crypt_auth_op(&compat_caop, &kcaop->caop);
79+
80+ return fill_kcaop_from_caop(kcaop, fcr);
81+}
82+
83+int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
84+ struct fcrypt *fcr, void __user *arg)
85+{
86+ int ret;
87+ struct compat_crypt_auth_op compat_caop;
88+
89+ ret = fill_caop_from_kcaop(kcaop, fcr);
90+ if (unlikely(ret)) {
91+ dprintk(1, KERN_ERR, "fill_caop_from_kcaop\n");
92+ return ret;
93+ }
94+
95+ crypt_auth_op_to_compat(&kcaop->caop, &compat_caop);
96+
97+ if (unlikely(copy_to_user(arg, &compat_caop, sizeof(compat_caop)))) {
98+ dprintk(1, KERN_ERR, "Error in copying to userspace\n");
99+ return -EFAULT;
100+ }
101+ return 0;
102+}
103+
104+#endif /* CONFIG_COMPAT */
105
106 int kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
107 struct fcrypt *fcr, void __user *arg)
108diff --git a/cryptodev_int.h b/cryptodev_int.h
109index d7660fa..8e687e7 100644
110--- a/cryptodev_int.h
111+++ b/cryptodev_int.h
112@@ -73,11 +73,42 @@ struct compat_crypt_op {
113 compat_uptr_t iv;/* initialization vector for encryption operations */
114 };
115
116+ /* input of CIOCAUTHCRYPT */
117+struct compat_crypt_auth_op {
118+ uint32_t ses; /* session identifier */
119+ uint16_t op; /* COP_ENCRYPT or COP_DECRYPT */
120+ uint16_t flags; /* see COP_FLAG_AEAD_* */
121+ uint32_t len; /* length of source data */
122+ uint32_t auth_len; /* length of auth data */
123+ compat_uptr_t auth_src; /* authenticated-only data */
124+
125+ /* The current implementation is more efficient if data are
126+ * encrypted in-place (src==dst). */
127+ compat_uptr_t src; /* data to be encrypted and
128+ authenticated */
129+ compat_uptr_t dst; /* pointer to output data. Must have
130+ * space for tag. For TLS this should be
131+ * at least len + tag_size + block_size
132+ * for padding */
133+
134+ compat_uptr_t tag; /* where the tag will be copied to. TLS
135+ * mode doesn't use that as tag is
136+ * copied to dst.
137+ * SRTP mode copies tag there. */
138+ uint32_t tag_len; /* the length of the tag. Use zero for
139+ * digest size or max tag. */
140+
141+ /* initialization vector for encryption operations */
142+ compat_uptr_t iv;
143+ uint32_t iv_len;
144+};
145+
146 /* compat ioctls, defined for the above structs */
147 #define COMPAT_CIOCGSESSION _IOWR('c', 102, struct compat_session_op)
148 #define COMPAT_CIOCCRYPT _IOWR('c', 104, struct compat_crypt_op)
149 #define COMPAT_CIOCASYNCCRYPT _IOW('c', 107, struct compat_crypt_op)
150 #define COMPAT_CIOCASYNCFETCH _IOR('c', 108, struct compat_crypt_op)
151+#define COMPAT_CIOCAUTHCRYPT _IOWR('c', 109, struct compat_crypt_auth_op)
152
153 #endif /* CONFIG_COMPAT */
154
155@@ -108,6 +139,15 @@ struct kernel_crypt_auth_op {
156
157 /* auth */
158
159+#ifdef CONFIG_COMPAT
160+int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
161+ struct fcrypt *fcr, void __user *arg);
162+
163+int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
164+ struct fcrypt *fcr, void __user *arg);
165+#endif /* CONFIG_COMPAT */
166+
167+
168 int kcaop_from_user(struct kernel_crypt_auth_op *kcop,
169 struct fcrypt *fcr, void __user *arg);
170 int kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
171diff --git a/ioctl.c b/ioctl.c
172index f9b9b2e..1563c75 100644
173--- a/ioctl.c
174+++ b/ioctl.c
175@@ -998,6 +998,7 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
176 struct session_op sop;
177 struct compat_session_op compat_sop;
178 struct kernel_crypt_op kcop;
179+ struct kernel_crypt_auth_op kcaop;
180 int ret;
181
182 if (unlikely(!pcr))
183@@ -1040,6 +1041,21 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
184 return ret;
185
186 return compat_kcop_to_user(&kcop, fcr, arg);
187+
188+ case COMPAT_CIOCAUTHCRYPT:
189+ if (unlikely(ret = compat_kcaop_from_user(&kcaop, fcr, arg))) {
190+ dprintk(1, KERN_WARNING, "Error copying from user\n");
191+ return ret;
192+ }
193+
194+ ret = crypto_auth_run(fcr, &kcaop);
195+ if (unlikely(ret)) {
196+ dprintk(1, KERN_WARNING, "Error in crypto_auth_run\n");
197+ return ret;
198+ }
199+
200+ return compat_kcaop_to_user(&kcaop, fcr, arg);
201+
202 #ifdef ENABLE_ASYNC
203 case COMPAT_CIOCASYNCCRYPT:
204 if (unlikely(ret = compat_kcop_from_user(&kcop, fcr, arg)))
205--
2061.8.3.1
207
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0003-PKC-support-added-in-cryptodev-module.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0003-PKC-support-added-in-cryptodev-module.patch
new file mode 100644
index 0000000..a4f7816
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0003-PKC-support-added-in-cryptodev-module.patch
@@ -0,0 +1,898 @@
1From 5b57fc2124cef0acc3c7e8de376ebd9aa4f1fdd3 Mon Sep 17 00:00:00 2001
2From: Yashpal Dutta <yashpal.dutta@freescale.com>
3Date: Fri, 7 Mar 2014 06:16:09 +0545
4Subject: [PATCH 3/9] PKC support added in cryptodev module
5
6Upstream-status: Pending
7
8Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
9---
10 cryptlib.c | 66 +++++++++-
11 cryptlib.h | 28 ++++
12 crypto/cryptodev.h | 15 ++-
13 cryptodev_int.h | 20 ++-
14 ioctl.c | 196 +++++++++++++++++++++++++--
15 main.c | 378 +++++++++++++++++++++++++++++++++++++++++++++++++++++
16 6 files changed, 685 insertions(+), 18 deletions(-)
17
18diff --git a/cryptlib.c b/cryptlib.c
19index 44ce763..6900028 100644
20--- a/cryptlib.c
21+++ b/cryptlib.c
22@@ -5,6 +5,8 @@
23 * Portions Copyright (c) 2010 Michael Weiser
24 * Portions Copyright (c) 2010 Phil Sutter
25 *
26+ * Copyright 2012 Freescale Semiconductor, Inc.
27+ *
28 * This file is part of linux cryptodev.
29 *
30 * This program is free software; you can redistribute it and/or
31@@ -39,11 +41,6 @@
32 #include "cryptodev_int.h"
33
34
35-struct cryptodev_result {
36- struct completion completion;
37- int err;
38-};
39-
40 static void cryptodev_complete(struct crypto_async_request *req, int err)
41 {
42 struct cryptodev_result *res = req->data;
43@@ -259,7 +256,6 @@ static inline int waitfor(struct cryptodev_result *cr, ssize_t ret)
44 case 0:
45 break;
46 case -EINPROGRESS:
47- case -EBUSY:
48 wait_for_completion(&cr->completion);
49 /* At this point we known for sure the request has finished,
50 * because wait_for_completion above was not interruptible.
51@@ -439,3 +435,61 @@ int cryptodev_hash_final(struct hash_data *hdata, void *output)
52 return waitfor(hdata->async.result, ret);
53 }
54
55+int cryptodev_pkc_offload(struct cryptodev_pkc *pkc)
56+{
57+ int ret = 0;
58+ struct pkc_request *pkc_req = &pkc->req, *pkc_requested;
59+
60+ switch (pkc_req->type) {
61+ case RSA_PUB:
62+ case RSA_PRIV_FORM1:
63+ case RSA_PRIV_FORM2:
64+ case RSA_PRIV_FORM3:
65+ pkc->s = crypto_alloc_pkc("pkc(rsa)",
66+ CRYPTO_ALG_TYPE_PKC_RSA, 0);
67+ break;
68+ case DSA_SIGN:
69+ case DSA_VERIFY:
70+ case ECDSA_SIGN:
71+ case ECDSA_VERIFY:
72+ pkc->s = crypto_alloc_pkc("pkc(dsa)",
73+ CRYPTO_ALG_TYPE_PKC_DSA, 0);
74+ break;
75+ case DH_COMPUTE_KEY:
76+ case ECDH_COMPUTE_KEY:
77+ pkc->s = crypto_alloc_pkc("pkc(dh)",
78+ CRYPTO_ALG_TYPE_PKC_DH, 0);
79+ break;
80+ default:
81+ return -EINVAL;
82+ }
83+
84+ if (IS_ERR_OR_NULL(pkc->s))
85+ return -EINVAL;
86+
87+ init_completion(&pkc->result.completion);
88+ pkc_requested = pkc_request_alloc(pkc->s, GFP_KERNEL);
89+
90+ if (unlikely(IS_ERR_OR_NULL(pkc_requested))) {
91+ ret = -ENOMEM;
92+ goto error;
93+ }
94+ pkc_requested->type = pkc_req->type;
95+ pkc_requested->curve_type = pkc_req->curve_type;
96+ memcpy(&pkc_requested->req_u, &pkc_req->req_u, sizeof(pkc_req->req_u));
97+ pkc_request_set_callback(pkc_requested, CRYPTO_TFM_REQ_MAY_BACKLOG,
98+ cryptodev_complete_asym, pkc);
99+ ret = crypto_pkc_op(pkc_requested);
100+ if (ret != -EINPROGRESS && ret != 0)
101+ goto error2;
102+
103+ if (pkc->type == SYNCHRONOUS)
104+ ret = waitfor(&pkc->result, ret);
105+
106+ return ret;
107+error2:
108+ kfree(pkc_requested);
109+error:
110+ crypto_free_pkc(pkc->s);
111+ return ret;
112+}
113diff --git a/cryptlib.h b/cryptlib.h
114index a0a8a63..56d325a 100644
115--- a/cryptlib.h
116+++ b/cryptlib.h
117@@ -1,3 +1,6 @@
118+/*
119+ * Copyright 2012 Freescale Semiconductor, Inc.
120+ */
121 #ifndef CRYPTLIB_H
122 # define CRYPTLIB_H
123
124@@ -89,5 +92,30 @@ void cryptodev_hash_deinit(struct hash_data *hdata);
125 int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
126 int hmac_mode, void *mackey, size_t mackeylen);
127
128+/* Operation Type */
129+enum offload_type {
130+ SYNCHRONOUS,
131+ ASYNCHRONOUS
132+};
133+
134+struct cryptodev_result {
135+ struct completion completion;
136+ int err;
137+};
138+
139+struct cryptodev_pkc {
140+ struct list_head list; /* To maintain the Jobs in completed
141+ cryptodev lists */
142+ struct kernel_crypt_kop kop;
143+ struct crypto_pkc *s; /* Transform pointer from CryptoAPI */
144+ struct cryptodev_result result; /* Result to be updated by
145+ completion handler */
146+ struct pkc_request req; /* PKC request structure allocated
147+ from CryptoAPI */
148+ enum offload_type type; /* Synchronous Vs Asynchronous request */
149+ void *cookie; /*Additional opaque cookie to be used in future */
150+ struct crypt_priv *priv;
151+};
152
153+int cryptodev_pkc_offload(struct cryptodev_pkc *);
154 #endif
155diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
156index c0e8cd4..96675fe 100644
157--- a/crypto/cryptodev.h
158+++ b/crypto/cryptodev.h
159@@ -1,6 +1,10 @@
160-/* This is a source compatible implementation with the original API of
161+/*
162+ * Copyright 2012 Freescale Semiconductor, Inc.
163+ *
164+ * This is a source compatible implementation with the original API of
165 * cryptodev by Angelos D. Keromytis, found at openbsd cryptodev.h.
166- * Placed under public domain */
167+ * Placed under public domain
168+ */
169
170 #ifndef L_CRYPTODEV_H
171 #define L_CRYPTODEV_H
172@@ -245,6 +249,9 @@ struct crypt_kop {
173 __u16 crk_oparams;
174 __u32 crk_pad1;
175 struct crparam crk_param[CRK_MAXPARAM];
176+ enum curve_t curve_type; /* 0 == Discrete Log,
177+ 1 = EC_PRIME, 2 = EC_BINARY */
178+ void *cookie;
179 };
180
181 enum cryptodev_crk_op_t {
182@@ -289,5 +296,7 @@ enum cryptodev_crk_op_t {
183 */
184 #define CIOCASYNCCRYPT _IOW('c', 110, struct crypt_op)
185 #define CIOCASYNCFETCH _IOR('c', 111, struct crypt_op)
186-
187+/* additional ioctls for asynchronous operation for asymmetric ciphers*/
188+#define CIOCASYMASYNCRYPT _IOW('c', 112, struct crypt_kop)
189+#define CIOCASYMASYNFETCH _IOR('c', 113, struct crypt_kop)
190 #endif /* L_CRYPTODEV_H */
191diff --git a/cryptodev_int.h b/cryptodev_int.h
192index 8e687e7..fdbcc61 100644
193--- a/cryptodev_int.h
194+++ b/cryptodev_int.h
195@@ -1,4 +1,6 @@
196-/* cipher stuff */
197+/* cipher stuff
198+ * Copyright 2012 Freescale Semiconductor, Inc.
199+ */
200 #ifndef CRYPTODEV_INT_H
201 # define CRYPTODEV_INT_H
202
203@@ -112,6 +114,14 @@ struct compat_crypt_auth_op {
204
205 #endif /* CONFIG_COMPAT */
206
207+/* kernel-internal extension to struct crypt_kop */
208+struct kernel_crypt_kop {
209+ struct crypt_kop kop;
210+
211+ struct task_struct *task;
212+ struct mm_struct *mm;
213+};
214+
215 /* kernel-internal extension to struct crypt_op */
216 struct kernel_crypt_op {
217 struct crypt_op cop;
218@@ -157,6 +167,14 @@ int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop);
219
220 #include <cryptlib.h>
221
222+/* Cryptodev Key operation handler */
223+int crypto_bn_modexp(struct cryptodev_pkc *);
224+int crypto_modexp_crt(struct cryptodev_pkc *);
225+int crypto_kop_dsasign(struct cryptodev_pkc *);
226+int crypto_kop_dsaverify(struct cryptodev_pkc *);
227+int crypto_run_asym(struct cryptodev_pkc *);
228+void cryptodev_complete_asym(struct crypto_async_request *, int);
229+
230 /* other internal structs */
231 struct csession {
232 struct list_head entry;
233diff --git a/ioctl.c b/ioctl.c
234index 1563c75..782d7fe 100644
235--- a/ioctl.c
236+++ b/ioctl.c
237@@ -4,6 +4,7 @@
238 * Copyright (c) 2004 Michal Ludvig <mludvig@logix.net.nz>, SuSE Labs
239 * Copyright (c) 2009,2010,2011 Nikos Mavrogiannopoulos <nmav@gnutls.org>
240 * Copyright (c) 2010 Phil Sutter
241+ * Copyright 2012 Freescale Semiconductor, Inc.
242 *
243 * This file is part of linux cryptodev.
244 *
245@@ -89,8 +90,37 @@ struct crypt_priv {
246 int itemcount;
247 struct work_struct cryptask;
248 wait_queue_head_t user_waiter;
249+ /* List of pending cryptodev_pkc asym requests */
250+ struct list_head asym_completed_list;
251+ /* For addition/removal of entry in pending list of asymmetric request*/
252+ spinlock_t completion_lock;
253 };
254
255+/* Asymmetric request Completion handler */
256+void cryptodev_complete_asym(struct crypto_async_request *req, int err)
257+{
258+ struct cryptodev_pkc *pkc = req->data;
259+ struct cryptodev_result *res = &pkc->result;
260+
261+ crypto_free_pkc(pkc->s);
262+ res->err = err;
263+ if (pkc->type == SYNCHRONOUS) {
264+ if (err == -EINPROGRESS)
265+ return;
266+ complete(&res->completion);
267+ } else {
268+ struct crypt_priv *pcr = pkc->priv;
269+ unsigned long flags;
270+ spin_lock_irqsave(&pcr->completion_lock, flags);
271+ list_add_tail(&pkc->list, &pcr->asym_completed_list);
272+ spin_unlock_irqrestore(&pcr->completion_lock, flags);
273+ /* wake for POLLIN */
274+ wake_up_interruptible(&pcr->user_waiter);
275+ }
276+
277+ kfree(req);
278+}
279+
280 #define FILL_SG(sg, ptr, len) \
281 do { \
282 (sg)->page = virt_to_page(ptr); \
283@@ -472,7 +502,8 @@ cryptodev_open(struct inode *inode, struct file *filp)
284 INIT_LIST_HEAD(&pcr->free.list);
285 INIT_LIST_HEAD(&pcr->todo.list);
286 INIT_LIST_HEAD(&pcr->done.list);
287-
288+ INIT_LIST_HEAD(&pcr->asym_completed_list);
289+ spin_lock_init(&pcr->completion_lock);
290 INIT_WORK(&pcr->cryptask, cryptask_routine);
291
292 init_waitqueue_head(&pcr->user_waiter);
293@@ -639,6 +670,79 @@ static int crypto_async_fetch(struct crypt_priv *pcr,
294 }
295 #endif
296
297+/* get the first asym cipher completed job from the "done" queue
298+ *
299+ * returns:
300+ * -EBUSY if no completed jobs are ready (yet)
301+ * the return value otherwise */
302+static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
303+{
304+ int ret = 0;
305+ struct kernel_crypt_kop *kop = &pkc->kop;
306+ struct crypt_kop *ckop = &kop->kop;
307+ struct pkc_request *pkc_req = &pkc->req;
308+
309+ switch (ckop->crk_op) {
310+ case CRK_MOD_EXP:
311+ {
312+ struct rsa_pub_req_s *rsa_req = &pkc_req->req_u.rsa_pub_req;
313+ copy_to_user(ckop->crk_param[3].crp_p, rsa_req->g,
314+ rsa_req->g_len);
315+ }
316+ break;
317+ case CRK_MOD_EXP_CRT:
318+ {
319+ struct rsa_priv_frm3_req_s *rsa_req =
320+ &pkc_req->req_u.rsa_priv_f3;
321+ copy_to_user(ckop->crk_param[6].crp_p,
322+ rsa_req->f, rsa_req->f_len);
323+ }
324+ break;
325+ case CRK_DSA_SIGN:
326+ {
327+ struct dsa_sign_req_s *dsa_req = &pkc_req->req_u.dsa_sign;
328+
329+ if (pkc_req->type == ECDSA_SIGN) {
330+ copy_to_user(ckop->crk_param[6].crp_p,
331+ dsa_req->c, dsa_req->d_len);
332+ copy_to_user(ckop->crk_param[7].crp_p,
333+ dsa_req->d, dsa_req->d_len);
334+ } else {
335+ copy_to_user(ckop->crk_param[5].crp_p,
336+ dsa_req->c, dsa_req->d_len);
337+ copy_to_user(ckop->crk_param[6].crp_p,
338+ dsa_req->d, dsa_req->d_len);
339+ }
340+ }
341+ break;
342+ case CRK_DSA_VERIFY:
343+ break;
344+ case CRK_DH_COMPUTE_KEY:
345+ {
346+ struct dh_key_req_s *dh_req = &pkc_req->req_u.dh_req;
347+ if (pkc_req->type == ECDH_COMPUTE_KEY)
348+ copy_to_user(ckop->crk_param[4].crp_p,
349+ dh_req->z, dh_req->z_len);
350+ else
351+ copy_to_user(ckop->crk_param[3].crp_p,
352+ dh_req->z, dh_req->z_len);
353+ }
354+ break;
355+ default:
356+ ret = -EINVAL;
357+ }
358+ kfree(pkc->cookie);
359+ return ret;
360+}
361+
362+/* this function has to be called from process context */
363+static int fill_kop_from_cop(struct kernel_crypt_kop *kop)
364+{
365+ kop->task = current;
366+ kop->mm = current->mm;
367+ return 0;
368+}
369+
370 /* this function has to be called from process context */
371 static int fill_kcop_from_cop(struct kernel_crypt_op *kcop, struct fcrypt *fcr)
372 {
373@@ -662,11 +766,8 @@ static int fill_kcop_from_cop(struct kernel_crypt_op *kcop, struct fcrypt *fcr)
374
375 if (cop->iv) {
376 rc = copy_from_user(kcop->iv, cop->iv, kcop->ivlen);
377- if (unlikely(rc)) {
378- derr(1, "error copying IV (%d bytes), copy_from_user returned %d for address %p",
379- kcop->ivlen, rc, cop->iv);
380+ if (unlikely(rc))
381 return -EFAULT;
382- }
383 }
384
385 return 0;
386@@ -692,6 +793,25 @@ static int fill_cop_from_kcop(struct kernel_crypt_op *kcop, struct fcrypt *fcr)
387 return 0;
388 }
389
390+static int kop_from_user(struct kernel_crypt_kop *kop,
391+ void __user *arg)
392+{
393+ if (unlikely(copy_from_user(&kop->kop, arg, sizeof(kop->kop))))
394+ return -EFAULT;
395+
396+ return fill_kop_from_cop(kop);
397+}
398+
399+static int kop_to_user(struct kernel_crypt_kop *kop,
400+ void __user *arg)
401+{
402+ if (unlikely(copy_to_user(arg, &kop->kop, sizeof(kop->kop)))) {
403+ dprintk(1, KERN_ERR, "Cannot copy to userspace\n");
404+ return -EFAULT;
405+ }
406+ return 0;
407+}
408+
409 static int kcop_from_user(struct kernel_crypt_op *kcop,
410 struct fcrypt *fcr, void __user *arg)
411 {
412@@ -821,7 +941,8 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
413
414 switch (cmd) {
415 case CIOCASYMFEAT:
416- return put_user(0, p);
417+ return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP |
418+ CRF_DSA_SIGN | CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY, p);
419 case CRIOGET:
420 fd = clonefd(filp);
421 ret = put_user(fd, p);
422@@ -857,6 +978,24 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
423 if (unlikely(ret))
424 return ret;
425 return copy_to_user(arg, &siop, sizeof(siop));
426+ case CIOCKEY:
427+ {
428+ struct cryptodev_pkc *pkc =
429+ kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
430+
431+ if (!pkc)
432+ return -ENOMEM;
433+
434+ ret = kop_from_user(&pkc->kop, arg);
435+ if (unlikely(ret)) {
436+ kfree(pkc);
437+ return ret;
438+ }
439+ pkc->type = SYNCHRONOUS;
440+ ret = crypto_run_asym(pkc);
441+ kfree(pkc);
442+ }
443+ return ret;
444 case CIOCCRYPT:
445 if (unlikely(ret = kcop_from_user(&kcop, fcr, arg))) {
446 dwarning(1, "Error copying from user");
447@@ -895,6 +1034,45 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
448
449 return kcop_to_user(&kcop, fcr, arg);
450 #endif
451+ case CIOCASYMASYNCRYPT:
452+ {
453+ struct cryptodev_pkc *pkc =
454+ kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
455+ ret = kop_from_user(&pkc->kop, arg);
456+
457+ if (unlikely(ret))
458+ return -EINVAL;
459+
460+ /* Store associated FD priv data with asymmetric request */
461+ pkc->priv = pcr;
462+ pkc->type = ASYNCHRONOUS;
463+ ret = crypto_run_asym(pkc);
464+ if (ret == -EINPROGRESS)
465+ ret = 0;
466+ }
467+ return ret;
468+ case CIOCASYMASYNFETCH:
469+ {
470+ struct cryptodev_pkc *pkc;
471+ unsigned long flags;
472+
473+ spin_lock_irqsave(&pcr->completion_lock, flags);
474+ if (list_empty(&pcr->asym_completed_list)) {
475+ spin_unlock_irqrestore(&pcr->completion_lock, flags);
476+ return -ENOMEM;
477+ }
478+ pkc = list_first_entry(&pcr->asym_completed_list,
479+ struct cryptodev_pkc, list);
480+ list_del(&pkc->list);
481+ spin_unlock_irqrestore(&pcr->completion_lock, flags);
482+ ret = crypto_async_fetch_asym(pkc);
483+
484+ /* Reflect the updated request to user-space */
485+ if (!ret)
486+ kop_to_user(&pkc->kop, arg);
487+ kfree(pkc);
488+ }
489+ return ret;
490 default:
491 return -EINVAL;
492 }
493@@ -1083,9 +1261,11 @@ static unsigned int cryptodev_poll(struct file *file, poll_table *wait)
494
495 poll_wait(file, &pcr->user_waiter, wait);
496
497- if (!list_empty_careful(&pcr->done.list))
498+ if (!list_empty_careful(&pcr->done.list) ||
499+ !list_empty_careful(&pcr->asym_completed_list))
500 ret |= POLLIN | POLLRDNORM;
501- if (!list_empty_careful(&pcr->free.list) || pcr->itemcount < MAX_COP_RINGSIZE)
502+ if (!list_empty_careful(&pcr->free.list) ||
503+ pcr->itemcount < MAX_COP_RINGSIZE)
504 ret |= POLLOUT | POLLWRNORM;
505
506 return ret;
507diff --git a/main.c b/main.c
508index 57e5c38..0b7951e 100644
509--- a/main.c
510+++ b/main.c
511@@ -181,6 +181,384 @@ __crypto_run_zc(struct csession *ses_ptr, struct kernel_crypt_op *kcop)
512 return ret;
513 }
514
515+int crypto_kop_dsasign(struct cryptodev_pkc *pkc)
516+{
517+ struct kernel_crypt_kop *kop = &pkc->kop;
518+ struct crypt_kop *cop = &kop->kop;
519+ struct pkc_request *pkc_req = &pkc->req;
520+ struct dsa_sign_req_s *dsa_req = &pkc_req->req_u.dsa_sign;
521+ int rc, buf_size;
522+ uint8_t *buf;
523+
524+ if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
525+ !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
526+ !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits ||
527+ !cop->crk_param[6].crp_nbits || (cop->crk_iparams == 6 &&
528+ !cop->crk_param[7].crp_nbits))
529+ return -EINVAL;
530+
531+ dsa_req->m_len = (cop->crk_param[0].crp_nbits + 7)/8;
532+ dsa_req->q_len = (cop->crk_param[1].crp_nbits + 7)/8;
533+ dsa_req->r_len = (cop->crk_param[2].crp_nbits + 7)/8;
534+ dsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8;
535+ dsa_req->priv_key_len = (cop->crk_param[4].crp_nbits + 7)/8;
536+ dsa_req->d_len = (cop->crk_param[6].crp_nbits + 7)/8;
537+ buf_size = dsa_req->m_len + dsa_req->q_len + dsa_req->r_len +
538+ dsa_req->g_len + dsa_req->priv_key_len + dsa_req->d_len +
539+ dsa_req->d_len;
540+ if (cop->crk_iparams == 6) {
541+ dsa_req->ab_len = (cop->crk_param[5].crp_nbits + 7)/8;
542+ buf_size += dsa_req->ab_len;
543+ pkc_req->type = ECDSA_SIGN;
544+ pkc_req->curve_type = cop->curve_type;
545+ } else {
546+ pkc_req->type = DSA_SIGN;
547+ }
548+
549+ buf = kzalloc(buf_size, GFP_DMA);
550+
551+ dsa_req->q = buf;
552+ dsa_req->r = dsa_req->q + dsa_req->q_len;
553+ dsa_req->g = dsa_req->r + dsa_req->r_len;
554+ dsa_req->priv_key = dsa_req->g + dsa_req->g_len;
555+ dsa_req->m = dsa_req->priv_key + dsa_req->priv_key_len;
556+ dsa_req->c = dsa_req->m + dsa_req->m_len;
557+ dsa_req->d = dsa_req->c + dsa_req->d_len;
558+ copy_from_user(dsa_req->m, cop->crk_param[0].crp_p, dsa_req->m_len);
559+ copy_from_user(dsa_req->q, cop->crk_param[1].crp_p, dsa_req->q_len);
560+ copy_from_user(dsa_req->r, cop->crk_param[2].crp_p, dsa_req->r_len);
561+ copy_from_user(dsa_req->g, cop->crk_param[3].crp_p, dsa_req->g_len);
562+ copy_from_user(dsa_req->priv_key, cop->crk_param[4].crp_p,
563+ dsa_req->priv_key_len);
564+ if (cop->crk_iparams == 6) {
565+ dsa_req->ab = dsa_req->d + dsa_req->d_len;
566+ copy_from_user(dsa_req->ab, cop->crk_param[5].crp_p,
567+ dsa_req->ab_len);
568+ }
569+ rc = cryptodev_pkc_offload(pkc);
570+ if (pkc->type == SYNCHRONOUS) {
571+ if (rc)
572+ goto err;
573+ if (cop->crk_iparams == 6) {
574+ copy_to_user(cop->crk_param[6].crp_p, dsa_req->c,
575+ dsa_req->d_len);
576+ copy_to_user(cop->crk_param[7].crp_p, dsa_req->d,
577+ dsa_req->d_len);
578+ } else {
579+ copy_to_user(cop->crk_param[5].crp_p, dsa_req->c,
580+ dsa_req->d_len);
581+ copy_to_user(cop->crk_param[6].crp_p, dsa_req->d,
582+ dsa_req->d_len);
583+ }
584+ } else {
585+ if (rc != -EINPROGRESS && rc != 0)
586+ goto err;
587+
588+ pkc->cookie = buf;
589+ return rc;
590+ }
591+err:
592+ kfree(buf);
593+ return rc;
594+}
595+
596+int crypto_kop_dsaverify(struct cryptodev_pkc *pkc)
597+{
598+ struct kernel_crypt_kop *kop = &pkc->kop;
599+ struct crypt_kop *cop = &kop->kop;
600+ struct pkc_request *pkc_req;
601+ struct dsa_verify_req_s *dsa_req;
602+ int rc, buf_size;
603+ uint8_t *buf;
604+
605+ if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
606+ !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
607+ !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits ||
608+ !cop->crk_param[6].crp_nbits || (cop->crk_iparams == 8 &&
609+ !cop->crk_param[7].crp_nbits))
610+ return -EINVAL;
611+
612+ pkc_req = &pkc->req;
613+ dsa_req = &pkc_req->req_u.dsa_verify;
614+ dsa_req->m_len = (cop->crk_param[0].crp_nbits + 7)/8;
615+ dsa_req->q_len = (cop->crk_param[1].crp_nbits + 7)/8;
616+ dsa_req->r_len = (cop->crk_param[2].crp_nbits + 7)/8;
617+ dsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8;
618+ dsa_req->pub_key_len = (cop->crk_param[4].crp_nbits + 7)/8;
619+ dsa_req->d_len = (cop->crk_param[6].crp_nbits + 7)/8;
620+ buf_size = dsa_req->m_len + dsa_req->q_len + dsa_req->r_len +
621+ dsa_req->g_len + dsa_req->pub_key_len + dsa_req->d_len +
622+ dsa_req->d_len;
623+ if (cop->crk_iparams == 8) {
624+ dsa_req->ab_len = (cop->crk_param[5].crp_nbits + 7)/8;
625+ buf_size += dsa_req->ab_len;
626+ pkc_req->type = ECDSA_VERIFY;
627+ pkc_req->curve_type = cop->curve_type;
628+ } else {
629+ pkc_req->type = DSA_VERIFY;
630+ }
631+
632+ buf = kzalloc(buf_size, GFP_DMA);
633+
634+ dsa_req->q = buf;
635+ dsa_req->r = dsa_req->q + dsa_req->q_len;
636+ dsa_req->g = dsa_req->r + dsa_req->r_len;
637+ dsa_req->pub_key = dsa_req->g + dsa_req->g_len;
638+ dsa_req->m = dsa_req->pub_key + dsa_req->pub_key_len;
639+ dsa_req->c = dsa_req->m + dsa_req->m_len;
640+ dsa_req->d = dsa_req->c + dsa_req->d_len;
641+ copy_from_user(dsa_req->m, cop->crk_param[0].crp_p, dsa_req->m_len);
642+ copy_from_user(dsa_req->q, cop->crk_param[1].crp_p, dsa_req->q_len);
643+ copy_from_user(dsa_req->r, cop->crk_param[2].crp_p, dsa_req->r_len);
644+ copy_from_user(dsa_req->g, cop->crk_param[3].crp_p, dsa_req->g_len);
645+ copy_from_user(dsa_req->pub_key, cop->crk_param[4].crp_p,
646+ dsa_req->pub_key_len);
647+ if (cop->crk_iparams == 8) {
648+ dsa_req->ab = dsa_req->d + dsa_req->d_len;
649+ copy_from_user(dsa_req->ab, cop->crk_param[5].crp_p,
650+ dsa_req->ab_len);
651+ copy_from_user(dsa_req->c, cop->crk_param[6].crp_p,
652+ dsa_req->d_len);
653+ copy_from_user(dsa_req->d, cop->crk_param[7].crp_p,
654+ dsa_req->d_len);
655+ } else {
656+ copy_from_user(dsa_req->c, cop->crk_param[5].crp_p,
657+ dsa_req->d_len);
658+ copy_from_user(dsa_req->d, cop->crk_param[6].crp_p,
659+ dsa_req->d_len);
660+ }
661+ rc = cryptodev_pkc_offload(pkc);
662+ if (pkc->type == SYNCHRONOUS) {
663+ if (rc)
664+ goto err;
665+ } else {
666+ if (rc != -EINPROGRESS && !rc)
667+ goto err;
668+ pkc->cookie = buf;
669+ return rc;
670+ }
671+err:
672+ kfree(buf);
673+ return rc;
674+}
675+
676+int crypto_kop_dh_key(struct cryptodev_pkc *pkc)
677+{
678+ struct kernel_crypt_kop *kop = &pkc->kop;
679+ struct crypt_kop *cop = &kop->kop;
680+ struct pkc_request *pkc_req;
681+ struct dh_key_req_s *dh_req;
682+ int buf_size;
683+ uint8_t *buf;
684+ int rc = -EINVAL;
685+
686+ pkc_req = &pkc->req;
687+ dh_req = &pkc_req->req_u.dh_req;
688+ dh_req->s_len = (cop->crk_param[0].crp_nbits + 7)/8;
689+ dh_req->pub_key_len = (cop->crk_param[1].crp_nbits + 7)/8;
690+ dh_req->q_len = (cop->crk_param[2].crp_nbits + 7)/8;
691+ buf_size = dh_req->q_len + dh_req->pub_key_len + dh_req->s_len;
692+ if (cop->crk_iparams == 4) {
693+ pkc_req->type = ECDH_COMPUTE_KEY;
694+ dh_req->ab_len = (cop->crk_param[3].crp_nbits + 7)/8;
695+ dh_req->z_len = (cop->crk_param[4].crp_nbits + 7)/8;
696+ buf_size += dh_req->ab_len;
697+ } else {
698+ dh_req->z_len = (cop->crk_param[3].crp_nbits + 7)/8;
699+ pkc_req->type = DH_COMPUTE_KEY;
700+ }
701+ buf_size += dh_req->z_len;
702+ buf = kzalloc(buf_size, GFP_DMA);
703+ dh_req->q = buf;
704+ dh_req->s = dh_req->q + dh_req->q_len;
705+ dh_req->pub_key = dh_req->s + dh_req->s_len;
706+ dh_req->z = dh_req->pub_key + dh_req->pub_key_len;
707+ if (cop->crk_iparams == 4) {
708+ dh_req->ab = dh_req->z + dh_req->z_len;
709+ pkc_req->curve_type = cop->curve_type;
710+ copy_from_user(dh_req->ab, cop->crk_param[3].crp_p,
711+ dh_req->ab_len);
712+ }
713+ copy_from_user(dh_req->s, cop->crk_param[0].crp_p, dh_req->s_len);
714+ copy_from_user(dh_req->pub_key, cop->crk_param[1].crp_p,
715+ dh_req->pub_key_len);
716+ copy_from_user(dh_req->q, cop->crk_param[2].crp_p, dh_req->q_len);
717+ rc = cryptodev_pkc_offload(pkc);
718+ if (pkc->type == SYNCHRONOUS) {
719+ if (rc)
720+ goto err;
721+ if (cop->crk_iparams == 4)
722+ copy_to_user(cop->crk_param[4].crp_p, dh_req->z,
723+ dh_req->z_len);
724+ else
725+ copy_to_user(cop->crk_param[3].crp_p, dh_req->z,
726+ dh_req->z_len);
727+ } else {
728+ if (rc != -EINPROGRESS && rc != 0)
729+ goto err;
730+
731+ pkc->cookie = buf;
732+ return rc;
733+ }
734+err:
735+ kfree(buf);
736+ return rc;
737+}
738+
739+int crypto_modexp_crt(struct cryptodev_pkc *pkc)
740+{
741+ struct kernel_crypt_kop *kop = &pkc->kop;
742+ struct crypt_kop *cop = &kop->kop;
743+ struct pkc_request *pkc_req;
744+ struct rsa_priv_frm3_req_s *rsa_req;
745+ int rc;
746+ uint8_t *buf;
747+
748+ if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
749+ !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
750+ !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits)
751+ return -EINVAL;
752+
753+ pkc_req = &pkc->req;
754+ pkc_req->type = RSA_PRIV_FORM3;
755+ rsa_req = &pkc_req->req_u.rsa_priv_f3;
756+ rsa_req->p_len = (cop->crk_param[0].crp_nbits + 7)/8;
757+ rsa_req->q_len = (cop->crk_param[1].crp_nbits + 7)/8;
758+ rsa_req->g_len = (cop->crk_param[2].crp_nbits + 7)/8;
759+ rsa_req->dp_len = (cop->crk_param[3].crp_nbits + 7)/8;
760+ rsa_req->dq_len = (cop->crk_param[4].crp_nbits + 7)/8;
761+ rsa_req->c_len = (cop->crk_param[5].crp_nbits + 7)/8;
762+ rsa_req->f_len = (cop->crk_param[6].crp_nbits + 7)/8;
763+ buf = kzalloc(rsa_req->p_len + rsa_req->q_len + rsa_req->f_len +
764+ rsa_req->dp_len + rsa_req->dp_len + rsa_req->c_len +
765+ rsa_req->g_len, GFP_DMA);
766+ rsa_req->p = buf;
767+ rsa_req->q = rsa_req->p + rsa_req->p_len;
768+ rsa_req->g = rsa_req->q + rsa_req->q_len;
769+ rsa_req->dp = rsa_req->g + rsa_req->g_len;
770+ rsa_req->dq = rsa_req->dp + rsa_req->dp_len;
771+ rsa_req->c = rsa_req->dq + rsa_req->dq_len;
772+ rsa_req->f = rsa_req->c + rsa_req->c_len;
773+ copy_from_user(rsa_req->p, cop->crk_param[0].crp_p, rsa_req->p_len);
774+ copy_from_user(rsa_req->q, cop->crk_param[1].crp_p, rsa_req->q_len);
775+ copy_from_user(rsa_req->g, cop->crk_param[2].crp_p, rsa_req->g_len);
776+ copy_from_user(rsa_req->dp, cop->crk_param[3].crp_p, rsa_req->dp_len);
777+ copy_from_user(rsa_req->dq, cop->crk_param[4].crp_p, rsa_req->dq_len);
778+ copy_from_user(rsa_req->c, cop->crk_param[5].crp_p, rsa_req->c_len);
779+ rc = cryptodev_pkc_offload(pkc);
780+
781+ if (pkc->type == SYNCHRONOUS) {
782+ if (rc)
783+ goto err;
784+ copy_to_user(cop->crk_param[6].crp_p, rsa_req->f,
785+ rsa_req->f_len);
786+ } else {
787+ if (rc != -EINPROGRESS && rc != 0)
788+ goto err;
789+
790+ pkc->cookie = buf;
791+ return rc;
792+ }
793+err:
794+ kfree(buf);
795+ return rc;
796+}
797+
798+int crypto_bn_modexp(struct cryptodev_pkc *pkc)
799+{
800+ struct pkc_request *pkc_req;
801+ struct rsa_pub_req_s *rsa_req;
802+ int rc;
803+ struct kernel_crypt_kop *kop = &pkc->kop;
804+ struct crypt_kop *cop = &kop->kop;
805+ uint8_t *buf;
806+
807+ if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
808+ !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits)
809+ return -EINVAL;
810+
811+ pkc_req = &pkc->req;
812+ pkc_req->type = RSA_PUB;
813+ rsa_req = &pkc_req->req_u.rsa_pub_req;
814+ rsa_req->f_len = (cop->crk_param[0].crp_nbits + 7)/8;
815+ rsa_req->e_len = (cop->crk_param[1].crp_nbits + 7)/8;
816+ rsa_req->n_len = (cop->crk_param[2].crp_nbits + 7)/8;
817+ rsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8;
818+ buf = kzalloc(rsa_req->f_len + rsa_req->e_len + rsa_req->n_len
819+ + rsa_req->g_len, GFP_DMA);
820+ if (!buf)
821+ return -ENOMEM;
822+
823+ rsa_req->e = buf;
824+ rsa_req->f = rsa_req->e + rsa_req->e_len;
825+ rsa_req->g = rsa_req->f + rsa_req->f_len;
826+ rsa_req->n = rsa_req->g + rsa_req->g_len;
827+ copy_from_user(rsa_req->f, cop->crk_param[0].crp_p, rsa_req->f_len);
828+ copy_from_user(rsa_req->e, cop->crk_param[1].crp_p, rsa_req->e_len);
829+ copy_from_user(rsa_req->n, cop->crk_param[2].crp_p, rsa_req->n_len);
830+ rc = cryptodev_pkc_offload(pkc);
831+ if (pkc->type == SYNCHRONOUS) {
832+ if (rc)
833+ goto err;
834+
835+ copy_to_user(cop->crk_param[3].crp_p, rsa_req->g,
836+ rsa_req->g_len);
837+ } else {
838+ if (rc != -EINPROGRESS && rc != 0)
839+ goto err;
840+
841+ /* This one will be freed later in fetch handler */
842+ pkc->cookie = buf;
843+ return rc;
844+ }
845+err:
846+ kfree(buf);
847+ return rc;
848+}
849+
850+int crypto_run_asym(struct cryptodev_pkc *pkc)
851+{
852+ int ret = -EINVAL;
853+ struct kernel_crypt_kop *kop = &pkc->kop;
854+
855+ switch (kop->kop.crk_op) {
856+ case CRK_MOD_EXP:
857+ if (kop->kop.crk_iparams != 3 && kop->kop.crk_oparams != 1)
858+ goto err;
859+
860+ ret = crypto_bn_modexp(pkc);
861+ break;
862+ case CRK_MOD_EXP_CRT:
863+ if (kop->kop.crk_iparams != 6 && kop->kop.crk_oparams != 1)
864+ goto err;
865+
866+ ret = crypto_modexp_crt(pkc);
867+ break;
868+ case CRK_DSA_SIGN:
869+ if ((kop->kop.crk_iparams != 5 && kop->kop.crk_iparams != 6) ||
870+ kop->kop.crk_oparams != 2)
871+ goto err;
872+
873+ ret = crypto_kop_dsasign(pkc);
874+ break;
875+ case CRK_DSA_VERIFY:
876+ if ((kop->kop.crk_iparams != 7 && kop->kop.crk_iparams != 8) ||
877+ kop->kop.crk_oparams != 0)
878+ goto err;
879+
880+ ret = crypto_kop_dsaverify(pkc);
881+ break;
882+ case CRK_DH_COMPUTE_KEY:
883+ if ((kop->kop.crk_iparams != 3 && kop->kop.crk_iparams != 4) ||
884+ kop->kop.crk_oparams != 1)
885+ goto err;
886+ ret = crypto_kop_dh_key(pkc);
887+ break;
888+ }
889+err:
890+ return ret;
891+}
892+
893 int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop)
894 {
895 struct csession *ses_ptr;
896--
8971.8.3.1
898
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0004-Compat-versions-of-PKC-IOCTLs.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0004-Compat-versions-of-PKC-IOCTLs.patch
new file mode 100644
index 0000000..2eedcc7
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0004-Compat-versions-of-PKC-IOCTLs.patch
@@ -0,0 +1,200 @@
1From 5435dfd329cd90837ce36c6dadc26166c7906cab Mon Sep 17 00:00:00 2001
2From: Yashpal Dutta <yashpal.dutta@freescale.com>
3Date: Fri, 7 Mar 2014 06:52:13 +0545
4Subject: [PATCH 4/9] Compat versions of PKC IOCTLs
5
6Upstream-status: Pending
7
8Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
9---
10 cryptodev_int.h | 20 ++++++++++
11 ioctl.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 2 files changed, 140 insertions(+)
13
14diff --git a/cryptodev_int.h b/cryptodev_int.h
15index fdbcc61..cf54dac 100644
16--- a/cryptodev_int.h
17+++ b/cryptodev_int.h
18@@ -75,6 +75,24 @@ struct compat_crypt_op {
19 compat_uptr_t iv;/* initialization vector for encryption operations */
20 };
21
22+/* input of CIOCKEY */
23+struct compat_crparam {
24+ compat_uptr_t crp_p;
25+ uint32_t crp_nbits;
26+};
27+
28+struct compat_crypt_kop {
29+ uint32_t crk_op; /* cryptodev_crk_ot_t */
30+ uint32_t crk_status;
31+ uint16_t crk_iparams;
32+ uint16_t crk_oparams;
33+ uint32_t crk_pad1;
34+ struct compat_crparam crk_param[CRK_MAXPARAM];
35+ enum curve_t curve_type; /* 0 == Discrete Log, 1 = EC_PRIME,
36+ 2 = EC_BINARY */
37+ compat_uptr_t cookie;
38+};
39+
40 /* input of CIOCAUTHCRYPT */
41 struct compat_crypt_auth_op {
42 uint32_t ses; /* session identifier */
43@@ -111,6 +129,8 @@ struct compat_crypt_auth_op {
44 #define COMPAT_CIOCASYNCCRYPT _IOW('c', 107, struct compat_crypt_op)
45 #define COMPAT_CIOCASYNCFETCH _IOR('c', 108, struct compat_crypt_op)
46 #define COMPAT_CIOCAUTHCRYPT _IOWR('c', 109, struct compat_crypt_auth_op)
47+#define COMPAT_CIOCASYMASYNCRYPT _IOW('c', 110, struct compat_crypt_kop)
48+#define COMPAT_CIOCASYMASYNFETCH _IOR('c', 111, struct compat_crypt_kop)
49
50 #endif /* CONFIG_COMPAT */
51
52diff --git a/ioctl.c b/ioctl.c
53index 782d7fe..3baf3e6 100644
54--- a/ioctl.c
55+++ b/ioctl.c
56@@ -1081,6 +1081,68 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
57 /* compatibility code for 32bit userlands */
58 #ifdef CONFIG_COMPAT
59
60+static inline void compat_to_crypt_kop(struct compat_crypt_kop *compat,
61+ struct crypt_kop *kop)
62+{
63+ int i;
64+ kop->crk_op = compat->crk_op;
65+ kop->crk_status = compat->crk_status;
66+ kop->crk_iparams = compat->crk_iparams;
67+ kop->crk_oparams = compat->crk_oparams;
68+
69+ for (i = 0; i < CRK_MAXPARAM; i++) {
70+ kop->crk_param[i].crp_p =
71+ compat_ptr(compat->crk_param[i].crp_p);
72+ kop->crk_param[i].crp_nbits = compat->crk_param[i].crp_nbits;
73+ }
74+
75+ kop->curve_type = compat->curve_type;
76+ kop->cookie = compat->cookie;
77+}
78+
79+static int compat_kop_from_user(struct kernel_crypt_kop *kop,
80+ void __user *arg)
81+{
82+ struct compat_crypt_kop compat_kop;
83+
84+ if (unlikely(copy_from_user(&compat_kop, arg, sizeof(compat_kop))))
85+ return -EFAULT;
86+
87+ compat_to_crypt_kop(&compat_kop, &kop->kop);
88+ return fill_kop_from_cop(kop);
89+}
90+
91+static inline void crypt_kop_to_compat(struct crypt_kop *kop,
92+ struct compat_crypt_kop *compat)
93+{
94+ int i;
95+
96+ compat->crk_op = kop->crk_op;
97+ compat->crk_status = kop->crk_status;
98+ compat->crk_iparams = kop->crk_iparams;
99+ compat->crk_oparams = kop->crk_oparams;
100+
101+ for (i = 0; i < CRK_MAXPARAM; i++) {
102+ compat->crk_param[i].crp_p =
103+ ptr_to_compat(kop->crk_param[i].crp_p);
104+ compat->crk_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
105+ }
106+ compat->cookie = kop->cookie;
107+ compat->curve_type = kop->curve_type;
108+}
109+
110+static int compat_kop_to_user(struct kernel_crypt_kop *kop, void __user *arg)
111+{
112+ struct compat_crypt_kop compat_kop;
113+
114+ crypt_kop_to_compat(&kop->kop, &compat_kop);
115+ if (unlikely(copy_to_user(arg, &compat_kop, sizeof(compat_kop)))) {
116+ dprintk(1, KERN_ERR, "Cannot copy to userspace\n");
117+ return -EFAULT;
118+ }
119+ return 0;
120+}
121+
122 static inline void
123 compat_to_session_op(struct compat_session_op *compat, struct session_op *sop)
124 {
125@@ -1208,7 +1270,26 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
126 return -EFAULT;
127 }
128 return ret;
129+ case COMPAT_CIOCKEY:
130+ {
131+ struct cryptodev_pkc *pkc =
132+ kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
133+
134+ if (!pkc)
135+ return -ENOMEM;
136+
137+ ret = compat_kop_from_user(&pkc->kop, arg);
138+
139+ if (unlikely(ret)) {
140+ kfree(pkc);
141+ return ret;
142+ }
143
144+ pkc->type = SYNCHRONOUS;
145+ ret = crypto_run_asym(pkc);
146+ kfree(pkc);
147+ }
148+ return ret;
149 case COMPAT_CIOCCRYPT:
150 ret = compat_kcop_from_user(&kcop, fcr, arg);
151 if (unlikely(ret))
152@@ -1247,6 +1328,45 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
153
154 return compat_kcop_to_user(&kcop, fcr, arg);
155 #endif
156+ case COMPAT_CIOCASYMASYNCRYPT:
157+ {
158+ struct cryptodev_pkc *pkc =
159+ kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
160+
161+ ret = compat_kop_from_user(&pkc->kop, arg);
162+ if (unlikely(ret))
163+ return -EINVAL;
164+
165+ /* Store associated FD priv data with asymmetric request */
166+ pkc->priv = pcr;
167+ pkc->type = ASYNCHRONOUS;
168+ ret = crypto_run_asym(pkc);
169+ if (ret == -EINPROGRESS)
170+ ret = 0;
171+ }
172+ return ret;
173+ case COMPAT_CIOCASYMASYNFETCH:
174+ {
175+ struct cryptodev_pkc *pkc;
176+ unsigned long flags;
177+
178+ spin_lock_irqsave(&pcr->completion_lock, flags);
179+ if (list_empty(&pcr->asym_completed_list)) {
180+ spin_unlock_irqrestore(&pcr->completion_lock, flags);
181+ return -ENOMEM;
182+ }
183+ pkc = list_first_entry(&pcr->asym_completed_list,
184+ struct cryptodev_pkc, list);
185+ list_del(&pkc->list);
186+ spin_unlock_irqrestore(&pcr->completion_lock, flags);
187+ ret = crypto_async_fetch_asym(pkc);
188+
189+ /* Reflect the updated request to user-space */
190+ if (!ret)
191+ compat_kop_to_user(&pkc->kop, arg);
192+ kfree(pkc);
193+ }
194+ return ret;
195 default:
196 return -EINVAL;
197 }
198--
1991.8.3.1
200
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0005-Asynchronous-interface-changes-in-cryptodev.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0005-Asynchronous-interface-changes-in-cryptodev.patch
new file mode 100644
index 0000000..2f88eda
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0005-Asynchronous-interface-changes-in-cryptodev.patch
@@ -0,0 +1,213 @@
1From ddc4179a454cea79c8385fd6756d20cbf3c6dcb5 Mon Sep 17 00:00:00 2001
2From: Yashpal Dutta <yashpal.dutta@freescale.com>
3Date: Fri, 7 Mar 2014 07:24:00 +0545
4Subject: [PATCH 5/9] Asynchronous interface changes in cryptodev
5
6Upstream-status: Pending
7
8Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
9---
10 cryptlib.h | 7 ++++-
11 crypto/cryptodev.h | 10 ++++++-
12 cryptodev_int.h | 10 ++++++-
13 ioctl.c | 76 +++++++++++++++++++++++++++++++++++++-----------------
14 4 files changed, 76 insertions(+), 27 deletions(-)
15
16diff --git a/cryptlib.h b/cryptlib.h
17index 56d325a..7ffa54c 100644
18--- a/cryptlib.h
19+++ b/cryptlib.h
20@@ -113,7 +113,12 @@ struct cryptodev_pkc {
21 struct pkc_request req; /* PKC request structure allocated
22 from CryptoAPI */
23 enum offload_type type; /* Synchronous Vs Asynchronous request */
24- void *cookie; /*Additional opaque cookie to be used in future */
25+ /*
26+ * cookie used for transfering tranparent information from async
27+ * submission to async fetch. Currently some dynamic allocated
28+ * buffers are maintained which will be freed later during fetch
29+ */
30+ void *cookie;
31 struct crypt_priv *priv;
32 };
33
34diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
35index 96675fe..4436fbf 100644
36--- a/crypto/cryptodev.h
37+++ b/crypto/cryptodev.h
38@@ -254,6 +254,14 @@ struct crypt_kop {
39 void *cookie;
40 };
41
42+#define MAX_COOKIES 4
43+
44+struct pkc_cookie_list_s {
45+ int cookie_available;
46+ void *cookie[MAX_COOKIES];
47+ int status[MAX_COOKIES];
48+};
49+
50 enum cryptodev_crk_op_t {
51 CRK_MOD_EXP = 0,
52 CRK_MOD_EXP_CRT = 1,
53@@ -298,5 +306,5 @@ enum cryptodev_crk_op_t {
54 #define CIOCASYNCFETCH _IOR('c', 111, struct crypt_op)
55 /* additional ioctls for asynchronous operation for asymmetric ciphers*/
56 #define CIOCASYMASYNCRYPT _IOW('c', 112, struct crypt_kop)
57-#define CIOCASYMASYNFETCH _IOR('c', 113, struct crypt_kop)
58+#define CIOCASYMFETCHCOOKIE _IOR('c', 113, struct pkc_cookie_list_s)
59 #endif /* L_CRYPTODEV_H */
60diff --git a/cryptodev_int.h b/cryptodev_int.h
61index cf54dac..5347cae 100644
62--- a/cryptodev_int.h
63+++ b/cryptodev_int.h
64@@ -93,6 +93,12 @@ struct compat_crypt_kop {
65 compat_uptr_t cookie;
66 };
67
68+struct compat_pkc_cookie_list_s {
69+ int cookie_available;
70+ compat_uptr_t cookie[MAX_COOKIES];
71+ int status[MAX_COOKIES];
72+};
73+
74 /* input of CIOCAUTHCRYPT */
75 struct compat_crypt_auth_op {
76 uint32_t ses; /* session identifier */
77@@ -126,11 +132,13 @@ struct compat_crypt_auth_op {
78 /* compat ioctls, defined for the above structs */
79 #define COMPAT_CIOCGSESSION _IOWR('c', 102, struct compat_session_op)
80 #define COMPAT_CIOCCRYPT _IOWR('c', 104, struct compat_crypt_op)
81+#define COMPAT_CIOCKEY _IOW('c', 105, struct compat_crypt_kop)
82 #define COMPAT_CIOCASYNCCRYPT _IOW('c', 107, struct compat_crypt_op)
83 #define COMPAT_CIOCASYNCFETCH _IOR('c', 108, struct compat_crypt_op)
84 #define COMPAT_CIOCAUTHCRYPT _IOWR('c', 109, struct compat_crypt_auth_op)
85 #define COMPAT_CIOCASYMASYNCRYPT _IOW('c', 110, struct compat_crypt_kop)
86-#define COMPAT_CIOCASYMASYNFETCH _IOR('c', 111, struct compat_crypt_kop)
87+#define COMPAT_CIOCASYMFETCHCOOKIE _IOR('c', 111, \
88+ struct compat_pkc_cookie_list_s)
89
90 #endif /* CONFIG_COMPAT */
91
92diff --git a/ioctl.c b/ioctl.c
93index 3baf3e6..2eb7f03 100644
94--- a/ioctl.c
95+++ b/ioctl.c
96@@ -105,8 +105,6 @@ void cryptodev_complete_asym(struct crypto_async_request *req, int err)
97 crypto_free_pkc(pkc->s);
98 res->err = err;
99 if (pkc->type == SYNCHRONOUS) {
100- if (err == -EINPROGRESS)
101- return;
102 complete(&res->completion);
103 } else {
104 struct crypt_priv *pcr = pkc->priv;
105@@ -1051,26 +1049,41 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
106 ret = 0;
107 }
108 return ret;
109- case CIOCASYMASYNFETCH:
110+ case CIOCASYMFETCHCOOKIE:
111 {
112 struct cryptodev_pkc *pkc;
113 unsigned long flags;
114+ int i;
115+ struct pkc_cookie_list_s cookie_list;
116
117 spin_lock_irqsave(&pcr->completion_lock, flags);
118- if (list_empty(&pcr->asym_completed_list)) {
119- spin_unlock_irqrestore(&pcr->completion_lock, flags);
120- return -ENOMEM;
121+ cookie_list.cookie_available = 0;
122+ for (i = 0; i < MAX_COOKIES; i++) {
123+ if (!list_empty(&pcr->asym_completed_list)) {
124+ /* Run a loop in the list for upto elements
125+ and copy their response back */
126+ pkc =
127+ list_first_entry(&pcr->asym_completed_list,
128+ struct cryptodev_pkc, list);
129+ list_del(&pkc->list);
130+ ret = crypto_async_fetch_asym(pkc);
131+ if (!ret) {
132+ cookie_list.cookie_available++;
133+ cookie_list.cookie[i] =
134+ pkc->kop.kop.cookie;
135+ cookie_list.status[i] = pkc->result.err;
136+ }
137+ kfree(pkc);
138+ } else {
139+ break;
140+ }
141 }
142- pkc = list_first_entry(&pcr->asym_completed_list,
143- struct cryptodev_pkc, list);
144- list_del(&pkc->list);
145 spin_unlock_irqrestore(&pcr->completion_lock, flags);
146- ret = crypto_async_fetch_asym(pkc);
147
148 /* Reflect the updated request to user-space */
149- if (!ret)
150- kop_to_user(&pkc->kop, arg);
151- kfree(pkc);
152+ if (cookie_list.cookie_available)
153+ copy_to_user(arg, &cookie_list,
154+ sizeof(struct pkc_cookie_list_s));
155 }
156 return ret;
157 default:
158@@ -1345,26 +1358,41 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
159 ret = 0;
160 }
161 return ret;
162- case COMPAT_CIOCASYMASYNFETCH:
163+ case COMPAT_CIOCASYMFETCHCOOKIE:
164 {
165 struct cryptodev_pkc *pkc;
166 unsigned long flags;
167+ int i = 0;
168+ struct compat_pkc_cookie_list_s cookie_list;
169
170 spin_lock_irqsave(&pcr->completion_lock, flags);
171- if (list_empty(&pcr->asym_completed_list)) {
172- spin_unlock_irqrestore(&pcr->completion_lock, flags);
173- return -ENOMEM;
174+ cookie_list.cookie_available = 0;
175+
176+ for (i = 0; i < MAX_COOKIES; i++) {
177+ if (!list_empty(&pcr->asym_completed_list)) {
178+ /* Run a loop in the list for upto elements
179+ and copy their response back */
180+ pkc =
181+ list_first_entry(&pcr->asym_completed_list,
182+ struct cryptodev_pkc, list);
183+ list_del(&pkc->list);
184+ ret = crypto_async_fetch_asym(pkc);
185+ if (!ret) {
186+ cookie_list.cookie_available++;
187+ cookie_list.cookie[i] =
188+ pkc->kop.kop.cookie;
189+ }
190+ kfree(pkc);
191+ } else {
192+ break;
193+ }
194 }
195- pkc = list_first_entry(&pcr->asym_completed_list,
196- struct cryptodev_pkc, list);
197- list_del(&pkc->list);
198 spin_unlock_irqrestore(&pcr->completion_lock, flags);
199- ret = crypto_async_fetch_asym(pkc);
200
201 /* Reflect the updated request to user-space */
202- if (!ret)
203- compat_kop_to_user(&pkc->kop, arg);
204- kfree(pkc);
205+ if (cookie_list.cookie_available)
206+ copy_to_user(arg, &cookie_list,
207+ sizeof(struct compat_pkc_cookie_list_s));
208 }
209 return ret;
210 default:
211--
2121.8.3.1
213
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch
new file mode 100644
index 0000000..e70a057
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch
@@ -0,0 +1,212 @@
1From 30fc86a09109f169815befc2cd8bbfcae79fe7e0 Mon Sep 17 00:00:00 2001
2From: Yashpal Dutta <yashpal.dutta@freescale.com>
3Date: Fri, 7 Mar 2014 07:53:53 +0545
4Subject: [PATCH 6/9] ECC_KEYGEN and DLC_KEYGEN supported in cryptodev module
5
6Upstream-status: Pending
7
8Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
9---
10 cryptlib.c | 2 ++
11 crypto/cryptodev.h | 5 +++-
12 ioctl.c | 29 +++++++++++++++++--
13 main.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
14 4 files changed, 118 insertions(+), 3 deletions(-)
15
16diff --git a/cryptlib.c b/cryptlib.c
17index 6900028..47cd568 100644
18--- a/cryptlib.c
19+++ b/cryptlib.c
20@@ -452,6 +452,8 @@ int cryptodev_pkc_offload(struct cryptodev_pkc *pkc)
21 case DSA_VERIFY:
22 case ECDSA_SIGN:
23 case ECDSA_VERIFY:
24+ case DLC_KEYGEN:
25+ case ECC_KEYGEN:
26 pkc->s = crypto_alloc_pkc("pkc(dsa)",
27 CRYPTO_ALG_TYPE_PKC_DSA, 0);
28 break;
29diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
30index 4436fbf..275a55c 100644
31--- a/crypto/cryptodev.h
32+++ b/crypto/cryptodev.h
33@@ -268,6 +268,8 @@ enum cryptodev_crk_op_t {
34 CRK_DSA_SIGN = 2,
35 CRK_DSA_VERIFY = 3,
36 CRK_DH_COMPUTE_KEY = 4,
37+ CRK_DSA_GENERATE_KEY = 5,
38+ CRK_DH_GENERATE_KEY = 6,
39 CRK_ALGORITHM_ALL
40 };
41
42@@ -280,7 +282,8 @@ enum cryptodev_crk_op_t {
43 #define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
44 #define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
45 #define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
46-
47+#define CRF_DSA_GENERATE_KEY (1 << CRK_DSA_GENERATE_KEY)
48+#define CRF_DH_GENERATE_KEY (1 << CRK_DH_GENERATE_KEY)
49
50 /* ioctl's. Compatible with old linux cryptodev.h
51 */
52diff --git a/ioctl.c b/ioctl.c
53index 2eb7f03..c813c8c 100644
54--- a/ioctl.c
55+++ b/ioctl.c
56@@ -726,6 +726,23 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
57 dh_req->z, dh_req->z_len);
58 }
59 break;
60+ case CRK_DSA_GENERATE_KEY:
61+ case CRK_DH_GENERATE_KEY:
62+ {
63+ struct keygen_req_s *key_req = &pkc_req->req_u.keygen;
64+
65+ if (pkc_req->type == ECC_KEYGEN) {
66+ copy_to_user(ckop->crk_param[4].crp_p, key_req->pub_key,
67+ key_req->pub_key_len);
68+ copy_to_user(ckop->crk_param[5].crp_p,
69+ key_req->priv_key, key_req->priv_key_len);
70+ } else {
71+ copy_to_user(ckop->crk_param[3].crp_p,
72+ key_req->pub_key, key_req->pub_key_len);
73+ copy_to_user(ckop->crk_param[4].crp_p,
74+ key_req->priv_key, key_req->priv_key_len);
75+ }
76+ }
77 default:
78 ret = -EINVAL;
79 }
80@@ -939,8 +956,9 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
81
82 switch (cmd) {
83 case CIOCASYMFEAT:
84- return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP |
85- CRF_DSA_SIGN | CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY, p);
86+ return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_DSA_SIGN |
87+ CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY |
88+ CRF_DSA_GENERATE_KEY, p);
89 case CRIOGET:
90 fd = clonefd(filp);
91 ret = put_user(fd, p);
92@@ -1084,7 +1102,14 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
93 if (cookie_list.cookie_available)
94 copy_to_user(arg, &cookie_list,
95 sizeof(struct pkc_cookie_list_s));
96+ else {
97+ struct pkc_cookie_list_s *user_ck_list = (void *)arg;
98+
99+ put_user(0, &(user_ck_list->cookie_available));
100+ }
101+ ret = cookie_list.cookie_available;
102 }
103+
104 return ret;
105 default:
106 return -EINVAL;
107diff --git a/main.c b/main.c
108index 0b7951e..c901bc7 100644
109--- a/main.c
110+++ b/main.c
111@@ -342,6 +342,85 @@ err:
112 return rc;
113 }
114
115+int crypto_kop_keygen(struct cryptodev_pkc *pkc)
116+{
117+ struct kernel_crypt_kop *kop = &pkc->kop;
118+ struct crypt_kop *cop = &kop->kop;
119+ struct pkc_request *pkc_req;
120+ struct keygen_req_s *key_req;
121+ int rc, buf_size;
122+ uint8_t *buf;
123+
124+ if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
125+ !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
126+ !cop->crk_param[4].crp_nbits)
127+ return -EINVAL;
128+
129+ pkc_req = &pkc->req;
130+ key_req = &pkc_req->req_u.keygen;
131+ key_req->q_len = (cop->crk_param[0].crp_nbits + 7)/8;
132+ key_req->r_len = (cop->crk_param[1].crp_nbits + 7)/8;
133+ key_req->g_len = (cop->crk_param[2].crp_nbits + 7)/8;
134+ if (cop->crk_iparams == 3) {
135+ key_req->pub_key_len = (cop->crk_param[3].crp_nbits + 7)/8;
136+ key_req->priv_key_len = (cop->crk_param[4].crp_nbits + 7)/8;
137+ buf_size = key_req->q_len + key_req->r_len + key_req->g_len +
138+ key_req->pub_key_len + key_req->priv_key_len;
139+ pkc_req->type = DLC_KEYGEN;
140+ } else {
141+ key_req->ab_len = (cop->crk_param[3].crp_nbits + 7)/8;
142+ key_req->pub_key_len = (cop->crk_param[4].crp_nbits + 7)/8;
143+ key_req->priv_key_len = (cop->crk_param[5].crp_nbits + 7)/8;
144+ buf_size = key_req->q_len + key_req->r_len + key_req->g_len +
145+ key_req->pub_key_len + key_req->priv_key_len +
146+ key_req->ab_len;
147+ pkc_req->type = ECC_KEYGEN;
148+ pkc_req->curve_type = cop->curve_type;
149+ }
150+
151+ buf = kzalloc(buf_size, GFP_DMA);
152+ if (!buf)
153+ return -ENOMEM;
154+
155+ key_req->q = buf;
156+ key_req->r = key_req->q + key_req->q_len;
157+ key_req->g = key_req->r + key_req->r_len;
158+ key_req->pub_key = key_req->g + key_req->g_len;
159+ key_req->priv_key = key_req->pub_key + key_req->pub_key_len;
160+ copy_from_user(key_req->q, cop->crk_param[0].crp_p, key_req->q_len);
161+ copy_from_user(key_req->r, cop->crk_param[1].crp_p, key_req->r_len);
162+ copy_from_user(key_req->g, cop->crk_param[2].crp_p, key_req->g_len);
163+ if (cop->crk_iparams == 3) {
164+ copy_from_user(key_req->pub_key, cop->crk_param[3].crp_p,
165+ key_req->pub_key_len);
166+ copy_from_user(key_req->priv_key, cop->crk_param[4].crp_p,
167+ key_req->priv_key_len);
168+ } else {
169+ key_req->ab = key_req->priv_key + key_req->priv_key_len;
170+ copy_from_user(key_req->ab, cop->crk_param[3].crp_p,
171+ key_req->ab_len);
172+ copy_from_user(key_req->pub_key, cop->crk_param[4].crp_p,
173+ key_req->pub_key_len);
174+ copy_from_user(key_req->priv_key, cop->crk_param[5].crp_p,
175+ key_req->priv_key_len);
176+ }
177+
178+ rc = cryptodev_pkc_offload(pkc);
179+ if (pkc->type == SYNCHRONOUS) {
180+ if (rc)
181+ goto err;
182+ } else {
183+ if (rc != -EINPROGRESS && !rc)
184+ goto err;
185+
186+ pkc->cookie = buf;
187+ return rc;
188+ }
189+err:
190+ kfree(buf);
191+ return rc;
192+}
193+
194 int crypto_kop_dh_key(struct cryptodev_pkc *pkc)
195 {
196 struct kernel_crypt_kop *kop = &pkc->kop;
197@@ -554,6 +633,12 @@ int crypto_run_asym(struct cryptodev_pkc *pkc)
198 goto err;
199 ret = crypto_kop_dh_key(pkc);
200 break;
201+ case CRK_DH_GENERATE_KEY:
202+ case CRK_DSA_GENERATE_KEY:
203+ if ((kop->kop.crk_iparams != 3 && kop->kop.crk_iparams != 4))
204+ goto err;
205+ ret = crypto_kop_keygen(pkc);
206+ break;
207 }
208 err:
209 return ret;
210--
2111.8.3.1
212
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch
new file mode 100644
index 0000000..93a2248
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch
@@ -0,0 +1,238 @@
1From d60b9dbf53d63092fd292c00bb03c250c26703cf Mon Sep 17 00:00:00 2001
2From: Yashpal Dutta <yashpal.dutta@freescale.com>
3Date: Fri, 7 Mar 2014 08:49:15 +0545
4Subject: [PATCH 7/9] RCU stall fixed in PKC asynchronous interface
5
6Upstream-status: Pending
7
8Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
9---
10 ioctl.c | 23 +++++++++++------------
11 main.c | 43 +++++++++++++++++++++++++++----------------
12 2 files changed, 38 insertions(+), 28 deletions(-)
13
14diff --git a/ioctl.c b/ioctl.c
15index c813c8c..7e4c671 100644
16--- a/ioctl.c
17+++ b/ioctl.c
18@@ -108,10 +108,9 @@ void cryptodev_complete_asym(struct crypto_async_request *req, int err)
19 complete(&res->completion);
20 } else {
21 struct crypt_priv *pcr = pkc->priv;
22- unsigned long flags;
23- spin_lock_irqsave(&pcr->completion_lock, flags);
24+ spin_lock_bh(&pcr->completion_lock);
25 list_add_tail(&pkc->list, &pcr->asym_completed_list);
26- spin_unlock_irqrestore(&pcr->completion_lock, flags);
27+ spin_unlock_bh(&pcr->completion_lock);
28 /* wake for POLLIN */
29 wake_up_interruptible(&pcr->user_waiter);
30 }
31@@ -958,7 +957,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
32 case CIOCASYMFEAT:
33 return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_DSA_SIGN |
34 CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY |
35- CRF_DSA_GENERATE_KEY, p);
36+ CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY, p);
37 case CRIOGET:
38 fd = clonefd(filp);
39 ret = put_user(fd, p);
40@@ -997,7 +996,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
41 case CIOCKEY:
42 {
43 struct cryptodev_pkc *pkc =
44- kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
45+ kmalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
46
47 if (!pkc)
48 return -ENOMEM;
49@@ -1053,7 +1052,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
50 case CIOCASYMASYNCRYPT:
51 {
52 struct cryptodev_pkc *pkc =
53- kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
54+ kmalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
55 ret = kop_from_user(&pkc->kop, arg);
56
57 if (unlikely(ret))
58@@ -1070,13 +1069,12 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
59 case CIOCASYMFETCHCOOKIE:
60 {
61 struct cryptodev_pkc *pkc;
62- unsigned long flags;
63 int i;
64 struct pkc_cookie_list_s cookie_list;
65
66- spin_lock_irqsave(&pcr->completion_lock, flags);
67 cookie_list.cookie_available = 0;
68 for (i = 0; i < MAX_COOKIES; i++) {
69+ spin_lock_bh(&pcr->completion_lock);
70 if (!list_empty(&pcr->asym_completed_list)) {
71 /* Run a loop in the list for upto elements
72 and copy their response back */
73@@ -1084,6 +1082,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
74 list_first_entry(&pcr->asym_completed_list,
75 struct cryptodev_pkc, list);
76 list_del(&pkc->list);
77+ spin_unlock_bh(&pcr->completion_lock);
78 ret = crypto_async_fetch_asym(pkc);
79 if (!ret) {
80 cookie_list.cookie_available++;
81@@ -1093,10 +1092,10 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
82 }
83 kfree(pkc);
84 } else {
85+ spin_unlock_bh(&pcr->completion_lock);
86 break;
87 }
88 }
89- spin_unlock_irqrestore(&pcr->completion_lock, flags);
90
91 /* Reflect the updated request to user-space */
92 if (cookie_list.cookie_available)
93@@ -1386,14 +1385,13 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
94 case COMPAT_CIOCASYMFETCHCOOKIE:
95 {
96 struct cryptodev_pkc *pkc;
97- unsigned long flags;
98 int i = 0;
99 struct compat_pkc_cookie_list_s cookie_list;
100
101- spin_lock_irqsave(&pcr->completion_lock, flags);
102 cookie_list.cookie_available = 0;
103
104 for (i = 0; i < MAX_COOKIES; i++) {
105+ spin_lock_bh(&pcr->completion_lock);
106 if (!list_empty(&pcr->asym_completed_list)) {
107 /* Run a loop in the list for upto elements
108 and copy their response back */
109@@ -1401,6 +1399,7 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
110 list_first_entry(&pcr->asym_completed_list,
111 struct cryptodev_pkc, list);
112 list_del(&pkc->list);
113+ spin_unlock_bh(&pcr->completion_lock);
114 ret = crypto_async_fetch_asym(pkc);
115 if (!ret) {
116 cookie_list.cookie_available++;
117@@ -1409,10 +1408,10 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
118 }
119 kfree(pkc);
120 } else {
121+ spin_unlock_bh(&pcr->completion_lock);
122 break;
123 }
124 }
125- spin_unlock_irqrestore(&pcr->completion_lock, flags);
126
127 /* Reflect the updated request to user-space */
128 if (cookie_list.cookie_available)
129diff --git a/main.c b/main.c
130index c901bc7..2747706 100644
131--- a/main.c
132+++ b/main.c
133@@ -215,7 +215,9 @@ int crypto_kop_dsasign(struct cryptodev_pkc *pkc)
134 pkc_req->type = DSA_SIGN;
135 }
136
137- buf = kzalloc(buf_size, GFP_DMA);
138+ buf = kmalloc(buf_size, GFP_DMA);
139+ if (!buf)
140+ return -ENOMEM;
141
142 dsa_req->q = buf;
143 dsa_req->r = dsa_req->q + dsa_req->q_len;
144@@ -298,7 +300,9 @@ int crypto_kop_dsaverify(struct cryptodev_pkc *pkc)
145 pkc_req->type = DSA_VERIFY;
146 }
147
148- buf = kzalloc(buf_size, GFP_DMA);
149+ buf = kmalloc(buf_size, GFP_DMA);
150+ if (!buf)
151+ return -ENOMEM;
152
153 dsa_req->q = buf;
154 dsa_req->r = dsa_req->q + dsa_req->q_len;
155@@ -378,7 +382,7 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
156 pkc_req->curve_type = cop->curve_type;
157 }
158
159- buf = kzalloc(buf_size, GFP_DMA);
160+ buf = kmalloc(buf_size, GFP_DMA);
161 if (!buf)
162 return -ENOMEM;
163
164@@ -390,25 +394,28 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
165 copy_from_user(key_req->q, cop->crk_param[0].crp_p, key_req->q_len);
166 copy_from_user(key_req->r, cop->crk_param[1].crp_p, key_req->r_len);
167 copy_from_user(key_req->g, cop->crk_param[2].crp_p, key_req->g_len);
168- if (cop->crk_iparams == 3) {
169- copy_from_user(key_req->pub_key, cop->crk_param[3].crp_p,
170- key_req->pub_key_len);
171- copy_from_user(key_req->priv_key, cop->crk_param[4].crp_p,
172- key_req->priv_key_len);
173- } else {
174+ if (cop->crk_iparams == 4) {
175 key_req->ab = key_req->priv_key + key_req->priv_key_len;
176 copy_from_user(key_req->ab, cop->crk_param[3].crp_p,
177 key_req->ab_len);
178- copy_from_user(key_req->pub_key, cop->crk_param[4].crp_p,
179- key_req->pub_key_len);
180- copy_from_user(key_req->priv_key, cop->crk_param[5].crp_p,
181- key_req->priv_key_len);
182 }
183
184 rc = cryptodev_pkc_offload(pkc);
185 if (pkc->type == SYNCHRONOUS) {
186 if (rc)
187 goto err;
188+
189+ if (cop->crk_iparams == 4) {
190+ copy_to_user(cop->crk_param[4].crp_p, key_req->pub_key,
191+ key_req->pub_key_len);
192+ copy_to_user(cop->crk_param[5].crp_p, key_req->priv_key,
193+ key_req->priv_key_len);
194+ } else {
195+ copy_to_user(cop->crk_param[3].crp_p, key_req->pub_key,
196+ key_req->pub_key_len);
197+ copy_to_user(cop->crk_param[4].crp_p,
198+ key_req->priv_key, key_req->priv_key_len);
199+ }
200 } else {
201 if (rc != -EINPROGRESS && !rc)
202 goto err;
203@@ -447,7 +454,9 @@ int crypto_kop_dh_key(struct cryptodev_pkc *pkc)
204 pkc_req->type = DH_COMPUTE_KEY;
205 }
206 buf_size += dh_req->z_len;
207- buf = kzalloc(buf_size, GFP_DMA);
208+ buf = kmalloc(buf_size, GFP_DMA);
209+ if (!buf)
210+ return -ENOMEM;
211 dh_req->q = buf;
212 dh_req->s = dh_req->q + dh_req->q_len;
213 dh_req->pub_key = dh_req->s + dh_req->s_len;
214@@ -508,9 +517,11 @@ int crypto_modexp_crt(struct cryptodev_pkc *pkc)
215 rsa_req->dq_len = (cop->crk_param[4].crp_nbits + 7)/8;
216 rsa_req->c_len = (cop->crk_param[5].crp_nbits + 7)/8;
217 rsa_req->f_len = (cop->crk_param[6].crp_nbits + 7)/8;
218- buf = kzalloc(rsa_req->p_len + rsa_req->q_len + rsa_req->f_len +
219+ buf = kmalloc(rsa_req->p_len + rsa_req->q_len + rsa_req->f_len +
220 rsa_req->dp_len + rsa_req->dp_len + rsa_req->c_len +
221 rsa_req->g_len, GFP_DMA);
222+ if (!buf)
223+ return -ENOMEM;
224 rsa_req->p = buf;
225 rsa_req->q = rsa_req->p + rsa_req->p_len;
226 rsa_req->g = rsa_req->q + rsa_req->q_len;
227@@ -563,7 +574,7 @@ int crypto_bn_modexp(struct cryptodev_pkc *pkc)
228 rsa_req->e_len = (cop->crk_param[1].crp_nbits + 7)/8;
229 rsa_req->n_len = (cop->crk_param[2].crp_nbits + 7)/8;
230 rsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8;
231- buf = kzalloc(rsa_req->f_len + rsa_req->e_len + rsa_req->n_len
232+ buf = kmalloc(rsa_req->f_len + rsa_req->e_len + rsa_req->n_len
233 + rsa_req->g_len, GFP_DMA);
234 if (!buf)
235 return -ENOMEM;
236--
2371.8.3.1
238
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0008-Add-RSA-Key-generation-offloading.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0008-Add-RSA-Key-generation-offloading.patch
new file mode 100644
index 0000000..affb2e7
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0008-Add-RSA-Key-generation-offloading.patch
@@ -0,0 +1,170 @@
1From af5e4289f60c38ab17adab14c82d6204d155f25f Mon Sep 17 00:00:00 2001
2From: Hou Zhiqiang <B48286@freescale.com>
3Date: Wed, 19 Mar 2014 14:02:46 +0800
4Subject: [PATCH 8/9] Add RSA Key generation offloading
5
6Upstream-status: Pending
7
8Signed-off-by: Hou Zhiqiang <B48286@freescale.com>
9Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
10---
11 cryptlib.c | 1 +
12 crypto/cryptodev.h | 2 ++
13 ioctl.c | 3 +-
14 main.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
15 4 files changed, 84 insertions(+), 2 deletions(-)
16
17diff --git a/cryptlib.c b/cryptlib.c
18index 47cd568..4dd1847 100644
19--- a/cryptlib.c
20+++ b/cryptlib.c
21@@ -441,6 +441,7 @@ int cryptodev_pkc_offload(struct cryptodev_pkc *pkc)
22 struct pkc_request *pkc_req = &pkc->req, *pkc_requested;
23
24 switch (pkc_req->type) {
25+ case RSA_KEYGEN:
26 case RSA_PUB:
27 case RSA_PRIV_FORM1:
28 case RSA_PRIV_FORM2:
29diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
30index 275a55c..d0cc542 100644
31--- a/crypto/cryptodev.h
32+++ b/crypto/cryptodev.h
33@@ -270,6 +270,7 @@ enum cryptodev_crk_op_t {
34 CRK_DH_COMPUTE_KEY = 4,
35 CRK_DSA_GENERATE_KEY = 5,
36 CRK_DH_GENERATE_KEY = 6,
37+ CRK_RSA_GENERATE_KEY = 7,
38 CRK_ALGORITHM_ALL
39 };
40
41@@ -279,6 +280,7 @@ enum cryptodev_crk_op_t {
42 */
43 #define CRF_MOD_EXP (1 << CRK_MOD_EXP)
44 #define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
45+#define CRF_RSA_GENERATE_KEY (1 << CRK_RSA_GENERATE_KEY)
46 #define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
47 #define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
48 #define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
49diff --git a/ioctl.c b/ioctl.c
50index 7e4c671..14888d6 100644
51--- a/ioctl.c
52+++ b/ioctl.c
53@@ -957,7 +957,8 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
54 case CIOCASYMFEAT:
55 return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_DSA_SIGN |
56 CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY |
57- CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY, p);
58+ CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY |
59+ CRF_RSA_GENERATE_KEY, p);
60 case CRIOGET:
61 fd = clonefd(filp);
62 ret = put_user(fd, p);
63diff --git a/main.c b/main.c
64index 2747706..14dcf40 100644
65--- a/main.c
66+++ b/main.c
67@@ -346,6 +346,82 @@ err:
68 return rc;
69 }
70
71+int crypto_kop_rsa_keygen(struct cryptodev_pkc *pkc)
72+{
73+ struct kernel_crypt_kop *kop = &pkc->kop;
74+ struct crypt_kop *cop = &kop->kop;
75+ struct pkc_request *pkc_req;
76+ struct rsa_keygen_req_s *key_req;
77+ int rc, buf_size;
78+ uint8_t *buf;
79+
80+ if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
81+ !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
82+ !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits ||
83+ !cop->crk_param[6].crp_nbits)
84+ return -EINVAL;
85+
86+ pkc_req = &pkc->req;
87+ pkc_req->type = RSA_KEYGEN;
88+ key_req = &pkc_req->req_u.rsa_keygen;
89+ key_req->n_len = (cop->crk_param[2].crp_nbits + 7)/8;
90+ key_req->p_len = (cop->crk_param[0].crp_nbits + 7) / 8;
91+ key_req->q_len = (cop->crk_param[1].crp_nbits + 7) / 8;
92+ key_req->n_len = (cop->crk_param[2].crp_nbits + 7) / 8;
93+ key_req->d_len = (cop->crk_param[3].crp_nbits + 7) / 8;
94+ key_req->dp_len = (cop->crk_param[4].crp_nbits + 7) / 8;
95+ key_req->dq_len = (cop->crk_param[5].crp_nbits + 7) / 8;
96+ key_req->c_len = (cop->crk_param[6].crp_nbits + 7) / 8;
97+
98+ buf_size = key_req->p_len + key_req->q_len + key_req->n_len +
99+ key_req->d_len + key_req->dp_len +
100+ key_req->dq_len + key_req->c_len;
101+
102+ buf = kmalloc(buf_size, GFP_DMA);
103+ if (!buf)
104+ return -ENOMEM;
105+ key_req->p = buf;
106+ key_req->q = key_req->p + key_req->p_len;
107+ key_req->n = key_req->q + key_req->q_len;
108+ key_req->d = key_req->n + key_req->n_len;
109+ key_req->dp = key_req->d + key_req->d_len;
110+ key_req->dq = key_req->dp + key_req->dp_len;
111+ key_req->c = key_req->dq + key_req->dq_len;
112+
113+ rc = cryptodev_pkc_offload(pkc);
114+
115+ if (pkc->type == SYNCHRONOUS) {
116+ if (rc)
117+ goto err;
118+
119+ copy_to_user(cop->crk_param[0].crp_p,
120+ key_req->p, key_req->p_len);
121+ copy_to_user(cop->crk_param[1].crp_p,
122+ key_req->q, key_req->q_len);
123+ copy_to_user(cop->crk_param[2].crp_p,
124+ key_req->n, key_req->n_len);
125+ copy_to_user(cop->crk_param[3].crp_p,
126+ key_req->d, key_req->d_len);
127+ copy_to_user(cop->crk_param[4].crp_p,
128+ key_req->dp, key_req->dp_len);
129+ copy_to_user(cop->crk_param[5].crp_p,
130+ key_req->dq, key_req->dq_len);
131+ copy_to_user(cop->crk_param[6].crp_p,
132+ key_req->c, key_req->c_len);
133+ } else {
134+ if (rc != -EINPROGRESS && !rc) {
135+ printk("%s: Failed\n", __func__);
136+ goto err;
137+ }
138+ pkc->cookie = buf;
139+ return rc;
140+ }
141+err:
142+ kfree(buf);
143+ return rc;
144+
145+}
146+
147 int crypto_kop_keygen(struct cryptodev_pkc *pkc)
148 {
149 struct kernel_crypt_kop *kop = &pkc->kop;
150@@ -385,7 +461,6 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
151 buf = kmalloc(buf_size, GFP_DMA);
152 if (!buf)
153 return -ENOMEM;
154-
155 key_req->q = buf;
156 key_req->r = key_req->q + key_req->q_len;
157 key_req->g = key_req->r + key_req->r_len;
158@@ -650,6 +725,9 @@ int crypto_run_asym(struct cryptodev_pkc *pkc)
159 goto err;
160 ret = crypto_kop_keygen(pkc);
161 break;
162+ case CRK_RSA_GENERATE_KEY:
163+ ret = crypto_kop_rsa_keygen(pkc);
164+ break;
165 }
166 err:
167 return ret;
168--
1691.8.3.1
170
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch
new file mode 100644
index 0000000..32757ca
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch
@@ -0,0 +1,160 @@
1From e791b55b03d295ee11476382a7bd93ab131e2e52 Mon Sep 17 00:00:00 2001
2From: Yashpal Dutta <yashpal.dutta@freescale.com>
3Date: Thu, 17 Apr 2014 07:08:47 +0545
4Subject: [PATCH 9/9] Fixed compilation error of openssl with fsl cryptodev
5
6Upstream-status: Pending
7
8Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
9Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
10---
11 authenc.c | 1 +
12 cryptlib.c | 9 ++++-----
13 crypto/cryptodev.h | 9 ++++++++-
14 cryptodev_int.h | 2 +-
15 ioctl.c | 8 ++++++--
16 main.c | 1 +
17 6 files changed, 21 insertions(+), 9 deletions(-)
18
19diff --git a/authenc.c b/authenc.c
20index ef0d3db..2aa4d38 100644
21--- a/authenc.c
22+++ b/authenc.c
23@@ -2,6 +2,7 @@
24 * Driver for /dev/crypto device (aka CryptoDev)
25 *
26 * Copyright (c) 2011, 2012 OpenSSL Software Foundation, Inc.
27+ * Copyright (c) 2014 Freescale Semiconductor, Inc.
28 *
29 * Author: Nikos Mavrogiannopoulos
30 *
31diff --git a/cryptlib.c b/cryptlib.c
32index 4dd1847..ec6693e 100644
33--- a/cryptlib.c
34+++ b/cryptlib.c
35@@ -4,8 +4,7 @@
36 * Copyright (c) 2010,2011 Nikos Mavrogiannopoulos <nmav@gnutls.org>
37 * Portions Copyright (c) 2010 Michael Weiser
38 * Portions Copyright (c) 2010 Phil Sutter
39- *
40- * Copyright 2012 Freescale Semiconductor, Inc.
41+ * Copyright 2012-2014 Freescale Semiconductor, Inc.
42 *
43 * This file is part of linux cryptodev.
44 *
45@@ -144,7 +143,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
46 if (alg->max_keysize > 0 &&
47 unlikely((keylen < alg->min_keysize) ||
48 (keylen > alg->max_keysize))) {
49- ddebug(1, "Wrong keylen '%zu' for algorithm '%s'. Use %u to %u.",
50+ ddebug(1, "Wrong keylen '%u' for algorithm '%s'. Use %u to %u.",
51 keylen, alg_name, alg->min_keysize, alg->max_keysize);
52 ret = -EINVAL;
53 goto error;
54@@ -171,7 +170,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
55 }
56
57 if (unlikely(ret)) {
58- ddebug(1, "Setting key failed for %s-%zu.", alg_name, keylen*8);
59+ ddebug(1, "Setting key failed for %s-%u.", alg_name, keylen*8);
60 ret = -EINVAL;
61 goto error;
62 }
63@@ -338,7 +337,7 @@ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
64 if (hmac_mode != 0) {
65 ret = crypto_ahash_setkey(hdata->async.s, mackey, mackeylen);
66 if (unlikely(ret)) {
67- ddebug(1, "Setting hmac key failed for %s-%zu.",
68+ ddebug(1, "Setting hmac key failed for %s-%u.",
69 alg_name, mackeylen*8);
70 ret = -EINVAL;
71 goto error;
72diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
73index d0cc542..e7edd97 100644
74--- a/crypto/cryptodev.h
75+++ b/crypto/cryptodev.h
76@@ -234,6 +234,13 @@ struct crypt_auth_op {
77 #define CRYPTO_ALG_FLAG_RNG_ENABLE 2
78 #define CRYPTO_ALG_FLAG_DSA_SHA 4
79
80+enum ec_curve_t {
81+ EC_DISCRETE_LOG,
82+ EC_PRIME,
83+ EC_BINARY,
84+ MAX_EC_TYPE
85+};
86+
87 struct crparam {
88 __u8 *crp_p;
89 __u32 crp_nbits;
90@@ -249,7 +256,7 @@ struct crypt_kop {
91 __u16 crk_oparams;
92 __u32 crk_pad1;
93 struct crparam crk_param[CRK_MAXPARAM];
94- enum curve_t curve_type; /* 0 == Discrete Log,
95+ enum ec_curve_t curve_type; /* 0 == Discrete Log,
96 1 = EC_PRIME, 2 = EC_BINARY */
97 void *cookie;
98 };
99diff --git a/cryptodev_int.h b/cryptodev_int.h
100index 5347cae..c83c885 100644
101--- a/cryptodev_int.h
102+++ b/cryptodev_int.h
103@@ -88,7 +88,7 @@ struct compat_crypt_kop {
104 uint16_t crk_oparams;
105 uint32_t crk_pad1;
106 struct compat_crparam crk_param[CRK_MAXPARAM];
107- enum curve_t curve_type; /* 0 == Discrete Log, 1 = EC_PRIME,
108+ enum ec_curve_t curve_type; /* 0 == Discrete Log, 1 = EC_PRIME,
109 2 = EC_BINARY */
110 compat_uptr_t cookie;
111 };
112diff --git a/ioctl.c b/ioctl.c
113index 14888d6..20ab4ca 100644
114--- a/ioctl.c
115+++ b/ioctl.c
116@@ -4,7 +4,7 @@
117 * Copyright (c) 2004 Michal Ludvig <mludvig@logix.net.nz>, SuSE Labs
118 * Copyright (c) 2009,2010,2011 Nikos Mavrogiannopoulos <nmav@gnutls.org>
119 * Copyright (c) 2010 Phil Sutter
120- * Copyright 2012 Freescale Semiconductor, Inc.
121+ * Copyright 2012-2014 Freescale Semiconductor, Inc.
122 *
123 * This file is part of linux cryptodev.
124 *
125@@ -501,6 +501,7 @@ cryptodev_open(struct inode *inode, struct file *filp)
126 INIT_LIST_HEAD(&pcr->done.list);
127 INIT_LIST_HEAD(&pcr->asym_completed_list);
128 spin_lock_init(&pcr->completion_lock);
129+
130 INIT_WORK(&pcr->cryptask, cryptask_routine);
131
132 init_waitqueue_head(&pcr->user_waiter);
133@@ -780,8 +781,11 @@ static int fill_kcop_from_cop(struct kernel_crypt_op *kcop, struct fcrypt *fcr)
134
135 if (cop->iv) {
136 rc = copy_from_user(kcop->iv, cop->iv, kcop->ivlen);
137- if (unlikely(rc))
138+ if (unlikely(rc)) {
139+ derr(1, "error copying IV (%d bytes), copy_from_user returned %d for address %p",
140+ kcop->ivlen, rc, cop->iv);
141 return -EFAULT;
142+ }
143 }
144
145 return 0;
146diff --git a/main.c b/main.c
147index 14dcf40..6365911 100644
148--- a/main.c
149+++ b/main.c
150@@ -3,6 +3,7 @@
151 *
152 * Copyright (c) 2004 Michal Ludvig <mludvig@logix.net.nz>, SuSE Labs
153 * Copyright (c) 2009-2013 Nikos Mavrogiannopoulos <nmav@gnutls.org>
154+ * Copyright (c) 2014 Freescale Semiconductor, Inc.
155 *
156 * This file is part of linux cryptodev.
157 *
158--
1592.2.0
160
diff --git a/recipes-kernel/cryptodev/cryptodev-linux_1.6.bbappend b/recipes-kernel/cryptodev/cryptodev-linux_1.6.bbappend
new file mode 100644
index 0000000..3cbbb3d
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-linux_1.6.bbappend
@@ -0,0 +1,2 @@
1require recipes-kernel/cryptodev/cryptodev-fsl.inc
2
diff --git a/recipes-kernel/cryptodev/cryptodev-module_1.6.bbappend b/recipes-kernel/cryptodev/cryptodev-module_1.6.bbappend
new file mode 100644
index 0000000..2bf012c
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-module_1.6.bbappend
@@ -0,0 +1,12 @@
1require recipes-kernel/cryptodev/cryptodev-fsl.inc
2
3inherit qoriq_build_64bit_kernel
4
5do_install_append_qoriq-ppc () {
6 rm -fr ${D}/usr
7}
8
9# Currently pkc-host does not support RSA_KEYGEN, remove this
10# if it is fixed.
11SRC_URI_append_qoriq-ppc = "${@base_contains('DISTRO_FEATURES', 'c29x_pkc', ' file://0001-don-t-advertise-RSA-keygen.patch', '', d)}"
12