1 From 107a10d45db0f2e58482f698add04ed9183f7268 Mon Sep 17 00:00:00 2001
 
   2 From: Yashpal Dutta <yashpal.dutta@freescale.com>
 
   3 Date: Tue, 11 Mar 2014 06:29:52 +0545
 
   4 Subject: [PATCH 08/26] Initial support for PKC in cryptodev engine
 
   6 Upstream-status: Pending
 
   8 Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
 
  10  crypto/engine/eng_cryptodev.c | 1343 ++++++++++++++++++++++++++++++++++++-----
 
  11  1 file changed, 1183 insertions(+), 160 deletions(-)
 
  13 diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
 
  14 index e3eb98b..7ee314b 100644
 
  15 --- a/crypto/engine/eng_cryptodev.c
 
  16 +++ b/crypto/engine/eng_cryptodev.c
 
  17 @@ -54,11 +54,14 @@ ENGINE_load_cryptodev(void)
 
  20  #include <sys/types.h>
 
  21 -#include <crypto/cryptodev.h>
 
  22  #include <crypto/dh/dh.h>
 
  23  #include <crypto/dsa/dsa.h>
 
  24  #include <crypto/err/err.h>
 
  25  #include <crypto/rsa/rsa.h>
 
  26 +#include <crypto/ecdsa/ecs_locl.h>
 
  27 +#include <crypto/ecdh/ech_locl.h>
 
  28 +#include <crypto/ec/ec_lcl.h>
 
  29 +#include <crypto/ec/ec.h>
 
  30  #include <sys/ioctl.h>
 
  33 @@ -68,6 +71,8 @@ ENGINE_load_cryptodev(void)
 
  37 +#include "eng_cryptodev_ec.h"
 
  38 +#include <crypto/cryptodev.h>
 
  40  struct dev_crypto_state {
 
  41         struct session_op d_sess;
 
  42 @@ -116,18 +121,10 @@ static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
 
  43  static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
 
  44      RSA *rsa, BN_CTX *ctx);
 
  45  static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
 
  46 -static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
 
  47 -    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
 
  48 -static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
 
  49 -    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
 
  50 -    BN_CTX *ctx, BN_MONT_CTX *mont);
 
  51  static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
 
  53  static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
 
  54      DSA_SIG *sig, DSA *dsa);
 
  55 -static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
 
  56 -    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
 
  57 -    BN_MONT_CTX *m_ctx);
 
  58  static int cryptodev_dh_compute_key(unsigned char *key,
 
  59      const BIGNUM *pub_key, DH *dh);
 
  60  static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
 
  61 @@ -136,6 +133,102 @@ void ENGINE_load_cryptodev(void);
 
  62  const EVP_CIPHER cryptodev_aes_128_cbc_hmac_sha1;
 
  63  const EVP_CIPHER cryptodev_aes_256_cbc_hmac_sha1;
 
  65 +inline int spcf_bn2bin(BIGNUM *bn, unsigned char **bin,  int *bin_len)
 
  70 +       len = BN_num_bytes(bn);
 
  87 +inline int spcf_bn2bin_ex(BIGNUM *bn, unsigned char **bin,  int *bin_len)
 
  92 +       len = BN_num_bytes(bn);
 
  98 +               p = malloc(*bin_len);
 
 105 +       if (len < *bin_len) {
 
 106 +               /* place padding */
 
 107 +               memset(p, 0, (*bin_len - len));
 
 108 +               BN_bn2bin(bn,p+(*bin_len-len));
 
 114 +       if (len >= *bin_len)
 
 121 + * Convert an ECC F2m 'b' parameter into the 'c' parameter.
 
 123 + * q, the curve's modulus
 
 124 + * b, the curve's b parameter
 
 125 + * (a bignum for b, a buffer for c)
 
 127 + * c, written into bin, right-adjusted to fill q_len bytes.
 
 130 +eng_ec_compute_cparam(const BIGNUM* b, const BIGNUM* q,
 
 131 +                       unsigned char **bin, int *bin_len)
 
 133 +       BIGNUM* c = BN_new();
 
 134 +       BIGNUM* exp = BN_new();
 
 135 +       BN_CTX *ctx = BN_CTX_new();
 
 136 +       int m = BN_num_bits(q) - 1;
 
 139 +       if (!c || !exp || !ctx || *bin)
 
 143 +        * We have to compute c, where b = c^4, i.e., the fourth root of b.
 
 144 +        * The equation for c is c = b^(2^(m-2))
 
 145 +        * Compute exp = 2^(m-2)
 
 147 +        * and then compute c = b^exp
 
 149 +       BN_lshift(exp, BN_value_one(), m-2);
 
 150 +       BN_GF2m_mod_exp(c, b, exp, q, ctx);
 
 152 +       spcf_bn2bin_ex(c, bin, bin_len);
 
 155 +       if (ctx) BN_CTX_free(ctx);
 
 157 +       if (exp) BN_free(exp);
 
 161  static const ENGINE_CMD_DEFN cryptodev_defns[] = {
 
 164 @@ -1139,7 +1232,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
 
 166  bn2crparam(const BIGNUM *a, struct crparam *crp)
 
 172 @@ -1156,15 +1248,7 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
 
 174         crp->crp_p = (caddr_t) b;
 
 175         crp->crp_nbits = bits;
 
 177 -       for (i = 0, j = 0; i < a->top; i++) {
 
 178 -               for (k = 0; k < BN_BITS2 / 8; k++) {
 
 179 -                       if ((j + k) >= bytes)
 
 181 -                       b[j + k] = a->d[i] >> (k * 8);
 
 185 +       BN_bn2bin(a, crp->crp_p);
 
 189 @@ -1172,22 +1256,14 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
 
 191  crparam2bn(struct crparam *crp, BIGNUM *a)
 
 197         bytes = (crp->crp_nbits + 7) / 8;
 
 202 -       if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
 
 205 -       for (i = 0; i < bytes; i++)
 
 206 -               pd[i] = crp->crp_p[bytes - i - 1];
 
 208 -       BN_bin2bn(pd, bytes, a);
 
 210 +       BN_bin2bn(crp->crp_p, bytes, a);
 
 214 @@ -1235,6 +1311,32 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
 
 218 +/* Close an opened instance of cryptodev engine */
 
 219 +void cryptodev_close_instance(void *handle)
 
 224 +               fd = *(int *)handle;
 
 230 +/* Create an instance of cryptodev for asynchronous interface */
 
 231 +void *cryptodev_init_instance(void)
 
 233 +       int *fd = malloc(sizeof(int));
 
 236 +               if ((*fd = open("/dev/crypto", O_RDWR, 0)) == -1) {
 
 245  cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 
 246      const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
 
 247 @@ -1250,9 +1352,9 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 
 251 -       memset(&kop, 0, sizeof kop);
 
 252         kop.crk_op = CRK_MOD_EXP;
 
 254 +       kop.crk_oparams = 0;
 
 255 +       kop.crk_status = 0;
 
 256         /* inputs: a^p % m */
 
 257         if (bn2crparam(a, &kop.crk_param[0]))
 
 259 @@ -1293,28 +1395,38 @@ static int
 
 260  cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
 
 262         struct crypt_kop kop;
 
 264 +       int ret = 1, f_len, p_len, q_len;
 
 265 +       unsigned char *f = NULL, *p = NULL, *q = NULL, *dp = NULL, *dq = NULL, *c = NULL;
 
 267         if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
 
 268                 /* XXX 0 means failure?? */
 
 272 -       memset(&kop, 0, sizeof kop);
 
 273 +       kop.crk_oparams = 0;
 
 274 +       kop.crk_status = 0;
 
 275         kop.crk_op = CRK_MOD_EXP_CRT;
 
 276 +       f_len = BN_num_bytes(rsa->n);
 
 277 +       spcf_bn2bin_ex(I, &f, &f_len);
 
 278 +       spcf_bn2bin(rsa->p, &p, &p_len);
 
 279 +       spcf_bn2bin(rsa->q, &q, &q_len);
 
 280 +       spcf_bn2bin_ex(rsa->dmp1, &dp, &p_len);
 
 281 +       spcf_bn2bin_ex(rsa->iqmp, &c, &p_len);
 
 282 +       spcf_bn2bin_ex(rsa->dmq1, &dq, &q_len);
 
 283         /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
 
 284 -       if (bn2crparam(rsa->p, &kop.crk_param[0]))
 
 286 -       if (bn2crparam(rsa->q, &kop.crk_param[1]))
 
 288 -       if (bn2crparam(I, &kop.crk_param[2]))
 
 290 -       if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
 
 292 -       if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
 
 294 -       if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
 
 296 +       kop.crk_param[0].crp_p = p;
 
 297 +       kop.crk_param[0].crp_nbits = p_len * 8;
 
 298 +       kop.crk_param[1].crp_p = q;
 
 299 +       kop.crk_param[1].crp_nbits = q_len * 8;
 
 300 +       kop.crk_param[2].crp_p = f;
 
 301 +       kop.crk_param[2].crp_nbits = f_len * 8;
 
 302 +       kop.crk_param[3].crp_p = dp;
 
 303 +       kop.crk_param[3].crp_nbits = p_len * 8;
 
 304 +       /* dq must of length q, rest all of length p*/
 
 305 +       kop.crk_param[4].crp_p = dq;
 
 306 +       kop.crk_param[4].crp_nbits = q_len * 8;
 
 307 +       kop.crk_param[5].crp_p = c;
 
 308 +       kop.crk_param[5].crp_nbits = p_len * 8;
 
 311         if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
 
 312 @@ -1350,90 +1462,117 @@ static RSA_METHOD cryptodev_rsa = {
 
 313         NULL                            /* rsa_verify */
 
 317 -cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
 
 318 -    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
 
 320 -       return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
 
 324 -cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
 
 325 -    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
 
 326 -    BN_CTX *ctx, BN_MONT_CTX *mont)
 
 328 +cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
 
 335 -       /* v = ( g^u1 * y^u2 mod p ) mod q */
 
 336 -       /* let t1 = g ^ u1 mod p */
 
 338 +       struct crypt_kop kop;
 
 339 +       BIGNUM *c = NULL, *d = NULL;
 
 340 +       DSA_SIG *dsaret = NULL;
 
 341 +       int q_len = 0, r_len = 0, g_len = 0;
 
 342 +       int priv_key_len = 0, ret;
 
 343 +       unsigned char *q = NULL, *r = NULL, *g = NULL, *priv_key = NULL, *f = NULL;
 
 345 -       if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
 
 346 +       memset(&kop, 0, sizeof kop);
 
 347 +       if ((c = BN_new()) == NULL) {
 
 348 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 352 -       /* let t2 = y ^ u2 mod p */
 
 353 -       if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
 
 354 +       if ((d = BN_new()) == NULL) {
 
 356 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 358 -       /* let u1 = t1 * t2 mod p */
 
 359 -       if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
 
 362 +       if (spcf_bn2bin(dsa->p, &q, &q_len)) {
 
 363 +               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
 
 368 +       /* Get order of the field of private keys into plain buffer */
 
 369 +       if (spcf_bn2bin (dsa->q, &r, &r_len)) {
 
 370 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 380 +       if (dlen > r_len) {
 
 381 +               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
 
 386 -cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
 
 388 -       struct crypt_kop kop;
 
 389 -       BIGNUM *r = NULL, *s = NULL;
 
 390 -       DSA_SIG *dsaret = NULL;
 
 393 +        * Get generator into a plain buffer. If length is less than
 
 394 +        * q_len then add leading padding bytes.
 
 396 +       if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
 
 397 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 401 -       if ((r = BN_new()) == NULL)
 
 402 +       priv_key_len = r_len;
 
 404 +        * Get private key into a plain buffer. If length is less than
 
 405 +        * r_len then add leading padding bytes.
 
 407 +        if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
 
 408 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 410 -       if ((s = BN_new()) == NULL) {
 
 414 +       /* Allocate memory to store hash. */
 
 415 +       f = OPENSSL_malloc (r_len);
 
 417 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 421 -       memset(&kop, 0, sizeof kop);
 
 422 +       /* Add padding, since SEC expects hash to of size r_len */
 
 424 +               memset(f, 0, r_len - dlen);
 
 426 +       /* Skip leading bytes if dgst_len < r_len */
 
 427 +       memcpy(f + r_len - dlen, dgst, dlen);
 
 429         kop.crk_op = CRK_DSA_SIGN;
 
 431         /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
 
 432 -       kop.crk_param[0].crp_p = (caddr_t)dgst;
 
 433 -       kop.crk_param[0].crp_nbits = dlen * 8;
 
 434 -       if (bn2crparam(dsa->p, &kop.crk_param[1]))
 
 436 -       if (bn2crparam(dsa->q, &kop.crk_param[2]))
 
 438 -       if (bn2crparam(dsa->g, &kop.crk_param[3]))
 
 440 -       if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
 
 442 +       kop.crk_param[0].crp_p = (void*)f;
 
 443 +       kop.crk_param[0].crp_nbits = r_len * 8;
 
 444 +       kop.crk_param[1].crp_p = (void*)q;
 
 445 +       kop.crk_param[1].crp_nbits = q_len * 8;
 
 446 +       kop.crk_param[2].crp_p = (void*)r;
 
 447 +       kop.crk_param[2].crp_nbits = r_len * 8;
 
 448 +       kop.crk_param[3].crp_p = (void*)g;
 
 449 +       kop.crk_param[3].crp_nbits = g_len * 8;
 
 450 +       kop.crk_param[4].crp_p = (void*)priv_key;
 
 451 +       kop.crk_param[4].crp_nbits = priv_key_len * 8;
 
 454 -       if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
 
 455 -           BN_num_bytes(dsa->q), s) == 0) {
 
 456 -               dsaret = DSA_SIG_new();
 
 460 -               const DSA_METHOD *meth = DSA_OpenSSL();
 
 463 -               dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
 
 464 +       ret = cryptodev_asym(&kop, r_len, c, r_len, d);
 
 467 +               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DECODE_ERROR);
 
 471 -       kop.crk_param[0].crp_p = NULL;
 
 473 +       dsaret = DSA_SIG_new();
 
 481 +               const DSA_METHOD *meth = DSA_OpenSSL();
 
 486 +               dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
 
 492 @@ -1441,42 +1580,179 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
 
 493      DSA_SIG *sig, DSA *dsa)
 
 495         struct crypt_kop kop;
 
 497 +       int dsaret = 1, q_len = 0, r_len = 0, g_len = 0;
 
 498 +       int w_len = 0 ,c_len = 0, d_len = 0, ret = -1;
 
 499 +       unsigned char   * q = NULL, * r = NULL, * w = NULL, * g = NULL;
 
 500 +       unsigned char   * c = NULL, * d = NULL, *f = NULL;
 
 502         memset(&kop, 0, sizeof kop);
 
 503         kop.crk_op = CRK_DSA_VERIFY;
 
 505 -       /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
 
 506 -       kop.crk_param[0].crp_p = (caddr_t)dgst;
 
 507 -       kop.crk_param[0].crp_nbits = dlen * 8;
 
 508 -       if (bn2crparam(dsa->p, &kop.crk_param[1]))
 
 509 +       if (spcf_bn2bin(dsa->p, &q, &q_len)) {
 
 510 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
 514 +       /* Get Order of field of private keys */
 
 515 +       if (spcf_bn2bin(dsa->q, &r, &r_len)) {
 
 516 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
 518 -       if (bn2crparam(dsa->q, &kop.crk_param[2]))
 
 523 +        * Get generator into a plain buffer. If length is less than
 
 524 +        * q_len then add leading padding bytes.
 
 526 +       if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
 
 527 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
 529 -       if (bn2crparam(dsa->g, &kop.crk_param[3]))
 
 533 +        * Get public key into a plain buffer. If length is less than
 
 534 +        * q_len then add leading padding bytes.
 
 536 +       if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
 
 537 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
 541 +        * Get the 1st part of signature into a flat buffer with
 
 542 +        * appropriate padding
 
 546 +       if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
 
 547 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
 549 -       if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
 
 553 +        * Get the 2nd part of signature into a flat buffer with
 
 554 +        * appropriate padding
 
 558 +       if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
 
 559 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
 561 -       if (bn2crparam(sig->r, &kop.crk_param[5]))
 
 566 +       if (dlen > r_len) {
 
 567 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
 569 -       if (bn2crparam(sig->s, &kop.crk_param[6]))
 
 572 +       /* Allocate memory to store hash. */
 
 573 +       f = OPENSSL_malloc (r_len);
 
 575 +               DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
 579 +       /* Add padding, since SEC expects hash to of size r_len */
 
 581 +               memset(f, 0, r_len - dlen);
 
 583 +       /* Skip leading bytes if dgst_len < r_len */
 
 584 +       memcpy(f + r_len - dlen, dgst, dlen);
 
 586 +       /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
 
 587 +       kop.crk_param[0].crp_p = (void*)f;
 
 588 +       kop.crk_param[0].crp_nbits = r_len * 8;
 
 589 +       kop.crk_param[1].crp_p = q;
 
 590 +       kop.crk_param[1].crp_nbits = q_len * 8;
 
 591 +       kop.crk_param[2].crp_p = r;
 
 592 +       kop.crk_param[2].crp_nbits = r_len * 8;
 
 593 +       kop.crk_param[3].crp_p = g;
 
 594 +       kop.crk_param[3].crp_nbits = g_len * 8;
 
 595 +       kop.crk_param[4].crp_p = w;
 
 596 +       kop.crk_param[4].crp_nbits = w_len * 8;
 
 597 +       kop.crk_param[5].crp_p = c;
 
 598 +       kop.crk_param[5].crp_nbits = c_len * 8;
 
 599 +       kop.crk_param[6].crp_p = d;
 
 600 +       kop.crk_param[6].crp_nbits = d_len * 8;
 
 603 -       if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
 
 604 -/*OCF success value is 0, if not zero, change dsaret to fail*/
 
 605 -               if(0 != kop.crk_status) dsaret  = 0;
 
 607 -               const DSA_METHOD *meth = DSA_OpenSSL();
 
 608 +       if ((cryptodev_asym(&kop, 0, NULL, 0, NULL))) {
 
 609 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
 
 613 -               dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
 
 614 +       /*OCF success value is 0, if not zero, change dsaret to fail*/
 
 615 +       if(0 != kop.crk_status) {
 
 616 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
 
 620 -       kop.crk_param[0].crp_p = NULL;
 
 626 +               const DSA_METHOD *meth = DSA_OpenSSL();
 
 628 +               dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
 
 633 +/* Cryptodev DSA Key Gen routine */
 
 634 +static int cryptodev_dsa_keygen(DSA *dsa)
 
 636 +       struct crypt_kop kop;
 
 637 +       int ret = 1, g_len;
 
 638 +       unsigned char *g = NULL;
 
 640 +       if (dsa->priv_key == NULL)      {
 
 641 +               if ((dsa->priv_key=BN_new()) == NULL)
 
 645 +       if (dsa->pub_key == NULL) {
 
 646 +               if ((dsa->pub_key=BN_new()) == NULL)
 
 650 +       g_len = BN_num_bytes(dsa->p);
 
 652 +        * Get generator into a plain buffer. If length is less than
 
 653 +        * p_len then add leading padding bytes.
 
 655 +       if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
 
 656 +               DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
 
 660 +       memset(&kop, 0, sizeof kop);
 
 662 +       kop.crk_op = CRK_DSA_GENERATE_KEY;
 
 663 +       if (bn2crparam(dsa->p, &kop.crk_param[0]))
 
 665 +       if (bn2crparam(dsa->q, &kop.crk_param[1]))
 
 667 +       kop.crk_param[2].crp_p = g;
 
 668 +       kop.crk_param[2].crp_nbits = g_len * 8;
 
 669 +       kop.crk_iparams = 3;
 
 671 +       /* pub_key is or prime length while priv key is of length of order */
 
 672 +       if (cryptodev_asym(&kop, BN_num_bytes(dsa->p), dsa->pub_key,
 
 673 +           BN_num_bytes(dsa->q), dsa->priv_key))
 
 679 +               const DSA_METHOD *meth = DSA_OpenSSL();
 
 680 +               ret = (meth->dsa_keygen)(dsa);
 
 687  static DSA_METHOD cryptodev_dsa = {
 
 688         "cryptodev DSA method",
 
 690 @@ -1490,12 +1766,543 @@ static DSA_METHOD cryptodev_dsa = {
 
 695 -cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
 
 696 -    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
 
 697 -    BN_MONT_CTX *m_ctx)
 
 698 +static ECDSA_METHOD cryptodev_ecdsa = {
 
 699 +       "cryptodev ECDSA method",
 
 701 +       NULL,                           /* ecdsa_sign_setup */
 
 705 +       NULL    /* app_data */
 
 708 +typedef enum ec_curve_s
 
 714 +/* ENGINE handler for ECDSA Sign */
 
 715 +static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char  *dgst,
 
 716 +       int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
 
 718 -       return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
 
 719 +       BIGNUM  *m = NULL, *p = NULL, *a = NULL;
 
 720 +       BIGNUM  *b = NULL, *x = NULL, *y = NULL;
 
 721 +       BN_CTX  *ctx = NULL;
 
 722 +       ECDSA_SIG *ret = NULL;
 
 723 +       ECDSA_DATA *ecdsa = NULL;
 
 724 +       unsigned char  * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
 
 725 +       unsigned char  * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
 
 726 +       int     i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
 
 727 +       int     g_len = 0, d_len = 0, ab_len = 0;
 
 728 +       const BIGNUM   *order = NULL, *priv_key=NULL;
 
 729 +       const EC_GROUP *group = NULL;
 
 730 +       struct crypt_kop kop;
 
 731 +       ec_curve_t ec_crv = EC_PRIME;
 
 733 +       memset(&kop, 0, sizeof(kop));
 
 734 +       ecdsa = ecdsa_check(eckey);
 
 736 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
 
 740 +       group = EC_KEY_get0_group(eckey);
 
 741 +       priv_key = EC_KEY_get0_private_key(eckey);
 
 743 +       if (!group || !priv_key) {
 
 744 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
 
 748 +       if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
 
 749 +               (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
 
 750 +               (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
 
 751 +               (y = BN_new()) == NULL) {
 
 752 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 756 +       order = &group->order;
 
 757 +       if (!order || BN_is_zero(order)) {
 
 758 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
 
 762 +       i = BN_num_bits(order);
 
 763 +       /* Need to truncate digest if it is too long: first truncate whole
 
 765 +       if (8 * dgst_len > i)
 
 766 +               dgst_len = (i + 7)/8;
 
 768 +       if (!BN_bin2bn(dgst, dgst_len, m)) {
 
 769 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
 
 773 +       /* If still too long truncate remaining bits with a shift */
 
 774 +       if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
 
 775 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
 
 779 +       /* copy the truncated bits into plain buffer */
 
 780 +       if (spcf_bn2bin(m, &tmp_dgst, &dgst_len))  {
 
 781 +               fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__);
 
 785 +       ret = ECDSA_SIG_new();
 
 787 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
 
 791 +       /* check if this is prime or binary EC request */
 
 792 +       if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
 
 794 +               /* get the generator point pair */
 
 795 +               if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group),
 
 797 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
 
 801 +               /* get the ECC curve parameters */
 
 802 +               if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) {
 
 803 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
 
 806 +       } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) {
 
 807 +               ec_crv = EC_BINARY;
 
 808 +               /* get the ECC curve parameters */
 
 809 +               if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
 
 810 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
 
 814 +               /* get the generator point pair */
 
 815 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
 
 816 +                       EC_GROUP_get0_generator(group), x, y,ctx)) {
 
 817 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
 
 821 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
 
 825 +       if (spcf_bn2bin(order, &r, &r_len)) {
 
 826 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 830 +       if (spcf_bn2bin(p, &q, &q_len)) {
 
 831 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 835 +       priv_key_len = r_len;
 
 838 +        * If BN_num_bytes of priv_key returns less then r_len then
 
 839 +        * add padding bytes before the key
 
 841 +       if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len))  {
 
 842 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 846 +       /* Generation of ECC curve parameters */
 
 848 +       ab = eng_copy_curve_points(a, b, ab_len, q_len);
 
 850 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 854 +       if (ec_crv == EC_BINARY) {
 
 855 +               if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
 
 857 +                       unsigned char *c_temp = NULL;
 
 858 +                       int c_temp_len = q_len;
 
 859 +                       if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
 
 860 +                               memcpy(ab+q_len, c_temp, q_len);
 
 864 +               kop.curve_type = ECC_BINARY;
 
 867 +       /* Calculation of Generator point */
 
 869 +       g_xy = eng_copy_curve_points(x, y, g_len, q_len);
 
 871 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 875 +       /* Memory allocation for first part of digital signature */
 
 878 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 884 +       /* Memory allocation for second part of digital signature */
 
 887 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 891 +       /* memory for message representative */
 
 894 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
 898 +       /* Add padding, since SEC expects hash to of size r_len */
 
 899 +       memset(f, 0, r_len - dgst_len);
 
 901 +       /* Skip leading bytes if dgst_len < r_len */
 
 902 +       memcpy(f +  r_len - dgst_len, tmp_dgst, dgst_len);
 
 904 +       dgst_len +=  r_len - dgst_len;
 
 905 +       kop.crk_op = CRK_DSA_SIGN;
 
 906 +       /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
 
 907 +       kop.crk_param[0].crp_p = f;
 
 908 +       kop.crk_param[0].crp_nbits = dgst_len * 8;
 
 909 +       kop.crk_param[1].crp_p = q;
 
 910 +       kop.crk_param[1].crp_nbits = q_len * 8;
 
 911 +       kop.crk_param[2].crp_p = r;
 
 912 +       kop.crk_param[2].crp_nbits = r_len * 8;
 
 913 +       kop.crk_param[3].crp_p = g_xy;
 
 914 +       kop.crk_param[3].crp_nbits = g_len * 8;
 
 915 +       kop.crk_param[4].crp_p = s;
 
 916 +       kop.crk_param[4].crp_nbits = priv_key_len * 8;
 
 917 +       kop.crk_param[5].crp_p = ab;
 
 918 +       kop.crk_param[5].crp_nbits = ab_len * 8;
 
 919 +       kop.crk_iparams = 6;
 
 920 +       kop.crk_param[6].crp_p = c;
 
 921 +       kop.crk_param[6].crp_nbits = d_len * 8;
 
 922 +       kop.crk_param[7].crp_p = d;
 
 923 +       kop.crk_param[7].crp_nbits = d_len * 8;
 
 924 +       kop.crk_oparams = 2;
 
 926 +       if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
 
 927 +               /* Check if ret->r and s needs to allocated */
 
 928 +               crparam2bn(&kop.crk_param[6], ret->r);
 
 929 +               crparam2bn(&kop.crk_param[7], ret->s);
 
 931 +               const ECDSA_METHOD *meth = ECDSA_OpenSSL();
 
 932 +               ret = (meth->ecdsa_do_sign)(dgst, dgst_len, in_kinv, in_r, eckey);
 
 934 +       kop.crk_param[0].crp_p = NULL;
 
 938 +               ECDSA_SIG_free(ret);
 
 944 +static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len,
 
 945 +               ECDSA_SIG *sig, EC_KEY *eckey)
 
 947 +       BIGNUM  *m = NULL, *p = NULL, *a = NULL, *b = NULL;
 
 948 +       BIGNUM  *x = NULL, *y = NULL, *w_x = NULL, *w_y = NULL;
 
 949 +       BN_CTX  *ctx = NULL;
 
 950 +       ECDSA_DATA      *ecdsa = NULL;
 
 951 +       unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL, *w_xy = NULL;
 
 952 +       unsigned char *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
 
 953 +       int     i = 0, q_len = 0, pub_key_len = 0, r_len = 0, c_len = 0, g_len = 0;
 
 954 +       int     d_len = 0, ab_len = 0, ret = -1;
 
 955 +       const EC_POINT *pub_key = NULL;
 
 956 +       const BIGNUM   *order = NULL;
 
 957 +       const EC_GROUP *group=NULL;
 
 958 +       ec_curve_t       ec_crv = EC_PRIME;
 
 959 +       struct crypt_kop kop;
 
 961 +       memset(&kop, 0, sizeof kop);
 
 962 +       ecdsa = ecdsa_check(eckey);
 
 964 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
 
 968 +       group    = EC_KEY_get0_group(eckey);
 
 969 +       pub_key  = EC_KEY_get0_public_key(eckey);
 
 971 +       if (!group || !pub_key) {
 
 972 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
 
 976 +       if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
 
 977 +               (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
 
 978 +               (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
 
 979 +               (y = BN_new()) == NULL || (w_x = BN_new()) == NULL ||
 
 980 +               (w_y = BN_new()) == NULL) {
 
 981 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
 985 +       order = &group->order;
 
 986 +       if (!order || BN_is_zero(order)) {
 
 987 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
 
 991 +       i = BN_num_bits(order);
 
 992 +       /* Need to truncate digest if it is too long: first truncate whole
 
 994 +       if (8 * dgst_len > i)
 
 995 +               dgst_len = (i + 7)/8;
 
 997 +       if (!BN_bin2bn(dgst, dgst_len, m)) {
 
 998 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
 
1002 +       /* If still too long truncate remaining bits with a shift */
 
1003 +       if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
 
1004 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
 
1007 +       /* copy the truncated bits into plain buffer */
 
1008 +       if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
 
1009 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
1013 +       /* check if this is prime or binary EC request */
 
1014 +       if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
 
1015 +               ec_crv = EC_PRIME;
 
1017 +               /* get the generator point pair */
 
1018 +               if (!EC_POINT_get_affine_coordinates_GFp (group,
 
1019 +                       EC_GROUP_get0_generator(group), x, y,ctx)) {
 
1020 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
 
1024 +               /* get the public key pair for prime curve */
 
1025 +               if (!EC_POINT_get_affine_coordinates_GFp (group,
 
1026 +                       pub_key, w_x, w_y,ctx)) {
 
1027 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
 
1031 +               /* get the ECC curve parameters */
 
1032 +               if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
 
1033 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
 
1036 +       } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field){
 
1037 +               ec_crv = EC_BINARY;
 
1038 +               /* get the ECC curve parameters */
 
1039 +               if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
 
1040 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
 
1044 +               /* get the generator point pair */
 
1045 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
 
1046 +                       EC_GROUP_get0_generator(group),x, y,ctx)) {
 
1047 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
 
1051 +               /* get the public key pair for binary curve */
 
1052 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
 
1053 +                       pub_key, w_x, w_y,ctx)) {
 
1054 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
 
1058 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
 
1062 +       /* Get the order of the subgroup of private keys */
 
1063 +       if (spcf_bn2bin((BIGNUM*)order, &r, &r_len)) {
 
1064 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
1068 +       /* Get the irreducible polynomial that creates the field */
 
1069 +       if (spcf_bn2bin(p, &q, &q_len)) {
 
1070 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
1074 +       /* Get the public key into a flat buffer with appropriate padding */
 
1075 +       pub_key_len = 2 * q_len;
 
1077 +       w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
 
1079 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
1083 +       /* Generation of ECC curve parameters */
 
1086 +       ab = eng_copy_curve_points (a, b, ab_len, q_len);
 
1088 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
1092 +       if (ec_crv == EC_BINARY) {
 
1093 +               /* copy b' i.e c(b), instead of only b */
 
1094 +               if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
 
1096 +                       unsigned char *c_temp = NULL;
 
1097 +                       int c_temp_len = q_len;
 
1098 +                       if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
 
1099 +                               memcpy(ab+q_len, c_temp, q_len);
 
1103 +               kop.curve_type = ECC_BINARY;
 
1106 +       /* Calculation of Generator point */
 
1107 +       g_len = 2 * q_len;
 
1109 +       g_xy = eng_copy_curve_points (x, y, g_len, q_len);
 
1111 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
1116 +        * Get the 1st part of signature into a flat buffer with
 
1117 +        * appropriate padding
 
1119 +       if (BN_num_bytes(sig->r) < r_len)
 
1122 +       if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
 
1123 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
1128 +        * Get the 2nd part of signature into a flat buffer with
 
1129 +        * appropriate padding
 
1131 +       if (BN_num_bytes(sig->s) < r_len)
 
1134 +       if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
 
1135 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
1139 +       /* memory for message representative */
 
1140 +       f = malloc(r_len);
 
1142 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
 
1146 +       /* Add padding, since SEC expects hash to of size r_len */
 
1147 +       memset(f, 0, r_len-dgst_len);
 
1149 +       /* Skip leading bytes if dgst_len < r_len */
 
1150 +       memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len);
 
1151 +       dgst_len += r_len-dgst_len;
 
1152 +       kop.crk_op = CRK_DSA_VERIFY;
 
1153 +       /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
 
1154 +       kop.crk_param[0].crp_p = f;
 
1155 +       kop.crk_param[0].crp_nbits = dgst_len * 8;
 
1156 +       kop.crk_param[1].crp_p = q;
 
1157 +       kop.crk_param[1].crp_nbits = q_len * 8;
 
1158 +       kop.crk_param[2].crp_p = r;
 
1159 +       kop.crk_param[2].crp_nbits = r_len * 8;
 
1160 +       kop.crk_param[3].crp_p = g_xy;
 
1161 +       kop.crk_param[3].crp_nbits = g_len * 8;
 
1162 +       kop.crk_param[4].crp_p = w_xy;
 
1163 +       kop.crk_param[4].crp_nbits = pub_key_len * 8;
 
1164 +       kop.crk_param[5].crp_p = ab;
 
1165 +       kop.crk_param[5].crp_nbits = ab_len * 8;
 
1166 +       kop.crk_param[6].crp_p = c;
 
1167 +       kop.crk_param[6].crp_nbits = d_len * 8;
 
1168 +       kop.crk_param[7].crp_p = d;
 
1169 +       kop.crk_param[7].crp_nbits = d_len * 8;
 
1170 +       kop.crk_iparams = 8;
 
1172 +       if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
 
1173 +               /*OCF success value is 0, if not zero, change ret to fail*/
 
1174 +               if(0 == kop.crk_status)
 
1177 +               const ECDSA_METHOD *meth = ECDSA_OpenSSL();
 
1179 +               ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
 
1181 +       kop.crk_param[0].crp_p = NULL;
 
1188 +static int cryptodev_dh_keygen(DH *dh)
 
1190 +       struct crypt_kop kop;
 
1191 +       int ret = 1, g_len;
 
1192 +       unsigned char *g = NULL;
 
1194 +       if (dh->priv_key == NULL)       {
 
1195 +               if ((dh->priv_key=BN_new()) == NULL)
 
1199 +       if (dh->pub_key == NULL) {
 
1200 +               if ((dh->pub_key=BN_new()) == NULL)
 
1204 +       g_len = BN_num_bytes(dh->p);
 
1206 +        * Get generator into a plain buffer. If length is less than
 
1207 +        * q_len then add leading padding bytes.
 
1209 +       if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
 
1210 +               DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
 
1214 +       memset(&kop, 0, sizeof kop);
 
1215 +       kop.crk_op = CRK_DH_GENERATE_KEY;
 
1216 +       if (bn2crparam(dh->p, &kop.crk_param[0]))
 
1218 +       if (bn2crparam(dh->q, &kop.crk_param[1]))
 
1220 +       kop.crk_param[2].crp_p = g;
 
1221 +       kop.crk_param[2].crp_nbits = g_len * 8;
 
1222 +       kop.crk_iparams = 3;
 
1224 +       /* pub_key is or prime length while priv key is of length of order */
 
1225 +       if (cryptodev_asym(&kop, BN_num_bytes(dh->p), dh->pub_key,
 
1226 +           BN_num_bytes(dh->q), dh->priv_key))
 
1232 +               const DH_METHOD *meth = DH_OpenSSL();
 
1233 +               ret = (meth->generate_key)(dh);
 
1239 @@ -1503,43 +2310,234 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
 
1241         struct crypt_kop kop;
 
1245 +       BIGNUM *temp = NULL;
 
1246 +       unsigned char *padded_pub_key = NULL, *p = NULL;
 
1248 +       if ((fd = get_asym_dev_crypto()) < 0)
 
1251 +       memset(&kop, 0, sizeof kop);
 
1252 +       kop.crk_op = CRK_DH_COMPUTE_KEY;
 
1253 +       /* inputs: dh->priv_key pub_key dh->p key */
 
1254 +       spcf_bn2bin(dh->p, &p, &p_len);
 
1255 +       spcf_bn2bin_ex(pub_key, &padded_pub_key, &p_len);
 
1256 +       if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
 
1259 +       kop.crk_param[1].crp_p = padded_pub_key;
 
1260 +       kop.crk_param[1].crp_nbits = p_len * 8;
 
1261 +       kop.crk_param[2].crp_p = p;
 
1262 +       kop.crk_param[2].crp_nbits = p_len * 8;
 
1263 +       kop.crk_iparams = 3;
 
1264 +       kop.crk_param[3].crp_p = (void*) key;
 
1265 +       kop.crk_param[3].crp_nbits = p_len * 8;
 
1266 +       kop.crk_oparams = 1;
 
1269 +       if (ioctl(fd, CIOCKEY, &kop))
 
1272 -       if ((fd = get_asym_dev_crypto()) < 0) {
 
1273 +       if ((temp = BN_new())) {
 
1274 +               if (!BN_bin2bn(key, p_len, temp)) {
 
1275 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
 
1278 +               if (dhret > BN_num_bytes(temp))
 
1279 +                       dhret=BN_bn2bin(temp,key);
 
1283 +       kop.crk_param[3].crp_p = NULL;
 
1288                 const DH_METHOD *meth = DH_OpenSSL();
 
1290 -               return ((meth->compute_key)(key, pub_key, dh));
 
1291 +               dhret = (meth->compute_key)(key, pub_key, dh);
 
1296 -       keylen = BN_num_bits(dh->p);
 
1297 +int cryptodev_ecdh_compute_key(void *out, size_t outlen,
 
1298 +       const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen,
 
1299 +       void *out, size_t *outlen))
 
1301 +       ec_curve_t       ec_crv = EC_PRIME;
 
1302 +       unsigned char * q = NULL, *w_xy = NULL, *ab = NULL, *s = NULL, *r = NULL;
 
1303 +       BIGNUM         * w_x = NULL, *w_y = NULL;
 
1304 +       int q_len = 0, ab_len = 0, pub_key_len = 0, r_len = 0, priv_key_len = 0;
 
1305 +       BIGNUM * p = NULL, *a = NULL, *b = NULL;
 
1307 +       EC_POINT *tmp=NULL;
 
1308 +       BIGNUM *x=NULL, *y=NULL;
 
1309 +       const BIGNUM *priv_key;
 
1310 +       const EC_GROUP* group = NULL;
 
1312 +       size_t buflen, len;
 
1313 +       struct crypt_kop kop;
 
1315         memset(&kop, 0, sizeof kop);
 
1316 -       kop.crk_op = CRK_DH_COMPUTE_KEY;
 
1318 -       /* inputs: dh->priv_key pub_key dh->p key */
 
1319 -       if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
 
1320 +       if ((ctx = BN_CTX_new()) == NULL) goto err;
 
1321 +       BN_CTX_start(ctx);
 
1322 +       x = BN_CTX_get(ctx);
 
1323 +       y = BN_CTX_get(ctx);
 
1324 +       p = BN_CTX_get(ctx);
 
1325 +       a = BN_CTX_get(ctx);
 
1326 +       b = BN_CTX_get(ctx);
 
1327 +       w_x = BN_CTX_get(ctx);
 
1328 +       w_y = BN_CTX_get(ctx);
 
1330 +       if (!x || !y || !p || !a || !b || !w_x || !w_y) {
 
1331 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
 
1333 -       if (bn2crparam(pub_key, &kop.crk_param[1]))
 
1336 +       priv_key = EC_KEY_get0_private_key(ecdh);
 
1337 +       if (priv_key == NULL) {
 
1338 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
 
1340 -       if (bn2crparam(dh->p, &kop.crk_param[2]))
 
1343 +       group = EC_KEY_get0_group(ecdh);
 
1344 +       if ((tmp=EC_POINT_new(group)) == NULL) {
 
1345 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
 
1347 -       kop.crk_iparams = 3;
 
1350 -       kop.crk_param[3].crp_p = (caddr_t) key;
 
1351 -       kop.crk_param[3].crp_nbits = keylen * 8;
 
1352 -       kop.crk_oparams = 1;
 
1353 +       if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
 
1354 +               NID_X9_62_prime_field) {
 
1355 +               ec_crv = EC_PRIME;
 
1357 -       if (ioctl(fd, CIOCKEY, &kop) == -1) {
 
1358 -               const DH_METHOD *meth = DH_OpenSSL();
 
1359 +               if (!EC_POINT_get_affine_coordinates_GFp(group,
 
1360 +                       EC_GROUP_get0_generator(group), x, y, ctx)) {
 
1361 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
 
1365 -               dhret = (meth->compute_key)(key, pub_key, dh);
 
1366 +               /* get the ECC curve parameters */
 
1367 +               if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
 
1368 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
 
1372 +               /* get the public key pair for prime curve */
 
1373 +               if (!EC_POINT_get_affine_coordinates_GFp (group, pub_key, w_x, w_y,ctx)) {
 
1374 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
 
1378 +               ec_crv = EC_BINARY;
 
1380 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
 
1381 +                       EC_GROUP_get0_generator(group), x, y, ctx)) {
 
1382 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
 
1386 +               /* get the ECC curve parameters */
 
1387 +               if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
 
1388 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
 
1392 +               /* get the public key pair for binary curve */
 
1393 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
 
1394 +                       pub_key, w_x, w_y,ctx)) {
 
1395 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
 
1400 +       /* irreducible polynomial that creates the field */
 
1401 +       if (spcf_bn2bin((BIGNUM*)&group->order, &r, &r_len)) {
 
1402 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
1406 +       /* Get the irreducible polynomial that creates the field */
 
1407 +       if (spcf_bn2bin(p, &q, &q_len)) {
 
1408 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
 
1412 +       /* Get the public key into a flat buffer with appropriate padding */
 
1413 +       pub_key_len = 2 * q_len;
 
1414 +       w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
 
1416 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
1420 +       /* Generation of ECC curve parameters */
 
1422 +       ab = eng_copy_curve_points (a, b, ab_len, q_len);
 
1424 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
 
1428 +       if (ec_crv == EC_BINARY) {
 
1429 +               /* copy b' i.e c(b), instead of only b */
 
1430 +               if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
 
1432 +                       unsigned char *c_temp = NULL;
 
1433 +                       int c_temp_len = q_len;
 
1434 +                       if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
 
1435 +                               memcpy(ab+q_len, c_temp, q_len);
 
1439 +               kop.curve_type = ECC_BINARY;
 
1441 +               kop.curve_type = ECC_PRIME;
 
1443 +       priv_key_len = r_len;
 
1446 +        * If BN_num_bytes of priv_key returns less then r_len then
 
1447 +        * add padding bytes before the key
 
1449 +       if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
 
1450 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
 
1454 +       buflen = (EC_GROUP_get_degree(group) + 7)/8;
 
1455 +       len = BN_num_bytes(x);
 
1456 +       if (len > buflen || q_len < buflen) {
 
1457 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
 
1461 +       kop.crk_op = CRK_DH_COMPUTE_KEY;
 
1462 +       kop.crk_param[0].crp_p = (void*) s;
 
1463 +       kop.crk_param[0].crp_nbits = priv_key_len*8;
 
1464 +       kop.crk_param[1].crp_p = (void*) w_xy;
 
1465 +       kop.crk_param[1].crp_nbits = pub_key_len*8;
 
1466 +       kop.crk_param[2].crp_p = (void*) q;
 
1467 +       kop.crk_param[2].crp_nbits = q_len*8;
 
1468 +       kop.crk_param[3].crp_p = (void*) ab;
 
1469 +       kop.crk_param[3].crp_nbits = ab_len*8;
 
1470 +       kop.crk_iparams = 4;
 
1471 +       kop.crk_param[4].crp_p = (void*) out;
 
1472 +       kop.crk_param[4].crp_nbits = q_len*8;
 
1473 +       kop.crk_oparams = 1;
 
1475 +       if (cryptodev_asym(&kop, 0, NULL, 0, NULL)) {
 
1476 +               const ECDH_METHOD *meth = ECDH_OpenSSL();
 
1477 +               ret = (meth->compute_key)(out, outlen, pub_key, ecdh, KDF);
 
1481 -       kop.crk_param[3].crp_p = NULL;
 
1482 +       kop.crk_param[4].crp_p = NULL;
 
1489  static DH_METHOD cryptodev_dh = {
 
1490         "cryptodev DH method",
 
1491         NULL,                           /* cryptodev_dh_generate_key */
 
1492 @@ -1551,6 +2549,14 @@ static DH_METHOD cryptodev_dh = {
 
1496 +static ECDH_METHOD cryptodev_ecdh = {
 
1497 +       "cryptodev ECDH method",
 
1498 +       NULL,   /* cryptodev_ecdh_compute_key */
 
1501 +       NULL    /* app_data */
 
1505   * ctrl right now is just a wrapper that doesn't do much
 
1506   * but I expect we'll want some options soon.
 
1507 @@ -1634,25 +2640,42 @@ ENGINE_load_cryptodev(void)
 
1508                 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
 
1509                 if (cryptodev_asymfeat & CRF_DSA_SIGN)
 
1510                         cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
 
1511 -               if (cryptodev_asymfeat & CRF_MOD_EXP) {
 
1512 -                       cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
 
1513 -                       cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
 
1515                 if (cryptodev_asymfeat & CRF_DSA_VERIFY)
 
1516                         cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
 
1517 +               if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY)
 
1518 +                       cryptodev_dsa.dsa_keygen = cryptodev_dsa_keygen;
 
1521         if (ENGINE_set_DH(engine, &cryptodev_dh)){
 
1522                 const DH_METHOD *dh_meth = DH_OpenSSL();
 
1523 +               memcpy(&cryptodev_dh, dh_meth, sizeof(DH_METHOD));
 
1524 +               if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
 
1525 +                       cryptodev_dh.compute_key =
 
1526 +                               cryptodev_dh_compute_key;
 
1528 +               if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) {
 
1529 +                       cryptodev_dh.generate_key =
 
1530 +                               cryptodev_dh_keygen;
 
1534 -               cryptodev_dh.generate_key = dh_meth->generate_key;
 
1535 -               cryptodev_dh.compute_key = dh_meth->compute_key;
 
1536 -               cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
 
1537 -               if (cryptodev_asymfeat & CRF_MOD_EXP) {
 
1538 -                       cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
 
1539 -                       if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
 
1540 -                               cryptodev_dh.compute_key =
 
1541 -                                   cryptodev_dh_compute_key;
 
1542 +       if (ENGINE_set_ECDSA(engine, &cryptodev_ecdsa)) {
 
1543 +               const ECDSA_METHOD *meth = ECDSA_OpenSSL();
 
1544 +               memcpy(&cryptodev_ecdsa, meth, sizeof(ECDSA_METHOD));
 
1545 +               if (cryptodev_asymfeat & CRF_DSA_SIGN) {
 
1546 +                       cryptodev_ecdsa.ecdsa_do_sign = cryptodev_ecdsa_do_sign;
 
1548 +               if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
 
1549 +                       cryptodev_ecdsa.ecdsa_do_verify =
 
1550 +                               cryptodev_ecdsa_verify;
 
1554 +       if (ENGINE_set_ECDH(engine, &cryptodev_ecdh)) {
 
1555 +               const ECDH_METHOD *ecdh_meth = ECDH_OpenSSL();
 
1556 +               memcpy(&cryptodev_ecdh, ecdh_meth, sizeof(ECDH_METHOD));
 
1557 +               if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
 
1558 +                       cryptodev_ecdh.compute_key = cryptodev_ecdh_compute_key;