]> code.ossystems Code Review - meta-freescale.git/blob
ad253064e100f10a0c03dcc438cc9f6bf4b267dc
[meta-freescale.git] /
1 From e28df2a5c63dc6195a6065bfd7de9fc860129f56 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 05/48] Initial support for PKC in cryptodev engine
5
6 Upstream-status: Pending
7
8 Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
9 ---
10  crypto/engine/eng_cryptodev.c | 1365 ++++++++++++++++++++++++++++++++++++-----
11  1 file changed, 1202 insertions(+), 163 deletions(-)
12
13 diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
14 index 3b6515e..0b41bb2 100644
15 --- a/crypto/engine/eng_cryptodev.c
16 +++ b/crypto/engine/eng_cryptodev.c
17 @@ -58,6 +58,10 @@ void ENGINE_load_cryptodev(void)
18  # include <openssl/dsa.h>
19  # include <openssl/err.h>
20  # include <openssl/rsa.h>
21 +# include <crypto/ecdsa/ecs_locl.h>
22 +# include <crypto/ecdh/ech_locl.h>
23 +# include <crypto/ec/ec_lcl.h>
24 +# include <crypto/ec/ec.h>
25  # include <sys/ioctl.h>
26  # include <errno.h>
27  # include <stdio.h>
28 @@ -67,6 +71,7 @@ void ENGINE_load_cryptodev(void)
29  # include <syslog.h>
30  # include <errno.h>
31  # include <string.h>
32 +# include "eng_cryptodev_ec.h"
33  
34  struct dev_crypto_state {
35      struct session_op d_sess;
36 @@ -115,20 +120,10 @@ static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
37                                         BN_CTX *ctx);
38  static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
39                                   BN_CTX *ctx);
40 -static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
41 -                                    const BIGNUM *p, const BIGNUM *m,
42 -                                    BN_CTX *ctx, BN_MONT_CTX *m_ctx);
43 -static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
44 -                                     BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2,
45 -                                     BIGNUM *p, BN_CTX *ctx,
46 -                                     BN_MONT_CTX *mont);
47  static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
48                                        DSA *dsa);
49  static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
50                                  DSA_SIG *sig, DSA *dsa);
51 -static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
52 -                                const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
53 -                                BN_MONT_CTX *m_ctx);
54  static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key,
55                                      DH *dh);
56  static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
57 @@ -137,6 +132,105 @@ void ENGINE_load_cryptodev(void);
58  const EVP_CIPHER cryptodev_aes_128_cbc_hmac_sha1;
59  const EVP_CIPHER cryptodev_aes_256_cbc_hmac_sha1;
60  
61 +inline int spcf_bn2bin(BIGNUM *bn, unsigned char **bin, int *bin_len)
62 +{
63 +    int len;
64 +    unsigned char *p;
65 +
66 +    len = BN_num_bytes(bn);
67 +
68 +    if (!len)
69 +        return -1;
70 +
71 +    p = malloc(len);
72 +    if (!p)
73 +        return -1;
74 +
75 +    BN_bn2bin(bn, p);
76 +
77 +    *bin = p;
78 +    *bin_len = len;
79 +
80 +    return 0;
81 +}
82 +
83 +inline int spcf_bn2bin_ex(BIGNUM *bn, unsigned char **bin, int *bin_len)
84 +{
85 +    int len;
86 +    unsigned char *p;
87 +
88 +    len = BN_num_bytes(bn);
89 +
90 +    if (!len)
91 +        return -1;
92 +
93 +    if (len < *bin_len)
94 +        p = malloc(*bin_len);
95 +    else
96 +        p = malloc(len);
97 +
98 +    if (!p)
99 +        return -ENOMEM;
100 +
101 +    if (len < *bin_len) {
102 +        /* place padding */
103 +        memset(p, 0, (*bin_len - len));
104 +        BN_bn2bin(bn, p + (*bin_len - len));
105 +    } else {
106 +        BN_bn2bin(bn, p);
107 +    }
108 +
109 +    *bin = p;
110 +    if (len >= *bin_len)
111 +        *bin_len = len;
112 +
113 +    return 0;
114 +}
115 +
116 +/**
117 + * Convert an ECC F2m 'b' parameter into the 'c' parameter.
118 + *Inputs:
119 + * q, the curve's modulus
120 + * b, the curve's b parameter
121 + * (a bignum for b, a buffer for c)
122 + * Output:
123 + * c, written into bin, right-adjusted to fill q_len bytes.
124 + */
125 +static int
126 +eng_ec_compute_cparam(const BIGNUM *b, const BIGNUM *q,
127 +                      unsigned char **bin, int *bin_len)
128 +{
129 +    BIGNUM *c = BN_new();
130 +    BIGNUM *exp = BN_new();
131 +    BN_CTX *ctx = BN_CTX_new();
132 +    int m = BN_num_bits(q) - 1;
133 +    int ok = 0;
134 +
135 +    if (!c || !exp || !ctx || *bin)
136 +        goto err;
137 +
138 +    /*
139 +     * We have to compute c, where b = c^4, i.e., the fourth root of b.
140 +     * The equation for c is c = b^(2^(m-2))
141 +     * Compute exp = 2^(m-2)
142 +     * (1 << x) == 2^x
143 +     * and then compute c = b^exp
144 +     */
145 +    BN_lshift(exp, BN_value_one(), m - 2);
146 +    BN_GF2m_mod_exp(c, b, exp, q, ctx);
147 +    /* Store c */
148 +    spcf_bn2bin_ex(c, bin, bin_len);
149 +    ok = 1;
150 + err:
151 +    if (ctx)
152 +        BN_CTX_free(ctx);
153 +    if (c)
154 +        BN_free(c);
155 +    if (exp)
156 +        BN_free(exp);
157 +    return ok;
158 +}
159 +
160  static const ENGINE_CMD_DEFN cryptodev_defns[] = {
161      {0, NULL, NULL, 0}
162  };
163 @@ -1225,7 +1319,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
164   */
165  static int bn2crparam(const BIGNUM *a, struct crparam *crp)
166  {
167 -    int i, j, k;
168      ssize_t bytes, bits;
169      u_char *b;
170  
171 @@ -1243,36 +1336,21 @@ static int bn2crparam(const BIGNUM *a, struct crparam *crp)
172      crp->crp_p = (caddr_t) b;
173      crp->crp_nbits = bits;
174  
175 -    for (i = 0, j = 0; i < a->top; i++) {
176 -        for (k = 0; k < BN_BITS2 / 8; k++) {
177 -            if ((j + k) >= bytes)
178 -                return (0);
179 -            b[j + k] = a->d[i] >> (k * 8);
180 -        }
181 -        j += BN_BITS2 / 8;
182 -    }
183 +    BN_bn2bin(a, crp->crp_p);
184      return (0);
185  }
186  
187  /* Convert a /dev/crypto parameter to a BIGNUM */
188  static int crparam2bn(struct crparam *crp, BIGNUM *a)
189  {
190 -    u_int8_t *pd;
191 -    int i, bytes;
192 +    int bytes;
193  
194      bytes = (crp->crp_nbits + 7) / 8;
195  
196      if (bytes == 0)
197          return (-1);
198  
199 -    if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
200 -        return (-1);
201 -
202 -    for (i = 0; i < bytes; i++)
203 -        pd[i] = crp->crp_p[bytes - i - 1];
204 -
205 -    BN_bin2bn(pd, bytes, a);
206 -    free(pd);
207 +    BN_bin2bn(crp->crp_p, bytes, a);
208  
209      return (0);
210  }
211 @@ -1321,6 +1399,32 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
212      return (ret);
213  }
214  
215 +/* Close an opened instance of cryptodev engine */
216 +void cryptodev_close_instance(void *handle)
217 +{
218 +    int fd;
219 +
220 +    if (handle) {
221 +        fd = *(int *)handle;
222 +        close(fd);
223 +        free(handle);
224 +    }
225 +}
226 +
227 +/* Create an instance of cryptodev for asynchronous interface */
228 +void *cryptodev_init_instance(void)
229 +{
230 +    int *fd = malloc(sizeof(int));
231 +
232 +    if (fd) {
233 +        if ((*fd = open("/dev/crypto", O_RDWR, 0)) == -1) {
234 +            free(fd);
235 +            return NULL;
236 +        }
237 +    }
238 +    return fd;
239 +}
240 +
241  static int
242  cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
243                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
244 @@ -1337,8 +1441,9 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
245          return (ret);
246      }
247  
248 -    memset(&kop, 0, sizeof kop);
249      kop.crk_op = CRK_MOD_EXP;
250 +    kop.crk_oparams = 0;
251 +    kop.crk_status = 0;
252  
253      /* inputs: a^p % m */
254      if (bn2crparam(a, &kop.crk_param[0]))
255 @@ -1381,28 +1486,39 @@ static int
256  cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
257  {
258      struct crypt_kop kop;
259 -    int ret = 1;
260 +    int ret = 1, f_len, p_len, q_len;
261 +    unsigned char *f = NULL, *p = NULL, *q = NULL, *dp = NULL, *dq =
262 +        NULL, *c = NULL;
263  
264      if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
265          /* XXX 0 means failure?? */
266          return (0);
267      }
268  
269 -    memset(&kop, 0, sizeof kop);
270 +    kop.crk_oparams = 0;
271 +    kop.crk_status = 0;
272      kop.crk_op = CRK_MOD_EXP_CRT;
273 +    f_len = BN_num_bytes(rsa->n);
274 +    spcf_bn2bin_ex(I, &f, &f_len);
275 +    spcf_bn2bin(rsa->p, &p, &p_len);
276 +    spcf_bn2bin(rsa->q, &q, &q_len);
277 +    spcf_bn2bin_ex(rsa->dmp1, &dp, &p_len);
278 +    spcf_bn2bin_ex(rsa->iqmp, &c, &p_len);
279 +    spcf_bn2bin_ex(rsa->dmq1, &dq, &q_len);
280      /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
281 -    if (bn2crparam(rsa->p, &kop.crk_param[0]))
282 -        goto err;
283 -    if (bn2crparam(rsa->q, &kop.crk_param[1]))
284 -        goto err;
285 -    if (bn2crparam(I, &kop.crk_param[2]))
286 -        goto err;
287 -    if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
288 -        goto err;
289 -    if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
290 -        goto err;
291 -    if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
292 -        goto err;
293 +    kop.crk_param[0].crp_p = p;
294 +    kop.crk_param[0].crp_nbits = p_len * 8;
295 +    kop.crk_param[1].crp_p = q;
296 +    kop.crk_param[1].crp_nbits = q_len * 8;
297 +    kop.crk_param[2].crp_p = f;
298 +    kop.crk_param[2].crp_nbits = f_len * 8;
299 +    kop.crk_param[3].crp_p = dp;
300 +    kop.crk_param[3].crp_nbits = p_len * 8;
301 +    /* dq must of length q, rest all of length p */
302 +    kop.crk_param[4].crp_p = dq;
303 +    kop.crk_param[4].crp_nbits = q_len * 8;
304 +    kop.crk_param[5].crp_p = c;
305 +    kop.crk_param[5].crp_nbits = p_len * 8;
306      kop.crk_iparams = 6;
307  
308      if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
309 @@ -1438,93 +1554,120 @@ static RSA_METHOD cryptodev_rsa = {
310      NULL                        /* rsa_verify */
311  };
312  
313 -static int
314 -cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
315 -                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
316 -{
317 -    return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
318 -}
319 -
320 -static int
321 -cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
322 -                          BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
323 -                          BN_CTX *ctx, BN_MONT_CTX *mont)
324 +static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
325 +                                      DSA *dsa)
326  {
327 -    BIGNUM t2;
328 -    int ret = 0;
329 -
330 -    BN_init(&t2);
331 -
332 -    /* v = ( g^u1 * y^u2 mod p ) mod q */
333 -    /* let t1 = g ^ u1 mod p */
334 -    ret = 0;
335 +    struct crypt_kop kop;
336 +    BIGNUM *c = NULL, *d = NULL;
337 +    DSA_SIG *dsaret = NULL;
338 +    int q_len = 0, r_len = 0, g_len = 0;
339 +    int priv_key_len = 0, ret;
340 +    unsigned char *q = NULL, *r = NULL, *g = NULL, *priv_key = NULL, *f =
341 +        NULL;
342  
343 -    if (!dsa->meth->bn_mod_exp(dsa, t1, dsa->g, u1, dsa->p, ctx, mont))
344 +    memset(&kop, 0, sizeof kop);
345 +    if ((c = BN_new()) == NULL) {
346 +        DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
347          goto err;
348 +    }
349  
350 -    /* let t2 = y ^ u2 mod p */
351 -    if (!dsa->meth->bn_mod_exp(dsa, &t2, dsa->pub_key, u2, dsa->p, ctx, mont))
352 +    if ((d = BN_new()) == NULL) {
353 +        BN_free(c);
354 +        DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
355          goto err;
356 -    /* let u1 = t1 * t2 mod p */
357 -    if (!BN_mod_mul(u1, t1, &t2, dsa->p, ctx))
358 +    }
359 +
360 +    if (spcf_bn2bin(dsa->p, &q, &q_len)) {
361 +        DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
362          goto err;
363 +    }
364  
365 -    BN_copy(t1, u1);
366 +    /* Get order of the field of private keys into plain buffer */
367 +    if (spcf_bn2bin(dsa->q, &r, &r_len)) {
368 +        DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
369 +        goto err;
370 +    }
371  
372 -    ret = 1;
373 - err:
374 -    BN_free(&t2);
375 -    return (ret);
376 -}
377 +    /* sanity test */
378 +    if (dlen > r_len) {
379 +        DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
380 +        goto err;
381 +    }
382  
383 -static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
384 -                                      DSA *dsa)
385 -{
386 -    struct crypt_kop kop;
387 -    BIGNUM *r = NULL, *s = NULL;
388 -    DSA_SIG *dsaret = NULL;
389 +    g_len = q_len;
390 +    /**
391 +     * Get generator into a plain buffer. If length is less than
392 +     * q_len then add leading padding bytes.
393 +     */
394 +    if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
395 +        DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
396 +        goto err;
397 +    }
398  
399 -    if ((r = BN_new()) == NULL)
400 +    priv_key_len = r_len;
401 +    /**
402 +     * Get private key into a plain buffer. If length is less than
403 +     * r_len then add leading padding bytes.
404 +     */
405 +    if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
406 +        DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
407          goto err;
408 -    if ((s = BN_new()) == NULL) {
409 -        BN_free(r);
410 +    }
411 +
412 +    /* Allocate memory to store hash. */
413 +    f = OPENSSL_malloc(r_len);
414 +    if (!f) {
415 +        DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
416          goto err;
417      }
418  
419 -    memset(&kop, 0, sizeof kop);
420 +    /* Add padding, since SEC expects hash to of size r_len */
421 +    if (dlen < r_len)
422 +        memset(f, 0, r_len - dlen);
423 +
424 +    /* Skip leading bytes if dgst_len < r_len */
425 +    memcpy(f + r_len - dlen, dgst, dlen);
426 +
427      kop.crk_op = CRK_DSA_SIGN;
428  
429      /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
430 -    kop.crk_param[0].crp_p = (caddr_t) dgst;
431 -    kop.crk_param[0].crp_nbits = dlen * 8;
432 -    if (bn2crparam(dsa->p, &kop.crk_param[1]))
433 -        goto err;
434 -    if (bn2crparam(dsa->q, &kop.crk_param[2]))
435 -        goto err;
436 -    if (bn2crparam(dsa->g, &kop.crk_param[3]))
437 +    kop.crk_param[0].crp_p = (void *)f;
438 +    kop.crk_param[0].crp_nbits = r_len * 8;
439 +    kop.crk_param[1].crp_p = (void *)q;
440 +    kop.crk_param[1].crp_nbits = q_len * 8;
441 +    kop.crk_param[2].crp_p = (void *)r;
442 +    kop.crk_param[2].crp_nbits = r_len * 8;
443 +    kop.crk_param[3].crp_p = (void *)g;
444 +    kop.crk_param[3].crp_nbits = g_len * 8;
445 +    kop.crk_param[4].crp_p = (void *)priv_key;
446 +    kop.crk_param[4].crp_nbits = priv_key_len * 8;
447 +    kop.crk_iparams = 5;
448 +
449 +    ret = cryptodev_asym(&kop, r_len, c, r_len, d);
450 +
451 +    if (ret) {
452 +        DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DECODE_ERROR);
453          goto err;
454 -    if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
455 +    }
456 +
457 +    dsaret = DSA_SIG_new();
458 +    if (dsaret == NULL)
459          goto err;
460 -    kop.crk_iparams = 5;
461 +    dsaret->r = c;
462 +    dsaret->s = d;
463  
464 -    if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
465 -                       BN_num_bytes(dsa->q), s) == 0) {
466 -        dsaret = DSA_SIG_new();
467 -        if (dsaret == NULL)
468 -            goto err;
469 -        dsaret->r = r;
470 -        dsaret->s = s;
471 -        r = s = NULL;
472 -    } else {
473 +    zapparams(&kop);
474 +    return (dsaret);
475 + err:
476 +    {
477          const DSA_METHOD *meth = DSA_OpenSSL();
478 +        if (c)
479 +            BN_free(c);
480 +        if (d)
481 +            BN_free(d);
482          dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa);
483 +        return (dsaret);
484      }
485 - err:
486 -    BN_free(r);
487 -    BN_free(s);
488 -    kop.crk_param[0].crp_p = NULL;
489 -    zapparams(&kop);
490 -    return (dsaret);
491  }
492  
493  static int
494 @@ -1532,43 +1675,175 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
495                       DSA_SIG *sig, DSA *dsa)
496  {
497      struct crypt_kop kop;
498 -    int dsaret = 1;
499 +    int dsaret = 1, q_len = 0, r_len = 0, g_len = 0;
500 +    int w_len = 0, c_len = 0, d_len = 0, ret = -1;
501 +    unsigned char *q = NULL, *r = NULL, *w = NULL, *g = NULL;
502 +    unsigned char *c = NULL, *d = NULL, *f = NULL;
503  
504      memset(&kop, 0, sizeof kop);
505      kop.crk_op = CRK_DSA_VERIFY;
506  
507 -    /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
508 -    kop.crk_param[0].crp_p = (caddr_t) dgst;
509 -    kop.crk_param[0].crp_nbits = dlen * 8;
510 -    if (bn2crparam(dsa->p, &kop.crk_param[1]))
511 +    if (spcf_bn2bin(dsa->p, &q, &q_len)) {
512 +        DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
513 +        return ret;
514 +    }
515 +
516 +    /* Get Order of field of private keys */
517 +    if (spcf_bn2bin(dsa->q, &r, &r_len)) {
518 +        DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
519 +        goto err;
520 +    }
521 +
522 +    g_len = q_len;
523 +        /**
524 +         * Get generator into a plain buffer. If length is less than
525 +         * q_len then add leading padding bytes.
526 +         */
527 +    if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
528 +        DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
529          goto err;
530 -    if (bn2crparam(dsa->q, &kop.crk_param[2]))
531 +    }
532 +    w_len = q_len;
533 +        /**
534 +         * Get public key into a plain buffer. If length is less than
535 +         * q_len then add leading padding bytes.
536 +         */
537 +    if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
538 +        DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
539          goto err;
540 -    if (bn2crparam(dsa->g, &kop.crk_param[3]))
541 +    }
542 +        /**
543 +         * Get the 1st part of signature into a flat buffer with
544 +         * appropriate padding
545 +         */
546 +    c_len = r_len;
547 +
548 +    if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
549 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
550          goto err;
551 -    if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
552 +    }
553 +
554 +        /**
555 +         * Get the 2nd part of signature into a flat buffer with
556 +         * appropriate padding
557 +         */
558 +    d_len = r_len;
559 +
560 +    if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
561 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
562          goto err;
563 -    if (bn2crparam(sig->r, &kop.crk_param[5]))
564 +    }
565 +
566 +    /* Sanity test */
567 +    if (dlen > r_len) {
568 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
569          goto err;
570 -    if (bn2crparam(sig->s, &kop.crk_param[6]))
571 +    }
572 +
573 +    /* Allocate memory to store hash. */
574 +    f = OPENSSL_malloc(r_len);
575 +    if (!f) {
576 +        DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
577          goto err;
578 +    }
579 +
580 +    /* Add padding, since SEC expects hash to of size r_len */
581 +    if (dlen < r_len)
582 +        memset(f, 0, r_len - dlen);
583 +
584 +    /* Skip leading bytes if dgst_len < r_len */
585 +    memcpy(f + r_len - dlen, dgst, dlen);
586 +
587 +    /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
588 +    kop.crk_param[0].crp_p = (void *)f;
589 +    kop.crk_param[0].crp_nbits = r_len * 8;
590 +    kop.crk_param[1].crp_p = q;
591 +    kop.crk_param[1].crp_nbits = q_len * 8;
592 +    kop.crk_param[2].crp_p = r;
593 +    kop.crk_param[2].crp_nbits = r_len * 8;
594 +    kop.crk_param[3].crp_p = g;
595 +    kop.crk_param[3].crp_nbits = g_len * 8;
596 +    kop.crk_param[4].crp_p = w;
597 +    kop.crk_param[4].crp_nbits = w_len * 8;
598 +    kop.crk_param[5].crp_p = c;
599 +    kop.crk_param[5].crp_nbits = c_len * 8;
600 +    kop.crk_param[6].crp_p = d;
601 +    kop.crk_param[6].crp_nbits = d_len * 8;
602      kop.crk_iparams = 7;
603  
604 -    if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
605 -        /*
606 -         * OCF success value is 0, if not zero, change dsaret to fail
607 -         */
608 -        if (0 != kop.crk_status)
609 -            dsaret = 0;
610 -    } else {
611 -        const DSA_METHOD *meth = DSA_OpenSSL();
612 +    if ((cryptodev_asym(&kop, 0, NULL, 0, NULL))) {
613 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
614 +        goto err;
615 +    }
616  
617 -        dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa);
618 +    /*
619 +     * OCF success value is 0, if not zero, change dsaret to fail
620 +     */
621 +    if (0 != kop.crk_status) {
622 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
623 +        goto err;
624      }
625 - err:
626 -    kop.crk_param[0].crp_p = NULL;
627 +
628      zapparams(&kop);
629      return (dsaret);
630 + err:
631 +    {
632 +        const DSA_METHOD *meth = DSA_OpenSSL();
633 +        dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa);
634 +        return dsaret;
635 +    }
636 +}
637 +
638 +/* Cryptodev DSA Key Gen routine */
639 +static int cryptodev_dsa_keygen(DSA *dsa)
640 +{
641 +    struct crypt_kop kop;
642 +    int ret = 1, g_len;
643 +    unsigned char *g = NULL;
644 +
645 +    if (dsa->priv_key == NULL) {
646 +        if ((dsa->priv_key = BN_new()) == NULL)
647 +            goto sw_try;
648 +    }
649 +
650 +    if (dsa->pub_key == NULL) {
651 +        if ((dsa->pub_key = BN_new()) == NULL)
652 +            goto sw_try;
653 +    }
654 +
655 +    g_len = BN_num_bytes(dsa->p);
656 +        /**
657 +         * Get generator into a plain buffer. If length is less than
658 +         * p_len then add leading padding bytes.
659 +         */
660 +    if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
661 +        DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
662 +        goto sw_try;
663 +    }
664 +
665 +    memset(&kop, 0, sizeof kop);
666 +
667 +    kop.crk_op = CRK_DSA_GENERATE_KEY;
668 +    if (bn2crparam(dsa->p, &kop.crk_param[0]))
669 +        goto sw_try;
670 +    if (bn2crparam(dsa->q, &kop.crk_param[1]))
671 +        goto sw_try;
672 +    kop.crk_param[2].crp_p = g;
673 +    kop.crk_param[2].crp_nbits = g_len * 8;
674 +    kop.crk_iparams = 3;
675 +
676 +    /* pub_key is or prime length while priv key is of length of order */
677 +    if (cryptodev_asym(&kop, BN_num_bytes(dsa->p), dsa->pub_key,
678 +                       BN_num_bytes(dsa->q), dsa->priv_key))
679 +        goto sw_try;
680 +
681 +    return ret;
682 + sw_try:
683 +    {
684 +        const DSA_METHOD *meth = DSA_OpenSSL();
685 +        ret = (meth->dsa_keygen) (dsa);
686 +    }
687 +    return ret;
688  }
689  
690  static DSA_METHOD cryptodev_dsa = {
691 @@ -1584,12 +1859,558 @@ static DSA_METHOD cryptodev_dsa = {
692      NULL                        /* app_data */
693  };
694  
695 -static int
696 -cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
697 -                     const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
698 -                     BN_MONT_CTX *m_ctx)
699 +static ECDSA_METHOD cryptodev_ecdsa = {
700 +    "cryptodev ECDSA method",
701 +    NULL,
702 +    NULL,                       /* ecdsa_sign_setup */
703 +    NULL,
704 +    NULL,
705 +    0,                          /* flags */
706 +    NULL                        /* app_data */
707 +};
708 +
709 +typedef enum ec_curve_s {
710 +    EC_PRIME,
711 +    EC_BINARY
712 +} ec_curve_t;
713 +
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,
717 +                                          const BIGNUM *in_r, EC_KEY *eckey)
718  {
719 -    return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
720 +    BIGNUM *m = NULL, *p = NULL, *a = NULL;
721 +    BIGNUM *b = NULL, *x = NULL, *y = NULL;
722 +    BN_CTX *ctx = NULL;
723 +    ECDSA_SIG *ret = NULL;
724 +    ECDSA_DATA *ecdsa = NULL;
725 +    unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
726 +    unsigned char *s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst =
727 +        NULL;
728 +    int i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
729 +    int g_len = 0, d_len = 0, ab_len = 0;
730 +    const BIGNUM *order = NULL, *priv_key = NULL;
731 +    const EC_GROUP *group = NULL;
732 +    struct crypt_kop kop;
733 +    ec_curve_t ec_crv = EC_PRIME;
734 +
735 +    memset(&kop, 0, sizeof(kop));
736 +    ecdsa = ecdsa_check(eckey);
737 +    if (!ecdsa) {
738 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
739 +        return NULL;
740 +    }
741 +
742 +    group = EC_KEY_get0_group(eckey);
743 +    priv_key = EC_KEY_get0_private_key(eckey);
744 +
745 +    if (!group || !priv_key) {
746 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
747 +        return NULL;
748 +    }
749 +
750 +    if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
751 +        (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
752 +        (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
753 +        (y = BN_new()) == NULL) {
754 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
755 +        goto err;
756 +    }
757 +
758 +    order = &group->order;
759 +    if (!order || BN_is_zero(order)) {
760 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
761 +        goto err;
762 +    }
763 +
764 +    i = BN_num_bits(order);
765 +    /*
766 +     * Need to truncate digest if it is too long: first truncate whole bytes
767 +     */
768 +    if (8 * dgst_len > i)
769 +        dgst_len = (i + 7) / 8;
770 +
771 +    if (!BN_bin2bn(dgst, dgst_len, m)) {
772 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
773 +        goto err;
774 +    }
775 +
776 +    /* If still too long truncate remaining bits with a shift */
777 +    if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
778 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
779 +        goto err;
780 +    }
781 +
782 +    /* copy the truncated bits into plain buffer */
783 +    if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
784 +        fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__,
785 +                __LINE__);
786 +        goto err;
787 +    }
788 +
789 +    ret = ECDSA_SIG_new();
790 +    if (!ret) {
791 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
792 +        goto err;
793 +    }
794 +
795 +    /* check if this is prime or binary EC request */
796 +    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
797 +        NID_X9_62_prime_field) {
798 +        ec_crv = EC_PRIME;
799 +        /* get the generator point pair */
800 +        if (!EC_POINT_get_affine_coordinates_GFp
801 +            (group, EC_GROUP_get0_generator(group), x, y, ctx)) {
802 +            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
803 +            goto err;
804 +        }
805 +
806 +        /* get the ECC curve parameters */
807 +        if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
808 +            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
809 +            goto err;
810 +        }
811 +    } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
812 +               NID_X9_62_characteristic_two_field) {
813 +        ec_crv = EC_BINARY;
814 +        /* get the ECC curve parameters */
815 +        if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) {
816 +            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
817 +            goto err;
818 +        }
819 +
820 +        /* get the generator point pair */
821 +        if (!EC_POINT_get_affine_coordinates_GF2m(group,
822 +                                                  EC_GROUP_get0_generator
823 +                                                  (group), x, y, ctx)) {
824 +            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
825 +            goto err;
826 +        }
827 +    } else {
828 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
829 +        goto err;
830 +    }
831 +
832 +    if (spcf_bn2bin(order, &r, &r_len)) {
833 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
834 +        goto err;
835 +    }
836 +
837 +    if (spcf_bn2bin(p, &q, &q_len)) {
838 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
839 +        goto err;
840 +    }
841 +
842 +    priv_key_len = r_len;
843 +
844 +        /**
845 +         * If BN_num_bytes of priv_key returns less then r_len then
846 +         * add padding bytes before the key
847 +         */
848 +    if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len)) {
849 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
850 +        goto err;
851 +    }
852 +
853 +    /* Generation of ECC curve parameters */
854 +    ab_len = 2 * q_len;
855 +    ab = eng_copy_curve_points(a, b, ab_len, q_len);
856 +    if (!ab) {
857 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
858 +        goto err;
859 +    }
860 +
861 +    if (ec_crv == EC_BINARY) {
862 +        if (eng_ec_get_cparam
863 +            (EC_GROUP_get_curve_name(group), ab + q_len, q_len)) {
864 +            unsigned char *c_temp = NULL;
865 +            int c_temp_len = q_len;
866 +            if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
867 +                memcpy(ab + q_len, c_temp, q_len);
868 +            else
869 +                goto err;
870 +        }
871 +        kop.curve_type = ECC_BINARY;
872 +    }
873 +
874 +    /* Calculation of Generator point */
875 +    g_len = 2 * q_len;
876 +    g_xy = eng_copy_curve_points(x, y, g_len, q_len);
877 +    if (!g_xy) {
878 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
879 +        goto err;
880 +    }
881 +
882 +    /* Memory allocation for first part of digital signature */
883 +    c = malloc(r_len);
884 +    if (!c) {
885 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
886 +        goto err;
887 +    }
888 +
889 +    d_len = r_len;
890 +
891 +    /* Memory allocation for second part of digital signature */
892 +    d = malloc(d_len);
893 +    if (!d) {
894 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
895 +        goto err;
896 +    }
897 +
898 +    /* memory for message representative */
899 +    f = malloc(r_len);
900 +    if (!f) {
901 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
902 +        goto err;
903 +    }
904 +
905 +    /* Add padding, since SEC expects hash to of size r_len */
906 +    memset(f, 0, r_len - dgst_len);
907 +
908 +    /* Skip leading bytes if dgst_len < r_len */
909 +    memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
910 +
911 +    dgst_len += r_len - dgst_len;
912 +    kop.crk_op = CRK_DSA_SIGN;
913 +    /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
914 +    kop.crk_param[0].crp_p = f;
915 +    kop.crk_param[0].crp_nbits = dgst_len * 8;
916 +    kop.crk_param[1].crp_p = q;
917 +    kop.crk_param[1].crp_nbits = q_len * 8;
918 +    kop.crk_param[2].crp_p = r;
919 +    kop.crk_param[2].crp_nbits = r_len * 8;
920 +    kop.crk_param[3].crp_p = g_xy;
921 +    kop.crk_param[3].crp_nbits = g_len * 8;
922 +    kop.crk_param[4].crp_p = s;
923 +    kop.crk_param[4].crp_nbits = priv_key_len * 8;
924 +    kop.crk_param[5].crp_p = ab;
925 +    kop.crk_param[5].crp_nbits = ab_len * 8;
926 +    kop.crk_iparams = 6;
927 +    kop.crk_param[6].crp_p = c;
928 +    kop.crk_param[6].crp_nbits = d_len * 8;
929 +    kop.crk_param[7].crp_p = d;
930 +    kop.crk_param[7].crp_nbits = d_len * 8;
931 +    kop.crk_oparams = 2;
932 +
933 +    if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
934 +        /* Check if ret->r and s needs to allocated */
935 +        crparam2bn(&kop.crk_param[6], ret->r);
936 +        crparam2bn(&kop.crk_param[7], ret->s);
937 +    } else {
938 +        const ECDSA_METHOD *meth = ECDSA_OpenSSL();
939 +        ret = (meth->ecdsa_do_sign) (dgst, dgst_len, in_kinv, in_r, eckey);
940 +    }
941 +    kop.crk_param[0].crp_p = NULL;
942 +    zapparams(&kop);
943 + err:
944 +    if (!ret) {
945 +        ECDSA_SIG_free(ret);
946 +        ret = NULL;
947 +    }
948 +    return ret;
949 +}
950 +
951 +static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len,
952 +                                  ECDSA_SIG *sig, EC_KEY *eckey)
953 +{
954 +    BIGNUM *m = NULL, *p = NULL, *a = NULL, *b = NULL;
955 +    BIGNUM *x = NULL, *y = NULL, *w_x = NULL, *w_y = NULL;
956 +    BN_CTX *ctx = NULL;
957 +    ECDSA_DATA *ecdsa = NULL;
958 +    unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL, *w_xy =
959 +        NULL;
960 +    unsigned char *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
961 +    int i = 0, q_len = 0, pub_key_len = 0, r_len = 0, c_len = 0, g_len = 0;
962 +    int d_len = 0, ab_len = 0, ret = -1;
963 +    const EC_POINT *pub_key = NULL;
964 +    const BIGNUM *order = NULL;
965 +    const EC_GROUP *group = NULL;
966 +    ec_curve_t ec_crv = EC_PRIME;
967 +    struct crypt_kop kop;
968 +
969 +    memset(&kop, 0, sizeof kop);
970 +    ecdsa = ecdsa_check(eckey);
971 +    if (!ecdsa) {
972 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
973 +        return ret;
974 +    }
975 +
976 +    group = EC_KEY_get0_group(eckey);
977 +    pub_key = EC_KEY_get0_public_key(eckey);
978 +
979 +    if (!group || !pub_key) {
980 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
981 +        return ret;
982 +    }
983 +
984 +    if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
985 +        (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
986 +        (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
987 +        (y = BN_new()) == NULL || (w_x = BN_new()) == NULL ||
988 +        (w_y = BN_new()) == NULL) {
989 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
990 +        goto err;
991 +    }
992 +
993 +    order = &group->order;
994 +    if (!order || BN_is_zero(order)) {
995 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
996 +        goto err;
997 +    }
998 +
999 +    i = BN_num_bits(order);
1000 +    /*
1001 +     * Need to truncate digest if it is too long: first truncate whole *
1002 +     * bytes
1003 +     */
1004 +    if (8 * dgst_len > i)
1005 +        dgst_len = (i + 7) / 8;
1006 +
1007 +    if (!BN_bin2bn(dgst, dgst_len, m)) {
1008 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1009 +        goto err;
1010 +    }
1011 +
1012 +    /* If still too long truncate remaining bits with a shift */
1013 +    if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
1014 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1015 +        goto err;
1016 +    }
1017 +    /* copy the truncated bits into plain buffer */
1018 +    if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
1019 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1020 +        goto err;
1021 +    }
1022 +
1023 +    /* check if this is prime or binary EC request */
1024 +    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1025 +        NID_X9_62_prime_field) {
1026 +        ec_crv = EC_PRIME;
1027 +
1028 +        /* get the generator point pair */
1029 +        if (!EC_POINT_get_affine_coordinates_GFp(group,
1030 +                                                 EC_GROUP_get0_generator
1031 +                                                 (group), x, y, ctx)) {
1032 +            ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1033 +            goto err;
1034 +        }
1035 +
1036 +        /* get the public key pair for prime curve */
1037 +        if (!EC_POINT_get_affine_coordinates_GFp(group,
1038 +                                                 pub_key, w_x, w_y, ctx)) {
1039 +            ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1040 +            goto err;
1041 +        }
1042 +
1043 +        /* get the ECC curve parameters */
1044 +        if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
1045 +            ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1046 +            goto err;
1047 +        }
1048 +    } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1049 +               NID_X9_62_characteristic_two_field) {
1050 +        ec_crv = EC_BINARY;
1051 +        /* get the ECC curve parameters */
1052 +        if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) {
1053 +            ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1054 +            goto err;
1055 +        }
1056 +
1057 +        /* get the generator point pair */
1058 +        if (!EC_POINT_get_affine_coordinates_GF2m(group,
1059 +                                                  EC_GROUP_get0_generator
1060 +                                                  (group), x, y, ctx)) {
1061 +            ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1062 +            goto err;
1063 +        }
1064 +
1065 +        /* get the public key pair for binary curve */
1066 +        if (!EC_POINT_get_affine_coordinates_GF2m(group,
1067 +                                                  pub_key, w_x, w_y, ctx)) {
1068 +            ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1069 +            goto err;
1070 +        }
1071 +    } else {
1072 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1073 +        goto err;
1074 +    }
1075 +
1076 +    /* Get the order of the subgroup of private keys */
1077 +    if (spcf_bn2bin((BIGNUM *)order, &r, &r_len)) {
1078 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1079 +        goto err;
1080 +    }
1081 +
1082 +    /* Get the irreducible polynomial that creates the field */
1083 +    if (spcf_bn2bin(p, &q, &q_len)) {
1084 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1085 +        goto err;
1086 +    }
1087 +
1088 +    /* Get the public key into a flat buffer with appropriate padding */
1089 +    pub_key_len = 2 * q_len;
1090 +
1091 +    w_xy = eng_copy_curve_points(w_x, w_y, pub_key_len, q_len);
1092 +    if (!w_xy) {
1093 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1094 +        goto err;
1095 +    }
1096 +
1097 +    /* Generation of ECC curve parameters */
1098 +    ab_len = 2 * q_len;
1099 +
1100 +    ab = eng_copy_curve_points(a, b, ab_len, q_len);
1101 +    if (!ab) {
1102 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1103 +        goto err;
1104 +    }
1105 +
1106 +    if (ec_crv == EC_BINARY) {
1107 +        /* copy b' i.e c(b), instead of only b */
1108 +        if (eng_ec_get_cparam
1109 +            (EC_GROUP_get_curve_name(group), ab + q_len, q_len)) {
1110 +            unsigned char *c_temp = NULL;
1111 +            int c_temp_len = q_len;
1112 +            if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1113 +                memcpy(ab + q_len, c_temp, q_len);
1114 +            else
1115 +                goto err;
1116 +        }
1117 +        kop.curve_type = ECC_BINARY;
1118 +    }
1119 +
1120 +    /* Calculation of Generator point */
1121 +    g_len = 2 * q_len;
1122 +
1123 +    g_xy = eng_copy_curve_points(x, y, g_len, q_len);
1124 +    if (!g_xy) {
1125 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1126 +        goto err;
1127 +    }
1128 +
1129 +        /**
1130 +         * Get the 1st part of signature into a flat buffer with
1131 +         * appropriate padding
1132 +         */
1133 +    if (BN_num_bytes(sig->r) < r_len)
1134 +        c_len = r_len;
1135 +
1136 +    if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
1137 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1138 +        goto err;
1139 +    }
1140 +
1141 +        /**
1142 +         * Get the 2nd part of signature into a flat buffer with
1143 +         * appropriate padding
1144 +         */
1145 +    if (BN_num_bytes(sig->s) < r_len)
1146 +        d_len = r_len;
1147 +
1148 +    if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1149 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1150 +        goto err;
1151 +    }
1152 +
1153 +    /* memory for message representative */
1154 +    f = malloc(r_len);
1155 +    if (!f) {
1156 +        ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1157 +        goto err;
1158 +    }
1159 +
1160 +    /* Add padding, since SEC expects hash to of size r_len */
1161 +    memset(f, 0, r_len - dgst_len);
1162 +
1163 +    /* Skip leading bytes if dgst_len < r_len */
1164 +    memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
1165 +    dgst_len += r_len - dgst_len;
1166 +    kop.crk_op = CRK_DSA_VERIFY;
1167 +    /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1168 +    kop.crk_param[0].crp_p = f;
1169 +    kop.crk_param[0].crp_nbits = dgst_len * 8;
1170 +    kop.crk_param[1].crp_p = q;
1171 +    kop.crk_param[1].crp_nbits = q_len * 8;
1172 +    kop.crk_param[2].crp_p = r;
1173 +    kop.crk_param[2].crp_nbits = r_len * 8;
1174 +    kop.crk_param[3].crp_p = g_xy;
1175 +    kop.crk_param[3].crp_nbits = g_len * 8;
1176 +    kop.crk_param[4].crp_p = w_xy;
1177 +    kop.crk_param[4].crp_nbits = pub_key_len * 8;
1178 +    kop.crk_param[5].crp_p = ab;
1179 +    kop.crk_param[5].crp_nbits = ab_len * 8;
1180 +    kop.crk_param[6].crp_p = c;
1181 +    kop.crk_param[6].crp_nbits = d_len * 8;
1182 +    kop.crk_param[7].crp_p = d;
1183 +    kop.crk_param[7].crp_nbits = d_len * 8;
1184 +    kop.crk_iparams = 8;
1185 +
1186 +    if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1187 +        /*
1188 +         * OCF success value is 0, if not zero, change ret to fail
1189 +         */
1190 +        if (0 == kop.crk_status)
1191 +            ret = 1;
1192 +    } else {
1193 +        const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1194 +
1195 +        ret = (meth->ecdsa_do_verify) (dgst, dgst_len, sig, eckey);
1196 +    }
1197 +    kop.crk_param[0].crp_p = NULL;
1198 +    zapparams(&kop);
1199 +
1200 + err:
1201 +    return ret;
1202 +}
1203 +
1204 +static int cryptodev_dh_keygen(DH *dh)
1205 +{
1206 +    struct crypt_kop kop;
1207 +    int ret = 1, g_len;
1208 +    unsigned char *g = NULL;
1209 +
1210 +    if (dh->priv_key == NULL) {
1211 +        if ((dh->priv_key = BN_new()) == NULL)
1212 +            goto sw_try;
1213 +    }
1214 +
1215 +    if (dh->pub_key == NULL) {
1216 +        if ((dh->pub_key = BN_new()) == NULL)
1217 +            goto sw_try;
1218 +    }
1219 +
1220 +    g_len = BN_num_bytes(dh->p);
1221 +        /**
1222 +         * Get generator into a plain buffer. If length is less than
1223 +         * q_len then add leading padding bytes.
1224 +         */
1225 +    if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
1226 +        DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
1227 +        goto sw_try;
1228 +    }
1229 +
1230 +    memset(&kop, 0, sizeof kop);
1231 +    kop.crk_op = CRK_DH_GENERATE_KEY;
1232 +    if (bn2crparam(dh->p, &kop.crk_param[0]))
1233 +        goto sw_try;
1234 +    if (bn2crparam(dh->q, &kop.crk_param[1]))
1235 +        goto sw_try;
1236 +    kop.crk_param[2].crp_p = g;
1237 +    kop.crk_param[2].crp_nbits = g_len * 8;
1238 +    kop.crk_iparams = 3;
1239 +
1240 +    /* pub_key is or prime length while priv key is of length of order */
1241 +    if (cryptodev_asym(&kop, BN_num_bytes(dh->p), dh->pub_key,
1242 +                       BN_num_bytes(dh->q), dh->priv_key))
1243 +        goto sw_try;
1244 +
1245 +    return ret;
1246 + sw_try:
1247 +    {
1248 +        const DH_METHOD *meth = DH_OpenSSL();
1249 +        ret = (meth->generate_key) (dh);
1250 +    }
1251 +    return ret;
1252  }
1253  
1254  static int
1255 @@ -1597,41 +2418,236 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1256  {
1257      struct crypt_kop kop;
1258      int dhret = 1;
1259 -    int fd, keylen;
1260 +    int fd, p_len;
1261 +    BIGNUM *temp = NULL;
1262 +    unsigned char *padded_pub_key = NULL, *p = NULL;
1263 +
1264 +    if ((fd = get_asym_dev_crypto()) < 0)
1265 +        goto sw_try;
1266 +
1267 +    memset(&kop, 0, sizeof kop);
1268 +    kop.crk_op = CRK_DH_COMPUTE_KEY;
1269 +    /* inputs: dh->priv_key pub_key dh->p key */
1270 +    spcf_bn2bin(dh->p, &p, &p_len);
1271 +    spcf_bn2bin_ex(pub_key, &padded_pub_key, &p_len);
1272 +    if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1273 +        goto sw_try;
1274 +
1275 +    kop.crk_param[1].crp_p = padded_pub_key;
1276 +    kop.crk_param[1].crp_nbits = p_len * 8;
1277 +    kop.crk_param[2].crp_p = p;
1278 +    kop.crk_param[2].crp_nbits = p_len * 8;
1279 +    kop.crk_iparams = 3;
1280 +    kop.crk_param[3].crp_p = (void *)key;
1281 +    kop.crk_param[3].crp_nbits = p_len * 8;
1282 +    kop.crk_oparams = 1;
1283 +    dhret = p_len;
1284 +
1285 +    if (ioctl(fd, CIOCKEY, &kop))
1286 +        goto sw_try;
1287 +
1288 +    if ((temp = BN_new())) {
1289 +        if (!BN_bin2bn(key, p_len, temp)) {
1290 +            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
1291 +            goto sw_try;
1292 +        }
1293 +        if (dhret > BN_num_bytes(temp))
1294 +            dhret = BN_bn2bin(temp, key);
1295 +        BN_free(temp);
1296 +    }
1297  
1298 -    if ((fd = get_asym_dev_crypto()) < 0) {
1299 +    kop.crk_param[3].crp_p = NULL;
1300 +    zapparams(&kop);
1301 +    return (dhret);
1302 + sw_try:
1303 +    {
1304          const DH_METHOD *meth = DH_OpenSSL();
1305  
1306 -        return ((meth->compute_key) (key, pub_key, dh));
1307 +        dhret = (meth->compute_key) (key, pub_key, dh);
1308      }
1309 +    return (dhret);
1310 +}
1311  
1312 -    keylen = BN_num_bits(dh->p);
1313 +int cryptodev_ecdh_compute_key(void *out, size_t outlen,
1314 +                               const EC_POINT *pub_key, EC_KEY *ecdh,
1315 +                               void *(*KDF) (const void *in, size_t inlen,
1316 +                                             void *out, size_t *outlen))
1317 +{
1318 +    ec_curve_t ec_crv = EC_PRIME;
1319 +    unsigned char *q = NULL, *w_xy = NULL, *ab = NULL, *s = NULL, *r = NULL;
1320 +    BIGNUM *w_x = NULL, *w_y = NULL;
1321 +    int q_len = 0, ab_len = 0, pub_key_len = 0, r_len = 0, priv_key_len = 0;
1322 +    BIGNUM *p = NULL, *a = NULL, *b = NULL;
1323 +    BN_CTX *ctx;
1324 +    EC_POINT *tmp = NULL;
1325 +    BIGNUM *x = NULL, *y = NULL;
1326 +    const BIGNUM *priv_key;
1327 +    const EC_GROUP *group = NULL;
1328 +    int ret = -1;
1329 +    size_t buflen, len;
1330 +    struct crypt_kop kop;
1331  
1332      memset(&kop, 0, sizeof kop);
1333 -    kop.crk_op = CRK_DH_COMPUTE_KEY;
1334  
1335 -    /* inputs: dh->priv_key pub_key dh->p key */
1336 -    if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1337 +    if ((ctx = BN_CTX_new()) == NULL)
1338          goto err;
1339 -    if (bn2crparam(pub_key, &kop.crk_param[1]))
1340 +    BN_CTX_start(ctx);
1341 +    x = BN_CTX_get(ctx);
1342 +    y = BN_CTX_get(ctx);
1343 +    p = BN_CTX_get(ctx);
1344 +    a = BN_CTX_get(ctx);
1345 +    b = BN_CTX_get(ctx);
1346 +    w_x = BN_CTX_get(ctx);
1347 +    w_y = BN_CTX_get(ctx);
1348 +
1349 +    if (!x || !y || !p || !a || !b || !w_x || !w_y) {
1350 +        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
1351          goto err;
1352 -    if (bn2crparam(dh->p, &kop.crk_param[2]))
1353 +    }
1354 +
1355 +    priv_key = EC_KEY_get0_private_key(ecdh);
1356 +    if (priv_key == NULL) {
1357 +        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_NO_PRIVATE_VALUE);
1358          goto err;
1359 -    kop.crk_iparams = 3;
1360 +    }
1361  
1362 -    kop.crk_param[3].crp_p = (caddr_t) key;
1363 -    kop.crk_param[3].crp_nbits = keylen * 8;
1364 -    kop.crk_oparams = 1;
1365 +    group = EC_KEY_get0_group(ecdh);
1366 +    if ((tmp = EC_POINT_new(group)) == NULL) {
1367 +        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
1368 +        goto err;
1369 +    }
1370  
1371 -    if (ioctl(fd, CIOCKEY, &kop) == -1) {
1372 -        const DH_METHOD *meth = DH_OpenSSL();
1373 +    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1374 +        NID_X9_62_prime_field) {
1375 +        ec_crv = EC_PRIME;
1376  
1377 -        dhret = (meth->compute_key) (key, pub_key, dh);
1378 +        if (!EC_POINT_get_affine_coordinates_GFp(group,
1379 +                                                 EC_GROUP_get0_generator
1380 +                                                 (group), x, y, ctx)) {
1381 +            ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE);
1382 +            goto err;
1383 +        }
1384 +
1385 +        /* get the ECC curve parameters */
1386 +        if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
1387 +            ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1388 +            goto err;
1389 +        }
1390 +
1391 +        /* get the public key pair for prime curve */
1392 +        if (!EC_POINT_get_affine_coordinates_GFp
1393 +            (group, pub_key, w_x, w_y, ctx)) {
1394 +            ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1395 +            goto err;
1396 +        }
1397 +    } else {
1398 +        ec_crv = EC_BINARY;
1399 +
1400 +        if (!EC_POINT_get_affine_coordinates_GF2m(group,
1401 +                                                  EC_GROUP_get0_generator
1402 +                                                  (group), x, y, ctx)) {
1403 +            ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE);
1404 +            goto err;
1405 +        }
1406 +
1407 +        /* get the ECC curve parameters */
1408 +        if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) {
1409 +            ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1410 +            goto err;
1411 +        }
1412 +
1413 +        /* get the public key pair for binary curve */
1414 +        if (!EC_POINT_get_affine_coordinates_GF2m(group,
1415 +                                                  pub_key, w_x, w_y, ctx)) {
1416 +            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1417 +            goto err;
1418 +        }
1419 +    }
1420 +
1421 +    /* irreducible polynomial that creates the field */
1422 +    if (spcf_bn2bin((BIGNUM *)&group->order, &r, &r_len)) {
1423 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1424 +        goto err;
1425 +    }
1426 +
1427 +    /* Get the irreducible polynomial that creates the field */
1428 +    if (spcf_bn2bin(p, &q, &q_len)) {
1429 +        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1430 +        goto err;
1431 +    }
1432 +
1433 +    /* Get the public key into a flat buffer with appropriate padding */
1434 +    pub_key_len = 2 * q_len;
1435 +    w_xy = eng_copy_curve_points(w_x, w_y, pub_key_len, q_len);
1436 +    if (!w_xy) {
1437 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1438 +        goto err;
1439 +    }
1440 +
1441 +    /* Generation of ECC curve parameters */
1442 +    ab_len = 2 * q_len;
1443 +    ab = eng_copy_curve_points(a, b, ab_len, q_len);
1444 +    if (!ab) {
1445 +        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1446 +        goto err;
1447 +    }
1448 +
1449 +    if (ec_crv == EC_BINARY) {
1450 +        /* copy b' i.e c(b), instead of only b */
1451 +        if (eng_ec_get_cparam
1452 +            (EC_GROUP_get_curve_name(group), ab + q_len, q_len)) {
1453 +            unsigned char *c_temp = NULL;
1454 +            int c_temp_len = q_len;
1455 +            if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1456 +                memcpy(ab + q_len, c_temp, q_len);
1457 +            else
1458 +                goto err;
1459 +        }
1460 +        kop.curve_type = ECC_BINARY;
1461 +    } else
1462 +        kop.curve_type = ECC_PRIME;
1463 +
1464 +    priv_key_len = r_len;
1465 +
1466 +    /*
1467 +     * If BN_num_bytes of priv_key returns less then r_len then
1468 +     * add padding bytes before the key
1469 +     */
1470 +    if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
1471 +        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1472 +        goto err;
1473 +    }
1474 +
1475 +    buflen = (EC_GROUP_get_degree(group) + 7) / 8;
1476 +    len = BN_num_bytes(x);
1477 +    if (len > buflen || q_len < buflen) {
1478 +        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
1479 +        goto err;
1480      }
1481 +
1482 +    kop.crk_op = CRK_DH_COMPUTE_KEY;
1483 +    kop.crk_param[0].crp_p = (void *)s;
1484 +    kop.crk_param[0].crp_nbits = priv_key_len * 8;
1485 +    kop.crk_param[1].crp_p = (void *)w_xy;
1486 +    kop.crk_param[1].crp_nbits = pub_key_len * 8;
1487 +    kop.crk_param[2].crp_p = (void *)q;
1488 +    kop.crk_param[2].crp_nbits = q_len * 8;
1489 +    kop.crk_param[3].crp_p = (void *)ab;
1490 +    kop.crk_param[3].crp_nbits = ab_len * 8;
1491 +    kop.crk_iparams = 4;
1492 +    kop.crk_param[4].crp_p = (void *)out;
1493 +    kop.crk_param[4].crp_nbits = q_len * 8;
1494 +    kop.crk_oparams = 1;
1495 +    ret = q_len;
1496 +    if (cryptodev_asym(&kop, 0, NULL, 0, NULL)) {
1497 +        const ECDH_METHOD *meth = ECDH_OpenSSL();
1498 +        ret = (meth->compute_key) (out, outlen, pub_key, ecdh, KDF);
1499 +    } else
1500 +        ret = q_len;
1501   err:
1502 -    kop.crk_param[3].crp_p = NULL;
1503 +    kop.crk_param[4].crp_p = NULL;
1504      zapparams(&kop);
1505 -    return (dhret);
1506 +    return ret;
1507  }
1508  
1509  static DH_METHOD cryptodev_dh = {
1510 @@ -1645,6 +2661,14 @@ static DH_METHOD cryptodev_dh = {
1511      NULL                        /* app_data */
1512  };
1513  
1514 +static ECDH_METHOD cryptodev_ecdh = {
1515 +    "cryptodev ECDH method",
1516 +    NULL,                       /* cryptodev_ecdh_compute_key */
1517 +    NULL,
1518 +    0,                          /* flags */
1519 +    NULL                        /* app_data */
1520 +};
1521 +
1522  /*
1523   * ctrl right now is just a wrapper that doesn't do much
1524   * but I expect we'll want some options soon.
1525 @@ -1724,24 +2748,39 @@ void ENGINE_load_cryptodev(void)
1526          memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1527          if (cryptodev_asymfeat & CRF_DSA_SIGN)
1528              cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1529 -        if (cryptodev_asymfeat & CRF_MOD_EXP) {
1530 -            cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1531 -            cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1532 -        }
1533          if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1534              cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1535 +        if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY)
1536 +            cryptodev_dsa.dsa_keygen = cryptodev_dsa_keygen;
1537      }
1538  
1539      if (ENGINE_set_DH(engine, &cryptodev_dh)) {
1540          const DH_METHOD *dh_meth = DH_OpenSSL();
1541 +        memcpy(&cryptodev_dh, dh_meth, sizeof(DH_METHOD));
1542 +        if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1543 +            cryptodev_dh.compute_key = cryptodev_dh_compute_key;
1544 +        }
1545 +        if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) {
1546 +            cryptodev_dh.generate_key = cryptodev_dh_keygen;
1547 +        }
1548 +    }
1549  
1550 -        cryptodev_dh.generate_key = dh_meth->generate_key;
1551 -        cryptodev_dh.compute_key = dh_meth->compute_key;
1552 -        cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1553 -        if (cryptodev_asymfeat & CRF_MOD_EXP) {
1554 -            cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1555 -            if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1556 -                cryptodev_dh.compute_key = cryptodev_dh_compute_key;
1557 +    if (ENGINE_set_ECDSA(engine, &cryptodev_ecdsa)) {
1558 +        const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1559 +        memcpy(&cryptodev_ecdsa, meth, sizeof(ECDSA_METHOD));
1560 +        if (cryptodev_asymfeat & CRF_DSA_SIGN) {
1561 +            cryptodev_ecdsa.ecdsa_do_sign = cryptodev_ecdsa_do_sign;
1562 +        }
1563 +        if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
1564 +            cryptodev_ecdsa.ecdsa_do_verify = cryptodev_ecdsa_verify;
1565 +        }
1566 +    }
1567 +
1568 +    if (ENGINE_set_ECDH(engine, &cryptodev_ecdh)) {
1569 +        const ECDH_METHOD *ecdh_meth = ECDH_OpenSSL();
1570 +        memcpy(&cryptodev_ecdh, ecdh_meth, sizeof(ECDH_METHOD));
1571 +        if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1572 +            cryptodev_ecdh.compute_key = cryptodev_ecdh_compute_key;
1573          }
1574      }
1575  
1576 -- 
1577 2.7.0
1578