aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-connectivity/openssl/openssl-qoriq/qoriq/0008-Initial-support-for-PKC-in-cryptodev-engine.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-connectivity/openssl/openssl-qoriq/qoriq/0008-Initial-support-for-PKC-in-cryptodev-engine.patch')
-rw-r--r--recipes-connectivity/openssl/openssl-qoriq/qoriq/0008-Initial-support-for-PKC-in-cryptodev-engine.patch1564
1 files changed, 0 insertions, 1564 deletions
diff --git a/recipes-connectivity/openssl/openssl-qoriq/qoriq/0008-Initial-support-for-PKC-in-cryptodev-engine.patch b/recipes-connectivity/openssl/openssl-qoriq/qoriq/0008-Initial-support-for-PKC-in-cryptodev-engine.patch
deleted file mode 100644
index 98272ab..0000000
--- a/recipes-connectivity/openssl/openssl-qoriq/qoriq/0008-Initial-support-for-PKC-in-cryptodev-engine.patch
+++ /dev/null
@@ -1,1564 +0,0 @@
-From 107a10d45db0f2e58482f698add04ed9183f7268 Mon Sep 17 00:00:00 2001
-From: Yashpal Dutta <yashpal.dutta@freescale.com>
-Date: Tue, 11 Mar 2014 06:29:52 +0545
-Subject: [PATCH 08/26] Initial support for PKC in cryptodev engine
-
-Upstream-status: Pending
-
-Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
----
- crypto/engine/eng_cryptodev.c | 1343 ++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 1183 insertions(+), 160 deletions(-)
-
-diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
-index e3eb98b..7ee314b 100644
---- a/crypto/engine/eng_cryptodev.c
-+++ b/crypto/engine/eng_cryptodev.c
-@@ -54,11 +54,14 @@ ENGINE_load_cryptodev(void)
- #else
-
- #include <sys/types.h>
--#include <crypto/cryptodev.h>
- #include <crypto/dh/dh.h>
- #include <crypto/dsa/dsa.h>
- #include <crypto/err/err.h>
- #include <crypto/rsa/rsa.h>
-+#include <crypto/ecdsa/ecs_locl.h>
-+#include <crypto/ecdh/ech_locl.h>
-+#include <crypto/ec/ec_lcl.h>
-+#include <crypto/ec/ec.h>
- #include <sys/ioctl.h>
- #include <errno.h>
- #include <stdio.h>
-@@ -68,6 +71,8 @@ ENGINE_load_cryptodev(void)
- #include <syslog.h>
- #include <errno.h>
- #include <string.h>
-+#include "eng_cryptodev_ec.h"
-+#include <crypto/cryptodev.h>
-
- struct dev_crypto_state {
- struct session_op d_sess;
-@@ -116,18 +121,10 @@ static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
- static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
- RSA *rsa, BN_CTX *ctx);
- static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
--static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
-- const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
--static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
-- BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
-- BN_CTX *ctx, BN_MONT_CTX *mont);
- static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
- int dlen, DSA *dsa);
- static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
- DSA_SIG *sig, DSA *dsa);
--static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
-- const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
-- BN_MONT_CTX *m_ctx);
- static int cryptodev_dh_compute_key(unsigned char *key,
- const BIGNUM *pub_key, DH *dh);
- static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
-@@ -136,6 +133,102 @@ void ENGINE_load_cryptodev(void);
- const EVP_CIPHER cryptodev_aes_128_cbc_hmac_sha1;
- const EVP_CIPHER cryptodev_aes_256_cbc_hmac_sha1;
-
-+static int spcf_bn2bin(BIGNUM *bn, unsigned char **bin, int *bin_len)
-+{
-+ int len;
-+ unsigned char *p;
-+
-+ len = BN_num_bytes(bn);
-+
-+ if (!len)
-+ return -1;
-+
-+ p = malloc(len);
-+ if (!p)
-+ return -1;
-+
-+ BN_bn2bin(bn,p);
-+
-+ *bin = p;
-+ *bin_len = len;
-+
-+ return 0;
-+}
-+
-+static int spcf_bn2bin_ex(BIGNUM *bn, unsigned char **bin, int *bin_len)
-+{
-+ int len;
-+ unsigned char *p;
-+
-+ len = BN_num_bytes(bn);
-+
-+ if (!len)
-+ return -1;
-+
-+ if (len < *bin_len)
-+ p = malloc(*bin_len);
-+ else
-+ p = malloc(len);
-+
-+ if (!p)
-+ return -ENOMEM;
-+
-+ if (len < *bin_len) {
-+ /* place padding */
-+ memset(p, 0, (*bin_len - len));
-+ BN_bn2bin(bn,p+(*bin_len-len));
-+ } else {
-+ BN_bn2bin(bn,p);
-+ }
-+
-+ *bin = p;
-+ if (len >= *bin_len)
-+ *bin_len = len;
-+
-+ return 0;
-+}
-+
-+/**
-+ * Convert an ECC F2m 'b' parameter into the 'c' parameter.
-+ *Inputs:
-+ * q, the curve's modulus
-+ * b, the curve's b parameter
-+ * (a bignum for b, a buffer for c)
-+ * Output:
-+ * c, written into bin, right-adjusted to fill q_len bytes.
-+ */
-+static int
-+eng_ec_compute_cparam(const BIGNUM* b, const BIGNUM* q,
-+ unsigned char **bin, int *bin_len)
-+{
-+ BIGNUM* c = BN_new();
-+ BIGNUM* exp = BN_new();
-+ BN_CTX *ctx = BN_CTX_new();
-+ int m = BN_num_bits(q) - 1;
-+ int ok = 0;
-+
-+ if (!c || !exp || !ctx || *bin)
-+ goto err;
-+
-+ /*
-+ * We have to compute c, where b = c^4, i.e., the fourth root of b.
-+ * The equation for c is c = b^(2^(m-2))
-+ * Compute exp = 2^(m-2)
-+ * (1 << x) == 2^x
-+ * and then compute c = b^exp
-+ */
-+ BN_lshift(exp, BN_value_one(), m-2);
-+ BN_GF2m_mod_exp(c, b, exp, q, ctx);
-+ /* Store c */
-+ spcf_bn2bin_ex(c, bin, bin_len);
-+ ok = 1;
-+err:
-+ if (ctx) BN_CTX_free(ctx);
-+ if (c) BN_free(c);
-+ if (exp) BN_free(exp);
-+ return ok;
-+}
-+
- static const ENGINE_CMD_DEFN cryptodev_defns[] = {
- { 0, NULL, NULL, 0 }
- };
-@@ -1139,7 +1232,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
- static int
- bn2crparam(const BIGNUM *a, struct crparam *crp)
- {
-- int i, j, k;
- ssize_t bytes, bits;
- u_char *b;
-
-@@ -1156,15 +1248,7 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
-
- crp->crp_p = (caddr_t) b;
- crp->crp_nbits = bits;
--
-- for (i = 0, j = 0; i < a->top; i++) {
-- for (k = 0; k < BN_BITS2 / 8; k++) {
-- if ((j + k) >= bytes)
-- return (0);
-- b[j + k] = a->d[i] >> (k * 8);
-- }
-- j += BN_BITS2 / 8;
-- }
-+ BN_bn2bin(a, crp->crp_p);
- return (0);
- }
-
-@@ -1172,22 +1256,14 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
- static int
- crparam2bn(struct crparam *crp, BIGNUM *a)
- {
-- u_int8_t *pd;
-- int i, bytes;
-+ int bytes;
-
- bytes = (crp->crp_nbits + 7) / 8;
-
- if (bytes == 0)
- return (-1);
-
-- if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
-- return (-1);
--
-- for (i = 0; i < bytes; i++)
-- pd[i] = crp->crp_p[bytes - i - 1];
--
-- BN_bin2bn(pd, bytes, a);
-- free(pd);
-+ BN_bin2bn(crp->crp_p, bytes, a);
-
- return (0);
- }
-@@ -1235,6 +1311,32 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
- return (ret);
- }
-
-+/* Close an opened instance of cryptodev engine */
-+void cryptodev_close_instance(void *handle)
-+{
-+ int fd;
-+
-+ if (handle) {
-+ fd = *(int *)handle;
-+ close(fd);
-+ free(handle);
-+ }
-+}
-+
-+/* Create an instance of cryptodev for asynchronous interface */
-+void *cryptodev_init_instance(void)
-+{
-+ int *fd = malloc(sizeof(int));
-+
-+ if (fd) {
-+ if ((*fd = open("/dev/crypto", O_RDWR, 0)) == -1) {
-+ free(fd);
-+ return NULL;
-+ }
-+ }
-+ return fd;
-+}
-+
- static int
- cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
-@@ -1250,9 +1352,9 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- return (ret);
- }
-
-- memset(&kop, 0, sizeof kop);
- kop.crk_op = CRK_MOD_EXP;
--
-+ kop.crk_oparams = 0;
-+ kop.crk_status = 0;
- /* inputs: a^p % m */
- if (bn2crparam(a, &kop.crk_param[0]))
- goto err;
-@@ -1293,28 +1395,38 @@ static int
- cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
- {
- struct crypt_kop kop;
-- int ret = 1;
-+ int ret = 1, f_len, p_len, q_len;
-+ unsigned char *f = NULL, *p = NULL, *q = NULL, *dp = NULL, *dq = NULL, *c = NULL;
-
- if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
- /* XXX 0 means failure?? */
- return (0);
- }
-
-- memset(&kop, 0, sizeof kop);
-+ kop.crk_oparams = 0;
-+ kop.crk_status = 0;
- kop.crk_op = CRK_MOD_EXP_CRT;
-+ f_len = BN_num_bytes(rsa->n);
-+ spcf_bn2bin_ex(I, &f, &f_len);
-+ spcf_bn2bin(rsa->p, &p, &p_len);
-+ spcf_bn2bin(rsa->q, &q, &q_len);
-+ spcf_bn2bin_ex(rsa->dmp1, &dp, &p_len);
-+ spcf_bn2bin_ex(rsa->iqmp, &c, &p_len);
-+ spcf_bn2bin_ex(rsa->dmq1, &dq, &q_len);
- /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
-- if (bn2crparam(rsa->p, &kop.crk_param[0]))
-- goto err;
-- if (bn2crparam(rsa->q, &kop.crk_param[1]))
-- goto err;
-- if (bn2crparam(I, &kop.crk_param[2]))
-- goto err;
-- if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
-- goto err;
-- if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
-- goto err;
-- if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
-- goto err;
-+ kop.crk_param[0].crp_p = p;
-+ kop.crk_param[0].crp_nbits = p_len * 8;
-+ kop.crk_param[1].crp_p = q;
-+ kop.crk_param[1].crp_nbits = q_len * 8;
-+ kop.crk_param[2].crp_p = f;
-+ kop.crk_param[2].crp_nbits = f_len * 8;
-+ kop.crk_param[3].crp_p = dp;
-+ kop.crk_param[3].crp_nbits = p_len * 8;
-+ /* dq must of length q, rest all of length p*/
-+ kop.crk_param[4].crp_p = dq;
-+ kop.crk_param[4].crp_nbits = q_len * 8;
-+ kop.crk_param[5].crp_p = c;
-+ kop.crk_param[5].crp_nbits = p_len * 8;
- kop.crk_iparams = 6;
-
- if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
-@@ -1350,90 +1462,117 @@ static RSA_METHOD cryptodev_rsa = {
- NULL /* rsa_verify */
- };
-
--static int
--cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
-- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
--{
-- return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
--}
--
--static int
--cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
-- BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
-- BN_CTX *ctx, BN_MONT_CTX *mont)
-+static DSA_SIG *
-+cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
- {
-- BIGNUM t2;
-- int ret = 0;
--
-- BN_init(&t2);
--
-- /* v = ( g^u1 * y^u2 mod p ) mod q */
-- /* let t1 = g ^ u1 mod p */
-- ret = 0;
-+ struct crypt_kop kop;
-+ BIGNUM *c = NULL, *d = NULL;
-+ DSA_SIG *dsaret = NULL;
-+ int q_len = 0, r_len = 0, g_len = 0;
-+ int priv_key_len = 0, ret;
-+ unsigned char *q = NULL, *r = NULL, *g = NULL, *priv_key = NULL, *f = NULL;
-
-- if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
-+ memset(&kop, 0, sizeof kop);
-+ if ((c = BN_new()) == NULL) {
-+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
- goto err;
-+ }
-
-- /* let t2 = y ^ u2 mod p */
-- if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
-+ if ((d = BN_new()) == NULL) {
-+ BN_free(c);
-+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
- goto err;
-- /* let u1 = t1 * t2 mod p */
-- if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
-+ }
-+
-+ if (spcf_bn2bin(dsa->p, &q, &q_len)) {
-+ DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
- goto err;
-+ }
-
-- BN_copy(t1,u1);
-+ /* Get order of the field of private keys into plain buffer */
-+ if (spcf_bn2bin (dsa->q, &r, &r_len)) {
-+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-
-- ret = 1;
--err:
-- BN_free(&t2);
-- return(ret);
--}
-+ /* sanity test */
-+ if (dlen > r_len) {
-+ DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-+ goto err;
-+ }
-
--static DSA_SIG *
--cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
--{
-- struct crypt_kop kop;
-- BIGNUM *r = NULL, *s = NULL;
-- DSA_SIG *dsaret = NULL;
-+ g_len = q_len;
-+ /**
-+ * Get generator into a plain buffer. If length is less than
-+ * q_len then add leading padding bytes.
-+ */
-+ if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
-+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-
-- if ((r = BN_new()) == NULL)
-+ priv_key_len = r_len;
-+ /**
-+ * Get private key into a plain buffer. If length is less than
-+ * r_len then add leading padding bytes.
-+ */
-+ if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
-+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
- goto err;
-- if ((s = BN_new()) == NULL) {
-- BN_free(r);
-+ }
-+
-+ /* Allocate memory to store hash. */
-+ f = OPENSSL_malloc (r_len);
-+ if (!f) {
-+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
-- memset(&kop, 0, sizeof kop);
-+ /* Add padding, since SEC expects hash to of size r_len */
-+ if (dlen < r_len)
-+ memset(f, 0, r_len - dlen);
-+
-+ /* Skip leading bytes if dgst_len < r_len */
-+ memcpy(f + r_len - dlen, dgst, dlen);
-+
- kop.crk_op = CRK_DSA_SIGN;
-
- /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
-- kop.crk_param[0].crp_p = (caddr_t)dgst;
-- kop.crk_param[0].crp_nbits = dlen * 8;
-- if (bn2crparam(dsa->p, &kop.crk_param[1]))
-- goto err;
-- if (bn2crparam(dsa->q, &kop.crk_param[2]))
-- goto err;
-- if (bn2crparam(dsa->g, &kop.crk_param[3]))
-- goto err;
-- if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
-- goto err;
-+ kop.crk_param[0].crp_p = (void*)f;
-+ kop.crk_param[0].crp_nbits = r_len * 8;
-+ kop.crk_param[1].crp_p = (void*)q;
-+ kop.crk_param[1].crp_nbits = q_len * 8;
-+ kop.crk_param[2].crp_p = (void*)r;
-+ kop.crk_param[2].crp_nbits = r_len * 8;
-+ kop.crk_param[3].crp_p = (void*)g;
-+ kop.crk_param[3].crp_nbits = g_len * 8;
-+ kop.crk_param[4].crp_p = (void*)priv_key;
-+ kop.crk_param[4].crp_nbits = priv_key_len * 8;
- kop.crk_iparams = 5;
-
-- if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
-- BN_num_bytes(dsa->q), s) == 0) {
-- dsaret = DSA_SIG_new();
-- dsaret->r = r;
-- dsaret->s = s;
-- } else {
-- const DSA_METHOD *meth = DSA_OpenSSL();
-- BN_free(r);
-- BN_free(s);
-- dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
-+ ret = cryptodev_asym(&kop, r_len, c, r_len, d);
-+
-+ if (ret) {
-+ DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DECODE_ERROR);
-+ goto err;
- }
--err:
-- kop.crk_param[0].crp_p = NULL;
-+
-+ dsaret = DSA_SIG_new();
-+ dsaret->r = c;
-+ dsaret->s = d;
-+
- zapparams(&kop);
- return (dsaret);
-+err:
-+ {
-+ const DSA_METHOD *meth = DSA_OpenSSL();
-+ if (c)
-+ BN_free(c);
-+ if (d)
-+ BN_free(d);
-+ dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
-+ return (dsaret);
-+ }
- }
-
- static int
-@@ -1441,42 +1580,179 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
- DSA_SIG *sig, DSA *dsa)
- {
- struct crypt_kop kop;
-- int dsaret = 1;
-+ int dsaret = 1, q_len = 0, r_len = 0, g_len = 0;
-+ int w_len = 0 ,c_len = 0, d_len = 0, ret = -1;
-+ unsigned char * q = NULL, * r = NULL, * w = NULL, * g = NULL;
-+ unsigned char * c = NULL, * d = NULL, *f = NULL;
-
- memset(&kop, 0, sizeof kop);
- kop.crk_op = CRK_DSA_VERIFY;
-
-- /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
-- kop.crk_param[0].crp_p = (caddr_t)dgst;
-- kop.crk_param[0].crp_nbits = dlen * 8;
-- if (bn2crparam(dsa->p, &kop.crk_param[1]))
-+ if (spcf_bn2bin(dsa->p, &q, &q_len)) {
-+ DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ return ret;
-+ }
-+
-+ /* Get Order of field of private keys */
-+ if (spcf_bn2bin(dsa->q, &r, &r_len)) {
-+ DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
- goto err;
-- if (bn2crparam(dsa->q, &kop.crk_param[2]))
-+ }
-+
-+ g_len = q_len;
-+ /**
-+ * Get generator into a plain buffer. If length is less than
-+ * q_len then add leading padding bytes.
-+ */
-+ if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
-+ DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
- goto err;
-- if (bn2crparam(dsa->g, &kop.crk_param[3]))
-+ }
-+ w_len = q_len;
-+ /**
-+ * Get public key into a plain buffer. If length is less than
-+ * q_len then add leading padding bytes.
-+ */
-+ if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
-+ DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+ /**
-+ * Get the 1st part of signature into a flat buffer with
-+ * appropriate padding
-+ */
-+ c_len = r_len;
-+
-+ if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
- goto err;
-- if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
-+ }
-+
-+ /**
-+ * Get the 2nd part of signature into a flat buffer with
-+ * appropriate padding
-+ */
-+ d_len = r_len;
-+
-+ if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
- goto err;
-- if (bn2crparam(sig->r, &kop.crk_param[5]))
-+ }
-+
-+
-+ /* Sanity test */
-+ if (dlen > r_len) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
- goto err;
-- if (bn2crparam(sig->s, &kop.crk_param[6]))
-+ }
-+
-+ /* Allocate memory to store hash. */
-+ f = OPENSSL_malloc (r_len);
-+ if (!f) {
-+ DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
- goto err;
-+ }
-+
-+ /* Add padding, since SEC expects hash to of size r_len */
-+ if (dlen < r_len)
-+ memset(f, 0, r_len - dlen);
-+
-+ /* Skip leading bytes if dgst_len < r_len */
-+ memcpy(f + r_len - dlen, dgst, dlen);
-+
-+ /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
-+ kop.crk_param[0].crp_p = (void*)f;
-+ kop.crk_param[0].crp_nbits = r_len * 8;
-+ kop.crk_param[1].crp_p = q;
-+ kop.crk_param[1].crp_nbits = q_len * 8;
-+ kop.crk_param[2].crp_p = r;
-+ kop.crk_param[2].crp_nbits = r_len * 8;
-+ kop.crk_param[3].crp_p = g;
-+ kop.crk_param[3].crp_nbits = g_len * 8;
-+ kop.crk_param[4].crp_p = w;
-+ kop.crk_param[4].crp_nbits = w_len * 8;
-+ kop.crk_param[5].crp_p = c;
-+ kop.crk_param[5].crp_nbits = c_len * 8;
-+ kop.crk_param[6].crp_p = d;
-+ kop.crk_param[6].crp_nbits = d_len * 8;
- kop.crk_iparams = 7;
-
-- if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
--/*OCF success value is 0, if not zero, change dsaret to fail*/
-- if(0 != kop.crk_status) dsaret = 0;
-- } else {
-- const DSA_METHOD *meth = DSA_OpenSSL();
-+ if ((cryptodev_asym(&kop, 0, NULL, 0, NULL))) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
-+ goto err;
-+ }
-
-- dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
-+ /*OCF success value is 0, if not zero, change dsaret to fail*/
-+ if(0 != kop.crk_status) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
-+ goto err;
- }
--err:
-- kop.crk_param[0].crp_p = NULL;
-+
- zapparams(&kop);
- return (dsaret);
-+err:
-+ {
-+ const DSA_METHOD *meth = DSA_OpenSSL();
-+
-+ dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
-+ }
-+ return dsaret;
- }
-
-+/* Cryptodev DSA Key Gen routine */
-+static int cryptodev_dsa_keygen(DSA *dsa)
-+{
-+ struct crypt_kop kop;
-+ int ret = 1, g_len;
-+ unsigned char *g = NULL;
-+
-+ if (dsa->priv_key == NULL) {
-+ if ((dsa->priv_key=BN_new()) == NULL)
-+ goto sw_try;
-+ }
-+
-+ if (dsa->pub_key == NULL) {
-+ if ((dsa->pub_key=BN_new()) == NULL)
-+ goto sw_try;
-+ }
-+
-+ g_len = BN_num_bytes(dsa->p);
-+ /**
-+ * Get generator into a plain buffer. If length is less than
-+ * p_len then add leading padding bytes.
-+ */
-+ if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
-+ DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
-+ goto sw_try;
-+ }
-+
-+ memset(&kop, 0, sizeof kop);
-+
-+ kop.crk_op = CRK_DSA_GENERATE_KEY;
-+ if (bn2crparam(dsa->p, &kop.crk_param[0]))
-+ goto sw_try;
-+ if (bn2crparam(dsa->q, &kop.crk_param[1]))
-+ goto sw_try;
-+ kop.crk_param[2].crp_p = g;
-+ kop.crk_param[2].crp_nbits = g_len * 8;
-+ kop.crk_iparams = 3;
-+
-+ /* pub_key is or prime length while priv key is of length of order */
-+ if (cryptodev_asym(&kop, BN_num_bytes(dsa->p), dsa->pub_key,
-+ BN_num_bytes(dsa->q), dsa->priv_key))
-+ goto sw_try;
-+
-+ return ret;
-+sw_try:
-+ {
-+ const DSA_METHOD *meth = DSA_OpenSSL();
-+ ret = (meth->dsa_keygen)(dsa);
-+ }
-+ return ret;
-+}
-+
-+
-+
- static DSA_METHOD cryptodev_dsa = {
- "cryptodev DSA method",
- NULL,
-@@ -1490,12 +1766,543 @@ static DSA_METHOD cryptodev_dsa = {
- NULL /* app_data */
- };
-
--static int
--cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
-- const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
-- BN_MONT_CTX *m_ctx)
-+static ECDSA_METHOD cryptodev_ecdsa = {
-+ "cryptodev ECDSA method",
-+ NULL,
-+ NULL, /* ecdsa_sign_setup */
-+ NULL,
-+ NULL,
-+ 0, /* flags */
-+ NULL /* app_data */
-+};
-+
-+typedef enum ec_curve_s
-+{
-+ EC_PRIME,
-+ EC_BINARY
-+} ec_curve_t;
-+
-+/* ENGINE handler for ECDSA Sign */
-+static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char *dgst,
-+ int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
- {
-- return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
-+ BIGNUM *m = NULL, *p = NULL, *a = NULL;
-+ BIGNUM *b = NULL, *x = NULL, *y = NULL;
-+ BN_CTX *ctx = NULL;
-+ ECDSA_SIG *ret = NULL;
-+ ECDSA_DATA *ecdsa = NULL;
-+ unsigned char * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
-+ unsigned char * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
-+ int i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
-+ int g_len = 0, d_len = 0, ab_len = 0;
-+ const BIGNUM *order = NULL, *priv_key=NULL;
-+ const EC_GROUP *group = NULL;
-+ struct crypt_kop kop;
-+ ec_curve_t ec_crv = EC_PRIME;
-+
-+ memset(&kop, 0, sizeof(kop));
-+ ecdsa = ecdsa_check(eckey);
-+ if (!ecdsa) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
-+ return NULL;
-+ }
-+
-+ group = EC_KEY_get0_group(eckey);
-+ priv_key = EC_KEY_get0_private_key(eckey);
-+
-+ if (!group || !priv_key) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
-+ return NULL;
-+ }
-+
-+ if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
-+ (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
-+ (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
-+ (y = BN_new()) == NULL) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ order = &group->order;
-+ if (!order || BN_is_zero(order)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
-+ goto err;
-+ }
-+
-+ i = BN_num_bits(order);
-+ /* Need to truncate digest if it is too long: first truncate whole
-+ bytes */
-+ if (8 * dgst_len > i)
-+ dgst_len = (i + 7)/8;
-+
-+ if (!BN_bin2bn(dgst, dgst_len, m)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
-+ goto err;
-+ }
-+
-+ /* If still too long truncate remaining bits with a shift */
-+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
-+ goto err;
-+ }
-+
-+ /* copy the truncated bits into plain buffer */
-+ if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
-+ fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__);
-+ goto err;
-+ }
-+
-+ ret = ECDSA_SIG_new();
-+ if (!ret) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
-+ goto err;
-+ }
-+
-+ /* check if this is prime or binary EC request */
-+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
-+ ec_crv = EC_PRIME;
-+ /* get the generator point pair */
-+ if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group),
-+ x, y,ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+
-+ /* get the ECC curve parameters */
-+ if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+ } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) {
-+ ec_crv = EC_BINARY;
-+ /* get the ECC curve parameters */
-+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+
-+ /* get the generator point pair */
-+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
-+ EC_GROUP_get0_generator(group), x, y,ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+ } else {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+
-+ if (spcf_bn2bin(order, &r, &r_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ if (spcf_bn2bin(p, &q, &q_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ priv_key_len = r_len;
-+
-+ /**
-+ * If BN_num_bytes of priv_key returns less then r_len then
-+ * add padding bytes before the key
-+ */
-+ if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Generation of ECC curve parameters */
-+ ab_len = 2*q_len;
-+ ab = eng_copy_curve_points(a, b, ab_len, q_len);
-+ if (!ab) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ if (ec_crv == EC_BINARY) {
-+ if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
-+ {
-+ unsigned char *c_temp = NULL;
-+ int c_temp_len = q_len;
-+ if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
-+ memcpy(ab+q_len, c_temp, q_len);
-+ else
-+ goto err;
-+ }
-+ kop.curve_type = ECC_BINARY;
-+ }
-+
-+ /* Calculation of Generator point */
-+ g_len = 2*q_len;
-+ g_xy = eng_copy_curve_points(x, y, g_len, q_len);
-+ if (!g_xy) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Memory allocation for first part of digital signature */
-+ c = malloc(r_len);
-+ if (!c) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ d_len = r_len;
-+
-+ /* Memory allocation for second part of digital signature */
-+ d = malloc(d_len);
-+ if (!d) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* memory for message representative */
-+ f = malloc(r_len);
-+ if (!f) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Add padding, since SEC expects hash to of size r_len */
-+ memset(f, 0, r_len - dgst_len);
-+
-+ /* Skip leading bytes if dgst_len < r_len */
-+ memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
-+
-+ dgst_len += r_len - dgst_len;
-+ kop.crk_op = CRK_DSA_SIGN;
-+ /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
-+ kop.crk_param[0].crp_p = f;
-+ kop.crk_param[0].crp_nbits = dgst_len * 8;
-+ kop.crk_param[1].crp_p = q;
-+ kop.crk_param[1].crp_nbits = q_len * 8;
-+ kop.crk_param[2].crp_p = r;
-+ kop.crk_param[2].crp_nbits = r_len * 8;
-+ kop.crk_param[3].crp_p = g_xy;
-+ kop.crk_param[3].crp_nbits = g_len * 8;
-+ kop.crk_param[4].crp_p = s;
-+ kop.crk_param[4].crp_nbits = priv_key_len * 8;
-+ kop.crk_param[5].crp_p = ab;
-+ kop.crk_param[5].crp_nbits = ab_len * 8;
-+ kop.crk_iparams = 6;
-+ kop.crk_param[6].crp_p = c;
-+ kop.crk_param[6].crp_nbits = d_len * 8;
-+ kop.crk_param[7].crp_p = d;
-+ kop.crk_param[7].crp_nbits = d_len * 8;
-+ kop.crk_oparams = 2;
-+
-+ if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
-+ /* Check if ret->r and s needs to allocated */
-+ crparam2bn(&kop.crk_param[6], ret->r);
-+ crparam2bn(&kop.crk_param[7], ret->s);
-+ } else {
-+ const ECDSA_METHOD *meth = ECDSA_OpenSSL();
-+ ret = (meth->ecdsa_do_sign)(dgst, dgst_len, in_kinv, in_r, eckey);
-+ }
-+ kop.crk_param[0].crp_p = NULL;
-+ zapparams(&kop);
-+err:
-+ if (!ret) {
-+ ECDSA_SIG_free(ret);
-+ ret = NULL;
-+ }
-+ return ret;
-+}
-+
-+static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len,
-+ ECDSA_SIG *sig, EC_KEY *eckey)
-+{
-+ BIGNUM *m = NULL, *p = NULL, *a = NULL, *b = NULL;
-+ BIGNUM *x = NULL, *y = NULL, *w_x = NULL, *w_y = NULL;
-+ BN_CTX *ctx = NULL;
-+ ECDSA_DATA *ecdsa = NULL;
-+ unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL, *w_xy = NULL;
-+ unsigned char *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
-+ int i = 0, q_len = 0, pub_key_len = 0, r_len = 0, c_len = 0, g_len = 0;
-+ int d_len = 0, ab_len = 0, ret = -1;
-+ const EC_POINT *pub_key = NULL;
-+ const BIGNUM *order = NULL;
-+ const EC_GROUP *group=NULL;
-+ ec_curve_t ec_crv = EC_PRIME;
-+ struct crypt_kop kop;
-+
-+ memset(&kop, 0, sizeof kop);
-+ ecdsa = ecdsa_check(eckey);
-+ if (!ecdsa) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
-+ return ret;
-+ }
-+
-+ group = EC_KEY_get0_group(eckey);
-+ pub_key = EC_KEY_get0_public_key(eckey);
-+
-+ if (!group || !pub_key) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
-+ return ret;
-+ }
-+
-+ if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
-+ (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
-+ (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
-+ (y = BN_new()) == NULL || (w_x = BN_new()) == NULL ||
-+ (w_y = BN_new()) == NULL) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ order = &group->order;
-+ if (!order || BN_is_zero(order)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
-+ goto err;
-+ }
-+
-+ i = BN_num_bits(order);
-+ /* Need to truncate digest if it is too long: first truncate whole
-+ * bytes */
-+ if (8 * dgst_len > i)
-+ dgst_len = (i + 7)/8;
-+
-+ if (!BN_bin2bn(dgst, dgst_len, m)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
-+ goto err;
-+ }
-+
-+ /* If still too long truncate remaining bits with a shift */
-+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
-+ goto err;
-+ }
-+ /* copy the truncated bits into plain buffer */
-+ if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* check if this is prime or binary EC request */
-+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
-+ ec_crv = EC_PRIME;
-+
-+ /* get the generator point pair */
-+ if (!EC_POINT_get_affine_coordinates_GFp (group,
-+ EC_GROUP_get0_generator(group), x, y,ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+
-+ /* get the public key pair for prime curve */
-+ if (!EC_POINT_get_affine_coordinates_GFp (group,
-+ pub_key, w_x, w_y,ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+
-+ /* get the ECC curve parameters */
-+ if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+ } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field){
-+ ec_crv = EC_BINARY;
-+ /* get the ECC curve parameters */
-+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+
-+ /* get the generator point pair */
-+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
-+ EC_GROUP_get0_generator(group),x, y,ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+
-+ /* get the public key pair for binary curve */
-+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
-+ pub_key, w_x, w_y,ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+ }else {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+
-+ /* Get the order of the subgroup of private keys */
-+ if (spcf_bn2bin((BIGNUM*)order, &r, &r_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Get the irreducible polynomial that creates the field */
-+ if (spcf_bn2bin(p, &q, &q_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Get the public key into a flat buffer with appropriate padding */
-+ pub_key_len = 2 * q_len;
-+
-+ w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
-+ if (!w_xy) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Generation of ECC curve parameters */
-+ ab_len = 2*q_len;
-+
-+ ab = eng_copy_curve_points (a, b, ab_len, q_len);
-+ if (!ab) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ if (ec_crv == EC_BINARY) {
-+ /* copy b' i.e c(b), instead of only b */
-+ if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
-+ {
-+ unsigned char *c_temp = NULL;
-+ int c_temp_len = q_len;
-+ if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
-+ memcpy(ab+q_len, c_temp, q_len);
-+ else
-+ goto err;
-+ }
-+ kop.curve_type = ECC_BINARY;
-+ }
-+
-+ /* Calculation of Generator point */
-+ g_len = 2 * q_len;
-+
-+ g_xy = eng_copy_curve_points (x, y, g_len, q_len);
-+ if (!g_xy) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /**
-+ * Get the 1st part of signature into a flat buffer with
-+ * appropriate padding
-+ */
-+ if (BN_num_bytes(sig->r) < r_len)
-+ c_len = r_len;
-+
-+ if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /**
-+ * Get the 2nd part of signature into a flat buffer with
-+ * appropriate padding
-+ */
-+ if (BN_num_bytes(sig->s) < r_len)
-+ d_len = r_len;
-+
-+ if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* memory for message representative */
-+ f = malloc(r_len);
-+ if (!f) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Add padding, since SEC expects hash to of size r_len */
-+ memset(f, 0, r_len-dgst_len);
-+
-+ /* Skip leading bytes if dgst_len < r_len */
-+ memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len);
-+ dgst_len += r_len-dgst_len;
-+ kop.crk_op = CRK_DSA_VERIFY;
-+ /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
-+ kop.crk_param[0].crp_p = f;
-+ kop.crk_param[0].crp_nbits = dgst_len * 8;
-+ kop.crk_param[1].crp_p = q;
-+ kop.crk_param[1].crp_nbits = q_len * 8;
-+ kop.crk_param[2].crp_p = r;
-+ kop.crk_param[2].crp_nbits = r_len * 8;
-+ kop.crk_param[3].crp_p = g_xy;
-+ kop.crk_param[3].crp_nbits = g_len * 8;
-+ kop.crk_param[4].crp_p = w_xy;
-+ kop.crk_param[4].crp_nbits = pub_key_len * 8;
-+ kop.crk_param[5].crp_p = ab;
-+ kop.crk_param[5].crp_nbits = ab_len * 8;
-+ kop.crk_param[6].crp_p = c;
-+ kop.crk_param[6].crp_nbits = d_len * 8;
-+ kop.crk_param[7].crp_p = d;
-+ kop.crk_param[7].crp_nbits = d_len * 8;
-+ kop.crk_iparams = 8;
-+
-+ if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
-+ /*OCF success value is 0, if not zero, change ret to fail*/
-+ if(0 == kop.crk_status)
-+ ret = 1;
-+ } else {
-+ const ECDSA_METHOD *meth = ECDSA_OpenSSL();
-+
-+ ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
-+ }
-+ kop.crk_param[0].crp_p = NULL;
-+ zapparams(&kop);
-+
-+err:
-+ return ret;
-+}
-+
-+static int cryptodev_dh_keygen(DH *dh)
-+{
-+ struct crypt_kop kop;
-+ int ret = 1, g_len;
-+ unsigned char *g = NULL;
-+
-+ if (dh->priv_key == NULL) {
-+ if ((dh->priv_key=BN_new()) == NULL)
-+ goto sw_try;
-+ }
-+
-+ if (dh->pub_key == NULL) {
-+ if ((dh->pub_key=BN_new()) == NULL)
-+ goto sw_try;
-+ }
-+
-+ g_len = BN_num_bytes(dh->p);
-+ /**
-+ * Get generator into a plain buffer. If length is less than
-+ * q_len then add leading padding bytes.
-+ */
-+ if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
-+ DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
-+ goto sw_try;
-+ }
-+
-+ memset(&kop, 0, sizeof kop);
-+ kop.crk_op = CRK_DH_GENERATE_KEY;
-+ if (bn2crparam(dh->p, &kop.crk_param[0]))
-+ goto sw_try;
-+ if (bn2crparam(dh->q, &kop.crk_param[1]))
-+ goto sw_try;
-+ kop.crk_param[2].crp_p = g;
-+ kop.crk_param[2].crp_nbits = g_len * 8;
-+ kop.crk_iparams = 3;
-+
-+ /* pub_key is or prime length while priv key is of length of order */
-+ if (cryptodev_asym(&kop, BN_num_bytes(dh->p), dh->pub_key,
-+ BN_num_bytes(dh->q), dh->priv_key))
-+ goto sw_try;
-+
-+ return ret;
-+sw_try:
-+ {
-+ const DH_METHOD *meth = DH_OpenSSL();
-+ ret = (meth->generate_key)(dh);
-+ }
-+ return ret;
- }
-
- static int
-@@ -1503,43 +2310,234 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
- {
- struct crypt_kop kop;
- int dhret = 1;
-- int fd, keylen;
-+ int fd, p_len;
-+ BIGNUM *temp = NULL;
-+ unsigned char *padded_pub_key = NULL, *p = NULL;
-+
-+ if ((fd = get_asym_dev_crypto()) < 0)
-+ goto sw_try;
-+
-+ memset(&kop, 0, sizeof kop);
-+ kop.crk_op = CRK_DH_COMPUTE_KEY;
-+ /* inputs: dh->priv_key pub_key dh->p key */
-+ spcf_bn2bin(dh->p, &p, &p_len);
-+ spcf_bn2bin_ex(pub_key, &padded_pub_key, &p_len);
-+ if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
-+ goto sw_try;
-+
-+ kop.crk_param[1].crp_p = padded_pub_key;
-+ kop.crk_param[1].crp_nbits = p_len * 8;
-+ kop.crk_param[2].crp_p = p;
-+ kop.crk_param[2].crp_nbits = p_len * 8;
-+ kop.crk_iparams = 3;
-+ kop.crk_param[3].crp_p = (void*) key;
-+ kop.crk_param[3].crp_nbits = p_len * 8;
-+ kop.crk_oparams = 1;
-+ dhret = p_len;
-+
-+ if (ioctl(fd, CIOCKEY, &kop))
-+ goto sw_try;
-
-- if ((fd = get_asym_dev_crypto()) < 0) {
-+ if ((temp = BN_new())) {
-+ if (!BN_bin2bn(key, p_len, temp)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
-+ goto sw_try;
-+ }
-+ if (dhret > BN_num_bytes(temp))
-+ dhret=BN_bn2bin(temp,key);
-+ BN_free(temp);
-+ }
-+
-+ kop.crk_param[3].crp_p = NULL;
-+ zapparams(&kop);
-+ return (dhret);
-+sw_try:
-+ {
- const DH_METHOD *meth = DH_OpenSSL();
-
-- return ((meth->compute_key)(key, pub_key, dh));
-+ dhret = (meth->compute_key)(key, pub_key, dh);
- }
-+ return (dhret);
-+}
-
-- keylen = BN_num_bits(dh->p);
-+int cryptodev_ecdh_compute_key(void *out, size_t outlen,
-+ const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen,
-+ void *out, size_t *outlen))
-+{
-+ ec_curve_t ec_crv = EC_PRIME;
-+ unsigned char * q = NULL, *w_xy = NULL, *ab = NULL, *s = NULL, *r = NULL;
-+ BIGNUM * w_x = NULL, *w_y = NULL;
-+ int q_len = 0, ab_len = 0, pub_key_len = 0, r_len = 0, priv_key_len = 0;
-+ BIGNUM * p = NULL, *a = NULL, *b = NULL;
-+ BN_CTX *ctx;
-+ EC_POINT *tmp=NULL;
-+ BIGNUM *x=NULL, *y=NULL;
-+ const BIGNUM *priv_key;
-+ const EC_GROUP* group = NULL;
-+ int ret = -1;
-+ size_t buflen, len;
-+ struct crypt_kop kop;
-
- memset(&kop, 0, sizeof kop);
-- kop.crk_op = CRK_DH_COMPUTE_KEY;
-
-- /* inputs: dh->priv_key pub_key dh->p key */
-- if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
-+ if ((ctx = BN_CTX_new()) == NULL) goto err;
-+ BN_CTX_start(ctx);
-+ x = BN_CTX_get(ctx);
-+ y = BN_CTX_get(ctx);
-+ p = BN_CTX_get(ctx);
-+ a = BN_CTX_get(ctx);
-+ b = BN_CTX_get(ctx);
-+ w_x = BN_CTX_get(ctx);
-+ w_y = BN_CTX_get(ctx);
-+
-+ if (!x || !y || !p || !a || !b || !w_x || !w_y) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
- goto err;
-- if (bn2crparam(pub_key, &kop.crk_param[1]))
-+ }
-+
-+ priv_key = EC_KEY_get0_private_key(ecdh);
-+ if (priv_key == NULL) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
- goto err;
-- if (bn2crparam(dh->p, &kop.crk_param[2]))
-+ }
-+
-+ group = EC_KEY_get0_group(ecdh);
-+ if ((tmp=EC_POINT_new(group)) == NULL) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
- goto err;
-- kop.crk_iparams = 3;
-+ }
-
-- kop.crk_param[3].crp_p = (caddr_t) key;
-- kop.crk_param[3].crp_nbits = keylen * 8;
-- kop.crk_oparams = 1;
-+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
-+ NID_X9_62_prime_field) {
-+ ec_crv = EC_PRIME;
-
-- if (ioctl(fd, CIOCKEY, &kop) == -1) {
-- const DH_METHOD *meth = DH_OpenSSL();
-+ if (!EC_POINT_get_affine_coordinates_GFp(group,
-+ EC_GROUP_get0_generator(group), x, y, ctx)) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
-+ goto err;
-+ }
-
-- dhret = (meth->compute_key)(key, pub_key, dh);
-+ /* get the ECC curve parameters */
-+ if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
-+ goto err;
-+ }
-+
-+ /* get the public key pair for prime curve */
-+ if (!EC_POINT_get_affine_coordinates_GFp (group, pub_key, w_x, w_y,ctx)) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
-+ goto err;
-+ }
-+ } else {
-+ ec_crv = EC_BINARY;
-+
-+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
-+ EC_GROUP_get0_generator(group), x, y, ctx)) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* get the ECC curve parameters */
-+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
-+ goto err;
-+ }
-+
-+ /* get the public key pair for binary curve */
-+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
-+ pub_key, w_x, w_y,ctx)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
-+ goto err;
-+ }
-+ }
-+
-+ /* irreducible polynomial that creates the field */
-+ if (spcf_bn2bin((BIGNUM*)&group->order, &r, &r_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Get the irreducible polynomial that creates the field */
-+ if (spcf_bn2bin(p, &q, &q_len)) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
-+ goto err;
- }
-+
-+ /* Get the public key into a flat buffer with appropriate padding */
-+ pub_key_len = 2 * q_len;
-+ w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
-+ if (!w_xy) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ /* Generation of ECC curve parameters */
-+ ab_len = 2*q_len;
-+ ab = eng_copy_curve_points (a, b, ab_len, q_len);
-+ if (!ab) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
-+ goto err;
-+ }
-+
-+ if (ec_crv == EC_BINARY) {
-+ /* copy b' i.e c(b), instead of only b */
-+ if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
-+ {
-+ unsigned char *c_temp = NULL;
-+ int c_temp_len = q_len;
-+ if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
-+ memcpy(ab+q_len, c_temp, q_len);
-+ else
-+ goto err;
-+ }
-+ kop.curve_type = ECC_BINARY;
-+ } else
-+ kop.curve_type = ECC_PRIME;
-+
-+ priv_key_len = r_len;
-+
-+ /*
-+ * If BN_num_bytes of priv_key returns less then r_len then
-+ * add padding bytes before the key
-+ */
-+ if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
-+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ buflen = (EC_GROUP_get_degree(group) + 7)/8;
-+ len = BN_num_bytes(x);
-+ if (len > buflen || q_len < buflen) {
-+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
-+ goto err;
-+ }
-+
-+ kop.crk_op = CRK_DH_COMPUTE_KEY;
-+ kop.crk_param[0].crp_p = (void*) s;
-+ kop.crk_param[0].crp_nbits = priv_key_len*8;
-+ kop.crk_param[1].crp_p = (void*) w_xy;
-+ kop.crk_param[1].crp_nbits = pub_key_len*8;
-+ kop.crk_param[2].crp_p = (void*) q;
-+ kop.crk_param[2].crp_nbits = q_len*8;
-+ kop.crk_param[3].crp_p = (void*) ab;
-+ kop.crk_param[3].crp_nbits = ab_len*8;
-+ kop.crk_iparams = 4;
-+ kop.crk_param[4].crp_p = (void*) out;
-+ kop.crk_param[4].crp_nbits = q_len*8;
-+ kop.crk_oparams = 1;
-+ ret = q_len;
-+ if (cryptodev_asym(&kop, 0, NULL, 0, NULL)) {
-+ const ECDH_METHOD *meth = ECDH_OpenSSL();
-+ ret = (meth->compute_key)(out, outlen, pub_key, ecdh, KDF);
-+ } else
-+ ret = q_len;
- err:
-- kop.crk_param[3].crp_p = NULL;
-+ kop.crk_param[4].crp_p = NULL;
- zapparams(&kop);
-- return (dhret);
-+ return ret;
- }
-
-+
- static DH_METHOD cryptodev_dh = {
- "cryptodev DH method",
- NULL, /* cryptodev_dh_generate_key */
-@@ -1551,6 +2549,14 @@ static DH_METHOD cryptodev_dh = {
- NULL /* app_data */
- };
-
-+static ECDH_METHOD cryptodev_ecdh = {
-+ "cryptodev ECDH method",
-+ NULL, /* cryptodev_ecdh_compute_key */
-+ NULL,
-+ 0, /* flags */
-+ NULL /* app_data */
-+};
-+
- /*
- * ctrl right now is just a wrapper that doesn't do much
- * but I expect we'll want some options soon.
-@@ -1634,25 +2640,42 @@ ENGINE_load_cryptodev(void)
- memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
- if (cryptodev_asymfeat & CRF_DSA_SIGN)
- cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
-- if (cryptodev_asymfeat & CRF_MOD_EXP) {
-- cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
-- cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
-- }
- if (cryptodev_asymfeat & CRF_DSA_VERIFY)
- cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
-+ if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY)
-+ cryptodev_dsa.dsa_keygen = cryptodev_dsa_keygen;
- }
-
- if (ENGINE_set_DH(engine, &cryptodev_dh)){
- const DH_METHOD *dh_meth = DH_OpenSSL();
-+ memcpy(&cryptodev_dh, dh_meth, sizeof(DH_METHOD));
-+ if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
-+ cryptodev_dh.compute_key =
-+ cryptodev_dh_compute_key;
-+ }
-+ if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) {
-+ cryptodev_dh.generate_key =
-+ cryptodev_dh_keygen;
-+ }
-+ }
-
-- cryptodev_dh.generate_key = dh_meth->generate_key;
-- cryptodev_dh.compute_key = dh_meth->compute_key;
-- cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
-- if (cryptodev_asymfeat & CRF_MOD_EXP) {
-- cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
-- if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
-- cryptodev_dh.compute_key =
-- cryptodev_dh_compute_key;
-+ if (ENGINE_set_ECDSA(engine, &cryptodev_ecdsa)) {
-+ const ECDSA_METHOD *meth = ECDSA_OpenSSL();
-+ memcpy(&cryptodev_ecdsa, meth, sizeof(ECDSA_METHOD));
-+ if (cryptodev_asymfeat & CRF_DSA_SIGN) {
-+ cryptodev_ecdsa.ecdsa_do_sign = cryptodev_ecdsa_do_sign;
-+ }
-+ if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
-+ cryptodev_ecdsa.ecdsa_do_verify =
-+ cryptodev_ecdsa_verify;
-+ }
-+ }
-+
-+ if (ENGINE_set_ECDH(engine, &cryptodev_ecdh)) {
-+ const ECDH_METHOD *ecdh_meth = ECDH_OpenSSL();
-+ memcpy(&cryptodev_ecdh, ecdh_meth, sizeof(ECDH_METHOD));
-+ if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
-+ cryptodev_ecdh.compute_key = cryptodev_ecdh_compute_key;
- }
- }
-
---
-2.3.5
-