aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel/cryptodev/sdk_patches
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/cryptodev/sdk_patches')
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch52
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0001-don-t-advertise-RSA-keygen.patch33
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch207
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0003-PKC-support-added-in-cryptodev-module.patch898
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0004-Compat-versions-of-PKC-IOCTLs.patch200
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0005-Asynchronous-interface-changes-in-cryptodev.patch213
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch212
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch238
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0008-Add-RSA-Key-generation-offloading.patch170
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch160
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0010-add-support-for-composite-TLS10-SHA1-3DES-algorithm-.patch54
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0011-add-support-for-TLSv1.1-record-offload.patch76
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0012-add-support-for-TLSv1.2-record-offload.patch72
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0013-clean-up-code-layout.patch186
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0014-remove-redundant-data-copy-for-pkc-operations.patch494
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0015-fix-pkc-request-deallocation.patch40
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0016-add-basic-detection-of-asym-features.patch37
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0017-remove-dead-code.patch67
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0018-fix-compat-warnings.patch64
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0019-fix-size_t-print-format.patch61
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0020-fix-uninitialized-variable-compiler-warning.patch38
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0021-check-return-codes-for-copy-to-from-user-functions.patch398
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0022-fix-double-free-pkc-req-on-error.patch26
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0023-remove-MAY_BACKLOG-flag-from-requests.patch69
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0024-fix-COMPAT_CIOCKEY-ioctl-command-number.patch29
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0025-fix-benchmarks-linking.patch25
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0026-fix-Makefile-to-allow-parallel-make-with-j-option.patch56
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0027-use-Linux-kernel-conventions-for-Makefile-variables.patch47
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0028-for-consistency-use-.-instead-of-.-in-makefiles.patch73
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0029-fix-clean-up-on-error-path-for-crypto_create_session.patch117
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0030-remove-code-duplication-in-cryptodev_hash_init.patch59
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0031-fix-comment-typo.patch26
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0032-avoid-calls-to-kmalloc-on-hotpaths.patch220
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0033-avoid-unnecessary-checks-for-hash-clean-up.patch33
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0034-extend-API-with-CIOCHASH-to-support-direct-hash-oper.patch114
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch315
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0036-add-compat-for-CIOCHASH-operation.patch120
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0037-rewrite-sha_speed.c-to-reduce-code-duplication.patch190
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0038-extend-sha_speed.c-to-test-CIOCHASH.patch143
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0039-fix-memory-leaks-on-error-path-for-CIOCHASH.patch70
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0040-fix-structure-init-in-sha_speed-test.patch53
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0041-add-separate-target-for-building-tests.patch38
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0042-fix-destination-for-staged-installs.patch55
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0043-add-install-target-for-tests.patch46
44 files changed, 5894 insertions, 0 deletions
diff --git a/recipes-kernel/cryptodev/sdk_patches/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch b/recipes-kernel/cryptodev/sdk_patches/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch
new file mode 100644
index 00000000..b8d2a001
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch
@@ -0,0 +1,52 @@
+From 25a68839e3aab5acebcbe51f7fbe9d2d26216bc0 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 01/38] add support for composite TLS10(SHA1,AES) algorithm
+ offload
+
+This adds support for composite algorithm offload as a primitive
+crypto (cipher + hmac) operation.
+
+It requires kernel support for tls10(hmac(sha1),cbc(aes)) algorithm
+provided either in software or accelerated by hardware such as
+Freescale B*, P* and T* platforms.
+
+Change-Id: Ia1c605da3860e91e681295dfc8df7c09eb4006cf
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Reviewed-on: http://git.am.freescale.net:8181/17218
+---
+ 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 b23f5fd..a3f8379 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -159,6 +159,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;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0001-don-t-advertise-RSA-keygen.patch b/recipes-kernel/cryptodev/sdk_patches/0001-don-t-advertise-RSA-keygen.patch
new file mode 100644
index 00000000..10d6c8b5
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0001-don-t-advertise-RSA-keygen.patch
@@ -0,0 +1,33 @@
+From d30c9c64aca4a7905e1b7eb3e28e1c616191bd34 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Tue, 9 Dec 2014 16:41:25 +0200
+Subject: [PATCH] don't advertise RSA keygen
+
+Disable RSA keygen operations when they are not available.
+
+Currently no testing can be done and this patch should be applied
+selectively on platforms that have incomplete support for RSA operations
+(for example pkc driver on C293)
+
+Change-Id: Ic8df014623410c3cf4b0b217a246efcea8f2eeef
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ ioctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index 53dbf64..27dc66e 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -979,7 +979,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ case CIOCASYMFEAT:
+ ses = 0;
+ if (crypto_has_alg("pkc(rsa)", 0, 0))
+- ses = CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_RSA_GENERATE_KEY;
++ ses = CRF_MOD_EXP_CRT | CRF_MOD_EXP ;
+ if (crypto_has_alg("pkc(dsa)", 0, 0))
+ ses |= CRF_DSA_SIGN | CRF_DSA_VERIFY | CRF_DSA_GENERATE_KEY;
+ if (crypto_has_alg("pkc(dh)", 0, 0))
+--
+2.3.5
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch b/recipes-kernel/cryptodev/sdk_patches/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch
new file mode 100644
index 00000000..d83da974
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch
@@ -0,0 +1,207 @@
+From d9f27d08708556e22e1b1dc87b0495896879ca66 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 02/38] add support for COMPAT_CIOCAUTHCRYPT ioctl()
+
+Upstream-status: Pending
+
+Needed for 64b kernel with 32b user space.
+
+Change-Id: I44a999a4164e7ae7122dee6ed0716b2f25cadbc1
+Signed-off-by: Horia Geanta <horia.geanta@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ authenc.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ cryptodev_int.h | 40 +++++++++++++++++++++++++++++
+ ioctl.c | 16 ++++++++++++
+ 3 files changed, 134 insertions(+)
+
+diff --git a/authenc.c b/authenc.c
+index 1bd7377..ef0d3db 100644
+--- a/authenc.c
++++ b/authenc.c
+@@ -272,6 +272,84 @@ 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->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->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..8e687e7 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -73,11 +73,42 @@ 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 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 +139,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 a3f8379..5a44807 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -998,6 +998,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))
+@@ -1040,6 +1041,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)))
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0003-PKC-support-added-in-cryptodev-module.patch b/recipes-kernel/cryptodev/sdk_patches/0003-PKC-support-added-in-cryptodev-module.patch
new file mode 100644
index 00000000..ffa0b453
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0003-PKC-support-added-in-cryptodev-module.patch
@@ -0,0 +1,898 @@
+From 2bda43095b511e0052b3bc27b216ff9909cc03d2 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 03/38] 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 44ce763..6900028 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;
+@@ -259,7 +256,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.
+@@ -439,3 +435,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 a0a8a63..56d325a 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, size_t 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 c0e8cd4..96675fe 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
+@@ -245,6 +249,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 {
+@@ -289,5 +296,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 8e687e7..fdbcc61 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
+
+@@ -112,6 +114,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;
+@@ -157,6 +167,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 5a44807..69980e3 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.
+ *
+@@ -89,8 +90,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); \
+@@ -472,7 +502,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);
+@@ -639,6 +670,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)
+ {
+@@ -662,11 +766,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;
+@@ -692,6 +793,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)
+ {
+@@ -821,7 +941,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);
+@@ -857,6 +978,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");
+@@ -895,6 +1034,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;
+ }
+@@ -1083,9 +1261,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;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0004-Compat-versions-of-PKC-IOCTLs.patch b/recipes-kernel/cryptodev/sdk_patches/0004-Compat-versions-of-PKC-IOCTLs.patch
new file mode 100644
index 00000000..e963f589
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0004-Compat-versions-of-PKC-IOCTLs.patch
@@ -0,0 +1,200 @@
+From e0e5c1bfb21888bf9f87f72ac8cdf7eee951f619 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 04/38] 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 fdbcc61..cf54dac 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 */
+@@ -111,6 +129,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 69980e3..9431025 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -1081,6 +1081,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)
+ {
+@@ -1208,7 +1270,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))
+@@ -1247,6 +1328,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;
+ }
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0005-Asynchronous-interface-changes-in-cryptodev.patch b/recipes-kernel/cryptodev/sdk_patches/0005-Asynchronous-interface-changes-in-cryptodev.patch
new file mode 100644
index 00000000..5b96e841
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0005-Asynchronous-interface-changes-in-cryptodev.patch
@@ -0,0 +1,213 @@
+From d98f979d76c30058da24e62220f19c5b8c627819 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 05/38] 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 56d325a..7ffa54c 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 96675fe..4436fbf 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -254,6 +254,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,
+@@ -298,5 +306,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 cf54dac..5347cae 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 */
+@@ -126,11 +132,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 9431025..e2f407f 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -105,8 +105,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;
+@@ -1051,26 +1049,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:
+@@ -1345,26 +1358,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:
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch b/recipes-kernel/cryptodev/sdk_patches/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch
new file mode 100644
index 00000000..978efd16
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch
@@ -0,0 +1,212 @@
+From b92d23a790d9634d52db3b9a5e1882fde620b073 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 06/38] 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 6900028..47cd568 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -452,6 +452,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 4436fbf..275a55c 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -268,6 +268,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
+ };
+
+@@ -280,7 +282,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 e2f407f..1f0741a 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -726,6 +726,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;
+ }
+@@ -939,8 +956,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);
+@@ -1084,7 +1102,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;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch b/recipes-kernel/cryptodev/sdk_patches/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch
new file mode 100644
index 00000000..cfaabaec
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch
@@ -0,0 +1,238 @@
+From 00a8ac310a33767eac0a07e32597c1a6f467315f 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 07/38] 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 1f0741a..e4e16a8 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -108,10 +108,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);
+ }
+@@ -958,7 +957,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);
+@@ -997,7 +996,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;
+@@ -1053,7 +1052,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))
+@@ -1070,13 +1069,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 */
+@@ -1084,6 +1082,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++;
+@@ -1093,10 +1092,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)
+@@ -1386,14 +1385,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 */
+@@ -1401,6 +1399,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++;
+@@ -1409,10 +1408,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;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0008-Add-RSA-Key-generation-offloading.patch b/recipes-kernel/cryptodev/sdk_patches/0008-Add-RSA-Key-generation-offloading.patch
new file mode 100644
index 00000000..ef4ea091
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0008-Add-RSA-Key-generation-offloading.patch
@@ -0,0 +1,170 @@
+From a2cbb5fcc2d6f3734b5ed2826e828d852cfdf8ba Mon Sep 17 00:00:00 2001
+From: Hou Zhiqiang <B48286@freescale.com>
+Date: Wed, 19 Mar 2014 14:02:46 +0800
+Subject: [PATCH 08/38] 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 47cd568..4dd1847 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -441,6 +441,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 275a55c..d0cc542 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -270,6 +270,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
+ };
+
+@@ -279,6 +280,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 e4e16a8..3762a47 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -957,7 +957,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;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch b/recipes-kernel/cryptodev/sdk_patches/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch
new file mode 100644
index 00000000..47fd2e16
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch
@@ -0,0 +1,160 @@
+From 263483d1023f6c1c35b5488b9b79796ee2605e9b 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 09/38] 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>
+---
+ authenc.c | 1 +
+ cryptlib.c | 9 ++++-----
+ crypto/cryptodev.h | 9 ++++++++-
+ cryptodev_int.h | 2 +-
+ ioctl.c | 8 ++++++--
+ main.c | 1 +
+ 6 files changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/authenc.c b/authenc.c
+index ef0d3db..2aa4d38 100644
+--- a/authenc.c
++++ b/authenc.c
+@@ -2,6 +2,7 @@
+ * Driver for /dev/crypto device (aka CryptoDev)
+ *
+ * Copyright (c) 2011, 2012 OpenSSL Software Foundation, Inc.
++ * Copyright (c) 2014 Freescale Semiconductor, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+diff --git a/cryptlib.c b/cryptlib.c
+index 4dd1847..ec6693e 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -4,8 +4,7 @@
+ * Copyright (c) 2010,2011 Nikos Mavrogiannopoulos <nmav@gnutls.org>
+ * Portions Copyright (c) 2010 Michael Weiser
+ * Portions Copyright (c) 2010 Phil Sutter
+- *
+- * Copyright 2012 Freescale Semiconductor, Inc.
++ * Copyright 2012-2014 Freescale Semiconductor, Inc.
+ *
+ * This file is part of linux cryptodev.
+ *
+@@ -144,7 +143,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;
+@@ -171,7 +170,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;
+ }
+@@ -338,7 +337,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 d0cc542..e7edd97 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -234,6 +234,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;
+@@ -249,7 +256,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 5347cae..c83c885 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 3762a47..c97320b 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -4,7 +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.
++ * Copyright 2012-2014 Freescale Semiconductor, Inc.
+ *
+ * This file is part of linux cryptodev.
+ *
+@@ -501,6 +501,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);
+@@ -780,8 +781,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;
+diff --git a/main.c b/main.c
+index 14dcf40..6365911 100644
+--- a/main.c
++++ b/main.c
+@@ -3,6 +3,7 @@
+ *
+ * Copyright (c) 2004 Michal Ludvig <mludvig@logix.net.nz>, SuSE Labs
+ * Copyright (c) 2009-2013 Nikos Mavrogiannopoulos <nmav@gnutls.org>
++ * Copyright (c) 2014 Freescale Semiconductor, Inc.
+ *
+ * This file is part of linux cryptodev.
+ *
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0010-add-support-for-composite-TLS10-SHA1-3DES-algorithm-.patch b/recipes-kernel/cryptodev/sdk_patches/0010-add-support-for-composite-TLS10-SHA1-3DES-algorithm-.patch
new file mode 100644
index 00000000..352a45d2
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0010-add-support-for-composite-TLS10-SHA1-3DES-algorithm-.patch
@@ -0,0 +1,54 @@
+From 269564f4e00fa907388ccfa046b930b3c4eef4dc Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@freescale.com>
+Date: Tue, 10 Jun 2014 08:27:59 +0300
+Subject: [PATCH 10/38] add support for composite TLS10(SHA1,3DES) algorithm
+ offload
+
+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.
+
+Change-Id: Ibce0ceb4174809c9c96b453cd3202bc5220ff084
+Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com>
+Reviewed-on: http://git.am.freescale.net:8181/34000
+Reviewed-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@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 e7edd97..07f40b2 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -55,6 +55,7 @@ enum cryptodev_crypto_op_t {
+ CRYPTO_SHA2_512,
+ CRYPTO_SHA2_224_HMAC,
+ CRYPTO_TLS10_AES_CBC_HMAC_SHA1,
++ CRYPTO_TLS10_3DES_CBC_HMAC_SHA1,
+ CRYPTO_ALGORITHM_ALL, /* Keep updated - see below */
+ };
+
+diff --git a/ioctl.c b/ioctl.c
+index c97320b..574e913 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -191,6 +191,11 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ stream = 0;
+ aead = 1;
+ break;
++ case CRYPTO_TLS10_3DES_CBC_HMAC_SHA1:
++ alg_name = "tls10(hmac(sha1),cbc(des3_ede))";
++ stream = 0;
++ aead = 1;
++ break;
+ case CRYPTO_NULL:
+ alg_name = "ecb(cipher_null)";
+ stream = 1;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0011-add-support-for-TLSv1.1-record-offload.patch b/recipes-kernel/cryptodev/sdk_patches/0011-add-support-for-TLSv1.1-record-offload.patch
new file mode 100644
index 00000000..34d6ade0
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0011-add-support-for-TLSv1.1-record-offload.patch
@@ -0,0 +1,76 @@
+From 73c20be9ae1ed57d8c428c86471f42d953e79fba Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@freescale.com>
+Date: Tue, 31 Mar 2015 16:15:47 +0300
+Subject: [PATCH 11/38] add support for TLSv1.1 record offload
+
+This adds support for composite algorithm offload in a single crypto
+(cipher + hmac) operation.
+
+Supported cipher suites:
+- 3des-ede-cbc-sha
+- aes-128-cbc-hmac-sha
+- aes-256-cbc-hmac-sha
+
+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: Tudor Ambarus <tudor.ambarus@freescale.com>
+Change-Id: Ia5f3fa7ec090d5643d71b0f608c68a274ec6b51f
+Reviewed-on: http://git.am.freescale.net:8181/33998
+Reviewed-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ crypto/cryptodev.h | 4 +++-
+ ioctl.c | 14 ++++++++++++--
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index 07f40b2..61e8599 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -54,8 +54,10 @@ enum cryptodev_crypto_op_t {
+ CRYPTO_SHA2_384,
+ CRYPTO_SHA2_512,
+ CRYPTO_SHA2_224_HMAC,
+- CRYPTO_TLS10_AES_CBC_HMAC_SHA1,
+ CRYPTO_TLS10_3DES_CBC_HMAC_SHA1,
++ CRYPTO_TLS10_AES_CBC_HMAC_SHA1,
++ CRYPTO_TLS11_3DES_CBC_HMAC_SHA1,
++ CRYPTO_TLS11_AES_CBC_HMAC_SHA1,
+ CRYPTO_ALGORITHM_ALL, /* Keep updated - see below */
+ };
+
+diff --git a/ioctl.c b/ioctl.c
+index 574e913..ba82387 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -186,13 +186,23 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ stream = 1;
+ aead = 1;
+ break;
++ case CRYPTO_TLS10_3DES_CBC_HMAC_SHA1:
++ alg_name = "tls10(hmac(sha1),cbc(des3_ede))";
++ stream = 0;
++ aead = 1;
++ break;
+ case CRYPTO_TLS10_AES_CBC_HMAC_SHA1:
+ alg_name = "tls10(hmac(sha1),cbc(aes))";
+ stream = 0;
+ aead = 1;
+ break;
+- case CRYPTO_TLS10_3DES_CBC_HMAC_SHA1:
+- alg_name = "tls10(hmac(sha1),cbc(des3_ede))";
++ case CRYPTO_TLS11_3DES_CBC_HMAC_SHA1:
++ alg_name = "tls11(hmac(sha1),cbc(des3_ede))";
++ stream = 0;
++ aead = 1;
++ break;
++ case CRYPTO_TLS11_AES_CBC_HMAC_SHA1:
++ alg_name = "tls11(hmac(sha1),cbc(aes))";
+ stream = 0;
+ aead = 1;
+ break;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0012-add-support-for-TLSv1.2-record-offload.patch b/recipes-kernel/cryptodev/sdk_patches/0012-add-support-for-TLSv1.2-record-offload.patch
new file mode 100644
index 00000000..b7a72683
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0012-add-support-for-TLSv1.2-record-offload.patch
@@ -0,0 +1,72 @@
+From f1a519d9eed072bd45a45d251603c64f942814fb Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@freescale.com>
+Date: Tue, 31 Mar 2015 16:16:28 +0300
+Subject: [PATCH 12/38] add support for TLSv1.2 record offload
+
+This adds support for composite algorithm offload in a single crypto
+(cipher + hmac) operation.
+
+Supported cipher suites:
+- 3des-ede-cbc-sha
+- aes-128-cbc-hmac-sha
+- aes-256-cbc-hmac-sha
+- aes-128-cbc-hmac-sha256
+- aes-256-cbc-hmac-sha256
+
+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: Tudor Ambarus <tudor.ambarus@freescale.com>
+Change-Id: I21f45993505fc3dad09848a13aa20f778a7c2de0
+Reviewed-on: http://git.am.freescale.net:8181/33999
+Reviewed-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ crypto/cryptodev.h | 3 +++
+ ioctl.c | 15 +++++++++++++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index 61e8599..f6058ca 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -58,6 +58,9 @@ enum cryptodev_crypto_op_t {
+ CRYPTO_TLS10_AES_CBC_HMAC_SHA1,
+ CRYPTO_TLS11_3DES_CBC_HMAC_SHA1,
+ CRYPTO_TLS11_AES_CBC_HMAC_SHA1,
++ CRYPTO_TLS12_3DES_CBC_HMAC_SHA1,
++ CRYPTO_TLS12_AES_CBC_HMAC_SHA1,
++ CRYPTO_TLS12_AES_CBC_HMAC_SHA256,
+ CRYPTO_ALGORITHM_ALL, /* Keep updated - see below */
+ };
+
+diff --git a/ioctl.c b/ioctl.c
+index ba82387..fb4c4e3 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -206,6 +206,21 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ stream = 0;
+ aead = 1;
+ break;
++ case CRYPTO_TLS12_3DES_CBC_HMAC_SHA1:
++ alg_name = "tls12(hmac(sha1),cbc(des3_ede))";
++ stream = 0;
++ aead = 1;
++ break;
++ case CRYPTO_TLS12_AES_CBC_HMAC_SHA1:
++ alg_name = "tls12(hmac(sha1),cbc(aes))";
++ stream = 0;
++ aead = 1;
++ break;
++ case CRYPTO_TLS12_AES_CBC_HMAC_SHA256:
++ alg_name = "tls12(hmac(sha256),cbc(aes))";
++ stream = 0;
++ aead = 1;
++ break;
+ case CRYPTO_NULL:
+ alg_name = "ecb(cipher_null)";
+ stream = 1;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0013-clean-up-code-layout.patch b/recipes-kernel/cryptodev/sdk_patches/0013-clean-up-code-layout.patch
new file mode 100644
index 00000000..a6884fa8
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0013-clean-up-code-layout.patch
@@ -0,0 +1,186 @@
+From 5a87b9d5f2295ed0fd36a41c8376e01eb0df62b2 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Fri, 20 Feb 2015 12:46:58 +0200
+Subject: [PATCH 13/38] clean-up code layout
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Change-Id: I92c2f4baeed9470a2c3c42b592d878e65918b0af
+Reviewed-on: http://git.am.freescale.net:8181/34222
+---
+ cryptlib.c | 11 ++++-------
+ ioctl.c | 55 +++++++++++++++++++++----------------------------------
+ main.c | 4 +---
+ 3 files changed, 26 insertions(+), 44 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index ec6693e..21e691b 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -434,7 +434,7 @@ 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 cryptodev_pkc_offload(struct cryptodev_pkc *pkc)
+ {
+ int ret = 0;
+ struct pkc_request *pkc_req = &pkc->req, *pkc_requested;
+@@ -445,8 +445,7 @@ int cryptodev_pkc_offload(struct cryptodev_pkc *pkc)
+ 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);
++ pkc->s = crypto_alloc_pkc("pkc(rsa)", CRYPTO_ALG_TYPE_PKC_RSA, 0);
+ break;
+ case DSA_SIGN:
+ case DSA_VERIFY:
+@@ -454,13 +453,11 @@ int cryptodev_pkc_offload(struct cryptodev_pkc *pkc)
+ case ECDSA_VERIFY:
+ case DLC_KEYGEN:
+ case ECC_KEYGEN:
+- pkc->s = crypto_alloc_pkc("pkc(dsa)",
+- CRYPTO_ALG_TYPE_PKC_DSA, 0);
++ 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);
++ pkc->s = crypto_alloc_pkc("pkc(dh)", CRYPTO_ALG_TYPE_PKC_DH, 0);
+ break;
+ default:
+ return -EINVAL;
+diff --git a/ioctl.c b/ioctl.c
+index fb4c4e3..ee0486c 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -714,16 +714,13 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ 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);
++ 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);
++ 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:
+@@ -731,15 +728,11 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ 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);
++ 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);
++ 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;
+@@ -749,11 +742,9 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ {
+ 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);
++ 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);
++ copy_to_user(ckop->crk_param[3].crp_p, dh_req->z, dh_req->z_len);
+ }
+ break;
+ case CRK_DSA_GENERATE_KEY:
+@@ -763,14 +754,14 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+
+ 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);
++ 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);
++ 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:
+@@ -1113,16 +1104,14 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ 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,
++ pkc = 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++;
+- cookie_list.cookie[i] =
+- pkc->kop.kop.cookie;
++ cookie_list.cookie[i] = pkc->kop.kop.cookie;
+ cookie_list.status[i] = pkc->result.err;
+ }
+ kfree(pkc);
+@@ -1133,12 +1122,10 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ }
+
+ /* Reflect the updated request to user-space */
+- if (cookie_list.cookie_available)
+- copy_to_user(arg, &cookie_list,
+- sizeof(struct pkc_cookie_list_s));
+- else {
++ 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;
+diff --git a/main.c b/main.c
+index 6365911..af66553 100644
+--- a/main.c
++++ b/main.c
+@@ -666,9 +666,7 @@ int crypto_bn_modexp(struct cryptodev_pkc *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);
++ copy_to_user(cop->crk_param[3].crp_p, rsa_req->g, rsa_req->g_len);
+ } else {
+ if (rc != -EINPROGRESS && rc != 0)
+ goto err;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0014-remove-redundant-data-copy-for-pkc-operations.patch b/recipes-kernel/cryptodev/sdk_patches/0014-remove-redundant-data-copy-for-pkc-operations.patch
new file mode 100644
index 00000000..58d37fa8
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0014-remove-redundant-data-copy-for-pkc-operations.patch
@@ -0,0 +1,494 @@
+From a4d88e5379ddb7d9bceac3141f508b8173d1e902 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Mon, 23 Feb 2015 12:14:07 +0200
+Subject: [PATCH 14/38] remove redundant data copy for pkc operations
+
+This patch removes a copy of a pkc request that was
+allocated on the hot-path. The copy was not necessary
+and was just slowing things down.
+
+Change-Id: I3ad85f78c188f100ab9fc03a5777bb704a9dcb63
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Reviewed-on: http://git.am.freescale.net:8181/34223
+---
+ cryptlib.c | 49 +++----------------
+ cryptlib.h | 3 +-
+ ioctl.c | 17 +++----
+ main.c | 162 +++++++++++++++++++++++++++++++++++++------------------------
+ 4 files changed, 113 insertions(+), 118 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index 21e691b..5882a30 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -436,59 +436,22 @@ int cryptodev_hash_final(struct hash_data *hdata, void *output)
+
+ 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_KEYGEN:
+- 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:
+- case DLC_KEYGEN:
+- case ECC_KEYGEN:
+- 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;
++ int ret;
+
+ 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,
++ pkc_request_set_callback(pkc->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ cryptodev_complete_asym, pkc);
+- ret = crypto_pkc_op(pkc_requested);
++ ret = crypto_pkc_op(pkc->req);
+ if (ret != -EINPROGRESS && ret != 0)
+- goto error2;
++ goto error;
+
+ if (pkc->type == SYNCHRONOUS)
+ ret = waitfor(&pkc->result, ret);
+
+ return ret;
+-error2:
+- kfree(pkc_requested);
++
+ error:
++ kfree(pkc->req);
+ crypto_free_pkc(pkc->s);
+ return ret;
+ }
+diff --git a/cryptlib.h b/cryptlib.h
+index 7ffa54c..4fac0c8 100644
+--- a/cryptlib.h
++++ b/cryptlib.h
+@@ -110,8 +110,7 @@ struct cryptodev_pkc {
+ 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 */
++ struct pkc_request *req; /* PKC request allocated from CryptoAPI */
+ enum offload_type type; /* Synchronous Vs Asynchronous request */
+ /*
+ * cookie used for transfering tranparent information from async
+diff --git a/ioctl.c b/ioctl.c
+index ee0486c..797b73c 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -708,26 +708,25 @@ 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;
++ 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;
++ 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;
++ struct dsa_sign_req_s *dsa_req = &pkc->req->req_u.dsa_sign;
+
+- if (pkc_req->type == ECDSA_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 {
+@@ -740,8 +739,8 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ 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)
++ 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);
+@@ -750,9 +749,9 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ case CRK_DSA_GENERATE_KEY:
+ case CRK_DH_GENERATE_KEY:
+ {
+- struct keygen_req_s *key_req = &pkc_req->req_u.keygen;
++ struct keygen_req_s *key_req = &pkc->req->req_u.keygen;
+
+- if (pkc_req->type == ECC_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,
+diff --git a/main.c b/main.c
+index af66553..ed1c69a 100644
+--- a/main.c
++++ b/main.c
+@@ -186,8 +186,7 @@ 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;
++ struct dsa_sign_req_s *dsa_req = &pkc->req->req_u.dsa_sign;
+ int rc, buf_size;
+ uint8_t *buf;
+
+@@ -210,10 +209,7 @@ int crypto_kop_dsasign(struct cryptodev_pkc *pkc)
+ 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;
++ pkc->req->curve_type = cop->curve_type;
+ }
+
+ buf = kmalloc(buf_size, GFP_DMA);
+@@ -269,7 +265,6 @@ 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;
+@@ -281,8 +276,7 @@ int crypto_kop_dsaverify(struct cryptodev_pkc *pkc)
+ !cop->crk_param[7].crp_nbits))
+ return -EINVAL;
+
+- pkc_req = &pkc->req;
+- dsa_req = &pkc_req->req_u.dsa_verify;
++ 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;
+@@ -295,10 +289,7 @@ int crypto_kop_dsaverify(struct cryptodev_pkc *pkc)
+ 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;
++ pkc->req->curve_type = cop->curve_type;
+ }
+
+ buf = kmalloc(buf_size, GFP_DMA);
+@@ -351,7 +342,6 @@ 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;
+@@ -362,9 +352,7 @@ int crypto_kop_rsa_keygen(struct cryptodev_pkc *pkc)
+ !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 = &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;
+@@ -427,7 +415,6 @@ 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;
+@@ -437,8 +424,7 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
+ !cop->crk_param[4].crp_nbits)
+ return -EINVAL;
+
+- pkc_req = &pkc->req;
+- key_req = &pkc_req->req_u.keygen;
++ 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;
+@@ -447,7 +433,6 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
+ 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;
+@@ -455,8 +440,7 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
+ 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;
++ pkc->req->curve_type = cop->curve_type;
+ }
+
+ buf = kmalloc(buf_size, GFP_DMA);
+@@ -508,26 +492,22 @@ 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 = &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 = kmalloc(buf_size, GFP_DMA);
+@@ -539,7 +519,7 @@ int crypto_kop_dh_key(struct cryptodev_pkc *pkc)
+ 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;
++ pkc->req->curve_type = cop->curve_type;
+ copy_from_user(dh_req->ab, cop->crk_param[3].crp_p,
+ dh_req->ab_len);
+ }
+@@ -573,7 +553,6 @@ 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;
+@@ -583,9 +562,7 @@ int crypto_modexp_crt(struct cryptodev_pkc *pkc)
+ !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 = &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;
+@@ -632,7 +609,6 @@ err:
+
+ 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;
+@@ -643,9 +619,7 @@ int crypto_bn_modexp(struct cryptodev_pkc *pkc)
+ !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 = &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;
+@@ -680,56 +654,116 @@ err:
+ return rc;
+ }
+
++static struct {
++ char *alg_name;
++ u32 type;
++ u32 mask;
++} pkc_alg_list[] = {
++ {"pkc(rsa)", CRYPTO_ALG_TYPE_PKC_RSA, 0},
++ {"pkc(dsa)", CRYPTO_ALG_TYPE_PKC_DSA, 0},
++ {"pkc(dh)", CRYPTO_ALG_TYPE_PKC_DH, 0},
++};
++
+ int crypto_run_asym(struct cryptodev_pkc *pkc)
+ {
+- int ret = -EINVAL;
++ int err = -EINVAL;
++ int id;
+ struct kernel_crypt_kop *kop = &pkc->kop;
++ enum pkc_req_type pkc_req_type;
++ int (*call_next_action)(struct cryptodev_pkc *pkc);
+
+ 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);
++ return err;
++ pkc_req_type = RSA_PUB;
++ id = 0;
++ call_next_action = crypto_bn_modexp;
+ break;
+ case CRK_MOD_EXP_CRT:
+ if (kop->kop.crk_iparams != 6 && kop->kop.crk_oparams != 1)
+- goto err;
+-
+- ret = crypto_modexp_crt(pkc);
++ return err;
++ pkc_req_type = RSA_PRIV_FORM3;
++ id = 0;
++ call_next_action = crypto_modexp_crt;
+ 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);
++ if (kop->kop.crk_oparams != 2)
++ return err;
++ else if (kop->kop.crk_iparams == 5)
++ pkc_req_type = DSA_SIGN;
++ else if (kop->kop.crk_iparams == 6)
++ pkc_req_type = ECDSA_SIGN;
++ else
++ return err;
++ id = 1;
++ call_next_action = crypto_kop_dsasign;
+ 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);
++ if (kop->kop.crk_oparams != 0)
++ return err;
++ else if (kop->kop.crk_iparams == 7)
++ pkc_req_type = DSA_VERIFY;
++ else if (kop->kop.crk_iparams == 8)
++ pkc_req_type = ECDSA_VERIFY;
++ else
++ return err;
++ id = 1;
++ call_next_action = crypto_kop_dsaverify;
+ 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);
++ if (kop->kop.crk_oparams != 1)
++ return err;
++ else if (kop->kop.crk_iparams == 3)
++ pkc_req_type = DH_COMPUTE_KEY;
++ else if (kop->kop.crk_iparams == 4)
++ pkc_req_type = ECDH_COMPUTE_KEY;
++ else
++ return err;
++ id = 2;
++ call_next_action = crypto_kop_dh_key;
+ 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);
++ if (kop->kop.crk_iparams == 3)
++ pkc_req_type = DLC_KEYGEN;
++ else if (kop->kop.crk_iparams == 4)
++ pkc_req_type = ECC_KEYGEN;
++ else
++ return err;
++ id = 1;
++ call_next_action = crypto_kop_keygen;
+ break;
+ case CRK_RSA_GENERATE_KEY:
+- ret = crypto_kop_rsa_keygen(pkc);
++ pkc_req_type = RSA_KEYGEN;
++ id = 0;
++ call_next_action = crypto_kop_rsa_keygen;
+ break;
++ default:
++ return err;
+ }
+-err:
+- return ret;
++ err = -ENOMEM;
++ pkc->s = crypto_alloc_pkc(pkc_alg_list[id].alg_name,
++ pkc_alg_list[id].type,
++ pkc_alg_list[id].mask);
++ if (IS_ERR_OR_NULL(pkc->s))
++ return err;
++
++ pkc->req = pkc_request_alloc(pkc->s, GFP_KERNEL);
++ if (IS_ERR_OR_NULL(pkc->req))
++ goto out_free_tfm;
++
++ /* todo - fix alloc-free on error path */
++ pkc->req->type = pkc_req_type;
++ err = call_next_action(pkc);
++ if (pkc->type == SYNCHRONOUS)
++ kfree(pkc->req);
++
++ return err;
++
++out_free_tfm:
++ crypto_free_pkc(pkc->s);
++ return err;
+ }
+
+ int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop)
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0015-fix-pkc-request-deallocation.patch b/recipes-kernel/cryptodev/sdk_patches/0015-fix-pkc-request-deallocation.patch
new file mode 100644
index 00000000..ef189921
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0015-fix-pkc-request-deallocation.patch
@@ -0,0 +1,40 @@
+From 212e418fa7b70c8ba79446006001c574cb9d42f8 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Mon, 23 Feb 2015 15:28:22 +0200
+Subject: [PATCH 15/38] fix pkc request deallocation
+
+The request to be freed is actually pkc->req, and should be done inside
+the fetch ioctl for ASYNC (this patch) and in crypt ioctl for SYNC
+operations.
+
+Change-Id: I6f046f2ebeae4cb513a419996ca96b52e37468ed
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Reviewed-on: http://git.am.freescale.net:8181/34224
+---
+ ioctl.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index 797b73c..da3a842 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -114,8 +114,6 @@ void cryptodev_complete_asym(struct crypto_async_request *req, int err)
+ /* wake for POLLIN */
+ wake_up_interruptible(&pcr->user_waiter);
+ }
+-
+- kfree(req);
+ }
+
+ #define FILL_SG(sg, ptr, len) \
+@@ -1113,6 +1111,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ cookie_list.cookie[i] = pkc->kop.kop.cookie;
+ cookie_list.status[i] = pkc->result.err;
+ }
++ kfree(pkc->req);
+ kfree(pkc);
+ } else {
+ spin_unlock_bh(&pcr->completion_lock);
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0016-add-basic-detection-of-asym-features.patch b/recipes-kernel/cryptodev/sdk_patches/0016-add-basic-detection-of-asym-features.patch
new file mode 100644
index 00000000..9301349a
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0016-add-basic-detection-of-asym-features.patch
@@ -0,0 +1,37 @@
+From 4ce4081d9abef651473e9d7e089a0748f77db631 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Mon, 20 Apr 2015 13:18:47 +0300
+Subject: [PATCH 16/38] add basic detection of asym features
+
+Change-Id: I3b3ba8664bf631a63be1f11e715024509e20f841
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ ioctl.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index da3a842..53dbf64 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -977,10 +977,14 @@ 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 |
+- CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY |
+- CRF_RSA_GENERATE_KEY, p);
++ ses = 0;
++ if (crypto_has_alg("pkc(rsa)", 0, 0))
++ ses = CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_RSA_GENERATE_KEY;
++ if (crypto_has_alg("pkc(dsa)", 0, 0))
++ ses |= CRF_DSA_SIGN | CRF_DSA_VERIFY | CRF_DSA_GENERATE_KEY;
++ if (crypto_has_alg("pkc(dh)", 0, 0))
++ ses |= CRF_DH_COMPUTE_KEY |CRF_DH_GENERATE_KEY;
++ return put_user(ses, p);
+ case CRIOGET:
+ fd = clonefd(filp);
+ ret = put_user(fd, p);
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0017-remove-dead-code.patch b/recipes-kernel/cryptodev/sdk_patches/0017-remove-dead-code.patch
new file mode 100644
index 00000000..07c389c7
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0017-remove-dead-code.patch
@@ -0,0 +1,67 @@
+From 0ca641091b4113d73e75d30ef530c88836849308 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@freescale.com>
+Date: Fri, 29 May 2015 15:28:47 +0300
+Subject: [PATCH 17/38] remove dead code
+
+Functions kop_to_user and compat_kop_to_user are never used. Delete them
+to avoid compiler warnings.
+
+
+crypto/../../cryptodev-linux/ioctl.c:841:12: warning: 'kop_to_user' defined but not used [-Wunused-function]
+ static int kop_to_user(struct kernel_crypt_kop *kop,
+ ^
+crypto/../../cryptodev-linux/ioctl.c: At top level:
+crypto/../../cryptodev-linux/ioctl.c:1195:12: warning: 'compat_kop_to_user' defined but not used [-Wunused-function]
+ static int compat_kop_to_user(struct kernel_crypt_kop *kop, void __user *arg)
+ ^
+Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com>
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+Change-Id: I6bd8a7eb6144224a20cd400813ab15a7a192dbb1
+Reviewed-on: http://git.am.freescale.net:8181/37440
+---
+ ioctl.c | 22 ----------------------
+ 1 file changed, 22 deletions(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index 53dbf64..39635a4 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -838,16 +838,6 @@ static int kop_from_user(struct kernel_crypt_kop *kop,
+ 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)
+ {
+@@ -1192,18 +1182,6 @@ static inline void crypt_kop_to_compat(struct crypt_kop *kop,
+ 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)
+ {
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0018-fix-compat-warnings.patch b/recipes-kernel/cryptodev/sdk_patches/0018-fix-compat-warnings.patch
new file mode 100644
index 00000000..b0fcf0f6
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0018-fix-compat-warnings.patch
@@ -0,0 +1,64 @@
+From 596378a22532908487f2c5e4d717c5ae618c4c7d Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@freescale.com>
+Date: Tue, 2 Jun 2015 10:44:12 +0300
+Subject: [PATCH 18/38] fix compat warnings
+
+ CC [M] crypto/../../cryptodev-linux/ioctl.o
+crypto/../../cryptodev-linux/ioctl.c: In function 'compat_to_crypt_kop':
+crypto/../../cryptodev-linux/ioctl.c:1161:14: warning: assignment makes pointer from integer without a cast
+ kop->cookie = compat->cookie;
+ ^
+crypto/../../cryptodev-linux/ioctl.c: In function 'crypt_kop_to_compat':
+crypto/../../cryptodev-linux/ioctl.c:1191:17: warning: assignment makes integer from pointer without a cast
+ compat->cookie = kop->cookie;
+ ^
+crypto/../../cryptodev-linux/ioctl.c: In function 'cryptodev_compat_ioctl':
+crypto/../../cryptodev-linux/ioctl.c:1430:28: warning: assignment makes integer from pointer without a cast
+ cookie_list.cookie[i] =
+ ^
+
+Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com>
+Change-Id: Id851408c0c743c01447f3b0ced38fbc1ae94d4db
+Reviewed-on: http://git.am.freescale.net:8181/37442
+Reviewed-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ ioctl.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index 39635a4..f3ce2f6 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -1148,7 +1148,7 @@ static inline void compat_to_crypt_kop(struct compat_crypt_kop *compat,
+ }
+
+ kop->curve_type = compat->curve_type;
+- kop->cookie = compat->cookie;
++ kop->cookie = compat_ptr(compat->cookie);
+ }
+
+ static int compat_kop_from_user(struct kernel_crypt_kop *kop,
+@@ -1178,7 +1178,7 @@ static inline void crypt_kop_to_compat(struct crypt_kop *kop,
+ 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->cookie = ptr_to_compat(kop->cookie);
+ compat->curve_type = kop->curve_type;
+ }
+
+@@ -1405,8 +1405,8 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ ret = crypto_async_fetch_asym(pkc);
+ if (!ret) {
+ cookie_list.cookie_available++;
+- cookie_list.cookie[i] =
+- pkc->kop.kop.cookie;
++ cookie_list.cookie[i] = ptr_to_compat(
++ pkc->kop.kop.cookie);
+ }
+ kfree(pkc);
+ } else {
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0019-fix-size_t-print-format.patch b/recipes-kernel/cryptodev/sdk_patches/0019-fix-size_t-print-format.patch
new file mode 100644
index 00000000..fdf8c5d3
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0019-fix-size_t-print-format.patch
@@ -0,0 +1,61 @@
+From 1d10f06bef0f07980a08b387850c1daf1d3a8e87 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@freescale.com>
+Date: Tue, 2 Jun 2015 12:11:12 +0300
+Subject: [PATCH 19/38] fix size_t print format
+
+ CC [M] crypto/../../cryptodev-linux/cryptlib.o
+crypto/../../cryptodev-linux/cryptlib.c: In function 'cryptodev_cipher_init':
+crypto/../../cryptodev-linux/cryptlib.c:146:5: warning: format '%u' expects argument of type 'unsigned int', but argument 6 has type 'size_t' [-Wformat=]
+ ddebug(1, "Wrong keylen '%u' for algorithm '%s'. Use %u to %u.",
+ ^
+crypto/../../cryptodev-linux/cryptlib.c:173:3: warning: format '%u' expects argument of type 'unsigned int', but argument 7 has type 'size_t' [-Wformat=]
+ ddebug(1, "Setting key failed for %s-%u.", alg_name, keylen*8);
+ ^
+crypto/../../cryptodev-linux/cryptlib.c: In function 'cryptodev_hash_init':
+crypto/../../cryptodev-linux/cryptlib.c:340:4: warning: format '%u' expects argument of type 'unsigned int', but argument 7 has type 'size_t' [-Wformat=]
+ ddebug(1, "Setting hmac key failed for %s-%u.",
+ ^
+
+Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com>
+Change-Id: I67f2d79f68b4d62b598073c6a918a110523fadfd
+Reviewed-on: http://git.am.freescale.net:8181/37443
+Reviewed-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ cryptlib.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index 5882a30..10f5e1a 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -143,7 +143,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 '%u' for algorithm '%s'. Use %u to %u.",
++ ddebug(1, "Wrong keylen '%zu' for algorithm '%s'. Use %u to %u.",
+ keylen, alg_name, alg->min_keysize, alg->max_keysize);
+ ret = -EINVAL;
+ goto error;
+@@ -170,7 +170,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ }
+
+ if (unlikely(ret)) {
+- ddebug(1, "Setting key failed for %s-%u.", alg_name, keylen*8);
++ ddebug(1, "Setting key failed for %s-%zu.", alg_name, keylen*8);
+ ret = -EINVAL;
+ goto error;
+ }
+@@ -337,7 +337,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-%u.",
++ ddebug(1, "Setting hmac key failed for %s-%zu.",
+ alg_name, mackeylen*8);
+ ret = -EINVAL;
+ goto error;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0020-fix-uninitialized-variable-compiler-warning.patch b/recipes-kernel/cryptodev/sdk_patches/0020-fix-uninitialized-variable-compiler-warning.patch
new file mode 100644
index 00000000..dddd77ea
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0020-fix-uninitialized-variable-compiler-warning.patch
@@ -0,0 +1,38 @@
+From be9f6a0dc90847dbb00307d23f47b8b3fc3ff130 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@freescale.com>
+Date: Fri, 29 May 2015 15:49:22 +0300
+Subject: [PATCH 20/38] fix uninitialized variable compiler warning
+
+crypto/../../cryptodev-linux/ioctl.c: In function 'cryptodev_compat_ioctl':
+crypto/../../cryptodev-linux/ioctl.c:1445:2: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
+ return ret;
+ ^
+
+Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com>
+Change-Id: Id5226fc97a3bb880ca6db86df58957122bbaa428
+Reviewed-on: http://git.am.freescale.net:8181/37441
+Reviewed-by: Cristian Stoica <cristian.stoica@freescale.com>
+Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ ioctl.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index f3ce2f6..7cd3c56 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -1387,9 +1387,10 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ case COMPAT_CIOCASYMFETCHCOOKIE:
+ {
+ struct cryptodev_pkc *pkc;
+- int i = 0;
++ int i;
+ struct compat_pkc_cookie_list_s cookie_list;
+
++ ret = 0;
+ cookie_list.cookie_available = 0;
+
+ for (i = 0; i < MAX_COOKIES; i++) {
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0021-check-return-codes-for-copy-to-from-user-functions.patch b/recipes-kernel/cryptodev/sdk_patches/0021-check-return-codes-for-copy-to-from-user-functions.patch
new file mode 100644
index 00000000..2cace5fd
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0021-check-return-codes-for-copy-to-from-user-functions.patch
@@ -0,0 +1,398 @@
+From 4078382cfc69c0f5e582d485fe8cc778f9e458d1 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Mon, 21 Sep 2015 16:39:52 +0300
+Subject: [PATCH 21/38] check return codes for copy to/from user functions
+
+- these functions may fail and we should check their return codes.
+- fix an unintended fall-through in CRK_DSA_GENERATE_KEY
+- fix incorrect return code for CIOCASYMFETCHCOOKIE
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ ioctl.c | 42 +++++++--------
+ main.c | 183 ++++++++++++++++++++++++++++++----------------------------------
+ 2 files changed, 108 insertions(+), 117 deletions(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index 7cd3c56..8fa3e5c 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -711,13 +711,13 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ 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);
++ ret = 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);
++ ret = copy_to_user(ckop->crk_param[6].crp_p, rsa_req->f, rsa_req->f_len);
+ }
+ break;
+ case CRK_DSA_SIGN:
+@@ -725,11 +725,11 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ 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);
++ ret = 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);
++ ret = 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;
+@@ -739,9 +739,9 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ {
+ 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);
++ ret = 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);
++ ret = copy_to_user(ckop->crk_param[3].crp_p, dh_req->z, dh_req->z_len);
+ }
+ break;
+ case CRK_DSA_GENERATE_KEY:
+@@ -750,16 +750,17 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc)
+ 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,
++ ret = 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,
++ ret = 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);
+ }
++ break;
+ }
+ default:
+ ret = -EINVAL;
+@@ -1115,14 +1116,12 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+
+ /* Reflect the updated request to user-space */
+ if (cookie_list.cookie_available) {
+- copy_to_user(arg, &cookie_list, sizeof(struct pkc_cookie_list_s));
++ ret = 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 = put_user(0, &(user_ck_list->cookie_available));
+ }
+- ret = cookie_list.cookie_available;
+ }
+-
+ return ret;
+ default:
+ return -EINVAL;
+@@ -1417,9 +1416,10 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ }
+
+ /* Reflect the updated request to user-space */
+- if (cookie_list.cookie_available)
+- copy_to_user(arg, &cookie_list,
+- sizeof(struct compat_pkc_cookie_list_s));
++ if (cookie_list.cookie_available) {
++ ret = copy_to_user(arg, &cookie_list,
++ sizeof(struct compat_pkc_cookie_list_s));
++ }
+ }
+ return ret;
+ default:
+diff --git a/main.c b/main.c
+index ed1c69a..e5adb93 100644
+--- a/main.c
++++ b/main.c
+@@ -223,31 +223,29 @@ int crypto_kop_dsasign(struct cryptodev_pkc *pkc)
+ 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);
++ rc = 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,
++ rc = rc || copy_from_user(dsa_req->ab, cop->crk_param[5].crp_p,
+ dsa_req->ab_len);
+ }
++ if (rc)
++ goto err;
++
+ 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);
++ rc = rc ||
++ 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);
++ rc = rc ||
++ 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)
+@@ -303,31 +301,28 @@ int crypto_kop_dsaverify(struct cryptodev_pkc *pkc)
+ 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);
++ rc = 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);
++ rc = rc ||
++ 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 = rc ||
++ 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);
+ }
++
++ if (rc)
++ goto err;
++
+ rc = cryptodev_pkc_offload(pkc);
+- if (pkc->type == SYNCHRONOUS) {
+- if (rc)
+- goto err;
+- } else {
++ if (pkc->type != SYNCHRONOUS) {
+ if (rc != -EINPROGRESS && !rc)
+ goto err;
+ pkc->cookie = buf;
+@@ -380,24 +375,15 @@ int crypto_kop_rsa_keygen(struct cryptodev_pkc *pkc)
+ 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 {
++ rc = rc ||
++ 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;
+@@ -451,30 +437,33 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc)
+ 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);
++ rc = 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 == 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,
++ rc = rc || copy_from_user(key_req->ab, cop->crk_param[3].crp_p,
+ key_req->ab_len);
+ }
+
++ if (rc)
++ goto err;
++
+ 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,
++ rc = rc ||
++ 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);
++ rc = rc ||
++ 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)
+@@ -495,7 +484,7 @@ int crypto_kop_dh_key(struct cryptodev_pkc *pkc)
+ struct dh_key_req_s *dh_req;
+ int buf_size;
+ uint8_t *buf;
+- int rc = -EINVAL;
++ int rc = 0;
+
+ dh_req = &pkc->req->req_u.dh_req;
+ dh_req->s_len = (cop->crk_param[0].crp_nbits + 7)/8;
+@@ -520,22 +509,23 @@ int crypto_kop_dh_key(struct cryptodev_pkc *pkc)
+ 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);
++ rc = 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 = rc ||
++ 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);
++ if (rc)
++ goto err;
++
+ 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,
++ rc = rc || 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,
++ rc = rc || copy_to_user(cop->crk_param[3].crp_p, dh_req->z,
+ dh_req->z_len);
+ } else {
+ if (rc != -EINPROGRESS && rc != 0)
+@@ -582,19 +572,19 @@ int crypto_modexp_crt(struct cryptodev_pkc *pkc)
+ 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 = 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);
++ if (rc)
++ goto err;
++
+ 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);
++ rc = rc || copy_to_user(cop->crk_param[6].crp_p, rsa_req->f, rsa_req->f_len);
+ } else {
+ if (rc != -EINPROGRESS && rc != 0)
+ goto err;
+@@ -633,14 +623,15 @@ int crypto_bn_modexp(struct cryptodev_pkc *pkc)
+ 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 = 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);
++ if (rc)
++ goto err;
++
+ 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);
++ rc = rc || copy_to_user(cop->crk_param[3].crp_p, rsa_req->g, rsa_req->g_len);
+ } else {
+ if (rc != -EINPROGRESS && rc != 0)
+ goto err;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0022-fix-double-free-pkc-req-on-error.patch b/recipes-kernel/cryptodev/sdk_patches/0022-fix-double-free-pkc-req-on-error.patch
new file mode 100644
index 00000000..7bc177e3
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0022-fix-double-free-pkc-req-on-error.patch
@@ -0,0 +1,26 @@
+From 85146b8429ba11bd0be68c24c17dd77b21ec8c25 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Mon, 12 Oct 2015 23:03:28 +0300
+Subject: [PATCH 22/38] fix double free pkc->req on error
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/main.c b/main.c
+index e5adb93..ec11129 100644
+--- a/main.c
++++ b/main.c
+@@ -747,7 +747,7 @@ int crypto_run_asym(struct cryptodev_pkc *pkc)
+ /* todo - fix alloc-free on error path */
+ pkc->req->type = pkc_req_type;
+ err = call_next_action(pkc);
+- if (pkc->type == SYNCHRONOUS)
++ if (err == 0 && pkc->type == SYNCHRONOUS)
+ kfree(pkc->req);
+
+ return err;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0023-remove-MAY_BACKLOG-flag-from-requests.patch b/recipes-kernel/cryptodev/sdk_patches/0023-remove-MAY_BACKLOG-flag-from-requests.patch
new file mode 100644
index 00000000..5674e035
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0023-remove-MAY_BACKLOG-flag-from-requests.patch
@@ -0,0 +1,69 @@
+From 7d0d0deb255f8c59b0cf6d3944ee2e3be4133b4c Mon Sep 17 00:00:00 2001
+From: Alex Porosanu <alexandru.porosanu@freescale.com>
+Date: Mon, 19 Oct 2015 11:53:11 +0300
+Subject: [PATCH 23/38] remove MAY_BACKLOG flag from requests
+
+cryptodev doesn't implement the backlogging mechanism properly,
+since it misses the possibility of sleeping and waiting for
+wake-up when the crypto driver below starts working on the
+submitted backloggable request.
+In case the crypto driver below implements backlogging mechanisms,
+this can lead to side-effects such as working on previously-free'ed
+data.
+This patch removes the MAY_BACKLOG flag from the requests.
+
+Change-Id: Ia3d822b1abfc1a51e2ce3e9682476b2c99d19c5a
+Signed-off-by: Alex Porosanu <alexandru.porosanu@freescale.com>
+---
+ cryptlib.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index 10f5e1a..eba4616 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -194,8 +194,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ goto error;
+ }
+
+- ablkcipher_request_set_callback(out->async.request,
+- CRYPTO_TFM_REQ_MAY_BACKLOG,
++ ablkcipher_request_set_callback(out->async.request, 0,
+ cryptodev_complete, out->async.result);
+ } else {
+ out->async.arequest = aead_request_alloc(out->async.as, GFP_KERNEL);
+@@ -205,8 +204,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ goto error;
+ }
+
+- aead_request_set_callback(out->async.arequest,
+- CRYPTO_TFM_REQ_MAY_BACKLOG,
++ aead_request_set_callback(out->async.arequest, 0,
+ cryptodev_complete, out->async.result);
+ }
+
+@@ -362,9 +360,8 @@ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
+ goto error;
+ }
+
+- ahash_request_set_callback(hdata->async.request,
+- CRYPTO_TFM_REQ_MAY_BACKLOG,
+- cryptodev_complete, hdata->async.result);
++ ahash_request_set_callback(hdata->async.request, 0,
++ cryptodev_complete, hdata->async.result);
+
+ ret = crypto_ahash_init(hdata->async.request);
+ if (unlikely(ret)) {
+@@ -439,8 +436,7 @@ int cryptodev_pkc_offload(struct cryptodev_pkc *pkc)
+ int ret;
+
+ init_completion(&pkc->result.completion);
+- pkc_request_set_callback(pkc->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+- cryptodev_complete_asym, pkc);
++ pkc_request_set_callback(pkc->req, 0, cryptodev_complete_asym, pkc);
+ ret = crypto_pkc_op(pkc->req);
+ if (ret != -EINPROGRESS && ret != 0)
+ goto error;
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0024-fix-COMPAT_CIOCKEY-ioctl-command-number.patch b/recipes-kernel/cryptodev/sdk_patches/0024-fix-COMPAT_CIOCKEY-ioctl-command-number.patch
new file mode 100644
index 00000000..72770863
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0024-fix-COMPAT_CIOCKEY-ioctl-command-number.patch
@@ -0,0 +1,29 @@
+From 53e4d0fe4a334dae3df32b2053e4ebdfda2e9148 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@freescale.com>
+Date: Tue, 27 Oct 2015 15:51:02 +0200
+Subject: [PATCH 24/38] fix COMPAT_CIOCKEY ioctl command number
+
+CIOCKEY and COMPAT_CIOCKEY had different command numbers,
+so that 32-bit applications got EINVAL error on 64-bit kernel.
+
+Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com>
+---
+ cryptodev_int.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index c83c885..cb005d7 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -132,7 +132,7 @@ 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_CIOCKEY _IOWR('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)
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0025-fix-benchmarks-linking.patch b/recipes-kernel/cryptodev/sdk_patches/0025-fix-benchmarks-linking.patch
new file mode 100644
index 00000000..608c6812
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0025-fix-benchmarks-linking.patch
@@ -0,0 +1,25 @@
+From 978cfcf9253c409520c0f168f8caa249f50a8843 Mon Sep 17 00:00:00 2001
+From: Fridolin Pokorny <fpokorny@redhat.com>
+Date: Fri, 8 Jan 2016 09:38:29 +0100
+Subject: [PATCH 25/38] fix benchmarks linking
+
+---
+ lib/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/Makefile b/lib/Makefile
+index af87795..3bedc34 100644
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -3,7 +3,7 @@ CFLAGS=-g -O2 -Wall
+ all: benchmark
+
+ benchmark: main.c libthreshold.a
+- gcc $(CFLAGS) -DDEBUG -o $@ $^ -lssl libthreshold.a
++ gcc $(CFLAGS) -DDEBUG -o $@ $^ -lssl -lcrypto libthreshold.a
+
+ .o:
+ gcc $(CCFLAGS) -c $< -o $@
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0026-fix-Makefile-to-allow-parallel-make-with-j-option.patch b/recipes-kernel/cryptodev/sdk_patches/0026-fix-Makefile-to-allow-parallel-make-with-j-option.patch
new file mode 100644
index 00000000..b8cf4e19
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0026-fix-Makefile-to-allow-parallel-make-with-j-option.patch
@@ -0,0 +1,56 @@
+From d96ae48c87f80af1a202c2d2e837bf477edc0fb7 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Thu, 10 Dec 2015 12:42:18 +0200
+Subject: [PATCH 26/38] fix Makefile to allow parallel make with -j option
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Recursive make commands should always use the variable MAKE, not the
+explicit command name ‘make’
+
+Documented in section "5.7.1 How the MAKE Variable Works" of GNU Make manual
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ Makefile | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 9e56e9d..2f50210 100644
+--- a/Makefile
++++ b/Makefile
+@@ -22,7 +22,7 @@ KERNEL_MAKE_OPTS += CROSS_COMPILE=${CROSS_COMPILE}
+ endif
+
+ build: version.h
+- make ${KERNEL_MAKE_OPTS} modules
++ $(MAKE) $(KERNEL_MAKE_OPTS) modules
+
+ version.h: Makefile
+ @echo "#define VERSION \"$(VERSION)\"" > version.h
+@@ -30,17 +30,17 @@ version.h: Makefile
+ install: modules_install
+
+ modules_install:
+- make -C $(KERNEL_DIR) SUBDIRS=`pwd` modules_install
++ $(MAKE) -C $(KERNEL_DIR) SUBDIRS=`pwd` modules_install
+ @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
++ $(MAKE) -C $(KERNEL_DIR) SUBDIRS=`pwd` clean
+ rm -f $(hostprogs) *~
+- CFLAGS=$(CRYPTODEV_CFLAGS) KERNEL_DIR=$(KERNEL_DIR) make -C tests clean
++ CFLAGS=$(CRYPTODEV_CFLAGS) KERNEL_DIR=$(KERNEL_DIR) $(MAKE) -C tests clean
+
+ check:
+- CFLAGS=$(CRYPTODEV_CFLAGS) KERNEL_DIR=$(KERNEL_DIR) make -C tests check
++ CFLAGS=$(CRYPTODEV_CFLAGS) KERNEL_DIR=$(KERNEL_DIR) $(MAKE) -C tests check
+
+ CPOPTS =
+ ifneq (${SHOW_TYPES},)
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0027-use-Linux-kernel-conventions-for-Makefile-variables.patch b/recipes-kernel/cryptodev/sdk_patches/0027-use-Linux-kernel-conventions-for-Makefile-variables.patch
new file mode 100644
index 00000000..ad18da81
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0027-use-Linux-kernel-conventions-for-Makefile-variables.patch
@@ -0,0 +1,47 @@
+From e51bf208fbd3796238ff4d721e8d070f711f8c56 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Thu, 10 Dec 2015 12:42:19 +0200
+Subject: [PATCH 27/38] use Linux kernel conventions for Makefile variables
+
+The kernel Makefile specifies to use M=... instead of SUBDIR=... for
+external modules.
+
+PWD variable is already set in a POSIX system and calling `pwd` to find
+it is redundant.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ Makefile | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 2f50210..7c7e193 100644
+--- a/Makefile
++++ b/Makefile
+@@ -13,7 +13,7 @@ cryptodev-objs = ioctl.o main.o cryptlib.o authenc.o zc.o util.o
+
+ obj-m += cryptodev.o
+
+-KERNEL_MAKE_OPTS := -C ${KERNEL_DIR} SUBDIRS=`pwd`
++KERNEL_MAKE_OPTS := -C $(KERNEL_DIR) M=$(PWD)
+ ifneq (${ARCH},)
+ KERNEL_MAKE_OPTS += ARCH=${ARCH}
+ endif
+@@ -30,12 +30,12 @@ version.h: Makefile
+ install: modules_install
+
+ modules_install:
+- $(MAKE) -C $(KERNEL_DIR) SUBDIRS=`pwd` modules_install
++ $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install
+ @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
++ $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
+ rm -f $(hostprogs) *~
+ CFLAGS=$(CRYPTODEV_CFLAGS) KERNEL_DIR=$(KERNEL_DIR) $(MAKE) -C tests clean
+
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0028-for-consistency-use-.-instead-of-.-in-makefiles.patch b/recipes-kernel/cryptodev/sdk_patches/0028-for-consistency-use-.-instead-of-.-in-makefiles.patch
new file mode 100644
index 00000000..756ca33f
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0028-for-consistency-use-.-instead-of-.-in-makefiles.patch
@@ -0,0 +1,73 @@
+From 22b63631de17507c12355c30e408dbd88350bb3a Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Thu, 10 Dec 2015 12:42:20 +0200
+Subject: [PATCH 28/38] for consistency, use $(...) instead of ${...} in
+ makefiles
+
+Both syntax rules are equaly valid and mixing them is permitted but
+looks inconsistent.
+
+See section "6.1 Basics of Variable References" of GNU make manual
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ Makefile | 16 ++++++++--------
+ tests/Makefile | 2 +-
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 7c7e193..7f8df37 100644
+--- a/Makefile
++++ b/Makefile
+@@ -14,11 +14,11 @@ cryptodev-objs = ioctl.o main.o cryptlib.o authenc.o zc.o util.o
+ obj-m += cryptodev.o
+
+ KERNEL_MAKE_OPTS := -C $(KERNEL_DIR) M=$(PWD)
+-ifneq (${ARCH},)
+-KERNEL_MAKE_OPTS += ARCH=${ARCH}
++ifneq ($(ARCH),)
++KERNEL_MAKE_OPTS += ARCH=$(ARCH)
+ endif
+-ifneq (${CROSS_COMPILE},)
+-KERNEL_MAKE_OPTS += CROSS_COMPILE=${CROSS_COMPILE}
++ifneq ($(CROSS_COMPILE),)
++KERNEL_MAKE_OPTS += CROSS_COMPILE=$(CROSS_COMPILE)
+ endif
+
+ build: version.h
+@@ -43,15 +43,15 @@ check:
+ CFLAGS=$(CRYPTODEV_CFLAGS) KERNEL_DIR=$(KERNEL_DIR) $(MAKE) -C tests check
+
+ CPOPTS =
+-ifneq (${SHOW_TYPES},)
++ifneq ($(SHOW_TYPES),)
+ CPOPTS += --show-types
+ endif
+-ifneq (${IGNORE_TYPES},)
+-CPOPTS += --ignore ${IGNORE_TYPES}
++ifneq ($(IGNORE_TYPES),)
++CPOPTS += --ignore $(IGNORE_TYPES)
+ endif
+
+ checkpatch:
+- $(KERNEL_DIR)/scripts/checkpatch.pl ${CPOPTS} --file *.c *.h
++ $(KERNEL_DIR)/scripts/checkpatch.pl $(CPOPTS) --file *.c *.h
+
+ VERSIONTAG = refs/tags/cryptodev-linux-$(VERSION)
+ FILEBASE = cryptodev-linux-$(VERSION)
+diff --git a/tests/Makefile b/tests/Makefile
+index 20c52ba..3155da9 100644
+--- a/tests/Makefile
++++ b/tests/Makefile
+@@ -6,7 +6,7 @@ comp_progs := cipher_comp hash_comp hmac_comp
+
+ hostprogs := cipher cipher-aead hmac speed async_cipher async_hmac \
+ async_speed sha_speed hashcrypt_speed fullspeed cipher-gcm \
+- cipher-aead-srtp ${comp_progs}
++ cipher-aead-srtp $(comp_progs)
+
+ example-cipher-objs := cipher.o
+ example-cipher-aead-objs := cipher-aead.o
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0029-fix-clean-up-on-error-path-for-crypto_create_session.patch b/recipes-kernel/cryptodev/sdk_patches/0029-fix-clean-up-on-error-path-for-crypto_create_session.patch
new file mode 100644
index 00000000..67e4a89d
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0029-fix-clean-up-on-error-path-for-crypto_create_session.patch
@@ -0,0 +1,117 @@
+From 294abaaa4540ec340ed6046a784c9789c8724420 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Mon, 11 Jan 2016 17:45:50 +0200
+Subject: [PATCH 29/38] fix clean-up on error path for crypto_create_session
+
+This patch fixes clean-up on error path for failed allocations of
+ses_new->pages or ses_new->sg. In these cases, allocations made in
+cryptodev_hash_init have not been undone resulting in possible memory
+leaks.
+
+We take advantage of the initializations with zeros of the session
+structure to trim the code to a single clean-up path.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ ioctl.c | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index b23f5fd..c781f9d 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -228,7 +228,8 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ return -EINVAL;
+ }
+
+- /* Create a session and put it to the list. */
++ /* Create a session and put it to the list. Zeroing the structure helps
++ * also with a single exit point in case of errors */
+ ses_new = kzalloc(sizeof(*ses_new), GFP_KERNEL);
+ if (!ses_new)
+ return -ENOMEM;
+@@ -240,19 +241,19 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ if (unlikely(ret < 0)) {
+ ddebug(1, "Setting key failed for %s-%zu.",
+ alg_name, (size_t)sop->keylen*8);
+- goto error_cipher;
++ goto session_error;
+ }
+
+ ret = cryptodev_get_cipher_key(keys.ckey, sop, aead);
+ if (unlikely(ret < 0))
+- goto error_cipher;
++ goto session_error;
+
+ 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;
+- goto error_cipher;
++ goto session_error;
+ }
+ }
+
+@@ -261,13 +262,13 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ ddebug(1, "Setting key failed for %s-%zu.",
+ hash_name, (size_t)sop->mackeylen*8);
+ ret = -EINVAL;
+- goto error_hash;
++ goto session_error;
+ }
+
+ if (sop->mackey && unlikely(copy_from_user(keys.mkey, sop->mackey,
+ sop->mackeylen))) {
+ ret = -EFAULT;
+- goto error_hash;
++ goto session_error;
+ }
+
+ ret = cryptodev_hash_init(&ses_new->hdata, hash_name, hmac_mode,
+@@ -275,7 +276,7 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ if (ret != 0) {
+ ddebug(1, "Failed to load hash for %s", hash_name);
+ ret = -EINVAL;
+- goto error_hash;
++ goto session_error;
+ }
+ }
+
+@@ -292,7 +293,7 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ if (ses_new->sg == NULL || ses_new->pages == NULL) {
+ ddebug(0, "Memory error");
+ ret = -ENOMEM;
+- goto error_hash;
++ goto session_error;
+ }
+
+ /* put the new session to the list */
+@@ -316,18 +317,19 @@ restart:
+
+ /* Fill in some values for the user. */
+ sop->ses = ses_new->sid;
+-
+ return 0;
+
+-error_hash:
++ /* We count on ses_new to be initialized with zeroes
++ * Since hdata and cdata are embedded within ses_new, it follows that
++ * hdata->init and cdata->init are either zero or one as they have been
++ * initialized or not */
++session_error:
++ cryptodev_hash_deinit(&ses_new->hdata);
+ cryptodev_cipher_deinit(&ses_new->cdata);
+ kfree(ses_new->sg);
+ kfree(ses_new->pages);
+-error_cipher:
+ kfree(ses_new);
+-
+ return ret;
+-
+ }
+
+ /* Everything that needs to be done when remowing a session. */
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0030-remove-code-duplication-in-cryptodev_hash_init.patch b/recipes-kernel/cryptodev/sdk_patches/0030-remove-code-duplication-in-cryptodev_hash_init.patch
new file mode 100644
index 00000000..1e3ebf34
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0030-remove-code-duplication-in-cryptodev_hash_init.patch
@@ -0,0 +1,59 @@
+From f4534df637b078fce275763bd8bc2a83bfad25e0 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Mon, 11 Jan 2016 18:01:06 +0200
+Subject: [PATCH 30/38] remove code duplication in cryptodev_hash_init
+
+cryptodev_hash_init is concerned mostly with allocating data structures
+for hash operations.
+This patch replaces the call it makes to crypto_ahash_init with
+one to cryptodev_hash_reset to avoid code duplication. This call is made
+now outside of the original function to increase modularity.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ cryptlib.c | 9 ---------
+ ioctl.c | 5 +++++
+ 2 files changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index eba4616..4fd29eb 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -362,18 +362,9 @@ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
+
+ ahash_request_set_callback(hdata->async.request, 0,
+ cryptodev_complete, hdata->async.result);
+-
+- ret = crypto_ahash_init(hdata->async.request);
+- if (unlikely(ret)) {
+- derr(0, "error in crypto_hash_init()");
+- goto error_request;
+- }
+-
+ hdata->init = 1;
+ return 0;
+
+-error_request:
+- ahash_request_free(hdata->async.request);
+ error:
+ kfree(hdata->async.result);
+ crypto_free_ahash(hdata->async.s);
+diff --git a/ioctl.c b/ioctl.c
+index b36dd03..a537886 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -338,6 +338,11 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+ ret = -EINVAL;
+ goto session_error;
+ }
++
++ ret = cryptodev_hash_reset(&ses_new->hdata);
++ if (ret != 0) {
++ goto session_error;
++ }
+ }
+
+ ses_new->alignmask = max(ses_new->cdata.alignmask,
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0031-fix-comment-typo.patch b/recipes-kernel/cryptodev/sdk_patches/0031-fix-comment-typo.patch
new file mode 100644
index 00000000..cde95524
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0031-fix-comment-typo.patch
@@ -0,0 +1,26 @@
+From 73a2489ba634503a0cc2bb6e84627ceeda0f059f Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Tue, 12 Jan 2016 17:15:56 +0200
+Subject: [PATCH 31/38] fix comment typo
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ ioctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index a537886..7adde75 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -397,7 +397,7 @@ session_error:
+ return ret;
+ }
+
+-/* Everything that needs to be done when remowing a session. */
++/* Everything that needs to be done when removing a session. */
+ static inline void
+ crypto_destroy_session(struct csession *ses_ptr)
+ {
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0032-avoid-calls-to-kmalloc-on-hotpaths.patch b/recipes-kernel/cryptodev/sdk_patches/0032-avoid-calls-to-kmalloc-on-hotpaths.patch
new file mode 100644
index 00000000..2aa5810b
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0032-avoid-calls-to-kmalloc-on-hotpaths.patch
@@ -0,0 +1,220 @@
+From 9b513838035c35fd3706bb824edd17d705641439 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Tue, 12 Jan 2016 15:13:15 +0200
+Subject: [PATCH 32/38] avoid calls to kmalloc on hotpaths
+
+We replace a pointer to a small structure with the structure itself to
+avoid unnecessary dynamic allocations at runtime. The embedding
+structure is itself dynamically allocated and we get a slight increase
+in performance from elimination of unnecessary code.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ cryptlib.c | 42 +++++++++++++-----------------------------
+ cryptlib.h | 14 +++++++-------
+ 2 files changed, 20 insertions(+), 36 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index 4fd29eb..5972fc2 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -178,13 +178,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ out->stream = stream;
+ out->aead = aead;
+
+- out->async.result = kzalloc(sizeof(*out->async.result), GFP_KERNEL);
+- if (unlikely(!out->async.result)) {
+- ret = -ENOMEM;
+- goto error;
+- }
+-
+- init_completion(&out->async.result->completion);
++ init_completion(&out->async.result.completion);
+
+ if (aead == 0) {
+ out->async.request = ablkcipher_request_alloc(out->async.s, GFP_KERNEL);
+@@ -195,7 +189,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ }
+
+ ablkcipher_request_set_callback(out->async.request, 0,
+- cryptodev_complete, out->async.result);
++ cryptodev_complete, &out->async.result);
+ } else {
+ out->async.arequest = aead_request_alloc(out->async.as, GFP_KERNEL);
+ if (unlikely(!out->async.arequest)) {
+@@ -205,7 +199,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
+ }
+
+ aead_request_set_callback(out->async.arequest, 0,
+- cryptodev_complete, out->async.result);
++ cryptodev_complete, &out->async.result);
+ }
+
+ out->init = 1;
+@@ -222,7 +216,6 @@ error:
+ if (out->async.as)
+ crypto_free_aead(out->async.as);
+ }
+- kfree(out->async.result);
+
+ return ret;
+ }
+@@ -242,7 +235,6 @@ void cryptodev_cipher_deinit(struct cipher_data *cdata)
+ crypto_free_aead(cdata->async.as);
+ }
+
+- kfree(cdata->async.result);
+ cdata->init = 0;
+ }
+ }
+@@ -279,7 +271,7 @@ ssize_t cryptodev_cipher_encrypt(struct cipher_data *cdata,
+ {
+ int ret;
+
+- reinit_completion(&cdata->async.result->completion);
++ reinit_completion(&cdata->async.result.completion);
+
+ if (cdata->aead == 0) {
+ ablkcipher_request_set_crypt(cdata->async.request,
+@@ -293,7 +285,7 @@ ssize_t cryptodev_cipher_encrypt(struct cipher_data *cdata,
+ ret = crypto_aead_encrypt(cdata->async.arequest);
+ }
+
+- return waitfor(cdata->async.result, ret);
++ return waitfor(&cdata->async.result, ret);
+ }
+
+ ssize_t cryptodev_cipher_decrypt(struct cipher_data *cdata,
+@@ -302,7 +294,7 @@ ssize_t cryptodev_cipher_decrypt(struct cipher_data *cdata,
+ {
+ int ret;
+
+- reinit_completion(&cdata->async.result->completion);
++ reinit_completion(&cdata->async.result.completion);
+ if (cdata->aead == 0) {
+ ablkcipher_request_set_crypt(cdata->async.request,
+ (struct scatterlist *)src, dst,
+@@ -315,7 +307,7 @@ ssize_t cryptodev_cipher_decrypt(struct cipher_data *cdata,
+ ret = crypto_aead_decrypt(cdata->async.arequest);
+ }
+
+- return waitfor(cdata->async.result, ret);
++ return waitfor(&cdata->async.result, ret);
+ }
+
+ /* Hash functions */
+@@ -345,13 +337,7 @@ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
+ hdata->digestsize = crypto_ahash_digestsize(hdata->async.s);
+ hdata->alignmask = crypto_ahash_alignmask(hdata->async.s);
+
+- hdata->async.result = kzalloc(sizeof(*hdata->async.result), GFP_KERNEL);
+- if (unlikely(!hdata->async.result)) {
+- ret = -ENOMEM;
+- goto error;
+- }
+-
+- init_completion(&hdata->async.result->completion);
++ init_completion(&hdata->async.result.completion);
+
+ hdata->async.request = ahash_request_alloc(hdata->async.s, GFP_KERNEL);
+ if (unlikely(!hdata->async.request)) {
+@@ -361,12 +347,11 @@ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
+ }
+
+ ahash_request_set_callback(hdata->async.request, 0,
+- cryptodev_complete, hdata->async.result);
++ cryptodev_complete, &hdata->async.result);
+ hdata->init = 1;
+ return 0;
+
+ error:
+- kfree(hdata->async.result);
+ crypto_free_ahash(hdata->async.s);
+ return ret;
+ }
+@@ -376,7 +361,6 @@ void cryptodev_hash_deinit(struct hash_data *hdata)
+ if (hdata->init) {
+ if (hdata->async.request)
+ ahash_request_free(hdata->async.request);
+- kfree(hdata->async.result);
+ if (hdata->async.s)
+ crypto_free_ahash(hdata->async.s);
+ hdata->init = 0;
+@@ -402,24 +386,24 @@ ssize_t cryptodev_hash_update(struct hash_data *hdata,
+ {
+ int ret;
+
+- reinit_completion(&hdata->async.result->completion);
++ reinit_completion(&hdata->async.result.completion);
+ ahash_request_set_crypt(hdata->async.request, sg, NULL, len);
+
+ ret = crypto_ahash_update(hdata->async.request);
+
+- return waitfor(hdata->async.result, ret);
++ return waitfor(&hdata->async.result, ret);
+ }
+
+ int cryptodev_hash_final(struct hash_data *hdata, void *output)
+ {
+ int ret;
+
+- reinit_completion(&hdata->async.result->completion);
++ reinit_completion(&hdata->async.result.completion);
+ ahash_request_set_crypt(hdata->async.request, NULL, output, 0);
+
+ ret = crypto_ahash_final(hdata->async.request);
+
+- return waitfor(hdata->async.result, ret);
++ return waitfor(&hdata->async.result, ret);
+ }
+
+ int cryptodev_pkc_offload(struct cryptodev_pkc *pkc)
+diff --git a/cryptlib.h b/cryptlib.h
+index e1c4e3e..d8e8046 100644
+--- a/cryptlib.h
++++ b/cryptlib.h
+@@ -6,6 +6,11 @@
+
+ #include <linux/version.h>
+
++struct cryptodev_result {
++ struct completion completion;
++ int err;
++};
++
+ struct cipher_data {
+ int init; /* 0 uninitialized */
+ int blocksize;
+@@ -22,7 +27,7 @@ struct cipher_data {
+ struct crypto_aead *as;
+ struct aead_request *arequest;
+
+- struct cryptodev_result *result;
++ struct cryptodev_result result;
+ uint8_t iv[EALG_MAX_BLOCK_LEN];
+ } async;
+ };
+@@ -85,7 +90,7 @@ struct hash_data {
+ int alignmask;
+ struct {
+ struct crypto_ahash *s;
+- struct cryptodev_result *result;
++ struct cryptodev_result result;
+ struct ahash_request *request;
+ } async;
+ };
+@@ -104,11 +109,6 @@ enum offload_type {
+ ASYNCHRONOUS
+ };
+
+-struct cryptodev_result {
+- struct completion completion;
+- int err;
+-};
+-
+ struct cryptodev_pkc {
+ struct list_head list; /* To maintain the Jobs in completed
+ cryptodev lists */
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0033-avoid-unnecessary-checks-for-hash-clean-up.patch b/recipes-kernel/cryptodev/sdk_patches/0033-avoid-unnecessary-checks-for-hash-clean-up.patch
new file mode 100644
index 00000000..3ce8a5ff
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0033-avoid-unnecessary-checks-for-hash-clean-up.patch
@@ -0,0 +1,33 @@
+From 774c6bd169b683ed54ebad164d0ff541e1381a64 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Tue, 12 Jan 2016 17:09:33 +0200
+Subject: [PATCH 33/38] avoid unnecessary checks for hash clean-up
+
+hdata->init is set only after all necessary allocations succeed. On
+clean-up is no longer necessary to make the allocation checks.
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ cryptlib.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/cryptlib.c b/cryptlib.c
+index 5972fc2..5d1a5a9 100644
+--- a/cryptlib.c
++++ b/cryptlib.c
+@@ -359,10 +359,8 @@ error:
+ void cryptodev_hash_deinit(struct hash_data *hdata)
+ {
+ if (hdata->init) {
+- if (hdata->async.request)
+- ahash_request_free(hdata->async.request);
+- if (hdata->async.s)
+- crypto_free_ahash(hdata->async.s);
++ ahash_request_free(hdata->async.request);
++ crypto_free_ahash(hdata->async.s);
+ hdata->init = 0;
+ }
+ }
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0034-extend-API-with-CIOCHASH-to-support-direct-hash-oper.patch b/recipes-kernel/cryptodev/sdk_patches/0034-extend-API-with-CIOCHASH-to-support-direct-hash-oper.patch
new file mode 100644
index 00000000..3a1f0c05
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0034-extend-API-with-CIOCHASH-to-support-direct-hash-oper.patch
@@ -0,0 +1,114 @@
+From c43fa74b9ed11f0183d25b21486b71fe02d84de7 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Tue, 15 Dec 2015 15:31:47 +0200
+Subject: [PATCH 34/38] extend API with CIOCHASH to support direct hash
+ operations
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ crypto/cryptodev.h | 16 ++++++++++++++++
+ ioctl.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 65 insertions(+)
+
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index f6058ca..c6083f7 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -167,6 +167,19 @@ struct crypt_auth_op {
+ __u32 iv_len;
+ };
+
++/* data container for CIOCHASH operations */
++struct hash_op_data {
++ __u32 ses; /* session identifier */
++ __u32 mac_op; /* cryptodev_crypto_op_t */
++ __u8 *mackey;
++ __u32 mackeylen;
++
++ __u16 flags; /* see COP_FLAG_* */
++ __u32 len; /* length of source data */
++ __u8 *src; /* source data */
++ __u8 *mac_result;
++};
++
+ /* In plain AEAD mode the following are required:
+ * flags : 0
+ * iv : the initialization vector (12 bytes)
+@@ -325,4 +338,7 @@ enum cryptodev_crk_op_t {
+ /* additional ioctls for asynchronous operation for asymmetric ciphers*/
+ #define CIOCASYMASYNCRYPT _IOW('c', 112, struct crypt_kop)
+ #define CIOCASYMFETCHCOOKIE _IOR('c', 113, struct pkc_cookie_list_s)
++
++#define CIOCHASH _IOWR('c', 114, struct hash_op_data)
++
+ #endif /* L_CRYPTODEV_H */
+diff --git a/ioctl.c b/ioctl.c
+index 7adde75..3763954 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -960,6 +960,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ void __user *arg = (void __user *)arg_;
+ int __user *p = arg;
+ struct session_op sop;
++ struct hash_op_data hash_op;
+ struct kernel_crypt_op kcop;
+ struct kernel_crypt_auth_op kcaop;
+ struct crypt_priv *pcr = filp->private_data;
+@@ -1049,6 +1050,54 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ }
+
+ return kcop_to_user(&kcop, fcr, arg);
++ case CIOCHASH:
++ /* get session */
++ if (unlikely(copy_from_user(&hash_op, arg, sizeof(struct hash_op_data)))) {
++ pr_err("copy from user fault\n");
++ return -EFAULT;
++ }
++
++ sop.cipher = 0;
++ sop.mac = hash_op.mac_op;
++ sop.mackey = hash_op.mackey;
++ sop.mackeylen = hash_op.mackeylen;
++
++ /* writes sop.ses as a side-effect */
++ ret = crypto_create_session(fcr, &sop);
++ if (unlikely(ret)) {
++ pr_err("can't get session\n");
++ return ret;
++ }
++
++ /* do hashing */
++ kcop.cop.ses = sop.ses;
++ kcop.cop.flags = hash_op.flags;
++ kcop.cop.len = hash_op.len;
++ kcop.cop.src = hash_op.src;
++ kcop.cop.mac = hash_op.mac_result;
++ kcop.cop.dst = 0;
++ kcop.cop.op = 0;
++ kcop.cop.iv = 0;
++ kcop.ivlen = 0;
++ kcop.digestsize = 0; /* will be updated during operation */
++ kcop.task = current;
++ kcop.mm = current->mm;
++
++ ret = crypto_run(fcr, &kcop);
++ if (unlikely(ret)) {
++ dwarning(1, "Error in hash run");
++ return ret;
++ }
++
++ ret = copy_to_user(kcop.cop.mac, kcop.hash_output, kcop.digestsize);
++ if (unlikely(ret)) {
++ dwarning(1, "Error in copy to user");
++ return ret;
++ }
++
++ /* put session */
++ ret = crypto_finish_session(fcr, sop.ses);
++ return 0;
+ case CIOCAUTHCRYPT:
+ if (unlikely(ret = kcaop_from_user(&kcaop, fcr, arg))) {
+ dwarning(1, "Error copying from user");
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch b/recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch
new file mode 100644
index 00000000..4745dc90
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0035-use-directly-crypto-API-digest-operation-for-CIOCHAS.patch
@@ -0,0 +1,315 @@
+From f123f38532ae022e818312a9bc04cdb287e9623f Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Thu, 17 Dec 2015 10:34:20 +0200
+Subject: [PATCH 35/38] use directly crypto API 'digest' operation for CIOCHASH
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ crypto/cryptodev.h | 2 +-
+ cryptodev_int.h | 10 ++++
+ ioctl.c | 158 ++++++++++++++++++++++++++++++++++++++++++++---------
+ main.c | 39 ++++++++++++-
+ 4 files changed, 179 insertions(+), 30 deletions(-)
+
+diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
+index c6083f7..9ade102 100644
+--- a/crypto/cryptodev.h
++++ b/crypto/cryptodev.h
+@@ -169,7 +169,7 @@ struct crypt_auth_op {
+
+ /* data container for CIOCHASH operations */
+ struct hash_op_data {
+- __u32 ses; /* session identifier */
++ struct csession *ses; /* session identifier */
+ __u32 mac_op; /* cryptodev_crypto_op_t */
+ __u8 *mackey;
+ __u32 mackeylen;
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index cb005d7..74c295a 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -164,6 +164,15 @@ struct kernel_crypt_op {
+ struct mm_struct *mm;
+ };
+
++struct kernel_hash_op {
++ struct hash_op_data hash_op;
++
++ int digestsize;
++ uint8_t hash_output[AALG_MAX_RESULT_LEN];
++ struct task_struct *task;
++ struct mm_struct *mm;
++};
++
+ struct kernel_crypt_auth_op {
+ struct crypt_auth_op caop;
+
+@@ -192,6 +201,7 @@ int kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
+ struct fcrypt *fcr, void __user *arg);
+ int crypto_auth_run(struct fcrypt *fcr, struct kernel_crypt_auth_op *kcaop);
+ int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop);
++int hash_run(struct kernel_hash_op *khop);
+
+ #include <cryptlib.h>
+
+diff --git a/ioctl.c b/ioctl.c
+index 3763954..a052614 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -397,7 +397,128 @@ session_error:
+ return ret;
+ }
+
+-/* Everything that needs to be done when removing a session. */
++static inline void hash_destroy_session(struct csession *ses_ptr)
++{
++ cryptodev_hash_deinit(&ses_ptr->hdata);
++ kfree(ses_ptr->pages);
++ kfree(ses_ptr->sg);
++ kfree(ses_ptr);
++}
++
++static int hash_create_session(struct hash_op_data *hash_op)
++{
++ struct csession *ses;
++ int ret = 0;
++ const char *hash_name;
++ int hmac_mode = 1;
++ uint8_t mkey[CRYPTO_HMAC_MAX_KEY_LEN];
++
++ switch (hash_op->mac_op) {
++ case CRYPTO_MD5_HMAC:
++ hash_name = "hmac(md5)";
++ break;
++ case CRYPTO_RIPEMD160_HMAC:
++ hash_name = "hmac(rmd160)";
++ break;
++ case CRYPTO_SHA1_HMAC:
++ hash_name = "hmac(sha1)";
++ break;
++ case CRYPTO_SHA2_224_HMAC:
++ hash_name = "hmac(sha224)";
++ break;
++ case CRYPTO_SHA2_256_HMAC:
++ hash_name = "hmac(sha256)";
++ break;
++ case CRYPTO_SHA2_384_HMAC:
++ hash_name = "hmac(sha384)";
++ break;
++ case CRYPTO_SHA2_512_HMAC:
++ hash_name = "hmac(sha512)";
++ break;
++ /* non-hmac cases */
++ case CRYPTO_MD5:
++ hash_name = "md5";
++ hmac_mode = 0;
++ break;
++ case CRYPTO_RIPEMD160:
++ hash_name = "rmd160";
++ hmac_mode = 0;
++ break;
++ case CRYPTO_SHA1:
++ hash_name = "sha1";
++ hmac_mode = 0;
++ break;
++ case CRYPTO_SHA2_224:
++ hash_name = "sha224";
++ hmac_mode = 0;
++ break;
++ case CRYPTO_SHA2_256:
++ hash_name = "sha256";
++ hmac_mode = 0;
++ break;
++ case CRYPTO_SHA2_384:
++ hash_name = "sha384";
++ hmac_mode = 0;
++ break;
++ case CRYPTO_SHA2_512:
++ hash_name = "sha512";
++ hmac_mode = 0;
++ break;
++ default:
++ ddebug(1, "bad mac: %d", hash_op->mac_op);
++ return -EINVAL;
++ }
++
++ ses = kzalloc(sizeof(*ses), GFP_KERNEL);
++ if (!ses) {
++ return -ENOMEM;
++ }
++
++ if (unlikely(hash_op->mackeylen > CRYPTO_HMAC_MAX_KEY_LEN)) {
++ ddebug(1, "Setting key failed for %s-%zu.", hash_name,
++ (size_t)hash_op->mackeylen * 8);
++ ret = -EINVAL;
++ goto error_hash;
++ }
++
++ if (hash_op->mackey &&
++ unlikely(copy_from_user(mkey, hash_op->mackey, hash_op->mackeylen))) {
++ ret = -EFAULT;
++ goto error_hash;
++ }
++
++ ret = cryptodev_hash_init(&ses->hdata, hash_name, hmac_mode,
++ mkey, hash_op->mackeylen);
++ if (ret != 0) {
++ ddebug(1, "Failed to load hash for %s", hash_name);
++ ret = -EINVAL;
++ goto error_hash;
++ }
++
++ ses->alignmask = ses->hdata.alignmask;
++ ddebug(2, "got alignmask %d", ses->alignmask);
++
++ ses->array_size = DEFAULT_PREALLOC_PAGES;
++ ddebug(2, "preallocating for %d user pages", ses->array_size);
++
++ ses->pages = kzalloc(ses->array_size * sizeof(struct page *), GFP_KERNEL);
++ ses->sg = kzalloc(ses->array_size * sizeof(struct scatterlist), GFP_KERNEL);
++ if (ses->sg == NULL || ses->pages == NULL) {
++ ddebug(0, "Memory error");
++ ret = -ENOMEM;
++ goto error_hash;
++ }
++
++ hash_op->ses = ses;
++ return 0;
++
++error_hash:
++ hash_destroy_session(ses);
++ return ret;
++}
++
++
++/* Everything that needs to be done when remowing a session. */
+ static inline void
+ crypto_destroy_session(struct csession *ses_ptr)
+ {
+@@ -960,7 +1081,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ void __user *arg = (void __user *)arg_;
+ int __user *p = arg;
+ struct session_op sop;
+- struct hash_op_data hash_op;
++ struct kernel_hash_op khop;
+ struct kernel_crypt_op kcop;
+ struct kernel_crypt_auth_op kcaop;
+ struct crypt_priv *pcr = filp->private_data;
+@@ -1051,52 +1172,35 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+
+ return kcop_to_user(&kcop, fcr, arg);
+ case CIOCHASH:
+- /* get session */
+- if (unlikely(copy_from_user(&hash_op, arg, sizeof(struct hash_op_data)))) {
++ if (unlikely(copy_from_user(&khop.hash_op, arg, sizeof(struct hash_op_data)))) {
+ pr_err("copy from user fault\n");
+ return -EFAULT;
+ }
++ khop.task = current;
++ khop.mm = current->mm;
+
+- sop.cipher = 0;
+- sop.mac = hash_op.mac_op;
+- sop.mackey = hash_op.mackey;
+- sop.mackeylen = hash_op.mackeylen;
+-
+- /* writes sop.ses as a side-effect */
+- ret = crypto_create_session(fcr, &sop);
++ /* get session */
++ ret = hash_create_session(&khop.hash_op);
+ if (unlikely(ret)) {
+ pr_err("can't get session\n");
+ return ret;
+ }
+
+ /* do hashing */
+- kcop.cop.ses = sop.ses;
+- kcop.cop.flags = hash_op.flags;
+- kcop.cop.len = hash_op.len;
+- kcop.cop.src = hash_op.src;
+- kcop.cop.mac = hash_op.mac_result;
+- kcop.cop.dst = 0;
+- kcop.cop.op = 0;
+- kcop.cop.iv = 0;
+- kcop.ivlen = 0;
+- kcop.digestsize = 0; /* will be updated during operation */
+- kcop.task = current;
+- kcop.mm = current->mm;
+-
+- ret = crypto_run(fcr, &kcop);
++ ret = hash_run(&khop);
+ if (unlikely(ret)) {
+ dwarning(1, "Error in hash run");
+ return ret;
+ }
+
+- ret = copy_to_user(kcop.cop.mac, kcop.hash_output, kcop.digestsize);
++ ret = copy_to_user(khop.hash_op.mac_result, khop.hash_output, khop.digestsize);
+ if (unlikely(ret)) {
+ dwarning(1, "Error in copy to user");
+ return ret;
+ }
+
+ /* put session */
+- ret = crypto_finish_session(fcr, sop.ses);
++ hash_destroy_session(khop.hash_op.ses);
+ return 0;
+ case CIOCAUTHCRYPT:
+ if (unlikely(ret = kcaop_from_user(&kcaop, fcr, arg))) {
+diff --git a/main.c b/main.c
+index ec11129..095aea5 100644
+--- a/main.c
++++ b/main.c
+@@ -159,8 +159,6 @@ __crypto_run_std(struct csession *ses_ptr, struct crypt_op *cop)
+ return ret;
+ }
+
+-
+-
+ /* This is the main crypto function - zero-copy edition */
+ static int
+ __crypto_run_zc(struct csession *ses_ptr, struct kernel_crypt_op *kcop)
+@@ -841,3 +839,40 @@ out_unlock:
+ crypto_put_session(ses_ptr);
+ return ret;
+ }
++
++int hash_run(struct kernel_hash_op *khop)
++{
++ struct hash_op_data *hash_op = &khop->hash_op;
++ struct csession *ses_ptr = hash_op->ses;
++ struct hash_data *hdata = &ses_ptr->hdata;
++ int ret;
++ struct scatterlist *src_sg;
++ struct scatterlist *dst_sg; /* required by get_userbuf but not used */
++
++ if (hash_op->len == 0) {
++ src_sg = NULL;
++ } else {
++ ret = get_userbuf(ses_ptr, hash_op->src, hash_op->len, NULL, 0,
++ khop->task, khop->mm, &src_sg, &dst_sg);
++ if (unlikely(ret)) {
++ derr(1, "Error getting user pages");
++ return ret;
++ }
++ }
++
++ ahash_request_set_crypt(hdata->async.request, src_sg, khop->hash_output, hash_op->len);
++
++ ret = crypto_ahash_digest(hdata->async.request);
++ if (ret == -EINPROGRESS || ret == -EBUSY) {
++ wait_for_completion(&hdata->async.result.completion);
++ ret = hdata->async.result.err;
++ if (ret != 0) {
++ derr(0, "CryptoAPI failure: %d", ret);
++ }
++ }
++
++ khop->digestsize = ses_ptr->hdata.digestsize;
++
++ release_user_pages(ses_ptr);
++ return ret;
++}
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0036-add-compat-for-CIOCHASH-operation.patch b/recipes-kernel/cryptodev/sdk_patches/0036-add-compat-for-CIOCHASH-operation.patch
new file mode 100644
index 00000000..c2069957
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0036-add-compat-for-CIOCHASH-operation.patch
@@ -0,0 +1,120 @@
+From 711529cc7b8743ae8c9c0db4980ac15f7acb8618 Mon Sep 17 00:00:00 2001
+From: Alex Porosanu <alexandru.porosanu@nxp.com>
+Date: Tue, 12 Jan 2016 14:51:00 +0200
+Subject: [PATCH 36/38] add compat for CIOCHASH operation
+
+This patch adds the necessary ioctl for using the CIOCHASH
+operation for different userspace & kernel (i.e. 32b userspace
+and 64b kernel).
+
+Signed-off-by: Alex Porosanu <alexandru.porosanu@nxp.com>
+---
+ cryptodev_int.h | 14 +++++++++++++-
+ ioctl.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 63 insertions(+), 1 deletion(-)
+
+diff --git a/cryptodev_int.h b/cryptodev_int.h
+index 74c295a..6dcfd69 100644
+--- a/cryptodev_int.h
++++ b/cryptodev_int.h
+@@ -129,6 +129,18 @@ struct compat_crypt_auth_op {
+ uint32_t iv_len;
+ };
+
++struct compat_hash_op_data {
++ compat_uptr_t ses;
++ uint32_t mac_op; /* cryptodev_crypto_op_t */
++ compat_uptr_t mackey;
++ uint32_t mackeylen;
++
++ uint16_t flags; /* see COP_FLAG_* */
++ uint32_t len; /* length of source data */
++ compat_uptr_t src; /* source data */
++ compat_uptr_t mac_result;
++};
++
+ /* 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)
+@@ -139,7 +151,7 @@ struct compat_crypt_auth_op {
+ #define COMPAT_CIOCASYMASYNCRYPT _IOW('c', 110, struct compat_crypt_kop)
+ #define COMPAT_CIOCASYMFETCHCOOKIE _IOR('c', 111, \
+ struct compat_pkc_cookie_list_s)
+-
++#define COMPAT_CIOCHASH _IOWR('c', 114, struct compat_hash_op_data)
+ #endif /* CONFIG_COMPAT */
+
+ /* kernel-internal extension to struct crypt_kop */
+diff --git a/ioctl.c b/ioctl.c
+index a052614..ff3de44 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -1435,8 +1435,11 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ struct fcrypt *fcr;
+ struct session_op sop;
+ struct compat_session_op compat_sop;
++ struct kernel_hash_op khop;
+ struct kernel_crypt_op kcop;
+ struct kernel_crypt_auth_op kcaop;
++ struct compat_hash_op_data compat_hash_op_data;
++
+ int ret;
+
+ if (unlikely(!pcr))
+@@ -1499,6 +1502,53 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+
+ return compat_kcop_to_user(&kcop, fcr, arg);
+
++ case COMPAT_CIOCHASH:
++ /* get session */
++ if (unlikely(copy_from_user(&compat_hash_op_data, arg,
++ sizeof(struct compat_hash_op_data)))) {
++ pr_err("copy from user fault\n");
++ return -EFAULT;
++ }
++
++ khop.task = current;
++ khop.mm = current->mm;
++
++ khop.hash_op.mac_op = compat_hash_op_data.mac_op;
++ khop.hash_op.mackey = compat_ptr(compat_hash_op_data.mackey);
++ khop.hash_op.mackeylen = compat_hash_op_data.mackeylen;
++ khop.hash_op.flags = compat_hash_op_data.flags;
++ khop.hash_op.len = compat_hash_op_data.len;
++ khop.hash_op.src = compat_ptr(compat_hash_op_data.src);
++ khop.hash_op.mac_result =
++ compat_ptr(compat_hash_op_data.mac_result);
++
++ ret = hash_create_session(&khop.hash_op);
++ if (unlikely(ret)) {
++ pr_err("can't get session\n");
++ return ret;
++ }
++
++ /* do hashing */
++ ret = hash_run(&khop);
++ if (unlikely(ret)) {
++ dwarning(1, "Error in hash run");
++ return ret;
++ }
++
++ ret = copy_to_user(khop.hash_op.mac_result, khop.hash_output,
++ khop.digestsize);
++ if (unlikely(ret)) {
++ dwarning(1, "Error in copy to user");
++ return ret;
++ }
++
++ copy_to_user(arg, &compat_hash_op_data,
++ sizeof(struct compat_hash_op_data));
++
++ /* put session */
++ hash_destroy_session(khop.hash_op.ses);
++ return 0;
++
+ case COMPAT_CIOCAUTHCRYPT:
+ if (unlikely(ret = compat_kcaop_from_user(&kcaop, fcr, arg))) {
+ dprintk(1, KERN_WARNING, "Error copying from user\n");
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0037-rewrite-sha_speed.c-to-reduce-code-duplication.patch b/recipes-kernel/cryptodev/sdk_patches/0037-rewrite-sha_speed.c-to-reduce-code-duplication.patch
new file mode 100644
index 00000000..eff6ed9f
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0037-rewrite-sha_speed.c-to-reduce-code-duplication.patch
@@ -0,0 +1,190 @@
+From 344a0243e31f8fc467253404a548eedbb72b35d0 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Wed, 20 Jan 2016 17:11:49 +0200
+Subject: [PATCH 37/38] rewrite sha_speed.c to reduce code duplication
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ tests/sha_speed.c | 131 ++++++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 84 insertions(+), 47 deletions(-)
+
+diff --git a/tests/sha_speed.c b/tests/sha_speed.c
+index e1dc54b..5f694bd 100644
+--- a/tests/sha_speed.c
++++ b/tests/sha_speed.c
+@@ -28,6 +28,13 @@
+
+ #include <crypto/cryptodev.h>
+
++/* Sizes of buffers to be hashed */
++int buffer_lengths[] = {256, 512, 1024, 2048, 4096, 8192, 65536, 0};
++
++/* Time in seconds allocated for each tested buffer lengths */
++#define BUFFER_TEST_TIME 10
++
++
+ static double udifftimeval(struct timeval start, struct timeval end)
+ {
+ return (double)(end.tv_usec - start.tv_usec) +
+@@ -97,7 +104,7 @@ int hash_data(struct session_op *sess, int fdc, int chunksize, int alignmask)
+ memset(buffer, val++, chunksize);
+
+ must_finish = 0;
+- alarm(5);
++ alarm(BUFFER_TEST_TIME);
+
+ gettimeofday(&start, NULL);
+ do {
+@@ -126,73 +133,103 @@ int hash_data(struct session_op *sess, int fdc, int chunksize, int alignmask)
+ return 0;
+ }
+
+-int main(void)
+-{
+- int fd, i, fdc = -1, alignmask = 0;
+- struct session_op sess;
+- char keybuf[32];
++
+ #ifdef CIOCGSESSINFO
++int get_alignmask(struct session_op *sess, int fdc)
++{
+ struct session_info_op siop;
++
++ siop.ses = sess->ses;
++ if (ioctl(fdc, CIOCGSESSINFO, &siop) < 0) {
++ perror("ioctl(CIOCGSESSINFO)");
++ /* continue test ignoring CIOCGSESSINFO error */
++ return 0;
++ }
++
++ printf("using algorithm %s with driver %s\n",
++ siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
++
++ return siop.alignmask;
++}
+ #endif
+
+- signal(SIGALRM, alarm_handler);
+
+- if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
+- perror("open()");
+- return 1;
+- }
+- if (ioctl(fd, CRIOGET, &fdc)) {
+- perror("ioctl(CRIOGET)");
+- return 1;
+- }
++int hash_session(struct session_op *sess, int fdc)
++{
++ int i;
++ int err;
++ int alignmask;
+
+- fprintf(stderr, "Testing SHA1 Hash: \n");
+- memset(&sess, 0, sizeof(sess));
+- sess.mac = CRYPTO_SHA1;
+- if (ioctl(fdc, CIOCGSESSION, &sess)) {
++ if (ioctl(fdc, CIOCGSESSION, sess)) {
+ perror("ioctl(CIOCGSESSION)");
+ return 1;
+ }
++
+ #ifdef CIOCGSESSINFO
+- siop.ses = sess.ses;
+- if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
+- perror("ioctl(CIOCGSESSINFO)");
+- return 1;
+- }
+- printf("requested hash CRYPTO_SHA1, got %s with driver %s\n",
+- siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
+- alignmask = siop.alignmask;
++ alignmask = get_alignmask(sess, fdc);
++#else
++ alignmask = 0;
+ #endif
+
+- for (i = 256; i <= (64 * 1024); i *= 4) {
+- if (hash_data(&sess, fdc, i, alignmask))
+- break;
++ err = 0;
++ for(i = 0; (err == 0) && (buffer_lengths[i] != 0); i++) {
++ err = hash_data(sess, fdc, buffer_lengths[i], alignmask);
+ }
+
+- fprintf(stderr, "\nTesting SHA256 Hash: \n");
+- memset(&sess, 0, sizeof(sess));
+- sess.mac = CRYPTO_SHA2_256;
+- if (ioctl(fdc, CIOCGSESSION, &sess)) {
+- perror("ioctl(CIOCGSESSION)");
++ if (ioctl(fdc, CIOCFSESSION, sess)) {
++ perror("ioctl(CIOCFSESSION)");
+ return 1;
+ }
+-#ifdef CIOCGSESSINFO
+- siop.ses = sess.ses;
+- if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
+- perror("ioctl(CIOCGSESSINFO)");
++
++ return err;
++}
++
++int test_sha1(struct session_op *sess, int fdc)
++{
++ fprintf(stderr, "Testing SHA1 Hash: \n");
++ memset(sess, 0, sizeof(sess));
++ sess->mac = CRYPTO_SHA1;
++ return hash_session(sess, fdc);
++}
++
++
++int test_sha256(struct session_op *sess, int fdc)
++{
++ fprintf(stderr, "Testing SHA256 Hash: \n");
++ memset(sess, 0, sizeof(sess));
++ sess->mac = CRYPTO_SHA2_256;
++ return hash_session(sess, fdc);
++}
++
++
++int main(void)
++{
++ int fd;
++ int fdc;
++ int err;
++ int i;
++ struct session_op sess;
++
++ signal(SIGALRM, alarm_handler);
++
++ fd = open("/dev/crypto", O_RDWR, 0);
++ if (fd < 0) {
++ perror("open()");
+ return 1;
+ }
+- printf("requested hash CRYPTO_SHA2_256, got %s with driver %s\n",
+- siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
+- alignmask = siop.alignmask;
+-#endif
+
+- for (i = 256; i <= (64 * 1024); i *= 4) {
+- if (hash_data(&sess, fdc, i, alignmask))
+- break;
++ err = ioctl(fd, CRIOGET, &fdc);
++ if (err != 0) {
++ perror("ioctl(CRIOGET)");
++ close(fd);
++ return 1;
+ }
+
++ /* run all tests but return an eventual error */
++ err |= test_sha1(&sess, fdc);
++ err |= test_sha256(&sess, fdc);
++
+ close(fdc);
+ close(fd);
+- return 0;
++ return err;
+ }
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0038-extend-sha_speed.c-to-test-CIOCHASH.patch b/recipes-kernel/cryptodev/sdk_patches/0038-extend-sha_speed.c-to-test-CIOCHASH.patch
new file mode 100644
index 00000000..eb8bf197
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0038-extend-sha_speed.c-to-test-CIOCHASH.patch
@@ -0,0 +1,143 @@
+From 65704ea24e80647e8c5f938300f51cb70af50c1c Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Thu, 21 Jan 2016 17:30:59 +0200
+Subject: [PATCH 38/38] extend sha_speed.c to test CIOCHASH
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ tests/sha_speed.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 90 insertions(+)
+
+diff --git a/tests/sha_speed.c b/tests/sha_speed.c
+index 5f694bd..d731c66 100644
+--- a/tests/sha_speed.c
++++ b/tests/sha_speed.c
+@@ -133,6 +133,62 @@ int hash_data(struct session_op *sess, int fdc, int chunksize, int alignmask)
+ return 0;
+ }
+
++int digest_data(struct session_op *sess, int fdc, int chunksize, int alignmask)
++{
++ struct hash_op_data hash_op;
++ char *buffer;
++ static int val = 23;
++ struct timeval start, end;
++ double total = 0;
++ double secs, ddata, dspeed;
++ char metric[16];
++ uint8_t mac[AALG_MAX_RESULT_LEN];
++
++ if (alignmask) {
++ if (posix_memalign((void **)&buffer, alignmask + 1, chunksize)) {
++ printf("posix_memalign() failed!\n");
++ return 1;
++ }
++ } else {
++ if (!(buffer = malloc(chunksize))) {
++ perror("malloc()");
++ return 1;
++ }
++ }
++
++ printf("\tEncrypting in chunks of %d bytes: ", chunksize);
++ fflush(stdout);
++
++ memset(buffer, val++, chunksize);
++
++ must_finish = 0;
++ alarm(BUFFER_TEST_TIME);
++
++ gettimeofday(&start, NULL);
++ do {
++ memset(&hash_op, 0, sizeof(hash_op));
++ hash_op.mac_op = sess->mac;
++ hash_op.len = chunksize;
++ hash_op.src = (unsigned char *)buffer;
++ hash_op.mac_result = mac;
++
++ if (ioctl(fdc, CIOCHASH, hash_op) != 0) {
++ perror("ioctl(CIOCHASH)");
++ return 1;
++ }
++ total += chunksize;
++ } while(must_finish == 0);
++ gettimeofday(&end, NULL);
++
++ secs = udifftimeval(start, end)/ 1000000.0;
++
++ value2human(1, total, secs, &ddata, &dspeed, metric);
++ printf ("done. %.2f %s in %.2f secs: ", ddata, metric, secs);
++ printf ("%.2f %s/sec\n", dspeed, metric);
++
++ free(buffer);
++ return 0;
++}
+
+ #ifdef CIOCGSESSINFO
+ int get_alignmask(struct session_op *sess, int fdc)
+@@ -154,6 +210,20 @@ int get_alignmask(struct session_op *sess, int fdc)
+ #endif
+
+
++int ciochash_session(struct session_op *sess, int fdc)
++{
++ int i;
++ int err = 0;
++
++ err = 0;
++ for(i = 0; (err == 0) && (buffer_lengths[i] != 0); i++) {
++ err = digest_data(sess, fdc, buffer_lengths[i], 0);
++ }
++
++ return err;
++}
++
++
+ int hash_session(struct session_op *sess, int fdc)
+ {
+ int i;
+@@ -193,6 +263,15 @@ int test_sha1(struct session_op *sess, int fdc)
+ }
+
+
++int test_sha1_ciochash(struct session_op *sess, int fdc)
++{
++ fprintf(stderr, "Testing SHA1 CIOCHASH: \n");
++ memset(sess, 0, sizeof(sess));
++ sess->mac = CRYPTO_SHA1;
++ return ciochash_session(sess, fdc);
++}
++
++
+ int test_sha256(struct session_op *sess, int fdc)
+ {
+ fprintf(stderr, "Testing SHA256 Hash: \n");
+@@ -202,6 +281,15 @@ int test_sha256(struct session_op *sess, int fdc)
+ }
+
+
++int test_sha256_ciochash(struct session_op *sess, int fdc)
++{
++ fprintf(stderr, "Testing SHA256 CIOCHASH: \n");
++ memset(sess, 0, sizeof(sess));
++ sess->mac = CRYPTO_SHA2_256;
++ return ciochash_session(sess, fdc);
++}
++
++
+ int main(void)
+ {
+ int fd;
+@@ -227,7 +315,9 @@ int main(void)
+
+ /* run all tests but return an eventual error */
+ err |= test_sha1(&sess, fdc);
++ err |= test_sha1_ciochash(&sess, fdc);
+ err |= test_sha256(&sess, fdc);
++ err |= test_sha256_ciochash(&sess, fdc);
+
+ close(fdc);
+ close(fd);
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0039-fix-memory-leaks-on-error-path-for-CIOCHASH.patch b/recipes-kernel/cryptodev/sdk_patches/0039-fix-memory-leaks-on-error-path-for-CIOCHASH.patch
new file mode 100644
index 00000000..fc2f4c88
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0039-fix-memory-leaks-on-error-path-for-CIOCHASH.patch
@@ -0,0 +1,70 @@
+From 3e3996b40fd3a93cbe2e5ddee244280dd7de6c18 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@freescale.com>
+Date: Tue, 9 Feb 2016 21:07:06 +0200
+Subject: [PATCH 39/40] fix memory leaks on error path for CIOCHASH
+
+Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
+---
+ ioctl.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/ioctl.c b/ioctl.c
+index ff3de44..8d81b56 100644
+--- a/ioctl.c
++++ b/ioctl.c
+@@ -1190,18 +1190,17 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
+ ret = hash_run(&khop);
+ if (unlikely(ret)) {
+ dwarning(1, "Error in hash run");
+- return ret;
++ goto hash_err;
+ }
+
+ ret = copy_to_user(khop.hash_op.mac_result, khop.hash_output, khop.digestsize);
+ if (unlikely(ret)) {
+ dwarning(1, "Error in copy to user");
+- return ret;
+ }
+
+- /* put session */
++ hash_err:
+ hash_destroy_session(khop.hash_op.ses);
+- return 0;
++ return ret;
+ case CIOCAUTHCRYPT:
+ if (unlikely(ret = kcaop_from_user(&kcaop, fcr, arg))) {
+ dwarning(1, "Error copying from user");
+@@ -1532,22 +1531,25 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
+ ret = hash_run(&khop);
+ if (unlikely(ret)) {
+ dwarning(1, "Error in hash run");
+- return ret;
++ goto hash_err;
+ }
+
+ ret = copy_to_user(khop.hash_op.mac_result, khop.hash_output,
+ khop.digestsize);
+ if (unlikely(ret)) {
+ dwarning(1, "Error in copy to user");
+- return ret;
++ goto hash_err;
+ }
+
+- copy_to_user(arg, &compat_hash_op_data,
++ ret = copy_to_user(arg, &compat_hash_op_data,
+ sizeof(struct compat_hash_op_data));
++ if (unlikely(ret)) {
++ dwarning(1, "Error in copy to user");
++ }
+
+- /* put session */
++ hash_err:
+ hash_destroy_session(khop.hash_op.ses);
+- return 0;
++ return ret;
+
+ case COMPAT_CIOCAUTHCRYPT:
+ if (unlikely(ret = compat_kcaop_from_user(&kcaop, fcr, arg))) {
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0040-fix-structure-init-in-sha_speed-test.patch b/recipes-kernel/cryptodev/sdk_patches/0040-fix-structure-init-in-sha_speed-test.patch
new file mode 100644
index 00000000..053d376c
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0040-fix-structure-init-in-sha_speed-test.patch
@@ -0,0 +1,53 @@
+From 3eb9ed52743584949ff9b4844e810333c34a3a1f Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Fri, 12 Feb 2016 11:23:41 +0200
+Subject: [PATCH 40/40] fix structure init in sha_speed test
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ tests/sha_speed.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tests/sha_speed.c b/tests/sha_speed.c
+index d731c66..75d0f42 100644
+--- a/tests/sha_speed.c
++++ b/tests/sha_speed.c
+@@ -257,7 +257,7 @@ int hash_session(struct session_op *sess, int fdc)
+ int test_sha1(struct session_op *sess, int fdc)
+ {
+ fprintf(stderr, "Testing SHA1 Hash: \n");
+- memset(sess, 0, sizeof(sess));
++ memset(sess, 0, sizeof(struct session_op));
+ sess->mac = CRYPTO_SHA1;
+ return hash_session(sess, fdc);
+ }
+@@ -266,7 +266,7 @@ int test_sha1(struct session_op *sess, int fdc)
+ int test_sha1_ciochash(struct session_op *sess, int fdc)
+ {
+ fprintf(stderr, "Testing SHA1 CIOCHASH: \n");
+- memset(sess, 0, sizeof(sess));
++ memset(sess, 0, sizeof(struct session_op));
+ sess->mac = CRYPTO_SHA1;
+ return ciochash_session(sess, fdc);
+ }
+@@ -275,7 +275,7 @@ int test_sha1_ciochash(struct session_op *sess, int fdc)
+ int test_sha256(struct session_op *sess, int fdc)
+ {
+ fprintf(stderr, "Testing SHA256 Hash: \n");
+- memset(sess, 0, sizeof(sess));
++ memset(sess, 0, sizeof(struct session_op));
+ sess->mac = CRYPTO_SHA2_256;
+ return hash_session(sess, fdc);
+ }
+@@ -284,7 +284,7 @@ int test_sha256(struct session_op *sess, int fdc)
+ int test_sha256_ciochash(struct session_op *sess, int fdc)
+ {
+ fprintf(stderr, "Testing SHA256 CIOCHASH: \n");
+- memset(sess, 0, sizeof(sess));
++ memset(sess, 0, sizeof(struct session_op));
+ sess->mac = CRYPTO_SHA2_256;
+ return ciochash_session(sess, fdc);
+ }
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0041-add-separate-target-for-building-tests.patch b/recipes-kernel/cryptodev/sdk_patches/0041-add-separate-target-for-building-tests.patch
new file mode 100644
index 00000000..ff738254
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0041-add-separate-target-for-building-tests.patch
@@ -0,0 +1,38 @@
+From 0d58530f5c5970db9787a23aef4227c68f941fcc Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Wed, 10 Feb 2016 16:22:05 +0200
+Subject: [PATCH 41/43] add separate target for building tests
+
+A separate target for build is useful with cross-compilation. In this
+case it makes sense to build the tests without running them on the host
+machine.
+
+The default target is now 'all' and only builds the tests
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ tests/Makefile | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tests/Makefile b/tests/Makefile
+index 3155da9..89f88fe 100644
+--- a/tests/Makefile
++++ b/tests/Makefile
+@@ -19,6 +19,8 @@ example-async-hmac-objs := async_hmac.o
+ example-async-speed-objs := async_speed.o
+ example-hashcrypt-speed-objs := hashcrypt_speed.c
+
++all: $(hostprogs)
++
+ check: $(hostprogs)
+ ./cipher
+ ./hmac
+@@ -33,3 +35,5 @@ clean:
+
+ ${comp_progs}: LDLIBS += -lssl -lcrypto
+ ${comp_progs}: %: %.o openssl_wrapper.o
++
++.PHONY: all clean check
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0042-fix-destination-for-staged-installs.patch b/recipes-kernel/cryptodev/sdk_patches/0042-fix-destination-for-staged-installs.patch
new file mode 100644
index 00000000..c8ae06e3
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0042-fix-destination-for-staged-installs.patch
@@ -0,0 +1,55 @@
+From dcb8fe0fcf71feac2a4f57c44a5153bfc404b4c3 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Thu, 11 Feb 2016 16:37:23 +0200
+Subject: [PATCH 42/43] fix destination for staged installs
+
+The standard variable for staged installations is DESTDIR and it should
+be set only by the user, outside of Makefile. This is consistent with
+recommendations from both GNU Make and FreeBSD porters-handbook.
+
+ make DESTDIR=/tmp/stage install
+
+$prefix and $PREFIX (in FreeBSD world) are used to specify where the
+files will be installed. It defaults to /usr/local but can be /usr or
+/opt or something else.
+
+Usually one wants to do a stage installation when cross-building or for
+other purposes. The convention is to use DESTDIR.
+Changing $prefix is useful for installers. They can override its value
+when calling make:
+
+ make prefix=/usr install
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ Makefile | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 7f8df37..9871a8e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -7,7 +7,9 @@ CRYPTODEV_CFLAGS ?= #-DENABLE_ASYNC
+ KBUILD_CFLAGS += -I$(src) $(CRYPTODEV_CFLAGS)
+ KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
+ VERSION = 1.8
+-PREFIX ?=
++
++prefix ?= /usr/local
++includedir = $(prefix)/include
+
+ cryptodev-objs = ioctl.o main.o cryptlib.o authenc.o zc.o util.o
+
+@@ -31,8 +33,7 @@ install: modules_install
+
+ modules_install:
+ $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install
+- @echo "Installing cryptodev.h in $(PREFIX)/usr/include/crypto ..."
+- @install -D crypto/cryptodev.h $(PREFIX)/usr/include/crypto/cryptodev.h
++ install -m 644 -D crypto/cryptodev.h $(DESTDIR)/$(includedir)/crypto/cryptodev.h
+
+ clean:
+ $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
+--
+2.7.0
+
diff --git a/recipes-kernel/cryptodev/sdk_patches/0043-add-install-target-for-tests.patch b/recipes-kernel/cryptodev/sdk_patches/0043-add-install-target-for-tests.patch
new file mode 100644
index 00000000..f3b70228
--- /dev/null
+++ b/recipes-kernel/cryptodev/sdk_patches/0043-add-install-target-for-tests.patch
@@ -0,0 +1,46 @@
+From 44629033d47543d106299b6c8bed9e5c9fed1513 Mon Sep 17 00:00:00 2001
+From: Cristian Stoica <cristian.stoica@nxp.com>
+Date: Thu, 11 Feb 2016 16:48:53 +0200
+Subject: [PATCH 43/43] add install target for tests
+
+Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
+---
+ tests/Makefile | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/tests/Makefile b/tests/Makefile
+index 89f88fe..5e3111d 100644
+--- a/tests/Makefile
++++ b/tests/Makefile
+@@ -19,6 +19,10 @@ example-async-hmac-objs := async_hmac.o
+ example-async-speed-objs := async_speed.o
+ example-hashcrypt-speed-objs := hashcrypt_speed.c
+
++prefix ?= /usr/local
++execprefix ?= $(prefix)
++bindir = $(execprefix)/bin
++
+ all: $(hostprogs)
+
+ check: $(hostprogs)
+@@ -30,10 +34,16 @@ check: $(hostprogs)
+ ./cipher-gcm
+ ./cipher-aead
+
++install:
++ install -d $(DESTDIR)/$(bindir)
++ for prog in $(hostprogs); do \
++ install -m 755 $$prog $(DESTDIR)/$(bindir); \
++ done
++
+ clean:
+ rm -f *.o *~ $(hostprogs)
+
+ ${comp_progs}: LDLIBS += -lssl -lcrypto
+ ${comp_progs}: %: %.o openssl_wrapper.o
+
+-.PHONY: all clean check
++.PHONY: all clean check install
+--
+2.7.0
+