aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel/cryptodev/sdk_patches/0003-PKC-support-added-in-cryptodev-module.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/cryptodev/sdk_patches/0003-PKC-support-added-in-cryptodev-module.patch')
-rw-r--r--recipes-kernel/cryptodev/sdk_patches/0003-PKC-support-added-in-cryptodev-module.patch898
1 files changed, 0 insertions, 898 deletions
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
deleted file mode 100644
index ffa0b453..00000000
--- a/recipes-kernel/cryptodev/sdk_patches/0003-PKC-support-added-in-cryptodev-module.patch
+++ /dev/null
@@ -1,898 +0,0 @@
-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
-