From 84cb2cc407cf85459fb463be2aabedd4f12ade77 Mon Sep 17 00:00:00 2001 From: Cristian Stoica Date: Mon, 25 Jan 2016 13:33:46 +0200 Subject: openssl-qoriq: upgrade to 1.0.2h plus fsl patches upstream recipe extended with patches from fsl and CIOCHASH feature. Signed-off-by: Cristian Stoica --- ...itial-support-for-PKC-in-cryptodev-engine.patch | 1564 -------------------- 1 file changed, 1564 deletions(-) delete mode 100644 recipes-connectivity/openssl/openssl-qoriq/qoriq/0008-Initial-support-for-PKC-in-cryptodev-engine.patch (limited to 'recipes-connectivity/openssl/openssl-qoriq/qoriq/0008-Initial-support-for-PKC-in-cryptodev-engine.patch') 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 -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 ---- - 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 --#include - #include - #include - #include - #include -+#include -+#include -+#include -+#include - #include - #include - #include -@@ -68,6 +71,8 @@ ENGINE_load_cryptodev(void) - #include - #include - #include -+#include "eng_cryptodev_ec.h" -+#include - - 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 - -- cgit v1.2.3-54-g00ecf