Patchwork [meta-fsl-ppc,v2,5/5] cryptodev-linux/module: use fsl maintained source

login
register
mail settings
Submitter Ting Liu
Date July 10, 2014, 10:28 a.m.
Message ID <1404988115-22761-5-git-send-email-ting.liu@freescale.com>
Download mbox | patch
Permalink /patch/75305/
State Accepted
Headers show

Comments

Ting Liu - July 10, 2014, 10:28 a.m.
From: Zhenhua Luo <zhenhua.luo@freescale.com>

FSL SDK released its own cryptodev based on 1.6, but not all the codes
was upstreamed, add bbappend to use fsl maintained source. This change
only be applied for fsl machines

Signed-off-by: Zhenhua Luo <zhenhua.luo@freescale.com>
Signed-off-by: Ting Liu <b28495@freescale.com>
---
 recipes-kernel/cryptodev/cryptodev-fsl.inc         |   24 +
 ...-for-composite-TLS-SHA1-AES-algorithm-off.patch |   53 ++
 ...on-local-storage-for-cipher-and-hmac-keys.patch |   87 ++
 ...rt-for-aead-keys-for-composite-algorithms.patch |  170 ++++
 ...-scatterlist-size-for-in-place-operations.patch |   39 +
 ..._len-parameter-to-be-provided-by-the-user.patch |   70 ++
 .../0006-fix-build-error-on-some-targets.patch     |   64 ++
 ...dd-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch |  209 +++++
 .../0008-fix-cipher-algorithm-memleaks.patch       |   53 ++
 ...009-PKC-support-added-in-cryptodev-module.patch |  898 ++++++++++++++++++++
 .../0010-Compat-versions-of-PKC-IOCTLs.patch       |  200 +++++
 ...ynchronous-interface-changes-in-cryptodev.patch |  213 +++++
 ...and-DLC_KEYGEN-supported-in-cryptodev-mod.patch |  213 +++++
 ...stall-fixed-in-PKC-asynchronous-interface.patch |  238 ++++++
 ...allocation-for-keys-copied-from-userspace.patch |  131 +++
 .../0015-Add-RSA-Key-generation-offloading.patch   |  170 ++++
 ...lation-error-of-openssl-with-fsl-cryptode.patch |  116 +++
 .../cryptodev/cryptodev-linux_1.6.bbappend         |    2 +
 .../cryptodev/cryptodev-module_1.6.bbappend        |    8 +
 recipes-kernel/cryptodev/cryptodev_1.5.bb          |   51 --
 ...pile-and-install-rules-for-cryptodev-test.patch |   69 --
 .../cryptodev/files/makefile_fixup.patch           |   26 -
 22 files changed, 2958 insertions(+), 146 deletions(-)
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl.inc
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS-SHA1-AES-algorithm-off.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0002-use-function-local-storage-for-cipher-and-hmac-keys.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0003-Add-support-for-aead-keys-for-composite-algorithms.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0004-fix-scatterlist-size-for-in-place-operations.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0005-add-dst_len-parameter-to-be-provided-by-the-user.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0006-fix-build-error-on-some-targets.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0007-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0008-fix-cipher-algorithm-memleaks.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0009-PKC-support-added-in-cryptodev-module.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0010-Compat-versions-of-PKC-IOCTLs.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0011-Asynchronous-interface-changes-in-cryptodev.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0012-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0013-RCU-stall-fixed-in-PKC-asynchronous-interface.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0014-use-static-allocation-for-keys-copied-from-userspace.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0015-Add-RSA-Key-generation-offloading.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-fsl/0016-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch
 create mode 100644 recipes-kernel/cryptodev/cryptodev-linux_1.6.bbappend
 create mode 100644 recipes-kernel/cryptodev/cryptodev-module_1.6.bbappend
 delete mode 100644 recipes-kernel/cryptodev/cryptodev_1.5.bb
 delete mode 100644 recipes-kernel/cryptodev/files/Add-the-compile-and-install-rules-for-cryptodev-test.patch
 delete mode 100644 recipes-kernel/cryptodev/files/makefile_fixup.patch

Patch

diff --git a/recipes-kernel/cryptodev/cryptodev-fsl.inc b/recipes-kernel/cryptodev/cryptodev-fsl.inc
new file mode 100644
index 0000000..774ef10
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl.inc
@@ -0,0 +1,24 @@ 
+FILESEXTRAPATHS_prepend := "${THISDIR}/cryptodev-fsl"
+
+SRC_URI_fslmachine = "git://github.com/nmav/cryptodev-linux.git \
+    file://0001-add-support-for-composite-TLS-SHA1-AES-algorithm-off.patch \
+    file://0002-use-function-local-storage-for-cipher-and-hmac-keys.patch \
+    file://0003-Add-support-for-aead-keys-for-composite-algorithms.patch \
+    file://0004-fix-scatterlist-size-for-in-place-operations.patch \
+    file://0005-add-dst_len-parameter-to-be-provided-by-the-user.patch \
+    file://0006-fix-build-error-on-some-targets.patch \
+    file://0007-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch \
+    file://0008-fix-cipher-algorithm-memleaks.patch \
+    file://0009-PKC-support-added-in-cryptodev-module.patch \
+    file://0010-Compat-versions-of-PKC-IOCTLs.patch \
+    file://0011-Asynchronous-interface-changes-in-cryptodev.patch \
+    file://0012-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch \
+    file://0013-RCU-stall-fixed-in-PKC-asynchronous-interface.patch \
+    file://0014-use-static-allocation-for-keys-copied-from-userspace.patch \
+    file://0015-Add-RSA-Key-generation-offloading.patch \
+    file://0016-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch \
+"
+SRCREV_fslmachine = "e8609a408d40c83ae8fc11bbe9a7b3847612669b"
+
+S_fslmachine = "${WORKDIR}/git"
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS-SHA1-AES-algorithm-off.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS-SHA1-AES-algorithm-off.patch
new file mode 100644
index 0000000..094fb0b
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS-SHA1-AES-algorithm-off.patch
@@ -0,0 +1,53 @@ 
+From 434790a1bbafa371c0c6647238234573db98d017 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Thu, 29 Aug 2013 16:52:30 +0300
+Subject: [[Patch][fsl 01/16] add support for composite TLS(SHA1,AES)
+ algorithm offload
+
+Upstream-status: Pending
+
+This adds support for composite algorithm offload in a single crypto
+(cipher + hmac) operation.
+
+It requires either software or hardware TLS support in the Linux kernel
+and can be used with Freescale B*, P* and T* platforms that have support
+for hardware TLS acceleration.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com>
+---
+ crypto/cryptodev.h |    1 +
+ ioctl.c            |    5 +++++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index 7fb9c7d..c0e8cd4 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -50,6 +50,7 @@ enum cryptodev_crypto_op_t {
+ 	CRYPTO_SHA2_384,
+ 	CRYPTO_SHA2_512,
+ 	CRYPTO_SHA2_224_HMAC,
++	CRYPTO_TLS10_AES_CBC_HMAC_SHA1,
+ 	CRYPTO_ALGORITHM_ALL, /* Keep updated - see below */
+ };
+ 
+diff --git a/ioctl.c b/ioctl.c
+index d4e83f4..a0f1db1 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -146,6 +146,11 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 		stream = 1;
+ 		aead = 1;
+ 		break;
++	case CRYPTO_TLS10_AES_CBC_HMAC_SHA1:
++		alg_name = "tls10(hmac(sha1),cbc(aes))";
++		stream = 0;
++		aead = 1;
++		break;
+ 	case CRYPTO_NULL:
+ 		alg_name = "ecb(cipher_null)";
+ 		stream = 1;
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0002-use-function-local-storage-for-cipher-and-hmac-keys.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0002-use-function-local-storage-for-cipher-and-hmac-keys.patch
new file mode 100644
index 0000000..4702fd4
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0002-use-function-local-storage-for-cipher-and-hmac-keys.patch
@@ -0,0 +1,87 @@ 
+From cc65307405a21c3b709ca6f2a6f64ff0c67c0eed Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Wed, 18 Sep 2013 13:42:31 +0300
+Subject: [[Patch][fsl 02/16] use function-local storage for cipher and hmac
+ keys
+
+Upstream-status: Pending
+
+This refactorization is necessary for next patches that add support for
+aead composite ciphers where the aead key is the sum of cipher and hmac
+keys.
+
+Without this patch, the hmac and cipher keys can't be combined in the
+same ioctl.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com>
+---
+ ioctl.c |   14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index a0f1db1..c614373 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -109,6 +109,8 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 	const char *alg_name = NULL;
+ 	const char *hash_name = NULL;
+ 	int hmac_mode = 1, stream = 0, aead = 0;
++	uint8_t enckey[CRYPTO_CIPHER_MAX_KEY_LEN];
++	uint8_t mackey[CRYPTO_HMAC_MAX_KEY_LEN];
+ 
+ 	/* Does the request make sense? */
+ 	if (unlikely(!sop->cipher && !sop->mac)) {
+@@ -227,8 +229,6 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 
+ 	/* Set-up crypto transform. */
+ 	if (alg_name) {
+-		uint8_t keyp[CRYPTO_CIPHER_MAX_KEY_LEN];
+-
+ 		if (unlikely(sop->keylen > CRYPTO_CIPHER_MAX_KEY_LEN)) {
+ 			ddebug(1, "Setting key failed for %s-%zu.",
+ 				alg_name, (size_t)sop->keylen*8);
+@@ -236,12 +236,12 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 			goto error_cipher;
+ 		}
+ 
+-		if (unlikely(copy_from_user(keyp, sop->key, sop->keylen))) {
++		if (unlikely(copy_from_user(enckey, sop->key, sop->keylen))) {
+ 			ret = -EFAULT;
+ 			goto error_cipher;
+ 		}
+ 
+-		ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, keyp,
++		ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, enckey,
+ 						sop->keylen, stream, aead);
+ 		if (ret < 0) {
+ 			ddebug(1, "Failed to load cipher for %s", alg_name);
+@@ -251,8 +251,6 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 	}
+ 
+ 	if (hash_name && aead == 0) {
+-		uint8_t keyp[CRYPTO_HMAC_MAX_KEY_LEN];
+-
+ 		if (unlikely(sop->mackeylen > CRYPTO_HMAC_MAX_KEY_LEN)) {
+ 			ddebug(1, "Setting key failed for %s-%zu.",
+ 				hash_name, (size_t)sop->mackeylen*8);
+@@ -260,14 +258,14 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 			goto error_hash;
+ 		}
+ 
+-		if (sop->mackey && unlikely(copy_from_user(keyp, sop->mackey,
++		if (sop->mackey && unlikely(copy_from_user(mackey, sop->mackey,
+ 					    sop->mackeylen))) {
+ 			ret = -EFAULT;
+ 			goto error_hash;
+ 		}
+ 
+ 		ret = cryptodev_hash_init(&ses_new->hdata, hash_name, hmac_mode,
+-							keyp, sop->mackeylen);
++							mackey, sop->mackeylen);
+ 		if (ret != 0) {
+ 			ddebug(1, "Failed to load hash for %s", hash_name);
+ 			ret = -EINVAL;
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0003-Add-support-for-aead-keys-for-composite-algorithms.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0003-Add-support-for-aead-keys-for-composite-algorithms.patch
new file mode 100644
index 0000000..033552a
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0003-Add-support-for-aead-keys-for-composite-algorithms.patch
@@ -0,0 +1,170 @@ 
+From 8cabaedb69acc5b44c7a9cf058045908130a6af7 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Wed, 23 Oct 2013 16:57:22 +0300
+Subject: [[Patch][fsl 03/16] Add support for aead keys for composite
+ algorithms
+
+Upstream-status: Pending
+
+Composite aead algorithms (e.g. AES-CBC + HMAC-SHA1) need two keys to
+operate. The two keys are wrapped in a single buffer in the form
+used also by crypto/authenc.c
+Blockcipher and non-composite aead algorithms (e.g. AES-GCM) use a
+single key which is simply copied from user-space.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com>
+---
+ cryptlib.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ cryptlib.h |    3 +++
+ ioctl.c    |   24 ++++++++++++++----------
+ 3 files changed, 76 insertions(+), 10 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index a7fbff4..2986d09 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -34,6 +34,8 @@
+ #include <crypto/hash.h>
+ #include <crypto/cryptodev.h>
+ #include <crypto/aead.h>
++#include <linux/rtnetlink.h>
++#include <crypto/authenc.h>
+ #include "cryptodev_int.h"
+ 
+ 
+@@ -53,6 +55,63 @@ static void cryptodev_complete(struct crypto_async_request *req, int err)
+ 	complete(&res->completion);
+ }
+ 
++int cryptodev_get_cipher_keylen(unsigned int *keylen, struct session_op *sop,
++		int aead)
++{
++	unsigned int klen = sop->keylen;
++
++	if (unlikely(sop->keylen > CRYPTO_CIPHER_MAX_KEY_LEN))
++		return -EINVAL;
++
++	if (aead && sop->mackeylen) {
++		if (unlikely(sop->mackeylen > CRYPTO_HMAC_MAX_KEY_LEN))
++			return -EINVAL;
++		klen += sop->mackeylen;
++		klen += RTA_SPACE(sizeof(struct crypto_authenc_key_param));
++	}
++
++	*keylen = klen;
++	return 0;
++}
++
++int cryptodev_get_cipher_key(uint8_t *key, struct session_op *sop, int aead)
++{
++	/* Get algorithm key from user-space. For composite aead algorithms,
++	 * the key representation is in the format used by linux kernel in
++	 * crypto/authenc.c
++	 */
++	struct crypto_authenc_key_param *param;
++	struct rtattr *rta;
++	int ret = 0;
++
++	if (aead && sop->mackeylen) {
++		/* the key header type and header length */
++		rta = (void *)key;
++		rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM;
++		rta->rta_len = RTA_LENGTH(sizeof(*param));
++
++		/* the key parameter is the length of the encryption key */
++		param = RTA_DATA(rta);
++		param->enckeylen = cpu_to_be32(sop->keylen);
++
++		/* copy the hash key */
++		key += RTA_SPACE(sizeof(*param));
++		if (unlikely(copy_from_user(key, sop->mackey, sop->mackeylen))) {
++			ret = -EFAULT;
++			goto error;
++		}
++		/* get the pointer ready for the encryption key */
++		key += sop->mackeylen;
++	}
++	/* blockcipher algorithms have the key ready to use */
++	if (unlikely(copy_from_user(key, sop->key, sop->keylen)))
++		ret = -EFAULT;
++
++error:
++	return ret;
++}
++
++
+ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ 				uint8_t *keyp, size_t keylen, int stream, int aead)
+ {
+diff --git a/cryptlib.h b/cryptlib.h
+index 0744284..a0a8a63 100644
+--- a/cryptlib.h
++++ b/cryptlib.h
+@@ -25,6 +25,9 @@ struct cipher_data {
+ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ 			  uint8_t *key, size_t keylen, int stream, int aead);
+ void cryptodev_cipher_deinit(struct cipher_data *cdata);
++int cryptodev_get_cipher_key(uint8_t *key, struct session_op *sop, int aead);
++int cryptodev_get_cipher_keylen(unsigned int *keylen, struct session_op *sop,
++		int aead);
+ ssize_t cryptodev_cipher_decrypt(struct cipher_data *cdata,
+ 			const struct scatterlist *sg1,
+ 			struct scatterlist *sg2, size_t len);
+diff --git a/ioctl.c b/ioctl.c
+index c614373..3baf195 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -109,7 +109,8 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 	const char *alg_name = NULL;
+ 	const char *hash_name = NULL;
+ 	int hmac_mode = 1, stream = 0, aead = 0;
+-	uint8_t enckey[CRYPTO_CIPHER_MAX_KEY_LEN];
++	uint8_t *key = NULL;
++	unsigned int keylen;
+ 	uint8_t mackey[CRYPTO_HMAC_MAX_KEY_LEN];
+ 
+ 	/* Does the request make sense? */
+@@ -229,20 +230,22 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 
+ 	/* Set-up crypto transform. */
+ 	if (alg_name) {
+-		if (unlikely(sop->keylen > CRYPTO_CIPHER_MAX_KEY_LEN)) {
+-			ddebug(1, "Setting key failed for %s-%zu.",
+-				alg_name, (size_t)sop->keylen*8);
+-			ret = -EINVAL;
++		ret = cryptodev_get_cipher_keylen(&keylen, sop, aead);
++		if (unlikely(ret < 0))
+ 			goto error_cipher;
+-		}
+ 
+-		if (unlikely(copy_from_user(enckey, sop->key, sop->keylen))) {
+-			ret = -EFAULT;
++		key = kmalloc(keylen, GFP_KERNEL);
++		if (unlikely(!key)) {
++			ret = -ENOMEM;
+ 			goto error_cipher;
+ 		}
+ 
+-		ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, enckey,
+-						sop->keylen, stream, aead);
++		ret = cryptodev_get_cipher_key(key, sop, aead);
++		if (unlikely(ret < 0))
++			goto error_cipher;
++
++		ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, key, keylen,
++				stream, aead);
+ 		if (ret < 0) {
+ 			ddebug(1, "Failed to load cipher for %s", alg_name);
+ 			ret = -EINVAL;
+@@ -318,6 +321,7 @@ error_hash:
+ 	kfree(ses_new->sg);
+ 	kfree(ses_new->pages);
+ error_cipher:
++	kfree(key);
+ 	kfree(ses_new);
+ 
+ 	return ret;
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0004-fix-scatterlist-size-for-in-place-operations.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0004-fix-scatterlist-size-for-in-place-operations.patch
new file mode 100644
index 0000000..c808606
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0004-fix-scatterlist-size-for-in-place-operations.patch
@@ -0,0 +1,39 @@ 
+From 5a6cd042d3cee9e3bbf3b0125a89e64d75dffdc7 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Thu, 31 Oct 2013 13:13:51 +0200
+Subject: [[Patch][fsl 04/16] fix scatterlist size for in-place operations
+
+Upstream-status: Pending
+
+For in-place operations, the scatterlist must be big enough to allow for
+either the source or destination data:
+ - for block ciphers, the destination will be bigger than the source if
+   the source is not multiple of blocksize
+ - for aead ciphers, the additional data and padding guarantees the
+   destination to be bigger than the source.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com>
+---
+ zc.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/zc.c b/zc.c
+index 809a36d..8855083 100644
+--- a/zc.c
++++ b/zc.c
+@@ -162,8 +162,9 @@ int get_userbuf(struct csession *ses,
+ 	}
+ 
+ 	if (src == dst) {	/* inplace operation */
+-		rc = __get_userbuf(src, src_len, 1, ses->used_pages,
+-			               ses->pages, ses->sg, task, mm);
++		rc = __get_userbuf(src, max(src_len, dst_len), 1, ses->used_pages,
++				ses->pages, ses->sg, task, mm);
++
+ 		if (unlikely(rc)) {
+ 			derr(1, "failed to get user pages for data IO");
+ 			return rc;
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0005-add-dst_len-parameter-to-be-provided-by-the-user.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0005-add-dst_len-parameter-to-be-provided-by-the-user.patch
new file mode 100644
index 0000000..480d2a9
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0005-add-dst_len-parameter-to-be-provided-by-the-user.patch
@@ -0,0 +1,70 @@ 
+From e673e6ec09770b624d524bcd82f911e4fe2e2075 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Thu, 31 Oct 2013 13:27:28 +0200
+Subject: [[Patch][fsl 05/16] add dst_len parameter to be provided by the user
+
+Upstream-status: Pending
+
+This allows the user to set the result length and relieves cryptodev
+from making assumptions about it.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com>
+---
+ authenc.c          |   13 +++----------
+ crypto/cryptodev.h |    1 +
+ 2 files changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/authenc.c b/authenc.c
+index a183820..5235973 100644
+--- a/authenc.c
++++ b/authenc.c
+@@ -199,7 +199,7 @@ static int fill_kcaop_from_caop(struct kernel_crypt_auth_op *kcaop, struct fcryp
+ 	kcaop->ivlen = caop->iv ? ses_ptr->cdata.ivsize : 0;
+ 
+ 	if (caop->flags & COP_FLAG_AEAD_TLS_TYPE)
+-		kcaop->dst_len = caop->len + ses_ptr->cdata.blocksize /* pad */ + caop->tag_len;
++		kcaop->dst_len = caop->dst_len;
+ 	else
+ 		kcaop->dst_len = caop->len;
+ 
+@@ -645,8 +645,6 @@ __crypto_auth_run_zc(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcao
+ 			ret = tls_auth_n_crypt(ses_ptr, kcaop, auth_sg, caop->auth_len,
+ 				   dst_sg, caop->len);
+ 		} else {
+-			int dst_len;
+-
+ 			if (unlikely(ses_ptr->cdata.init == 0 ||
+ 			             (ses_ptr->cdata.stream == 0 &&
+ 				      ses_ptr->cdata.aead == 0))) {
+@@ -655,13 +653,8 @@ __crypto_auth_run_zc(struct csession *ses_ptr, struct kernel_crypt_auth_op *kcao
+ 				goto free_auth_buf;
+ 			}
+ 
+-			if (caop->op == COP_ENCRYPT)
+-				dst_len = caop->len + cryptodev_cipher_get_tag_size(&ses_ptr->cdata);
+-			else
+-				dst_len = caop->len;
+-
+-			ret = get_userbuf(ses_ptr, caop->src, caop->len, caop->dst, dst_len,
+-					  kcaop->task, kcaop->mm, &src_sg, &dst_sg);
++			ret = get_userbuf(ses_ptr, caop->src, caop->len, caop->dst,
++					caop->dst_len, kcaop->task, kcaop->mm, &src_sg, &dst_sg);
+ 			if (unlikely(ret)) {
+ 				derr(1, "get_userbuf(): Error getting user pages.");
+ 				goto free_auth_buf;
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index c0e8cd4..3ea3d35 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -137,6 +137,7 @@ struct crypt_auth_op {
+ 	__u16	op;		/* COP_ENCRYPT or COP_DECRYPT */
+ 	__u16	flags;		/* see COP_FLAG_AEAD_* */
+ 	__u32	len;		/* length of source data */
++	__u32   dst_len;	/* length of result data */
+ 	__u32	auth_len;	/* length of auth data */
+ 	__u8	__user *auth_src;	/* authenticated-only data */
+ 
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0006-fix-build-error-on-some-targets.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0006-fix-build-error-on-some-targets.patch
new file mode 100644
index 0000000..510dee0
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0006-fix-build-error-on-some-targets.patch
@@ -0,0 +1,64 @@ 
+From 69e00f8c1633dfe6da20ccd0cf363a481c99fc97 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Wed, 20 Nov 2013 11:29:50 +0200
+Subject: [[Patch][fsl 06/16] fix build error on some targets
+
+Upstream-status: Pending
+
+This updates incomplete patch f681e2e5fd1088bfe0aafd1ae2560c1dc9d04778
+and allows building main.o
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com>
+---
+ cryptlib.c |    4 ++--
+ cryptlib.h |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index 2986d09..3576f39 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -113,7 +113,7 @@ error:
+ 
+ 
+ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+-				uint8_t *keyp, size_t keylen, int stream, int aead)
++				uint8_t *keyp, unsigned int keylen, int stream, int aead)
+ {
+ 	int ret;
+ 
+@@ -313,7 +313,7 @@ ssize_t cryptodev_cipher_decrypt(struct cipher_data *cdata,
+ /* Hash functions */
+ 
+ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
+-			int hmac_mode, void *mackey, size_t mackeylen)
++			int hmac_mode, void *mackey, unsigned int mackeylen)
+ {
+ 	int ret;
+ 
+diff --git a/cryptlib.h b/cryptlib.h
+index a0a8a63..4cb66ad 100644
+--- a/cryptlib.h
++++ b/cryptlib.h
+@@ -23,7 +23,7 @@ struct cipher_data {
+ };
+ 
+ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+-			  uint8_t *key, size_t keylen, int stream, int aead);
++			  uint8_t *key, unsigned int keylen, int stream, int aead);
+ void cryptodev_cipher_deinit(struct cipher_data *cdata);
+ int cryptodev_get_cipher_key(uint8_t *key, struct session_op *sop, int aead);
+ int cryptodev_get_cipher_keylen(unsigned int *keylen, struct session_op *sop,
+@@ -87,7 +87,7 @@ ssize_t cryptodev_hash_update(struct hash_data *hdata,
+ int cryptodev_hash_reset(struct hash_data *hdata);
+ void cryptodev_hash_deinit(struct hash_data *hdata);
+ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
+-			int hmac_mode, void *mackey, size_t mackeylen);
++			int hmac_mode, void *mackey, unsigned int mackeylen);
+ 
+ 
+ #endif
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0007-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0007-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch
new file mode 100644
index 0000000..b796f16
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0007-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch
@@ -0,0 +1,209 @@ 
+From 75e26bf18997488518228cb851585bf8e4c3120f Mon Sep 17 00:00:00 2001
+From: Horia Geanta <horia.geanta@freescale.com>
+Date: Wed, 4 Dec 2013 15:43:41 +0200
+Subject: [[Patch][fsl 07/16] add support for COMPAT_CIOCAUTHCRYPT ioctl()
+
+Upstream-status: Pending
+
+Needed for 64b kernel with 32b user space.
+
+Signed-off-by: Horia Geanta <horia.geanta@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ authenc.c       |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ cryptodev_int.h |   41 ++++++++++++++++++++++++++++
+ ioctl.c         |   16 +++++++++++
+ 3 files changed, 137 insertions(+)
+
+diff --git a/authenc.c b/authenc.c
+index 5235973..259a225 100644
+--- a/authenc.c
++++ b/authenc.c
+@@ -241,6 +241,86 @@ static int fill_caop_from_kcaop(struct kernel_crypt_auth_op *kcaop, struct fcryp
+ 	return 0;
+ }
+ 
++/* compatibility code for 32bit userlands */
++#ifdef CONFIG_COMPAT
++
++static inline void
++compat_to_crypt_auth_op(struct compat_crypt_auth_op *compat,
++			struct crypt_auth_op *caop)
++{
++	caop->ses = compat->ses;
++	caop->op = compat->op;
++	caop->flags = compat->flags;
++	caop->len = compat->len;
++	caop->dst_len = compat->dst_len;
++	caop->auth_len = compat->auth_len;
++	caop->tag_len = compat->tag_len;
++	caop->iv_len = compat->iv_len;
++
++	caop->auth_src = compat_ptr(compat->auth_src);
++	caop->src = compat_ptr(compat->src);
++	caop->dst = compat_ptr(compat->dst);
++	caop->tag = compat_ptr(compat->tag);
++	caop->iv = compat_ptr(compat->iv);
++}
++
++static inline void
++crypt_auth_op_to_compat(struct crypt_auth_op *caop,
++			struct compat_crypt_auth_op *compat)
++{
++	compat->ses = caop->ses;
++	compat->op = caop->op;
++	compat->flags = caop->flags;
++	compat->len = caop->len;
++	compat->dst_len = caop->dst_len;
++	compat->auth_len = caop->auth_len;
++	compat->tag_len = caop->tag_len;
++	compat->iv_len = caop->iv_len;
++
++	compat->auth_src = ptr_to_compat(caop->auth_src);
++	compat->src = ptr_to_compat(caop->src);
++	compat->dst = ptr_to_compat(caop->dst);
++	compat->tag = ptr_to_compat(caop->tag);
++	compat->iv = ptr_to_compat(caop->iv);
++}
++
++int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
++				struct fcrypt *fcr, void __user *arg)
++{
++	struct compat_crypt_auth_op compat_caop;
++
++	if (unlikely(copy_from_user(&compat_caop, arg, sizeof(compat_caop)))) {
++		dprintk(1, KERN_ERR, "Error in copying from userspace\n");
++		return -EFAULT;
++	}
++
++	compat_to_crypt_auth_op(&compat_caop, &kcaop->caop);
++
++	return fill_kcaop_from_caop(kcaop, fcr);
++}
++
++int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
++				struct fcrypt *fcr, void __user *arg)
++{
++	int ret;
++	struct compat_crypt_auth_op compat_caop;
++
++	ret = fill_caop_from_kcaop(kcaop, fcr);
++	if (unlikely(ret)) {
++		dprintk(1, KERN_ERR, "fill_caop_from_kcaop\n");
++		return ret;
++	}
++
++	crypt_auth_op_to_compat(&kcaop->caop, &compat_caop);
++
++	if (unlikely(copy_to_user(arg, &compat_caop, sizeof(compat_caop)))) {
++		dprintk(1, KERN_ERR, "Error in copying to userspace\n");
++		return -EFAULT;
++	}
++	return 0;
++}
++
++#endif /* CONFIG_COMPAT */
+ 
+ int kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
+ 			struct fcrypt *fcr, void __user *arg)
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index d7660fa..8d206c9 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -73,11 +73,43 @@ struct compat_crypt_op {
+ 	compat_uptr_t	iv;/* initialization vector for encryption operations */
+ };
+ 
++ /* input of CIOCAUTHCRYPT */
++struct compat_crypt_auth_op {
++	uint32_t	ses;		/* session identifier */
++	uint16_t	op;		/* COP_ENCRYPT or COP_DECRYPT */
++	uint16_t	flags;		/* see COP_FLAG_AEAD_* */
++	uint32_t	len;		/* length of source data */
++	uint32_t	dst_len;	/* length of result data */
++	uint32_t	auth_len;	/* length of auth data */
++	compat_uptr_t	auth_src;	/* authenticated-only data */
++
++	/* The current implementation is more efficient if data are
++	 * encrypted in-place (src==dst). */
++	compat_uptr_t	src;		/* data to be encrypted and
++	authenticated */
++	compat_uptr_t	dst;		/* pointer to output data. Must have
++					 * space for tag. For TLS this should be
++					 * at least len + tag_size + block_size
++					 * for padding */
++
++	compat_uptr_t	tag;		/* where the tag will be copied to. TLS
++					 * mode doesn't use that as tag is
++					 * copied to dst.
++					 * SRTP mode copies tag there. */
++	uint32_t	tag_len;	/* the length of the tag. Use zero for
++					 * digest size or max tag. */
++
++	/* initialization vector for encryption operations */
++	compat_uptr_t	iv;
++	uint32_t	iv_len;
++};
++
+ /* compat ioctls, defined for the above structs */
+ #define COMPAT_CIOCGSESSION    _IOWR('c', 102, struct compat_session_op)
+ #define COMPAT_CIOCCRYPT       _IOWR('c', 104, struct compat_crypt_op)
+ #define COMPAT_CIOCASYNCCRYPT  _IOW('c', 107, struct compat_crypt_op)
+ #define COMPAT_CIOCASYNCFETCH  _IOR('c', 108, struct compat_crypt_op)
++#define COMPAT_CIOCAUTHCRYPT   _IOWR('c', 109, struct compat_crypt_auth_op)
+ 
+ #endif /* CONFIG_COMPAT */
+ 
+@@ -108,6 +140,15 @@ struct kernel_crypt_auth_op {
+ 
+ /* auth */
+ 
++#ifdef CONFIG_COMPAT
++int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
++				struct fcrypt *fcr, void __user *arg);
++
++int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
++				struct fcrypt *fcr, void __user *arg);
++#endif /* CONFIG_COMPAT */
++
++
+ int kcaop_from_user(struct kernel_crypt_auth_op *kcop,
+ 			struct fcrypt *fcr, void __user *arg);
+ int kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
+diff --git a/ioctl.c b/ioctl.c
+index 3baf195..18874d3 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -991,6 +991,7 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ 	struct session_op sop;
+ 	struct compat_session_op compat_sop;
+ 	struct kernel_crypt_op kcop;
++	struct kernel_crypt_auth_op kcaop;
+ 	int ret;
+ 
+ 	if (unlikely(!pcr))
+@@ -1033,6 +1034,21 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ 			return ret;
+ 
+ 		return compat_kcop_to_user(&kcop, fcr, arg);
++
++	case COMPAT_CIOCAUTHCRYPT:
++		if (unlikely(ret = compat_kcaop_from_user(&kcaop, fcr, arg))) {
++			dprintk(1, KERN_WARNING, "Error copying from user\n");
++			return ret;
++		}
++
++		ret = crypto_auth_run(fcr, &kcaop);
++		if (unlikely(ret)) {
++			dprintk(1, KERN_WARNING, "Error in crypto_auth_run\n");
++			return ret;
++		}
++
++		return compat_kcaop_to_user(&kcaop, fcr, arg);
++
+ #ifdef ENABLE_ASYNC
+ 	case COMPAT_CIOCASYNCCRYPT:
+ 		if (unlikely(ret = compat_kcop_from_user(&kcop, fcr, arg)))
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0008-fix-cipher-algorithm-memleaks.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0008-fix-cipher-algorithm-memleaks.patch
new file mode 100644
index 0000000..995fbed
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0008-fix-cipher-algorithm-memleaks.patch
@@ -0,0 +1,53 @@ 
+From 9675e358fe73b33029a470aa5cf47527848f4054 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Tue, 26 Nov 2013 16:36:37 +0200
+Subject: [[Patch][fsl 08/16] fix cipher algorithm memleaks
+
+Upstream-status: Pending
+
+Patch 67e743aef130d107c1b41e0aace7677f9ff53bd1 allocates memory for
+cipher algorithm key without freeing it when session terminates. This
+patch addresses the deallocation issue.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com>
+---
+ cryptodev_int.h |    1 +
+ ioctl.c         |    2 ++
+ 2 files changed, 3 insertions(+)
+
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index 8d206c9..8891837 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -166,6 +166,7 @@ struct csession {
+ 	struct hash_data hdata;
+ 	uint32_t sid;
+ 	uint32_t alignmask;
++	uint8_t *key;
+ 
+ 	unsigned int array_size;
+ 	unsigned int used_pages; /* the number of pages that are used */
+diff --git a/ioctl.c b/ioctl.c
+index 18874d3..63467e0 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -235,6 +235,7 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 			goto error_cipher;
+ 
+ 		key = kmalloc(keylen, GFP_KERNEL);
++		ses_new->key = key;
+ 		if (unlikely(!key)) {
+ 			ret = -ENOMEM;
+ 			goto error_cipher;
+@@ -342,6 +343,7 @@ crypto_destroy_session(struct csession *ses_ptr)
+ 	ddebug(2, "freeing space for %d user pages", ses_ptr->array_size);
+ 	kfree(ses_ptr->pages);
+ 	kfree(ses_ptr->sg);
++	kfree(ses_ptr->key);
+ 	mutex_unlock(&ses_ptr->sem);
+ 	mutex_destroy(&ses_ptr->sem);
+ 	kfree(ses_ptr);
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0009-PKC-support-added-in-cryptodev-module.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0009-PKC-support-added-in-cryptodev-module.patch
new file mode 100644
index 0000000..b403731
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0009-PKC-support-added-in-cryptodev-module.patch
@@ -0,0 +1,898 @@ 
+From 55be37e9e308990b2eeeef7f974dfbfbb1120266 Mon Sep 17 00:00:00 2001
+From: Yashpal Dutta <yashpal.dutta@freescale.com>
+Date: Fri, 7 Mar 2014 06:16:09 +0545
+Subject: [[Patch][fsl 09/16] PKC support added in cryptodev module
+
+Upstream-status: Pending
+
+Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
+---
+ cryptlib.c         |   66 ++++++++-
+ cryptlib.h         |   28 ++++
+ crypto/cryptodev.h |   15 ++-
+ cryptodev_int.h    |   20 ++-
+ ioctl.c            |  196 +++++++++++++++++++++++++--
+ main.c             |  378 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 685 insertions(+), 18 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index 3576f39..fa0b63f 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -5,6 +5,8 @@
+  * Portions Copyright (c) 2010 Michael Weiser
+  * Portions Copyright (c) 2010 Phil Sutter
+  *
++ * Copyright 2012 Freescale Semiconductor, Inc.
++ *
+  * This file is part of linux cryptodev.
+  *
+  * This program is free software; you can redistribute it and/or
+@@ -39,11 +41,6 @@
+ #include "cryptodev_int.h"
+ 
+ 
+-struct cryptodev_result {
+-	struct completion completion;
+-	int err;
+-};
+-
+ static void cryptodev_complete(struct crypto_async_request *req, int err)
+ {
+ 	struct cryptodev_result *res = req->data;
+@@ -244,7 +241,6 @@ static inline int waitfor(struct cryptodev_result *cr, ssize_t ret)
+ 	case 0:
+ 		break;
+ 	case -EINPROGRESS:
+-	case -EBUSY:
+ 		wait_for_completion(&cr->completion);
+ 		/* At this point we known for sure the request has finished,
+ 		 * because wait_for_completion above was not interruptible.
+@@ -424,3 +420,61 @@ int cryptodev_hash_final(struct hash_data *hdata, void *output)
+ 	return waitfor(hdata->async.result, ret);
+ }
+ 
++int cryptodev_pkc_offload(struct cryptodev_pkc  *pkc)
++{
++	int ret = 0;
++	struct pkc_request *pkc_req = &pkc->req, *pkc_requested;
++
++	switch (pkc_req->type) {
++	case RSA_PUB:
++	case RSA_PRIV_FORM1:
++	case RSA_PRIV_FORM2:
++	case RSA_PRIV_FORM3:
++		pkc->s = crypto_alloc_pkc("pkc(rsa)",
++			 CRYPTO_ALG_TYPE_PKC_RSA, 0);
++		break;
++	case DSA_SIGN:
++	case DSA_VERIFY:
++	case ECDSA_SIGN:
++	case ECDSA_VERIFY:
++		pkc->s = crypto_alloc_pkc("pkc(dsa)",
++			 CRYPTO_ALG_TYPE_PKC_DSA, 0);
++		break;
++	case DH_COMPUTE_KEY:
++	case ECDH_COMPUTE_KEY:
++		pkc->s = crypto_alloc_pkc("pkc(dh)",
++			 CRYPTO_ALG_TYPE_PKC_DH, 0);
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	if (IS_ERR_OR_NULL(pkc->s))
++		return -EINVAL;
++
++	init_completion(&pkc->result.completion);
++	pkc_requested = pkc_request_alloc(pkc->s, GFP_KERNEL);
++
++	if (unlikely(IS_ERR_OR_NULL(pkc_requested))) {
++		ret = -ENOMEM;
++		goto error;
++	}
++	pkc_requested->type = pkc_req->type;
++	pkc_requested->curve_type = pkc_req->curve_type;
++	memcpy(&pkc_requested->req_u, &pkc_req->req_u, sizeof(pkc_req->req_u));
++	pkc_request_set_callback(pkc_requested, CRYPTO_TFM_REQ_MAY_BACKLOG,
++				 cryptodev_complete_asym, pkc);
++	ret = crypto_pkc_op(pkc_requested);
++	if (ret != -EINPROGRESS && ret != 0)
++		goto error2;
++
++	if (pkc->type == SYNCHRONOUS)
++		ret = waitfor(&pkc->result, ret);
++
++	return ret;
++error2:
++	kfree(pkc_requested);
++error:
++	crypto_free_pkc(pkc->s);
++	return ret;
++}
+diff --git a/cryptlib.h b/cryptlib.h
+index 4cb66ad..e77edc5 100644
+--- a/cryptlib.h
++++ b/cryptlib.h
+@@ -1,3 +1,6 @@
++/*
++ * Copyright 2012 Freescale Semiconductor, Inc.
++ */
+ #ifndef CRYPTLIB_H
+ # define CRYPTLIB_H
+ 
+@@ -89,5 +92,30 @@ void cryptodev_hash_deinit(struct hash_data *hdata);
+ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
+ 			int hmac_mode, void *mackey, unsigned int mackeylen);
+ 
++/* Operation Type */
++enum offload_type {
++	SYNCHRONOUS,
++	ASYNCHRONOUS
++};
++
++struct cryptodev_result {
++	struct completion completion;
++	int err;
++};
++
++struct cryptodev_pkc {
++	struct list_head list; /* To maintain the Jobs in completed
++				 cryptodev lists */
++	struct kernel_crypt_kop kop;
++	struct crypto_pkc *s;    /* Transform pointer from CryptoAPI */
++	struct cryptodev_result result;	/* Result to be updated by
++					 completion handler */
++	struct pkc_request req; /* PKC request structure allocated
++				 from CryptoAPI */
++	enum offload_type type; /* Synchronous Vs Asynchronous request */
++	void *cookie; /*Additional opaque cookie to be used in future */
++	struct crypt_priv *priv;
++};
+ 
++int cryptodev_pkc_offload(struct cryptodev_pkc  *);
+ #endif
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index 3ea3d35..575ce63 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -1,6 +1,10 @@
+-/* This is a source compatible implementation with the original API of
++/*
++ * Copyright 2012 Freescale Semiconductor, Inc.
++ *
++ * This is a source compatible implementation with the original API of
+  * cryptodev by Angelos D. Keromytis, found at openbsd cryptodev.h.
+- * Placed under public domain */
++ * Placed under public domain
++ */
+ 
+ #ifndef L_CRYPTODEV_H
+ #define L_CRYPTODEV_H
+@@ -246,6 +250,9 @@ struct crypt_kop {
+ 	__u16	crk_oparams;
+ 	__u32	crk_pad1;
+ 	struct crparam	crk_param[CRK_MAXPARAM];
++	enum curve_t curve_type; /* 0 == Discrete Log,
++				1 = EC_PRIME, 2 = EC_BINARY */
++	void *cookie;
+ };
+ 
+ enum cryptodev_crk_op_t {
+@@ -290,5 +297,7 @@ enum cryptodev_crk_op_t {
+  */
+ #define CIOCASYNCCRYPT    _IOW('c', 110, struct crypt_op)
+ #define CIOCASYNCFETCH    _IOR('c', 111, struct crypt_op)
+-
++/* additional ioctls for asynchronous  operation for asymmetric ciphers*/
++#define CIOCASYMASYNCRYPT    _IOW('c', 112, struct crypt_kop)
++#define CIOCASYMASYNFETCH    _IOR('c', 113, struct crypt_kop)
+ #endif /* L_CRYPTODEV_H */
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index 8891837..b08c253 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -1,4 +1,6 @@
+-/* cipher stuff */
++/* cipher stuff
++ * Copyright 2012 Freescale Semiconductor, Inc.
++ */
+ #ifndef CRYPTODEV_INT_H
+ # define CRYPTODEV_INT_H
+ 
+@@ -113,6 +115,14 @@ struct compat_crypt_auth_op {
+ 
+ #endif /* CONFIG_COMPAT */
+ 
++/* kernel-internal extension to struct crypt_kop */
++struct kernel_crypt_kop {
++	struct crypt_kop kop;
++
++	struct task_struct *task;
++	struct mm_struct *mm;
++};
++
+ /* kernel-internal extension to struct crypt_op */
+ struct kernel_crypt_op {
+ 	struct crypt_op cop;
+@@ -158,6 +168,14 @@ int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop);
+ 
+ #include <cryptlib.h>
+ 
++/* Cryptodev Key operation handler */
++int crypto_bn_modexp(struct cryptodev_pkc *);
++int crypto_modexp_crt(struct cryptodev_pkc *);
++int crypto_kop_dsasign(struct cryptodev_pkc *);
++int crypto_kop_dsaverify(struct cryptodev_pkc *);
++int crypto_run_asym(struct cryptodev_pkc *);
++void cryptodev_complete_asym(struct crypto_async_request *, int);
++
+ /* other internal structs */
+ struct csession {
+ 	struct list_head entry;
+diff --git a/ioctl.c b/ioctl.c
+index 63467e0..44070e1 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -4,6 +4,7 @@
+  * Copyright (c) 2004 Michal Ludvig <mludvig@logix.net.nz>, SuSE Labs
+  * Copyright (c) 2009,2010,2011 Nikos Mavrogiannopoulos <nmav@gnutls.org>
+  * Copyright (c) 2010 Phil Sutter
++ * Copyright 2012 Freescale Semiconductor, Inc.
+  *
+  * This file is part of linux cryptodev.
+  *
+@@ -87,8 +88,37 @@ struct crypt_priv {
+ 	int itemcount;
+ 	struct work_struct cryptask;
+ 	wait_queue_head_t user_waiter;
++	/* List of pending cryptodev_pkc asym requests */
++	struct list_head asym_completed_list;
++	/* For addition/removal of entry in pending list of asymmetric request*/
++	spinlock_t completion_lock;
+ };
+ 
++/* Asymmetric request Completion handler */
++void cryptodev_complete_asym(struct crypto_async_request *req, int err)
++{
++	struct cryptodev_pkc *pkc = req->data;
++	struct cryptodev_result *res = &pkc->result;
++
++	crypto_free_pkc(pkc->s);
++	res->err = err;
++	if (pkc->type == SYNCHRONOUS) {
++		if (err == -EINPROGRESS)
++			return;
++		complete(&res->completion);
++	} else {
++		struct crypt_priv *pcr = pkc->priv;
++		unsigned long flags;
++		spin_lock_irqsave(&pcr->completion_lock, flags);
++		list_add_tail(&pkc->list, &pcr->asym_completed_list);
++		spin_unlock_irqrestore(&pcr->completion_lock, flags);
++		/* wake for POLLIN */
++		wake_up_interruptible(&pcr->user_waiter);
++	}
++
++	kfree(req);
++}
++
+ #define FILL_SG(sg, ptr, len)					\
+ 	do {							\
+ 		(sg)->page = virt_to_page(ptr);			\
+@@ -467,7 +497,8 @@ cryptodev_open(struct inode *inode, struct file *filp)
+ 	INIT_LIST_HEAD(&pcr->free.list);
+ 	INIT_LIST_HEAD(&pcr->todo.list);
+ 	INIT_LIST_HEAD(&pcr->done.list);
+-
++	INIT_LIST_HEAD(&pcr->asym_completed_list);
++	spin_lock_init(&pcr->completion_lock);
+ 	INIT_WORK(&pcr->cryptask, cryptask_routine);
+ 
+ 	init_waitqueue_head(&pcr->user_waiter);
+@@ -634,6 +665,79 @@ static int crypto_async_fetch(struct crypt_priv *pcr,
+ }
+ #endif
+ 
++/* get the first asym cipher completed job from the "done" queue
++ *
++ * returns:
++ * -EBUSY if no completed jobs are ready (yet)
++ * the return value otherwise */
++static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
++{
++	int ret = 0;
++	struct kernel_crypt_kop *kop = &pkc->kop;
++	struct crypt_kop *ckop = &kop->kop;
++	struct pkc_request *pkc_req = &pkc->req;
++
++	switch (ckop->crk_op) {
++	case CRK_MOD_EXP:
++	{
++		struct rsa_pub_req_s *rsa_req = &pkc_req->req_u.rsa_pub_req;
++		copy_to_user(ckop->crk_param[3].crp_p, rsa_req->g,
++			     rsa_req->g_len);
++	}
++	break;
++	case CRK_MOD_EXP_CRT:
++	{
++		struct rsa_priv_frm3_req_s *rsa_req =
++			 &pkc_req->req_u.rsa_priv_f3;
++		copy_to_user(ckop->crk_param[6].crp_p,
++			     rsa_req->f, rsa_req->f_len);
++	}
++	break;
++	case CRK_DSA_SIGN:
++	{
++		struct dsa_sign_req_s *dsa_req = &pkc_req->req_u.dsa_sign;
++
++		if (pkc_req->type == ECDSA_SIGN) {
++			copy_to_user(ckop->crk_param[6].crp_p,
++				     dsa_req->c, dsa_req->d_len);
++			copy_to_user(ckop->crk_param[7].crp_p,
++				     dsa_req->d, dsa_req->d_len);
++		} else {
++			copy_to_user(ckop->crk_param[5].crp_p,
++				     dsa_req->c, dsa_req->d_len);
++			copy_to_user(ckop->crk_param[6].crp_p,
++				     dsa_req->d, dsa_req->d_len);
++		}
++	}
++	break;
++	case CRK_DSA_VERIFY:
++		break;
++	case CRK_DH_COMPUTE_KEY:
++	{
++		struct dh_key_req_s *dh_req = &pkc_req->req_u.dh_req;
++		if (pkc_req->type == ECDH_COMPUTE_KEY)
++			copy_to_user(ckop->crk_param[4].crp_p,
++				     dh_req->z, dh_req->z_len);
++		else
++			copy_to_user(ckop->crk_param[3].crp_p,
++				     dh_req->z, dh_req->z_len);
++	}
++	break;
++	default:
++		ret = -EINVAL;
++	}
++	kfree(pkc->cookie);
++	return ret;
++}
++
++/* this function has to be called from process context */
++static int fill_kop_from_cop(struct kernel_crypt_kop *kop)
++{
++	kop->task = current;
++	kop->mm = current->mm;
++	return 0;
++}
++
+ /* this function has to be called from process context */
+ static int fill_kcop_from_cop(struct kernel_crypt_op *kcop, struct fcrypt *fcr)
+ {
+@@ -657,11 +761,8 @@ static int fill_kcop_from_cop(struct kernel_crypt_op *kcop, struct fcrypt *fcr)
+ 
+ 	if (cop->iv) {
+ 		rc = copy_from_user(kcop->iv, cop->iv, kcop->ivlen);
+-		if (unlikely(rc)) {
+-			derr(1, "error copying IV (%d bytes), copy_from_user returned %d for address %p",
+-					kcop->ivlen, rc, cop->iv);
++		if (unlikely(rc))
+ 			return -EFAULT;
+-		}
+ 	}
+ 
+ 	return 0;
+@@ -687,6 +788,25 @@ static int fill_cop_from_kcop(struct kernel_crypt_op *kcop, struct fcrypt *fcr)
+ 	return 0;
+ }
+ 
++static int kop_from_user(struct kernel_crypt_kop *kop,
++			void __user *arg)
++{
++	if (unlikely(copy_from_user(&kop->kop, arg, sizeof(kop->kop))))
++		return -EFAULT;
++
++	return fill_kop_from_cop(kop);
++}
++
++static int kop_to_user(struct kernel_crypt_kop *kop,
++			void __user *arg)
++{
++	if (unlikely(copy_to_user(arg, &kop->kop, sizeof(kop->kop)))) {
++		dprintk(1, KERN_ERR, "Cannot copy to userspace\n");
++		return -EFAULT;
++	}
++	return 0;
++}
++
+ static int kcop_from_user(struct kernel_crypt_op *kcop,
+ 			struct fcrypt *fcr, void __user *arg)
+ {
+@@ -816,7 +936,8 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 
+ 	switch (cmd) {
+ 	case CIOCASYMFEAT:
+-		return put_user(0, p);
++		return put_user(CRF_MOD_EXP_CRT |  CRF_MOD_EXP |
++			CRF_DSA_SIGN | CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY, p);
+ 	case CRIOGET:
+ 		fd = clonefd(filp);
+ 		ret = put_user(fd, p);
+@@ -852,6 +973,24 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 		if (unlikely(ret))
+ 			return ret;
+ 		return copy_to_user(arg, &siop, sizeof(siop));
++	case CIOCKEY:
++	{
++		struct cryptodev_pkc *pkc =
++			kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
++
++		if (!pkc)
++			return -ENOMEM;
++
++		ret = kop_from_user(&pkc->kop, arg);
++		if (unlikely(ret)) {
++			kfree(pkc);
++			return ret;
++		}
++		pkc->type = SYNCHRONOUS;
++		ret = crypto_run_asym(pkc);
++		kfree(pkc);
++	}
++	return ret;
+ 	case CIOCCRYPT:
+ 		if (unlikely(ret = kcop_from_user(&kcop, fcr, arg))) {
+ 			dwarning(1, "Error copying from user");
+@@ -890,6 +1029,45 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 
+ 		return kcop_to_user(&kcop, fcr, arg);
+ #endif
++	case CIOCASYMASYNCRYPT:
++	{
++		struct cryptodev_pkc *pkc =
++			kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
++		ret = kop_from_user(&pkc->kop, arg);
++
++		if (unlikely(ret))
++			return -EINVAL;
++
++		/* Store associated FD priv data with asymmetric request */
++		pkc->priv = pcr;
++		pkc->type = ASYNCHRONOUS;
++		ret = crypto_run_asym(pkc);
++		if (ret == -EINPROGRESS)
++			ret = 0;
++	}
++	return ret;
++	case CIOCASYMASYNFETCH:
++	{
++		struct cryptodev_pkc *pkc;
++		unsigned long flags;
++
++		spin_lock_irqsave(&pcr->completion_lock, flags);
++		if (list_empty(&pcr->asym_completed_list)) {
++			spin_unlock_irqrestore(&pcr->completion_lock, flags);
++			return -ENOMEM;
++		}
++		pkc = list_first_entry(&pcr->asym_completed_list,
++			struct cryptodev_pkc, list);
++		list_del(&pkc->list);
++		spin_unlock_irqrestore(&pcr->completion_lock, flags);
++		ret = crypto_async_fetch_asym(pkc);
++
++		/* Reflect the updated request to user-space */
++		if (!ret)
++			kop_to_user(&pkc->kop, arg);
++		kfree(pkc);
++	}
++	return ret;
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -1078,9 +1256,11 @@ static unsigned int cryptodev_poll(struct file *file, poll_table *wait)
+ 
+ 	poll_wait(file, &pcr->user_waiter, wait);
+ 
+-	if (!list_empty_careful(&pcr->done.list))
++	if (!list_empty_careful(&pcr->done.list) ||
++	    !list_empty_careful(&pcr->asym_completed_list))
+ 		ret |= POLLIN | POLLRDNORM;
+-	if (!list_empty_careful(&pcr->free.list) || pcr->itemcount < MAX_COP_RINGSIZE)
++	if (!list_empty_careful(&pcr->free.list) ||
++	    pcr->itemcount < MAX_COP_RINGSIZE)
+ 		ret |= POLLOUT | POLLWRNORM;
+ 
+ 	return ret;
+diff --git a/main.c b/main.c
+index 57e5c38..0b7951e 100644
+--- a/main.c
++++ b/main.c
+@@ -181,6 +181,384 @@ __crypto_run_zc(struct csession *ses_ptr, struct kernel_crypt_op *kcop)
+ 	return ret;
+ }
+ 
++int crypto_kop_dsasign(struct cryptodev_pkc *pkc)
++{
++	struct kernel_crypt_kop *kop = &pkc->kop;
++	struct crypt_kop *cop = &kop->kop;
++	struct pkc_request *pkc_req = &pkc->req;
++	struct dsa_sign_req_s *dsa_req = &pkc_req->req_u.dsa_sign;
++	int rc, buf_size;
++	uint8_t *buf;
++
++	if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
++	    !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
++	    !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits ||
++	    !cop->crk_param[6].crp_nbits || (cop->crk_iparams == 6 &&
++	    !cop->crk_param[7].crp_nbits))
++		return -EINVAL;
++
++	dsa_req->m_len = (cop->crk_param[0].crp_nbits + 7)/8;
++	dsa_req->q_len = (cop->crk_param[1].crp_nbits + 7)/8;
++	dsa_req->r_len = (cop->crk_param[2].crp_nbits + 7)/8;
++	dsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8;
++	dsa_req->priv_key_len = (cop->crk_param[4].crp_nbits + 7)/8;
++	dsa_req->d_len = (cop->crk_param[6].crp_nbits + 7)/8;
++	buf_size = dsa_req->m_len + dsa_req->q_len + dsa_req->r_len +
++		   dsa_req->g_len + dsa_req->priv_key_len + dsa_req->d_len +
++		   dsa_req->d_len;
++	if (cop->crk_iparams == 6) {
++		dsa_req->ab_len = (cop->crk_param[5].crp_nbits + 7)/8;
++		buf_size += dsa_req->ab_len;
++		pkc_req->type = ECDSA_SIGN;
++		pkc_req->curve_type = cop->curve_type;
++	} else {
++		pkc_req->type = DSA_SIGN;
++	}
++
++	buf = kzalloc(buf_size, GFP_DMA);
++
++	dsa_req->q = buf;
++	dsa_req->r = dsa_req->q + dsa_req->q_len;
++	dsa_req->g = dsa_req->r + dsa_req->r_len;
++	dsa_req->priv_key = dsa_req->g + dsa_req->g_len;
++	dsa_req->m = dsa_req->priv_key + dsa_req->priv_key_len;
++	dsa_req->c = dsa_req->m + dsa_req->m_len;
++	dsa_req->d = dsa_req->c + dsa_req->d_len;
++	copy_from_user(dsa_req->m, cop->crk_param[0].crp_p, dsa_req->m_len);
++	copy_from_user(dsa_req->q, cop->crk_param[1].crp_p, dsa_req->q_len);
++	copy_from_user(dsa_req->r, cop->crk_param[2].crp_p, dsa_req->r_len);
++	copy_from_user(dsa_req->g, cop->crk_param[3].crp_p, dsa_req->g_len);
++	copy_from_user(dsa_req->priv_key, cop->crk_param[4].crp_p,
++		       dsa_req->priv_key_len);
++	if (cop->crk_iparams == 6) {
++		dsa_req->ab = dsa_req->d + dsa_req->d_len;
++		copy_from_user(dsa_req->ab, cop->crk_param[5].crp_p,
++			       dsa_req->ab_len);
++	}
++	rc = cryptodev_pkc_offload(pkc);
++	if (pkc->type == SYNCHRONOUS) {
++		if (rc)
++			goto err;
++		if (cop->crk_iparams == 6) {
++			copy_to_user(cop->crk_param[6].crp_p, dsa_req->c,
++				     dsa_req->d_len);
++			copy_to_user(cop->crk_param[7].crp_p, dsa_req->d,
++				     dsa_req->d_len);
++		} else {
++			copy_to_user(cop->crk_param[5].crp_p, dsa_req->c,
++				     dsa_req->d_len);
++			copy_to_user(cop->crk_param[6].crp_p, dsa_req->d,
++				     dsa_req->d_len);
++		}
++	} else {
++		if (rc != -EINPROGRESS && rc != 0)
++			goto err;
++
++		pkc->cookie = buf;
++		return rc;
++	}
++err:
++	kfree(buf);
++	return rc;
++}
++
++int crypto_kop_dsaverify(struct cryptodev_pkc *pkc)
++{
++	struct kernel_crypt_kop *kop = &pkc->kop;
++	struct crypt_kop *cop = &kop->kop;
++	struct pkc_request *pkc_req;
++	struct dsa_verify_req_s *dsa_req;
++	int rc, buf_size;
++	uint8_t *buf;
++
++	if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
++	    !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
++	    !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits ||
++	    !cop->crk_param[6].crp_nbits  || (cop->crk_iparams == 8 &&
++	    !cop->crk_param[7].crp_nbits))
++		return -EINVAL;
++
++	pkc_req = &pkc->req;
++	dsa_req = &pkc_req->req_u.dsa_verify;
++	dsa_req->m_len = (cop->crk_param[0].crp_nbits + 7)/8;
++	dsa_req->q_len = (cop->crk_param[1].crp_nbits + 7)/8;
++	dsa_req->r_len = (cop->crk_param[2].crp_nbits + 7)/8;
++	dsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8;
++	dsa_req->pub_key_len = (cop->crk_param[4].crp_nbits + 7)/8;
++	dsa_req->d_len = (cop->crk_param[6].crp_nbits + 7)/8;
++	buf_size = dsa_req->m_len + dsa_req->q_len + dsa_req->r_len +
++		dsa_req->g_len + dsa_req->pub_key_len + dsa_req->d_len +
++		dsa_req->d_len;
++	if (cop->crk_iparams == 8) {
++		dsa_req->ab_len = (cop->crk_param[5].crp_nbits + 7)/8;
++		buf_size += dsa_req->ab_len;
++		pkc_req->type = ECDSA_VERIFY;
++		pkc_req->curve_type = cop->curve_type;
++	} else {
++		pkc_req->type = DSA_VERIFY;
++	}
++
++	buf = kzalloc(buf_size, GFP_DMA);
++
++	dsa_req->q = buf;
++	dsa_req->r = dsa_req->q + dsa_req->q_len;
++	dsa_req->g = dsa_req->r + dsa_req->r_len;
++	dsa_req->pub_key = dsa_req->g + dsa_req->g_len;
++	dsa_req->m = dsa_req->pub_key + dsa_req->pub_key_len;
++	dsa_req->c = dsa_req->m + dsa_req->m_len;
++	dsa_req->d = dsa_req->c + dsa_req->d_len;
++	copy_from_user(dsa_req->m, cop->crk_param[0].crp_p, dsa_req->m_len);
++	copy_from_user(dsa_req->q, cop->crk_param[1].crp_p, dsa_req->q_len);
++	copy_from_user(dsa_req->r, cop->crk_param[2].crp_p, dsa_req->r_len);
++	copy_from_user(dsa_req->g, cop->crk_param[3].crp_p, dsa_req->g_len);
++	copy_from_user(dsa_req->pub_key, cop->crk_param[4].crp_p,
++		       dsa_req->pub_key_len);
++	if (cop->crk_iparams == 8) {
++		dsa_req->ab = dsa_req->d + dsa_req->d_len;
++		copy_from_user(dsa_req->ab, cop->crk_param[5].crp_p,
++			       dsa_req->ab_len);
++		copy_from_user(dsa_req->c, cop->crk_param[6].crp_p,
++			       dsa_req->d_len);
++		copy_from_user(dsa_req->d, cop->crk_param[7].crp_p,
++			       dsa_req->d_len);
++	} else {
++		copy_from_user(dsa_req->c, cop->crk_param[5].crp_p,
++			       dsa_req->d_len);
++		copy_from_user(dsa_req->d, cop->crk_param[6].crp_p,
++			       dsa_req->d_len);
++	}
++	rc = cryptodev_pkc_offload(pkc);
++	if (pkc->type == SYNCHRONOUS) {
++		if (rc)
++			goto err;
++	} else {
++		if (rc != -EINPROGRESS && !rc)
++			goto err;
++		pkc->cookie = buf;
++		return rc;
++	}
++err:
++	kfree(buf);
++	return rc;
++}
++
++int crypto_kop_dh_key(struct cryptodev_pkc *pkc)
++{
++	struct kernel_crypt_kop *kop = &pkc->kop;
++	struct crypt_kop *cop = &kop->kop;
++	struct pkc_request *pkc_req;
++	struct dh_key_req_s *dh_req;
++	int buf_size;
++	uint8_t *buf;
++	int rc = -EINVAL;
++
++	pkc_req = &pkc->req;
++	dh_req = &pkc_req->req_u.dh_req;
++	dh_req->s_len = (cop->crk_param[0].crp_nbits + 7)/8;
++	dh_req->pub_key_len = (cop->crk_param[1].crp_nbits + 7)/8;
++	dh_req->q_len = (cop->crk_param[2].crp_nbits + 7)/8;
++	buf_size = dh_req->q_len + dh_req->pub_key_len + dh_req->s_len;
++	if (cop->crk_iparams == 4) {
++		pkc_req->type = ECDH_COMPUTE_KEY;
++		dh_req->ab_len = (cop->crk_param[3].crp_nbits + 7)/8;
++		dh_req->z_len = (cop->crk_param[4].crp_nbits + 7)/8;
++		buf_size += dh_req->ab_len;
++	} else {
++		dh_req->z_len = (cop->crk_param[3].crp_nbits + 7)/8;
++		pkc_req->type = DH_COMPUTE_KEY;
++	}
++	buf_size += dh_req->z_len;
++	buf = kzalloc(buf_size, GFP_DMA);
++	dh_req->q = buf;
++	dh_req->s = dh_req->q + dh_req->q_len;
++	dh_req->pub_key = dh_req->s + dh_req->s_len;
++	dh_req->z = dh_req->pub_key + dh_req->pub_key_len;
++	if (cop->crk_iparams == 4) {
++		dh_req->ab = dh_req->z + dh_req->z_len;
++		pkc_req->curve_type = cop->curve_type;
++		copy_from_user(dh_req->ab, cop->crk_param[3].crp_p,
++			       dh_req->ab_len);
++	}
++	copy_from_user(dh_req->s, cop->crk_param[0].crp_p, dh_req->s_len);
++	copy_from_user(dh_req->pub_key, cop->crk_param[1].crp_p,
++		       dh_req->pub_key_len);
++	copy_from_user(dh_req->q, cop->crk_param[2].crp_p, dh_req->q_len);
++	rc = cryptodev_pkc_offload(pkc);
++	if (pkc->type == SYNCHRONOUS) {
++		if (rc)
++			goto err;
++		if (cop->crk_iparams == 4)
++			copy_to_user(cop->crk_param[4].crp_p, dh_req->z,
++				     dh_req->z_len);
++		else
++			copy_to_user(cop->crk_param[3].crp_p, dh_req->z,
++				     dh_req->z_len);
++	} else {
++		if (rc != -EINPROGRESS && rc != 0)
++			goto err;
++
++		pkc->cookie = buf;
++		return rc;
++	}
++err:
++	kfree(buf);
++	return rc;
++}
++
++int crypto_modexp_crt(struct cryptodev_pkc *pkc)
++{
++	struct kernel_crypt_kop *kop = &pkc->kop;
++	struct crypt_kop *cop = &kop->kop;
++	struct pkc_request *pkc_req;
++	struct rsa_priv_frm3_req_s *rsa_req;
++	int rc;
++	uint8_t *buf;
++
++	if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
++	    !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
++	    !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits)
++		return -EINVAL;
++
++	pkc_req = &pkc->req;
++	pkc_req->type = RSA_PRIV_FORM3;
++	rsa_req = &pkc_req->req_u.rsa_priv_f3;
++	rsa_req->p_len = (cop->crk_param[0].crp_nbits + 7)/8;
++	rsa_req->q_len = (cop->crk_param[1].crp_nbits + 7)/8;
++	rsa_req->g_len = (cop->crk_param[2].crp_nbits + 7)/8;
++	rsa_req->dp_len = (cop->crk_param[3].crp_nbits + 7)/8;
++	rsa_req->dq_len = (cop->crk_param[4].crp_nbits + 7)/8;
++	rsa_req->c_len = (cop->crk_param[5].crp_nbits + 7)/8;
++	rsa_req->f_len = (cop->crk_param[6].crp_nbits + 7)/8;
++	buf = kzalloc(rsa_req->p_len + rsa_req->q_len + rsa_req->f_len +
++		      rsa_req->dp_len + rsa_req->dp_len + rsa_req->c_len +
++		      rsa_req->g_len, GFP_DMA);
++	rsa_req->p = buf;
++	rsa_req->q = rsa_req->p + rsa_req->p_len;
++	rsa_req->g = rsa_req->q + rsa_req->q_len;
++	rsa_req->dp = rsa_req->g + rsa_req->g_len;
++	rsa_req->dq = rsa_req->dp + rsa_req->dp_len;
++	rsa_req->c = rsa_req->dq + rsa_req->dq_len;
++	rsa_req->f = rsa_req->c + rsa_req->c_len;
++	copy_from_user(rsa_req->p, cop->crk_param[0].crp_p, rsa_req->p_len);
++	copy_from_user(rsa_req->q, cop->crk_param[1].crp_p, rsa_req->q_len);
++	copy_from_user(rsa_req->g, cop->crk_param[2].crp_p, rsa_req->g_len);
++	copy_from_user(rsa_req->dp, cop->crk_param[3].crp_p, rsa_req->dp_len);
++	copy_from_user(rsa_req->dq, cop->crk_param[4].crp_p, rsa_req->dq_len);
++	copy_from_user(rsa_req->c, cop->crk_param[5].crp_p, rsa_req->c_len);
++	rc = cryptodev_pkc_offload(pkc);
++
++	if (pkc->type == SYNCHRONOUS) {
++		if (rc)
++			goto err;
++		copy_to_user(cop->crk_param[6].crp_p, rsa_req->f,
++			     rsa_req->f_len);
++	} else {
++		if (rc != -EINPROGRESS && rc != 0)
++			goto err;
++
++		pkc->cookie = buf;
++		return rc;
++	}
++err:
++	kfree(buf);
++	return rc;
++}
++
++int crypto_bn_modexp(struct cryptodev_pkc *pkc)
++{
++	struct pkc_request *pkc_req;
++	struct rsa_pub_req_s *rsa_req;
++	int rc;
++	struct kernel_crypt_kop *kop = &pkc->kop;
++	struct crypt_kop *cop = &kop->kop;
++	uint8_t *buf;
++
++	if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
++	    !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits)
++		return -EINVAL;
++
++	pkc_req = &pkc->req;
++	pkc_req->type = RSA_PUB;
++	rsa_req = &pkc_req->req_u.rsa_pub_req;
++	rsa_req->f_len = (cop->crk_param[0].crp_nbits + 7)/8;
++	rsa_req->e_len = (cop->crk_param[1].crp_nbits + 7)/8;
++	rsa_req->n_len = (cop->crk_param[2].crp_nbits + 7)/8;
++	rsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8;
++	buf = kzalloc(rsa_req->f_len + rsa_req->e_len + rsa_req->n_len
++			+ rsa_req->g_len, GFP_DMA);
++	if (!buf)
++		return -ENOMEM;
++
++	rsa_req->e = buf;
++	rsa_req->f = rsa_req->e + rsa_req->e_len;
++	rsa_req->g = rsa_req->f + rsa_req->f_len;
++	rsa_req->n = rsa_req->g + rsa_req->g_len;
++	copy_from_user(rsa_req->f, cop->crk_param[0].crp_p, rsa_req->f_len);
++	copy_from_user(rsa_req->e, cop->crk_param[1].crp_p, rsa_req->e_len);
++	copy_from_user(rsa_req->n, cop->crk_param[2].crp_p, rsa_req->n_len);
++	rc = cryptodev_pkc_offload(pkc);
++	if (pkc->type == SYNCHRONOUS) {
++		if (rc)
++			goto err;
++
++		copy_to_user(cop->crk_param[3].crp_p, rsa_req->g,
++			     rsa_req->g_len);
++	} else {
++		if (rc != -EINPROGRESS && rc != 0)
++			goto err;
++
++		/* This one will be freed later in fetch handler */
++		pkc->cookie = buf;
++		return rc;
++	}
++err:
++	kfree(buf);
++	return rc;
++}
++
++int crypto_run_asym(struct cryptodev_pkc *pkc)
++{
++	int ret = -EINVAL;
++	struct kernel_crypt_kop *kop = &pkc->kop;
++
++	switch (kop->kop.crk_op) {
++	case CRK_MOD_EXP:
++		if (kop->kop.crk_iparams != 3 && kop->kop.crk_oparams != 1)
++			goto err;
++
++		ret = crypto_bn_modexp(pkc);
++		break;
++	case CRK_MOD_EXP_CRT:
++		if (kop->kop.crk_iparams != 6 && kop->kop.crk_oparams != 1)
++			goto err;
++
++		ret = crypto_modexp_crt(pkc);
++		break;
++	case CRK_DSA_SIGN:
++		if ((kop->kop.crk_iparams != 5 && kop->kop.crk_iparams != 6) ||
++		    kop->kop.crk_oparams != 2)
++			goto err;
++
++		ret = crypto_kop_dsasign(pkc);
++		break;
++	case CRK_DSA_VERIFY:
++		if ((kop->kop.crk_iparams != 7 && kop->kop.crk_iparams != 8) ||
++		    kop->kop.crk_oparams != 0)
++			goto err;
++
++		ret = crypto_kop_dsaverify(pkc);
++		break;
++	case CRK_DH_COMPUTE_KEY:
++		if ((kop->kop.crk_iparams != 3 && kop->kop.crk_iparams != 4) ||
++		    kop->kop.crk_oparams != 1)
++			goto err;
++		ret = crypto_kop_dh_key(pkc);
++		break;
++	}
++err:
++	return ret;
++}
++
+ int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop)
+ {
+ 	struct csession *ses_ptr;
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0010-Compat-versions-of-PKC-IOCTLs.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0010-Compat-versions-of-PKC-IOCTLs.patch
new file mode 100644
index 0000000..0320462
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0010-Compat-versions-of-PKC-IOCTLs.patch
@@ -0,0 +1,200 @@ 
+From f6550035fe2c0e66798ace17d31d1d880beacc14 Mon Sep 17 00:00:00 2001
+From: Yashpal Dutta <yashpal.dutta@freescale.com>
+Date: Fri, 7 Mar 2014 06:52:13 +0545
+Subject: [[Patch][fsl 10/16] Compat versions of PKC IOCTLs
+
+Upstream-status: Pending
+
+Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
+---
+ cryptodev_int.h |   20 ++++++++++
+ ioctl.c         |  120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 140 insertions(+)
+
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index b08c253..229fcd0 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -75,6 +75,24 @@ struct compat_crypt_op {
+ 	compat_uptr_t	iv;/* initialization vector for encryption operations */
+ };
+ 
++/* input of CIOCKEY */
++struct compat_crparam {
++	compat_uptr_t	crp_p;
++	uint32_t	crp_nbits;
++};
++
++struct compat_crypt_kop {
++	uint32_t	crk_op;		/* cryptodev_crk_ot_t */
++	uint32_t	crk_status;
++	uint16_t	crk_iparams;
++	uint16_t	crk_oparams;
++	uint32_t	crk_pad1;
++	struct compat_crparam	crk_param[CRK_MAXPARAM];
++	enum curve_t curve_type; /* 0 == Discrete Log, 1 = EC_PRIME,
++				 2 = EC_BINARY */
++	compat_uptr_t cookie;
++};
++
+  /* input of CIOCAUTHCRYPT */
+ struct compat_crypt_auth_op {
+ 	uint32_t	ses;		/* session identifier */
+@@ -112,6 +130,8 @@ struct compat_crypt_auth_op {
+ #define COMPAT_CIOCASYNCCRYPT  _IOW('c', 107, struct compat_crypt_op)
+ #define COMPAT_CIOCASYNCFETCH  _IOR('c', 108, struct compat_crypt_op)
+ #define COMPAT_CIOCAUTHCRYPT   _IOWR('c', 109, struct compat_crypt_auth_op)
++#define COMPAT_CIOCASYMASYNCRYPT    _IOW('c', 110, struct compat_crypt_kop)
++#define COMPAT_CIOCASYMASYNFETCH    _IOR('c', 111, struct compat_crypt_kop)
+ 
+ #endif /* CONFIG_COMPAT */
+ 
+diff --git a/ioctl.c b/ioctl.c
+index 44070e1..ec82c69 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -1076,6 +1076,68 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ /* compatibility code for 32bit userlands */
+ #ifdef CONFIG_COMPAT
+ 
++static inline void compat_to_crypt_kop(struct compat_crypt_kop *compat,
++		 struct crypt_kop *kop)
++{
++	int i;
++	kop->crk_op      = compat->crk_op;
++	kop->crk_status  = compat->crk_status;
++	kop->crk_iparams = compat->crk_iparams;
++	kop->crk_oparams = compat->crk_oparams;
++
++	for (i = 0; i < CRK_MAXPARAM; i++) {
++		kop->crk_param[i].crp_p =
++			compat_ptr(compat->crk_param[i].crp_p);
++		kop->crk_param[i].crp_nbits = compat->crk_param[i].crp_nbits;
++	}
++
++	kop->curve_type = compat->curve_type;
++	kop->cookie = compat->cookie;
++}
++
++static int compat_kop_from_user(struct kernel_crypt_kop *kop,
++	void __user *arg)
++{
++	struct compat_crypt_kop compat_kop;
++
++	if (unlikely(copy_from_user(&compat_kop, arg, sizeof(compat_kop))))
++		return -EFAULT;
++
++	compat_to_crypt_kop(&compat_kop, &kop->kop);
++	return fill_kop_from_cop(kop);
++}
++
++static inline void crypt_kop_to_compat(struct crypt_kop *kop,
++				 struct compat_crypt_kop *compat)
++{
++	int i;
++
++	compat->crk_op      = kop->crk_op;
++	compat->crk_status  = kop->crk_status;
++	compat->crk_iparams = kop->crk_iparams;
++	compat->crk_oparams = kop->crk_oparams;
++
++	for (i = 0; i < CRK_MAXPARAM; i++) {
++		compat->crk_param[i].crp_p =
++			 ptr_to_compat(kop->crk_param[i].crp_p);
++		compat->crk_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
++	}
++	compat->cookie = kop->cookie;
++	compat->curve_type = kop->curve_type;
++}
++
++static int compat_kop_to_user(struct kernel_crypt_kop *kop, void __user *arg)
++{
++	struct compat_crypt_kop compat_kop;
++
++	crypt_kop_to_compat(&kop->kop, &compat_kop);
++	if (unlikely(copy_to_user(arg, &compat_kop, sizeof(compat_kop)))) {
++		dprintk(1, KERN_ERR, "Cannot copy to userspace\n");
++		return -EFAULT;
++	}
++	return 0;
++}
++
+ static inline void
+ compat_to_session_op(struct compat_session_op *compat, struct session_op *sop)
+ {
+@@ -1203,7 +1265,26 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ 			return -EFAULT;
+ 		}
+ 		return ret;
++	case COMPAT_CIOCKEY:
++	{
++		struct cryptodev_pkc *pkc =
++			 kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
++
++		if (!pkc)
++			return -ENOMEM;
++
++		ret = compat_kop_from_user(&pkc->kop, arg);
++
++		if (unlikely(ret)) {
++			kfree(pkc);
++			return ret;
++		}
+ 
++		pkc->type = SYNCHRONOUS;
++		ret = crypto_run_asym(pkc);
++		kfree(pkc);
++	}
++	return ret;
+ 	case COMPAT_CIOCCRYPT:
+ 		ret = compat_kcop_from_user(&kcop, fcr, arg);
+ 		if (unlikely(ret))
+@@ -1242,6 +1323,45 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ 
+ 		return compat_kcop_to_user(&kcop, fcr, arg);
+ #endif
++	case COMPAT_CIOCASYMASYNCRYPT:
++	{
++		struct cryptodev_pkc *pkc =
++			kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
++
++		ret = compat_kop_from_user(&pkc->kop, arg);
++		if (unlikely(ret))
++			return -EINVAL;
++
++		/* Store associated FD priv data with asymmetric request */
++		pkc->priv = pcr;
++		pkc->type = ASYNCHRONOUS;
++		ret = crypto_run_asym(pkc);
++		if (ret == -EINPROGRESS)
++			ret = 0;
++	}
++	return ret;
++	case COMPAT_CIOCASYMASYNFETCH:
++	{
++		struct cryptodev_pkc *pkc;
++		unsigned long flags;
++
++		spin_lock_irqsave(&pcr->completion_lock, flags);
++		if (list_empty(&pcr->asym_completed_list)) {
++			spin_unlock_irqrestore(&pcr->completion_lock, flags);
++			return -ENOMEM;
++		}
++		pkc = list_first_entry(&pcr->asym_completed_list,
++			 struct cryptodev_pkc, list);
++		list_del(&pkc->list);
++		spin_unlock_irqrestore(&pcr->completion_lock, flags);
++		ret = crypto_async_fetch_asym(pkc);
++
++		/* Reflect the updated request to user-space */
++		if (!ret)
++			compat_kop_to_user(&pkc->kop, arg);
++		kfree(pkc);
++	}
++	return ret;
+ 	default:
+ 		return -EINVAL;
+ 	}
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0011-Asynchronous-interface-changes-in-cryptodev.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0011-Asynchronous-interface-changes-in-cryptodev.patch
new file mode 100644
index 0000000..5331abc
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0011-Asynchronous-interface-changes-in-cryptodev.patch
@@ -0,0 +1,213 @@ 
+From ffa8fd090afaf3631e6abd0ab8daa6780be7c31c Mon Sep 17 00:00:00 2001
+From: Yashpal Dutta <yashpal.dutta@freescale.com>
+Date: Fri, 7 Mar 2014 07:24:00 +0545
+Subject: [[Patch][fsl 11/16] Asynchronous interface changes in cryptodev
+
+Upstream-status: Pending
+
+Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
+---
+ cryptlib.h         |    7 ++++-
+ crypto/cryptodev.h |   10 ++++++-
+ cryptodev_int.h    |   10 ++++++-
+ ioctl.c            |   76 +++++++++++++++++++++++++++++++++++-----------------
+ 4 files changed, 76 insertions(+), 27 deletions(-)
+
+diff --git a/cryptlib.h b/cryptlib.h
+index e77edc5..947d845 100644
+--- a/cryptlib.h
++++ b/cryptlib.h
+@@ -113,7 +113,12 @@ struct cryptodev_pkc {
+ 	struct pkc_request req; /* PKC request structure allocated
+ 				 from CryptoAPI */
+ 	enum offload_type type; /* Synchronous Vs Asynchronous request */
+-	void *cookie; /*Additional opaque cookie to be used in future */
++	/*
++	 * cookie used for transfering tranparent information from async
++	 * submission to async fetch. Currently some dynamic allocated
++	 * buffers are maintained which will be freed later during fetch
++	 */
++	void *cookie;
+ 	struct crypt_priv *priv;
+ };
+ 
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index 575ce63..0d65899 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -255,6 +255,14 @@ struct crypt_kop {
+ 	void *cookie;
+ };
+ 
++#define MAX_COOKIES 4
++
++struct pkc_cookie_list_s {
++	int cookie_available;
++	void *cookie[MAX_COOKIES];
++	int status[MAX_COOKIES];
++};
++
+ enum cryptodev_crk_op_t {
+ 	CRK_MOD_EXP = 0,
+ 	CRK_MOD_EXP_CRT = 1,
+@@ -299,5 +307,5 @@ enum cryptodev_crk_op_t {
+ #define CIOCASYNCFETCH    _IOR('c', 111, struct crypt_op)
+ /* additional ioctls for asynchronous  operation for asymmetric ciphers*/
+ #define CIOCASYMASYNCRYPT    _IOW('c', 112, struct crypt_kop)
+-#define CIOCASYMASYNFETCH    _IOR('c', 113, struct crypt_kop)
++#define CIOCASYMFETCHCOOKIE    _IOR('c', 113, struct pkc_cookie_list_s)
+ #endif /* L_CRYPTODEV_H */
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index 229fcd0..8beeef0 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -93,6 +93,12 @@ struct compat_crypt_kop {
+ 	compat_uptr_t cookie;
+ };
+ 
++struct compat_pkc_cookie_list_s {
++	int cookie_available;
++	compat_uptr_t cookie[MAX_COOKIES];
++	int status[MAX_COOKIES];
++};
++
+  /* input of CIOCAUTHCRYPT */
+ struct compat_crypt_auth_op {
+ 	uint32_t	ses;		/* session identifier */
+@@ -127,11 +133,13 @@ struct compat_crypt_auth_op {
+ /* compat ioctls, defined for the above structs */
+ #define COMPAT_CIOCGSESSION    _IOWR('c', 102, struct compat_session_op)
+ #define COMPAT_CIOCCRYPT       _IOWR('c', 104, struct compat_crypt_op)
++#define COMPAT_CIOCKEY    _IOW('c', 105, struct compat_crypt_kop)
+ #define COMPAT_CIOCASYNCCRYPT  _IOW('c', 107, struct compat_crypt_op)
+ #define COMPAT_CIOCASYNCFETCH  _IOR('c', 108, struct compat_crypt_op)
+ #define COMPAT_CIOCAUTHCRYPT   _IOWR('c', 109, struct compat_crypt_auth_op)
+ #define COMPAT_CIOCASYMASYNCRYPT    _IOW('c', 110, struct compat_crypt_kop)
+-#define COMPAT_CIOCASYMASYNFETCH    _IOR('c', 111, struct compat_crypt_kop)
++#define COMPAT_CIOCASYMFETCHCOOKIE    _IOR('c', 111, \
++				struct compat_pkc_cookie_list_s)
+ 
+ #endif /* CONFIG_COMPAT */
+ 
+diff --git a/ioctl.c b/ioctl.c
+index ec82c69..9f57d46 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -103,8 +103,6 @@ void cryptodev_complete_asym(struct crypto_async_request *req, int err)
+ 	crypto_free_pkc(pkc->s);
+ 	res->err = err;
+ 	if (pkc->type == SYNCHRONOUS) {
+-		if (err == -EINPROGRESS)
+-			return;
+ 		complete(&res->completion);
+ 	} else {
+ 		struct crypt_priv *pcr = pkc->priv;
+@@ -1046,26 +1044,41 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 			ret = 0;
+ 	}
+ 	return ret;
+-	case CIOCASYMASYNFETCH:
++	case CIOCASYMFETCHCOOKIE:
+ 	{
+ 		struct cryptodev_pkc *pkc;
+ 		unsigned long flags;
++		int i;
++		struct pkc_cookie_list_s cookie_list;
+ 
+ 		spin_lock_irqsave(&pcr->completion_lock, flags);
+-		if (list_empty(&pcr->asym_completed_list)) {
+-			spin_unlock_irqrestore(&pcr->completion_lock, flags);
+-			return -ENOMEM;
++		cookie_list.cookie_available = 0;
++		for (i = 0; i < MAX_COOKIES; i++) {
++			if (!list_empty(&pcr->asym_completed_list)) {
++				/* Run a loop in the list for upto  elements
++				 and copy their response back */
++				pkc =
++				 list_first_entry(&pcr->asym_completed_list,
++						struct cryptodev_pkc, list);
++				list_del(&pkc->list);
++				ret = crypto_async_fetch_asym(pkc);
++				if (!ret) {
++					cookie_list.cookie_available++;
++					cookie_list.cookie[i] =
++						pkc->kop.kop.cookie;
++					cookie_list.status[i] = pkc->result.err;
++				}
++				kfree(pkc);
++			} else {
++				break;
++			}
+ 		}
+-		pkc = list_first_entry(&pcr->asym_completed_list,
+-			struct cryptodev_pkc, list);
+-		list_del(&pkc->list);
+ 		spin_unlock_irqrestore(&pcr->completion_lock, flags);
+-		ret = crypto_async_fetch_asym(pkc);
+ 
+ 		/* Reflect the updated request to user-space */
+-		if (!ret)
+-			kop_to_user(&pkc->kop, arg);
+-		kfree(pkc);
++		if (cookie_list.cookie_available)
++			copy_to_user(arg, &cookie_list,
++				     sizeof(struct pkc_cookie_list_s));
+ 	}
+ 	return ret;
+ 	default:
+@@ -1340,26 +1353,41 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ 			ret = 0;
+ 	}
+ 	return ret;
+-	case COMPAT_CIOCASYMASYNFETCH:
++	case COMPAT_CIOCASYMFETCHCOOKIE:
+ 	{
+ 		struct cryptodev_pkc *pkc;
+ 		unsigned long flags;
++		int i = 0;
++		struct compat_pkc_cookie_list_s cookie_list;
+ 
+ 		spin_lock_irqsave(&pcr->completion_lock, flags);
+-		if (list_empty(&pcr->asym_completed_list)) {
+-			spin_unlock_irqrestore(&pcr->completion_lock, flags);
+-			return -ENOMEM;
++		cookie_list.cookie_available = 0;
++
++		for (i = 0; i < MAX_COOKIES; i++) {
++			if (!list_empty(&pcr->asym_completed_list)) {
++				/* Run a loop in the list for upto  elements
++				 and copy their response back */
++				pkc =
++				 list_first_entry(&pcr->asym_completed_list,
++						struct cryptodev_pkc, list);
++				list_del(&pkc->list);
++				ret = crypto_async_fetch_asym(pkc);
++				if (!ret) {
++					cookie_list.cookie_available++;
++					cookie_list.cookie[i] =
++						 pkc->kop.kop.cookie;
++				}
++				kfree(pkc);
++			} else {
++				break;
++			}
+ 		}
+-		pkc = list_first_entry(&pcr->asym_completed_list,
+-			 struct cryptodev_pkc, list);
+-		list_del(&pkc->list);
+ 		spin_unlock_irqrestore(&pcr->completion_lock, flags);
+-		ret = crypto_async_fetch_asym(pkc);
+ 
+ 		/* Reflect the updated request to user-space */
+-		if (!ret)
+-			compat_kop_to_user(&pkc->kop, arg);
+-		kfree(pkc);
++		if (cookie_list.cookie_available)
++			copy_to_user(arg, &cookie_list,
++				     sizeof(struct compat_pkc_cookie_list_s));
+ 	}
+ 	return ret;
+ 	default:
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0012-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0012-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch
new file mode 100644
index 0000000..acb5bea
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0012-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch
@@ -0,0 +1,213 @@ 
+From bda8dd5839da7a8e731b60b64b9fcb531c334b99 Mon Sep 17 00:00:00 2001
+From: Yashpal Dutta <yashpal.dutta@freescale.com>
+Date: Fri, 7 Mar 2014 07:53:53 +0545
+Subject: [[Patch][fsl 12/16] ECC_KEYGEN and DLC_KEYGEN supported in cryptodev
+ module
+
+Upstream-status: Pending
+
+Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
+---
+ cryptlib.c         |    2 ++
+ crypto/cryptodev.h |    5 +++-
+ ioctl.c            |   29 ++++++++++++++++--
+ main.c             |   85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 118 insertions(+), 3 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index fa0b63f..41acb2c 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -437,6 +437,8 @@ int cryptodev_pkc_offload(struct cryptodev_pkc  *pkc)
+ 	case DSA_VERIFY:
+ 	case ECDSA_SIGN:
+ 	case ECDSA_VERIFY:
++	case DLC_KEYGEN:
++	case ECC_KEYGEN:
+ 		pkc->s = crypto_alloc_pkc("pkc(dsa)",
+ 			 CRYPTO_ALG_TYPE_PKC_DSA, 0);
+ 		break;
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index 0d65899..33cca2e 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -269,6 +269,8 @@ enum cryptodev_crk_op_t {
+ 	CRK_DSA_SIGN = 2,
+ 	CRK_DSA_VERIFY = 3,
+ 	CRK_DH_COMPUTE_KEY = 4,
++	CRK_DSA_GENERATE_KEY = 5,
++	CRK_DH_GENERATE_KEY = 6,
+ 	CRK_ALGORITHM_ALL
+ };
+ 
+@@ -281,7 +283,8 @@ enum cryptodev_crk_op_t {
+ #define CRF_DSA_SIGN		(1 << CRK_DSA_SIGN)
+ #define CRF_DSA_VERIFY		(1 << CRK_DSA_VERIFY)
+ #define CRF_DH_COMPUTE_KEY	(1 << CRK_DH_COMPUTE_KEY)
+-
++#define CRF_DSA_GENERATE_KEY	(1 << CRK_DSA_GENERATE_KEY)
++#define CRF_DH_GENERATE_KEY	(1 << CRK_DH_GENERATE_KEY)
+ 
+ /* ioctl's. Compatible with old linux cryptodev.h
+  */
+diff --git a/ioctl.c b/ioctl.c
+index 9f57d46..cc1a2a9 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -721,6 +721,23 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ 				     dh_req->z, dh_req->z_len);
+ 	}
+ 	break;
++	case CRK_DSA_GENERATE_KEY:
++	case CRK_DH_GENERATE_KEY:
++	{
++		struct keygen_req_s *key_req = &pkc_req->req_u.keygen;
++
++		if (pkc_req->type == ECC_KEYGEN) {
++			copy_to_user(ckop->crk_param[4].crp_p, key_req->pub_key,
++				     key_req->pub_key_len);
++			copy_to_user(ckop->crk_param[5].crp_p,
++				     key_req->priv_key, key_req->priv_key_len);
++		} else {
++			copy_to_user(ckop->crk_param[3].crp_p,
++				     key_req->pub_key, key_req->pub_key_len);
++			copy_to_user(ckop->crk_param[4].crp_p,
++				     key_req->priv_key, key_req->priv_key_len);
++		}
++	}
+ 	default:
+ 		ret = -EINVAL;
+ 	}
+@@ -934,8 +951,9 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 
+ 	switch (cmd) {
+ 	case CIOCASYMFEAT:
+-		return put_user(CRF_MOD_EXP_CRT |  CRF_MOD_EXP |
+-			CRF_DSA_SIGN | CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY, p);
++		return put_user(CRF_MOD_EXP_CRT |  CRF_MOD_EXP | CRF_DSA_SIGN |
++			CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY |
++			CRF_DSA_GENERATE_KEY, p);
+ 	case CRIOGET:
+ 		fd = clonefd(filp);
+ 		ret = put_user(fd, p);
+@@ -1079,7 +1097,14 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 		if (cookie_list.cookie_available)
+ 			copy_to_user(arg, &cookie_list,
+ 				     sizeof(struct pkc_cookie_list_s));
++		else {
++			struct pkc_cookie_list_s *user_ck_list = (void *)arg;
++
++			put_user(0, &(user_ck_list->cookie_available));
++		}
++		ret = cookie_list.cookie_available;
+ 	}
++
+ 	return ret;
+ 	default:
+ 		return -EINVAL;
+diff --git a/main.c b/main.c
+index 0b7951e..c901bc7 100644
+--- a/main.c
++++ b/main.c
+@@ -342,6 +342,85 @@ err:
+ 	return rc;
+ }
+ 
++int crypto_kop_keygen(struct cryptodev_pkc *pkc)
++{
++	struct kernel_crypt_kop *kop = &pkc->kop;
++	struct crypt_kop *cop = &kop->kop;
++	struct pkc_request *pkc_req;
++	struct keygen_req_s *key_req;
++	int rc, buf_size;
++	uint8_t *buf;
++
++	if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
++	    !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
++	    !cop->crk_param[4].crp_nbits)
++		return -EINVAL;
++
++	pkc_req = &pkc->req;
++	key_req = &pkc_req->req_u.keygen;
++	key_req->q_len = (cop->crk_param[0].crp_nbits + 7)/8;
++	key_req->r_len = (cop->crk_param[1].crp_nbits + 7)/8;
++	key_req->g_len = (cop->crk_param[2].crp_nbits + 7)/8;
++	if (cop->crk_iparams == 3) {
++		key_req->pub_key_len = (cop->crk_param[3].crp_nbits + 7)/8;
++		key_req->priv_key_len = (cop->crk_param[4].crp_nbits + 7)/8;
++		buf_size = key_req->q_len + key_req->r_len + key_req->g_len +
++			key_req->pub_key_len + key_req->priv_key_len;
++		pkc_req->type = DLC_KEYGEN;
++	} else {
++		key_req->ab_len = (cop->crk_param[3].crp_nbits + 7)/8;
++		key_req->pub_key_len = (cop->crk_param[4].crp_nbits + 7)/8;
++		key_req->priv_key_len = (cop->crk_param[5].crp_nbits + 7)/8;
++		buf_size = key_req->q_len + key_req->r_len + key_req->g_len +
++			key_req->pub_key_len + key_req->priv_key_len +
++			key_req->ab_len;
++		pkc_req->type = ECC_KEYGEN;
++		pkc_req->curve_type = cop->curve_type;
++	}
++
++	buf = kzalloc(buf_size, GFP_DMA);
++	if (!buf)
++		return -ENOMEM;
++
++	key_req->q = buf;
++	key_req->r = key_req->q + key_req->q_len;
++	key_req->g = key_req->r + key_req->r_len;
++	key_req->pub_key = key_req->g + key_req->g_len;
++	key_req->priv_key = key_req->pub_key + key_req->pub_key_len;
++	copy_from_user(key_req->q, cop->crk_param[0].crp_p, key_req->q_len);
++	copy_from_user(key_req->r, cop->crk_param[1].crp_p, key_req->r_len);
++	copy_from_user(key_req->g, cop->crk_param[2].crp_p, key_req->g_len);
++	if (cop->crk_iparams == 3) {
++		copy_from_user(key_req->pub_key, cop->crk_param[3].crp_p,
++			       key_req->pub_key_len);
++		copy_from_user(key_req->priv_key, cop->crk_param[4].crp_p,
++			       key_req->priv_key_len);
++	} else {
++		key_req->ab = key_req->priv_key + key_req->priv_key_len;
++		copy_from_user(key_req->ab, cop->crk_param[3].crp_p,
++			       key_req->ab_len);
++		copy_from_user(key_req->pub_key, cop->crk_param[4].crp_p,
++			       key_req->pub_key_len);
++		copy_from_user(key_req->priv_key, cop->crk_param[5].crp_p,
++			       key_req->priv_key_len);
++	}
++
++	rc = cryptodev_pkc_offload(pkc);
++	if (pkc->type == SYNCHRONOUS) {
++		if (rc)
++			goto err;
++	} else {
++		if (rc != -EINPROGRESS && !rc)
++			goto err;
++
++		pkc->cookie = buf;
++		return rc;
++	}
++err:
++	kfree(buf);
++	return rc;
++}
++
+ int crypto_kop_dh_key(struct cryptodev_pkc *pkc)
+ {
+ 	struct kernel_crypt_kop *kop = &pkc->kop;
+@@ -554,6 +633,12 @@ int crypto_run_asym(struct cryptodev_pkc *pkc)
+ 			goto err;
+ 		ret = crypto_kop_dh_key(pkc);
+ 		break;
++	case CRK_DH_GENERATE_KEY:
++	case CRK_DSA_GENERATE_KEY:
++		if ((kop->kop.crk_iparams != 3 && kop->kop.crk_iparams != 4))
++			goto err;
++		ret = crypto_kop_keygen(pkc);
++		break;
+ 	}
+ err:
+ 	return ret;
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0013-RCU-stall-fixed-in-PKC-asynchronous-interface.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0013-RCU-stall-fixed-in-PKC-asynchronous-interface.patch
new file mode 100644
index 0000000..26c0168
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0013-RCU-stall-fixed-in-PKC-asynchronous-interface.patch
@@ -0,0 +1,238 @@ 
+From 211a494a4f8ee6d5d31a1db938b771958ea32c6b Mon Sep 17 00:00:00 2001
+From: Yashpal Dutta <yashpal.dutta@freescale.com>
+Date: Fri, 7 Mar 2014 08:49:15 +0545
+Subject: [[Patch][fsl 13/16] RCU stall fixed in PKC asynchronous interface
+
+Upstream-status: Pending
+
+Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
+---
+ ioctl.c |   23 +++++++++++------------
+ main.c  |   43 +++++++++++++++++++++++++++----------------
+ 2 files changed, 38 insertions(+), 28 deletions(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index cc1a2a9..1752880 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -106,10 +106,9 @@ void cryptodev_complete_asym(struct crypto_async_request *req, int err)
+ 		complete(&res->completion);
+ 	} else {
+ 		struct crypt_priv *pcr = pkc->priv;
+-		unsigned long flags;
+-		spin_lock_irqsave(&pcr->completion_lock, flags);
++		spin_lock_bh(&pcr->completion_lock);
+ 		list_add_tail(&pkc->list, &pcr->asym_completed_list);
+-		spin_unlock_irqrestore(&pcr->completion_lock, flags);
++		spin_unlock_bh(&pcr->completion_lock);
+ 		/* wake for POLLIN */
+ 		wake_up_interruptible(&pcr->user_waiter);
+ 	}
+@@ -953,7 +952,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 	case CIOCASYMFEAT:
+ 		return put_user(CRF_MOD_EXP_CRT |  CRF_MOD_EXP | CRF_DSA_SIGN |
+ 			CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY |
+-			CRF_DSA_GENERATE_KEY, p);
++			CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY, p);
+ 	case CRIOGET:
+ 		fd = clonefd(filp);
+ 		ret = put_user(fd, p);
+@@ -992,7 +991,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 	case CIOCKEY:
+ 	{
+ 		struct cryptodev_pkc *pkc =
+-			kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
++			kmalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
+ 
+ 		if (!pkc)
+ 			return -ENOMEM;
+@@ -1048,7 +1047,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 	case CIOCASYMASYNCRYPT:
+ 	{
+ 		struct cryptodev_pkc *pkc =
+-			kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
++			kmalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL);
+ 		ret = kop_from_user(&pkc->kop, arg);
+ 
+ 		if (unlikely(ret))
+@@ -1065,13 +1064,12 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 	case CIOCASYMFETCHCOOKIE:
+ 	{
+ 		struct cryptodev_pkc *pkc;
+-		unsigned long flags;
+ 		int i;
+ 		struct pkc_cookie_list_s cookie_list;
+ 
+-		spin_lock_irqsave(&pcr->completion_lock, flags);
+ 		cookie_list.cookie_available = 0;
+ 		for (i = 0; i < MAX_COOKIES; i++) {
++			spin_lock_bh(&pcr->completion_lock);
+ 			if (!list_empty(&pcr->asym_completed_list)) {
+ 				/* Run a loop in the list for upto  elements
+ 				 and copy their response back */
+@@ -1079,6 +1077,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 				 list_first_entry(&pcr->asym_completed_list,
+ 						struct cryptodev_pkc, list);
+ 				list_del(&pkc->list);
++				spin_unlock_bh(&pcr->completion_lock);
+ 				ret = crypto_async_fetch_asym(pkc);
+ 				if (!ret) {
+ 					cookie_list.cookie_available++;
+@@ -1088,10 +1087,10 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 				}
+ 				kfree(pkc);
+ 			} else {
++				spin_unlock_bh(&pcr->completion_lock);
+ 				break;
+ 			}
+ 		}
+-		spin_unlock_irqrestore(&pcr->completion_lock, flags);
+ 
+ 		/* Reflect the updated request to user-space */
+ 		if (cookie_list.cookie_available)
+@@ -1381,14 +1380,13 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ 	case COMPAT_CIOCASYMFETCHCOOKIE:
+ 	{
+ 		struct cryptodev_pkc *pkc;
+-		unsigned long flags;
+ 		int i = 0;
+ 		struct compat_pkc_cookie_list_s cookie_list;
+ 
+-		spin_lock_irqsave(&pcr->completion_lock, flags);
+ 		cookie_list.cookie_available = 0;
+ 
+ 		for (i = 0; i < MAX_COOKIES; i++) {
++			spin_lock_bh(&pcr->completion_lock);
+ 			if (!list_empty(&pcr->asym_completed_list)) {
+ 				/* Run a loop in the list for upto  elements
+ 				 and copy their response back */
+@@ -1396,6 +1394,7 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ 				 list_first_entry(&pcr->asym_completed_list,
+ 						struct cryptodev_pkc, list);
+ 				list_del(&pkc->list);
++				spin_unlock_bh(&pcr->completion_lock);
+ 				ret = crypto_async_fetch_asym(pkc);
+ 				if (!ret) {
+ 					cookie_list.cookie_available++;
+@@ -1404,10 +1403,10 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ 				}
+ 				kfree(pkc);
+ 			} else {
++				spin_unlock_bh(&pcr->completion_lock);
+ 				break;
+ 			}
+ 		}
+-		spin_unlock_irqrestore(&pcr->completion_lock, flags);
+ 
+ 		/* Reflect the updated request to user-space */
+ 		if (cookie_list.cookie_available)
+diff --git a/main.c b/main.c
+index c901bc7..2747706 100644
+--- a/main.c
++++ b/main.c
+@@ -215,7 +215,9 @@ int crypto_kop_dsasign(struct cryptodev_pkc *pkc)
+ 		pkc_req->type = DSA_SIGN;
+ 	}
+ 
+-	buf = kzalloc(buf_size, GFP_DMA);
++	buf = kmalloc(buf_size, GFP_DMA);
++	if (!buf)
++		return -ENOMEM;
+ 
+ 	dsa_req->q = buf;
+ 	dsa_req->r = dsa_req->q + dsa_req->q_len;
+@@ -298,7 +300,9 @@ int crypto_kop_dsaverify(struct cryptodev_pkc *pkc)
+ 		pkc_req->type = DSA_VERIFY;
+ 	}
+ 
+-	buf = kzalloc(buf_size, GFP_DMA);
++	buf = kmalloc(buf_size, GFP_DMA);
++	if (!buf)
++		return -ENOMEM;
+ 
+ 	dsa_req->q = buf;
+ 	dsa_req->r = dsa_req->q + dsa_req->q_len;
+@@ -378,7 +382,7 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
+ 		pkc_req->curve_type = cop->curve_type;
+ 	}
+ 
+-	buf = kzalloc(buf_size, GFP_DMA);
++	buf = kmalloc(buf_size, GFP_DMA);
+ 	if (!buf)
+ 		return -ENOMEM;
+ 
+@@ -390,25 +394,28 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
+ 	copy_from_user(key_req->q, cop->crk_param[0].crp_p, key_req->q_len);
+ 	copy_from_user(key_req->r, cop->crk_param[1].crp_p, key_req->r_len);
+ 	copy_from_user(key_req->g, cop->crk_param[2].crp_p, key_req->g_len);
+-	if (cop->crk_iparams == 3) {
+-		copy_from_user(key_req->pub_key, cop->crk_param[3].crp_p,
+-			       key_req->pub_key_len);
+-		copy_from_user(key_req->priv_key, cop->crk_param[4].crp_p,
+-			       key_req->priv_key_len);
+-	} else {
++	if (cop->crk_iparams == 4) {
+ 		key_req->ab = key_req->priv_key + key_req->priv_key_len;
+ 		copy_from_user(key_req->ab, cop->crk_param[3].crp_p,
+ 			       key_req->ab_len);
+-		copy_from_user(key_req->pub_key, cop->crk_param[4].crp_p,
+-			       key_req->pub_key_len);
+-		copy_from_user(key_req->priv_key, cop->crk_param[5].crp_p,
+-			       key_req->priv_key_len);
+ 	}
+ 
+ 	rc = cryptodev_pkc_offload(pkc);
+ 	if (pkc->type == SYNCHRONOUS) {
+ 		if (rc)
+ 			goto err;
++
++		if (cop->crk_iparams == 4) {
++			copy_to_user(cop->crk_param[4].crp_p, key_req->pub_key,
++				     key_req->pub_key_len);
++			copy_to_user(cop->crk_param[5].crp_p, key_req->priv_key,
++				     key_req->priv_key_len);
++		} else {
++			copy_to_user(cop->crk_param[3].crp_p, key_req->pub_key,
++				     key_req->pub_key_len);
++			copy_to_user(cop->crk_param[4].crp_p,
++				     key_req->priv_key, key_req->priv_key_len);
++		}
+ 	} else {
+ 		if (rc != -EINPROGRESS && !rc)
+ 			goto err;
+@@ -447,7 +454,9 @@ int crypto_kop_dh_key(struct cryptodev_pkc *pkc)
+ 		pkc_req->type = DH_COMPUTE_KEY;
+ 	}
+ 	buf_size += dh_req->z_len;
+-	buf = kzalloc(buf_size, GFP_DMA);
++	buf = kmalloc(buf_size, GFP_DMA);
++	if (!buf)
++		return -ENOMEM;
+ 	dh_req->q = buf;
+ 	dh_req->s = dh_req->q + dh_req->q_len;
+ 	dh_req->pub_key = dh_req->s + dh_req->s_len;
+@@ -508,9 +517,11 @@ int crypto_modexp_crt(struct cryptodev_pkc *pkc)
+ 	rsa_req->dq_len = (cop->crk_param[4].crp_nbits + 7)/8;
+ 	rsa_req->c_len = (cop->crk_param[5].crp_nbits + 7)/8;
+ 	rsa_req->f_len = (cop->crk_param[6].crp_nbits + 7)/8;
+-	buf = kzalloc(rsa_req->p_len + rsa_req->q_len + rsa_req->f_len +
++	buf = kmalloc(rsa_req->p_len + rsa_req->q_len + rsa_req->f_len +
+ 		      rsa_req->dp_len + rsa_req->dp_len + rsa_req->c_len +
+ 		      rsa_req->g_len, GFP_DMA);
++	if (!buf)
++		return -ENOMEM;
+ 	rsa_req->p = buf;
+ 	rsa_req->q = rsa_req->p + rsa_req->p_len;
+ 	rsa_req->g = rsa_req->q + rsa_req->q_len;
+@@ -563,7 +574,7 @@ int crypto_bn_modexp(struct cryptodev_pkc *pkc)
+ 	rsa_req->e_len = (cop->crk_param[1].crp_nbits + 7)/8;
+ 	rsa_req->n_len = (cop->crk_param[2].crp_nbits + 7)/8;
+ 	rsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8;
+-	buf = kzalloc(rsa_req->f_len + rsa_req->e_len + rsa_req->n_len
++	buf = kmalloc(rsa_req->f_len + rsa_req->e_len + rsa_req->n_len
+ 			+ rsa_req->g_len, GFP_DMA);
+ 	if (!buf)
+ 		return -ENOMEM;
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0014-use-static-allocation-for-keys-copied-from-userspace.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0014-use-static-allocation-for-keys-copied-from-userspace.patch
new file mode 100644
index 0000000..c68f3d7
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0014-use-static-allocation-for-keys-copied-from-userspace.patch
@@ -0,0 +1,131 @@ 
+From 50c116780f736b3e6a11389c9d9b3f4a1d5cab90 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Wed, 19 Mar 2014 17:59:17 +0200
+Subject: [[Patch][fsl 14/16] use static allocation for keys copied from
+ userspace
+
+Upstream-status: Pending
+
+There is no need to keep keys around for the entire duration of the
+session. The keys are copied from user-space and then used to initialize
+the ciphers. After this, the original keys can be discarded.
+The total required space for keys is small and known in advance. This
+patch uses this information to allocate required space on stack.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ cryptodev_int.h |    1 -
+ ioctl.c         |   38 ++++++++++++++++++++------------------
+ 2 files changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index 8beeef0..7ea6976 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -212,7 +212,6 @@ struct csession {
+ 	struct hash_data hdata;
+ 	uint32_t sid;
+ 	uint32_t alignmask;
+-	uint8_t *key;
+ 
+ 	unsigned int array_size;
+ 	unsigned int used_pages; /* the number of pages that are used */
+diff --git a/ioctl.c b/ioctl.c
+index 1752880..16ce72c 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -46,6 +46,8 @@
+ #include <linux/uaccess.h>
+ #include <crypto/cryptodev.h>
+ #include <linux/scatterlist.h>
++#include <linux/rtnetlink.h>
++#include <crypto/authenc.h>
+ 
+ #include <linux/sysctl.h>
+ 
+@@ -136,9 +138,17 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 	const char *alg_name = NULL;
+ 	const char *hash_name = NULL;
+ 	int hmac_mode = 1, stream = 0, aead = 0;
+-	uint8_t *key = NULL;
+-	unsigned int keylen;
+-	uint8_t mackey[CRYPTO_HMAC_MAX_KEY_LEN];
++	/*
++	 * With aead, only ckey is used and it can cover all the struct space;
++	 * otherwise both keys may be used simultaneously but they are confined
++	 * to their spaces
++	 */
++	struct {
++		uint8_t ckey[CRYPTO_CIPHER_MAX_KEY_LEN];
++		uint8_t mkey[CRYPTO_HMAC_MAX_KEY_LEN];
++		/* padding space for aead keys */
++		uint8_t pad[RTA_SPACE(sizeof(struct crypto_authenc_key_param))];
++	} keys;
+ 
+ 	/* Does the request make sense? */
+ 	if (unlikely(!sop->cipher && !sop->mac)) {
+@@ -257,23 +267,17 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 
+ 	/* Set-up crypto transform. */
+ 	if (alg_name) {
++		unsigned int keylen;
+ 		ret = cryptodev_get_cipher_keylen(&keylen, sop, aead);
+ 		if (unlikely(ret < 0))
+ 			goto error_cipher;
+ 
+-		key = kmalloc(keylen, GFP_KERNEL);
+-		ses_new->key = key;
+-		if (unlikely(!key)) {
+-			ret = -ENOMEM;
+-			goto error_cipher;
+-		}
+-
+-		ret = cryptodev_get_cipher_key(key, sop, aead);
++		ret = cryptodev_get_cipher_key(keys.ckey, sop, aead);
+ 		if (unlikely(ret < 0))
+ 			goto error_cipher;
+ 
+-		ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, key, keylen,
+-				stream, aead);
++		ret = cryptodev_cipher_init(&ses_new->cdata, alg_name,
++			keys.ckey, keylen, stream, aead);
+ 		if (ret < 0) {
+ 			ddebug(1, "Failed to load cipher for %s", alg_name);
+ 			ret = -EINVAL;
+@@ -289,14 +293,14 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ 			goto error_hash;
+ 		}
+ 
+-		if (sop->mackey && unlikely(copy_from_user(mackey, sop->mackey,
+-					    sop->mackeylen))) {
++		if (sop->mackey && unlikely(copy_from_user(keys.mkey,
++			sop->mackey, sop->mackeylen))) {
+ 			ret = -EFAULT;
+ 			goto error_hash;
+ 		}
+ 
+ 		ret = cryptodev_hash_init(&ses_new->hdata, hash_name, hmac_mode,
+-							mackey, sop->mackeylen);
++			keys.mkey, sop->mackeylen);
+ 		if (ret != 0) {
+ 			ddebug(1, "Failed to load hash for %s", hash_name);
+ 			ret = -EINVAL;
+@@ -349,7 +353,6 @@ error_hash:
+ 	kfree(ses_new->sg);
+ 	kfree(ses_new->pages);
+ error_cipher:
+-	kfree(key);
+ 	kfree(ses_new);
+ 
+ 	return ret;
+@@ -370,7 +373,6 @@ crypto_destroy_session(struct csession *ses_ptr)
+ 	ddebug(2, "freeing space for %d user pages", ses_ptr->array_size);
+ 	kfree(ses_ptr->pages);
+ 	kfree(ses_ptr->sg);
+-	kfree(ses_ptr->key);
+ 	mutex_unlock(&ses_ptr->sem);
+ 	mutex_destroy(&ses_ptr->sem);
+ 	kfree(ses_ptr);
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0015-Add-RSA-Key-generation-offloading.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0015-Add-RSA-Key-generation-offloading.patch
new file mode 100644
index 0000000..a419b58
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0015-Add-RSA-Key-generation-offloading.patch
@@ -0,0 +1,170 @@ 
+From 1d9c8084a9addaa071ca3e6c14167ebdb2673725 Mon Sep 17 00:00:00 2001
+From: Hou Zhiqiang <B48286@freescale.com>
+Date: Wed, 19 Mar 2014 14:02:46 +0800
+Subject: [[Patch][fsl 15/16] Add RSA Key generation offloading
+
+Upstream-status: Pending
+
+Signed-off-by: Hou Zhiqiang <B48286@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ cryptlib.c         |    1 +
+ crypto/cryptodev.h |    2 ++
+ ioctl.c            |    3 +-
+ main.c             |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 4 files changed, 84 insertions(+), 2 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index 41acb2c..89af77a 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -426,6 +426,7 @@ int cryptodev_pkc_offload(struct cryptodev_pkc  *pkc)
+ 	struct pkc_request *pkc_req = &pkc->req, *pkc_requested;
+ 
+ 	switch (pkc_req->type) {
++	case RSA_KEYGEN:
+ 	case RSA_PUB:
+ 	case RSA_PRIV_FORM1:
+ 	case RSA_PRIV_FORM2:
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index 33cca2e..7990f27 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -271,6 +271,7 @@ enum cryptodev_crk_op_t {
+ 	CRK_DH_COMPUTE_KEY = 4,
+ 	CRK_DSA_GENERATE_KEY = 5,
+ 	CRK_DH_GENERATE_KEY = 6,
++	CRK_RSA_GENERATE_KEY = 7,
+ 	CRK_ALGORITHM_ALL
+ };
+ 
+@@ -280,6 +281,7 @@ enum cryptodev_crk_op_t {
+  */
+ #define CRF_MOD_EXP		(1 << CRK_MOD_EXP)
+ #define CRF_MOD_EXP_CRT		(1 << CRK_MOD_EXP_CRT)
++#define CRF_RSA_GENERATE_KEY	(1 << CRK_RSA_GENERATE_KEY)
+ #define CRF_DSA_SIGN		(1 << CRK_DSA_SIGN)
+ #define CRF_DSA_VERIFY		(1 << CRK_DSA_VERIFY)
+ #define CRF_DH_COMPUTE_KEY	(1 << CRK_DH_COMPUTE_KEY)
+diff --git a/ioctl.c b/ioctl.c
+index 16ce72c..0344c0c 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -954,7 +954,8 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 	case CIOCASYMFEAT:
+ 		return put_user(CRF_MOD_EXP_CRT |  CRF_MOD_EXP | CRF_DSA_SIGN |
+ 			CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY |
+-			CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY, p);
++			CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY |
++			CRF_RSA_GENERATE_KEY, p);
+ 	case CRIOGET:
+ 		fd = clonefd(filp);
+ 		ret = put_user(fd, p);
+diff --git a/main.c b/main.c
+index 2747706..14dcf40 100644
+--- a/main.c
++++ b/main.c
+@@ -346,6 +346,82 @@ err:
+ 	return rc;
+ }
+ 
++int crypto_kop_rsa_keygen(struct cryptodev_pkc *pkc)
++{
++	struct kernel_crypt_kop *kop = &pkc->kop;
++	struct crypt_kop *cop = &kop->kop;
++	struct pkc_request *pkc_req;
++	struct rsa_keygen_req_s *key_req;
++	int rc, buf_size;
++	uint8_t *buf;
++
++	if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits ||
++		!cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits ||
++		!cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits ||
++		!cop->crk_param[6].crp_nbits)
++		return -EINVAL;
++
++	pkc_req = &pkc->req;
++	pkc_req->type = RSA_KEYGEN;
++	key_req = &pkc_req->req_u.rsa_keygen;
++	key_req->n_len = (cop->crk_param[2].crp_nbits + 7)/8;
++	key_req->p_len = (cop->crk_param[0].crp_nbits + 7) / 8;
++	key_req->q_len = (cop->crk_param[1].crp_nbits + 7) / 8;
++	key_req->n_len = (cop->crk_param[2].crp_nbits + 7) / 8;
++	key_req->d_len = (cop->crk_param[3].crp_nbits + 7) / 8;
++	key_req->dp_len = (cop->crk_param[4].crp_nbits + 7) / 8;
++	key_req->dq_len = (cop->crk_param[5].crp_nbits + 7) / 8;
++	key_req->c_len = (cop->crk_param[6].crp_nbits + 7) / 8;
++
++	buf_size = key_req->p_len + key_req->q_len + key_req->n_len +
++			key_req->d_len + key_req->dp_len +
++			key_req->dq_len + key_req->c_len;
++
++	buf = kmalloc(buf_size, GFP_DMA);
++	if (!buf)
++		return -ENOMEM;
++	key_req->p = buf;
++	key_req->q = key_req->p + key_req->p_len;
++	key_req->n = key_req->q + key_req->q_len;
++	key_req->d = key_req->n + key_req->n_len;
++	key_req->dp = key_req->d + key_req->d_len;
++	key_req->dq = key_req->dp + key_req->dp_len;
++	key_req->c = key_req->dq + key_req->dq_len;
++
++	rc = cryptodev_pkc_offload(pkc);
++
++	if (pkc->type == SYNCHRONOUS) {
++		if (rc)
++			goto err;
++
++		copy_to_user(cop->crk_param[0].crp_p,
++				key_req->p, key_req->p_len);
++		copy_to_user(cop->crk_param[1].crp_p,
++				key_req->q, key_req->q_len);
++		copy_to_user(cop->crk_param[2].crp_p,
++				key_req->n, key_req->n_len);
++		copy_to_user(cop->crk_param[3].crp_p,
++				key_req->d, key_req->d_len);
++		copy_to_user(cop->crk_param[4].crp_p,
++				key_req->dp, key_req->dp_len);
++		copy_to_user(cop->crk_param[5].crp_p,
++				key_req->dq, key_req->dq_len);
++		copy_to_user(cop->crk_param[6].crp_p,
++				key_req->c, key_req->c_len);
++		} else {
++		if (rc != -EINPROGRESS && !rc) {
++			printk("%s: Failed\n", __func__);
++			goto err;
++		}
++		pkc->cookie = buf;
++		return rc;
++	}
++err:
++	kfree(buf);
++	return rc;
++
++}
++
+ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
+ {
+ 	struct kernel_crypt_kop *kop = &pkc->kop;
+@@ -385,7 +461,6 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
+ 	buf = kmalloc(buf_size, GFP_DMA);
+ 	if (!buf)
+ 		return -ENOMEM;
+-
+ 	key_req->q = buf;
+ 	key_req->r = key_req->q + key_req->q_len;
+ 	key_req->g = key_req->r + key_req->r_len;
+@@ -650,6 +725,9 @@ int crypto_run_asym(struct cryptodev_pkc *pkc)
+ 			goto err;
+ 		ret = crypto_kop_keygen(pkc);
+ 		break;
++	case CRK_RSA_GENERATE_KEY:
++		ret = crypto_kop_rsa_keygen(pkc);
++		break;
+ 	}
+ err:
+ 	return ret;
+-- 
+1.7.9.7
+
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0016-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0016-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch
new file mode 100644
index 0000000..d5cc7f0
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-fsl/0016-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch
@@ -0,0 +1,116 @@ 
+From 2215332bff6034d0e22e92e8fda0993f2579a740 Mon Sep 17 00:00:00 2001
+From: Yashpal Dutta <yashpal.dutta@freescale.com>
+Date: Thu, 17 Apr 2014 07:08:47 +0545
+Subject: [[Patch][fsl 16/16] Fixed compilation error of openssl with fsl
+ cryptodev
+
+Upstream-status: Pending
+
+Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ cryptlib.c         |    6 +++---
+ crypto/cryptodev.h |    9 ++++++++-
+ cryptodev_int.h    |    2 +-
+ ioctl.c            |    6 +++++-
+ 4 files changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index 89af77a..1fc03e5 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -129,7 +129,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ 			if (alg->max_keysize > 0 &&
+ 					unlikely((keylen < alg->min_keysize) ||
+ 					(keylen > alg->max_keysize))) {
+-				ddebug(1, "Wrong keylen '%zu' for algorithm '%s'. Use %u to %u.",
++				ddebug(1, "Wrong keylen '%u' for algorithm '%s'. Use %u to %u.",
+ 						keylen, alg_name, alg->min_keysize, alg->max_keysize);
+ 				ret = -EINVAL;
+ 				goto error;
+@@ -156,7 +156,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ 	}
+ 
+ 	if (unlikely(ret)) {
+-		ddebug(1, "Setting key failed for %s-%zu.", alg_name, keylen*8);
++		ddebug(1, "Setting key failed for %s-%u.", alg_name, keylen*8);
+ 		ret = -EINVAL;
+ 		goto error;
+ 	}
+@@ -323,7 +323,7 @@ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
+ 	if (hmac_mode != 0) {
+ 		ret = crypto_ahash_setkey(hdata->async.s, mackey, mackeylen);
+ 		if (unlikely(ret)) {
+-			ddebug(1, "Setting hmac key failed for %s-%zu.",
++			ddebug(1, "Setting hmac key failed for %s-%u.",
+ 					alg_name, mackeylen*8);
+ 			ret = -EINVAL;
+ 			goto error;
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index 7990f27..77bffc9 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -235,6 +235,13 @@ struct crypt_auth_op {
+ #define	CRYPTO_ALG_FLAG_RNG_ENABLE	2
+ #define	CRYPTO_ALG_FLAG_DSA_SHA		4
+ 
++enum ec_curve_t {
++	EC_DISCRETE_LOG,
++	EC_PRIME,
++	EC_BINARY,
++	MAX_EC_TYPE
++};
++
+ struct crparam {
+ 	__u8	*crp_p;
+ 	__u32	crp_nbits;
+@@ -250,7 +257,7 @@ struct crypt_kop {
+ 	__u16	crk_oparams;
+ 	__u32	crk_pad1;
+ 	struct crparam	crk_param[CRK_MAXPARAM];
+-	enum curve_t curve_type; /* 0 == Discrete Log,
++	enum ec_curve_t curve_type; /* 0 == Discrete Log,
+ 				1 = EC_PRIME, 2 = EC_BINARY */
+ 	void *cookie;
+ };
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index 7ea6976..e379eaf 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -88,7 +88,7 @@ struct compat_crypt_kop {
+ 	uint16_t	crk_oparams;
+ 	uint32_t	crk_pad1;
+ 	struct compat_crparam	crk_param[CRK_MAXPARAM];
+-	enum curve_t curve_type; /* 0 == Discrete Log, 1 = EC_PRIME,
++	enum ec_curve_t curve_type; /* 0 == Discrete Log, 1 = EC_PRIME,
+ 				 2 = EC_BINARY */
+ 	compat_uptr_t cookie;
+ };
+diff --git a/ioctl.c b/ioctl.c
+index 0344c0c..66cb05a 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -498,6 +498,7 @@ cryptodev_open(struct inode *inode, struct file *filp)
+ 	INIT_LIST_HEAD(&pcr->done.list);
+ 	INIT_LIST_HEAD(&pcr->asym_completed_list);
+ 	spin_lock_init(&pcr->completion_lock);
++
+ 	INIT_WORK(&pcr->cryptask, cryptask_routine);
+ 
+ 	init_waitqueue_head(&pcr->user_waiter);
+@@ -777,8 +778,11 @@ static int fill_kcop_from_cop(struct kernel_crypt_op *kcop, struct fcrypt *fcr)
+ 
+ 	if (cop->iv) {
+ 		rc = copy_from_user(kcop->iv, cop->iv, kcop->ivlen);
+-		if (unlikely(rc))
++		if (unlikely(rc)) {
++			derr(1, "error copying IV (%d bytes), copy_from_user returned %d for address %p",
++					kcop->ivlen, rc, cop->iv);
+ 			return -EFAULT;
++		}
+ 	}
+ 
+ 	return 0;
+-- 
+1.7.9.7
+
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 @@ 
+require recipes-kernel/cryptodev/cryptodev-fsl.inc
+
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..1dbf3b6
--- /dev/null
+++ b/recipes-kernel/cryptodev/cryptodev-module_1.6.bbappend
@@ -0,0 +1,8 @@ 
+require recipes-kernel/cryptodev/cryptodev-fsl.inc
+
+inherit qoriq_build_64bit_kernel
+
+do_install_append_fslmachine () {
+    rm -fr ${D}/usr
+}
+
diff --git a/recipes-kernel/cryptodev/cryptodev_1.5.bb b/recipes-kernel/cryptodev/cryptodev_1.5.bb
deleted file mode 100644
index 4c1dade..0000000
--- a/recipes-kernel/cryptodev/cryptodev_1.5.bb
+++ /dev/null
@@ -1,51 +0,0 @@ 
-SECTION = "devel"
-SUMMARY = "Linux Cryptodev KERNEL MODULE"
-DESCRIPTION = "The Cryptodev package contains the kernel /dev/crypto module"
-LICENSE = "GPLv2"
-LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263"
-RCONFLICTS_${PN} = "ocf-linux"
-
-inherit module
-
-PR = "r1"
-DEPENDS += "openssl"
-
-SRCREV = "1c24a0aa996630518d47826a2e3fea129ea094c7"
-
-SRC_URI = "git://repo.or.cz/cryptodev-linux.git;protocol=git \
-           file://makefile_fixup.patch \
-           file://Add-the-compile-and-install-rules-for-cryptodev-test.patch"
-
-EXTRA_OEMAKE='KERNEL_DIR="${STAGING_KERNEL_DIR}" PREFIX="${D}"'
-
-S = "${WORKDIR}/git"
-python () {
-	ma = d.getVar("DISTRO_FEATURES", True)
-	arch = d.getVar("OVERRIDES", True)
-
-	# the : after the arch is to skip the message on 64b
-	if not "multiarch" in ma and ("e5500:" in arch or "e6500:" in arch):
-		raise bb.parse.SkipPackage("Building the kernel for this arch requires multiarch to be in DISTRO_FEATURES")
-
-	promote_kernel = d.getVar('BUILD_64BIT_KERNEL')
-
-	if promote_kernel == "1":
-		d.setVar('KERNEL_CC_append', ' -m64')
-		d.setVar('KERNEL_LD_append', ' -melf64ppc')
-
-	error_qa = d.getVar('ERROR_QA', True)
-	if 'arch' in error_qa:
-		d.setVar('ERROR_QA', error_qa.replace(' arch', ''))
-}
-
-do_compile_append() {
-        oe_runmake testprogs
-}
-
-do_install_append() {
-        oe_runmake install_tests
-}
-
-PACKAGES += "${PN}-tests"
-FILES_${PN}-dbg += "${bindir}/tests_cryptodev/.debug"
-FILES_${PN}-tests = "${bindir}/tests_cryptodev/*"
diff --git a/recipes-kernel/cryptodev/files/Add-the-compile-and-install-rules-for-cryptodev-test.patch b/recipes-kernel/cryptodev/files/Add-the-compile-and-install-rules-for-cryptodev-test.patch
deleted file mode 100644
index cb871f6..0000000
--- a/recipes-kernel/cryptodev/files/Add-the-compile-and-install-rules-for-cryptodev-test.patch
+++ /dev/null
@@ -1,69 +0,0 @@ 
-From 1980a8f4779a955e73285e7a0d86549b69bea5c8 Mon Sep 17 00:00:00 2001
-From: Yu Zongchun <b40527@freescale.com>
-Date: Sun, 28 Apr 2013 14:39:22 +0800
-Subject: [PATCH] Add the compile and install rules for cryptodev tests folder
-
-This is required to install the cryptodev tests folder to rootfs
-
-Signed-off-by: Yu Zongchun <b40527@freescale.com>
-
-Upstream-Status: Pending
-
----
- Makefile       |    6 ++++++
- tests/Makefile |    8 ++++++++
- 2 files changed, 14 insertions(+), 0 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index 2be8825..4cbb865 100644
---- a/Makefile
-+++ b/Makefile
-@@ -17,6 +17,9 @@ install:
- 	@echo "Installing cryptodev.h in /usr/include/crypto ..."
- 	@install -D crypto/cryptodev.h /usr/include/crypto/cryptodev.h
- 
-+install_tests:
-+	make -C tests install DESTDIR=$(PREFIX)
-+
- clean:
- 	make -C $(KERNEL_DIR) SUBDIRS=`pwd` clean
- 	rm -f $(hostprogs) *~
-@@ -25,6 +28,9 @@ clean:
- check:
- 	KERNEL_DIR=$(KERNEL_DIR) make -C tests check
- 
-+testprogs:
-+	KERNEL_DIR=$(KERNEL_DIR) make -C tests testprogs
-+
- FILEBASE = cryptodev-linux-$(VERSION)
- TMPDIR ?= /tmp
- OUTPUT = $(FILEBASE).tar.gz
-diff --git a/tests/Makefile b/tests/Makefile
-index 87ca3c7..0488cf6 100644
---- a/tests/Makefile
-+++ b/tests/Makefile
-@@ -19,6 +19,12 @@ example-async-hmac-objs := async_hmac.o
- example-async-speed-objs := async_speed.o
- example-hashcrypt-speed-objs := hashcrypt_speed.c
- 
-+install:
-+	install -d  $(DESTDIR)/usr/bin/tests_cryptodev
-+	for bin in $(hostprogs); do \
-+		install -m 755 $${bin} $(DESTDIR)/usr/bin/tests_cryptodev/; \
-+	done
-+
- check: $(hostprogs)
- 	./cipher
- 	./hmac
-@@ -28,6 +34,8 @@ check: $(hostprogs)
- 	./cipher-gcm
- 	./cipher-aead
- 
-+testprogs: $(hostprogs)
-+
- clean:
- 	rm -f *.o *~ $(hostprogs)
- 
--- 
-1.7.5.4
-
diff --git a/recipes-kernel/cryptodev/files/makefile_fixup.patch b/recipes-kernel/cryptodev/files/makefile_fixup.patch
deleted file mode 100644
index 323aacd..0000000
--- a/recipes-kernel/cryptodev/files/makefile_fixup.patch
+++ /dev/null
@@ -1,26 +0,0 @@ 
-diff --git a/Makefile b/Makefile
-index 2be8825..b36d68c 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,7 @@
- KBUILD_CFLAGS += -I$(src)
- KERNEL_DIR = /lib/modules/$(shell uname -r)/build
- VERSION = 1.5
-+PREFIX =
- 
- cryptodev-objs = ioctl.o main.o cryptlib.o authenc.o zc.o util.o
- 
-@@ -12,10 +13,10 @@ build: version.h
- version.h: Makefile
- 	@echo "#define VERSION \"$(VERSION)\"" > version.h
- 
--install:
-+modules_install:
- 	make -C $(KERNEL_DIR) SUBDIRS=`pwd` modules_install
--	@echo "Installing cryptodev.h in /usr/include/crypto ..."
--	@install -D crypto/cryptodev.h /usr/include/crypto/cryptodev.h
-+	@echo "Installing cryptodev.h in $(PREFIX)/usr/include/crypto ..."
-+	@install -D crypto/cryptodev.h $(PREFIX)/usr/include/crypto/cryptodev.h
- 
- clean:
- 	make -C $(KERNEL_DIR) SUBDIRS=`pwd` clean