From 5127db3483a2e4f6dc13330bea7237931c5f15a0 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Wed, 19 Mar 2014 14:02:46 +0800 Subject: [PATCH 08/15] Add RSA Key generation offloading Upstream-status: Pending Signed-off-by: Hou Zhiqiang Tested-by: Cristian Stoica --- 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.3.5