]> code.ossystems Code Review - meta-freescale.git/blob
8c8b1f228b15f3404d9f57cd6c34a99d22a89e13
[meta-freescale.git] /
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
5
6 Upstream-status: Pending
7
8 Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
9 ---
10  crypto/engine/eng_cryptodev.c | 1343 ++++++++++++++++++++++++++++++++++++-----
11  1 file changed, 1183 insertions(+), 160 deletions(-)
12
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)
18  #else 
19   
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>
31  #include <errno.h>
32  #include <stdio.h>
33 @@ -68,6 +71,8 @@ ENGINE_load_cryptodev(void)
34  #include <syslog.h>
35  #include <errno.h>
36  #include <string.h>
37 +#include "eng_cryptodev_ec.h"
38 +#include <crypto/cryptodev.h>
39  
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,
52      int dlen, DSA *dsa);
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;
64  
65 +inline int spcf_bn2bin(BIGNUM *bn, unsigned char **bin,  int *bin_len)
66 +{
67 +       int len;
68 +       unsigned char *p;
69 +
70 +       len = BN_num_bytes(bn);
71 +
72 +       if (!len)
73 +               return -1;
74 +
75 +       p = malloc(len);
76 +       if (!p)
77 +               return -1;
78 +
79 +       BN_bn2bin(bn,p);
80 +
81 +       *bin = p;
82 +       *bin_len = len;
83 +
84 +       return 0;
85 +}
86 +
87 +inline int spcf_bn2bin_ex(BIGNUM *bn, unsigned char **bin,  int *bin_len)
88 +{
89 +       int len;
90 +       unsigned char *p;
91 +
92 +       len = BN_num_bytes(bn);
93 +
94 +       if (!len)
95 +               return -1;
96 +
97 +       if (len < *bin_len)
98 +               p = malloc(*bin_len);
99 +       else
100 +               p = malloc(len);
101 +
102 +       if (!p)
103 +               return -ENOMEM;
104 +
105 +       if (len < *bin_len) {
106 +               /* place padding */
107 +               memset(p, 0, (*bin_len - len));
108 +               BN_bn2bin(bn,p+(*bin_len-len));
109 +       } else {
110 +               BN_bn2bin(bn,p);
111 +       }
112 +
113 +       *bin = p;
114 +       if (len >= *bin_len)
115 +               *bin_len = len;
116 +
117 +       return 0;
118 +}
119 +
120 +/**
121 + * Convert an ECC F2m 'b' parameter into the 'c' parameter.
122 + *Inputs:
123 + * q, the curve's modulus
124 + * b, the curve's b parameter
125 + * (a bignum for b, a buffer for c)
126 + * Output:
127 + * c, written into bin, right-adjusted to fill q_len bytes.
128 + */
129 +static int
130 +eng_ec_compute_cparam(const BIGNUM* b, const BIGNUM* q,
131 +                       unsigned char **bin, int *bin_len)
132 +{
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;
137 +       int ok = 0;
138 +
139 +       if (!c || !exp || !ctx || *bin)
140 +               goto err;
141 +
142 +       /*
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)
146 +        * (1 << x) == 2^x
147 +        * and then compute c = b^exp
148 +        */
149 +       BN_lshift(exp, BN_value_one(), m-2);
150 +       BN_GF2m_mod_exp(c, b, exp, q, ctx);
151 +       /* Store c */
152 +       spcf_bn2bin_ex(c, bin, bin_len);
153 +       ok = 1;
154 +err:
155 +       if (ctx) BN_CTX_free(ctx);
156 +       if (c) BN_free(c);
157 +       if (exp) BN_free(exp);
158 +       return ok;
159 +}
160 +
161  static const ENGINE_CMD_DEFN cryptodev_defns[] = {
162         { 0, NULL, NULL, 0 }
163  };
164 @@ -1139,7 +1232,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
165  static int
166  bn2crparam(const BIGNUM *a, struct crparam *crp)
167  {
168 -       int i, j, k;
169         ssize_t bytes, bits;
170         u_char *b;
171  
172 @@ -1156,15 +1248,7 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
173  
174         crp->crp_p = (caddr_t) b;
175         crp->crp_nbits = bits;
176 -
177 -       for (i = 0, j = 0; i < a->top; i++) {
178 -               for (k = 0; k < BN_BITS2 / 8; k++) {
179 -                       if ((j + k) >= bytes)
180 -                               return (0);
181 -                       b[j + k] = a->d[i] >> (k * 8);
182 -               }
183 -               j += BN_BITS2 / 8;
184 -       }
185 +       BN_bn2bin(a, crp->crp_p);
186         return (0);
187  }
188  
189 @@ -1172,22 +1256,14 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
190  static int
191  crparam2bn(struct crparam *crp, BIGNUM *a)
192  {
193 -       u_int8_t *pd;
194 -       int i, bytes;
195 +       int bytes;
196  
197         bytes = (crp->crp_nbits + 7) / 8;
198  
199         if (bytes == 0)
200                 return (-1);
201  
202 -       if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
203 -               return (-1);
204 -
205 -       for (i = 0; i < bytes; i++)
206 -               pd[i] = crp->crp_p[bytes - i - 1];
207 -
208 -       BN_bin2bn(pd, bytes, a);
209 -       free(pd);
210 +       BN_bin2bn(crp->crp_p, bytes, a);
211  
212         return (0);
213  }
214 @@ -1235,6 +1311,32 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
215         return (ret);
216  }
217  
218 +/* Close an opened instance of cryptodev engine */
219 +void cryptodev_close_instance(void *handle)
220 +{
221 +       int fd;
222 +
223 +       if (handle) {
224 +               fd = *(int *)handle;
225 +               close(fd);
226 +               free(handle);
227 +       }
228 +}
229 +
230 +/* Create an instance of cryptodev for asynchronous interface */
231 +void *cryptodev_init_instance(void)
232 +{
233 +       int *fd = malloc(sizeof(int));
234 +
235 +       if (fd) {
236 +               if ((*fd = open("/dev/crypto", O_RDWR, 0)) == -1) {
237 +                       free(fd);
238 +                       return NULL;
239 +               }
240 +       }
241 +       return fd;
242 +}
243 +
244  static int
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,
248                 return (ret);
249         }
250  
251 -       memset(&kop, 0, sizeof kop);
252         kop.crk_op = CRK_MOD_EXP;
253 -
254 +       kop.crk_oparams = 0;
255 +       kop.crk_status = 0;
256         /* inputs: a^p % m */
257         if (bn2crparam(a, &kop.crk_param[0]))
258                 goto err;
259 @@ -1293,28 +1395,38 @@ static int
260  cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
261  {
262         struct crypt_kop kop;
263 -       int ret = 1;
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;
266  
267         if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
268                 /* XXX 0 means failure?? */
269                 return (0);
270         }
271  
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]))
285 -               goto err;
286 -       if (bn2crparam(rsa->q, &kop.crk_param[1]))
287 -               goto err;
288 -       if (bn2crparam(I, &kop.crk_param[2]))
289 -               goto err;
290 -       if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
291 -               goto err;
292 -       if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
293 -               goto err;
294 -       if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
295 -               goto err;
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;
309         kop.crk_iparams = 6;
310  
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 */
314  };
315  
316 -static int
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)
319 -{
320 -       return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
321 -}
322 -
323 -static int
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)
327 +static DSA_SIG *
328 +cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
329  {
330 -       BIGNUM t2;
331 -       int ret = 0;
332 -
333 -       BN_init(&t2);
334 -
335 -       /* v = ( g^u1 * y^u2 mod p ) mod q */
336 -       /* let t1 = g ^ u1 mod p */
337 -       ret = 0;
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;
344  
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);
349                 goto err;
350 +       }
351  
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) {
355 +               BN_free(c);
356 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
357                 goto err;
358 -       /* let u1 = t1 * t2 mod p */
359 -       if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
360 +       }
361 +
362 +       if (spcf_bn2bin(dsa->p, &q, &q_len)) {
363 +               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
364                 goto err;
365 +       }
366  
367 -       BN_copy(t1,u1);
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);
371 +               goto err;
372 +       }
373  
374 -       ret = 1;
375 -err:
376 -       BN_free(&t2);
377 -       return(ret);
378 -}
379 +       /* sanity test */
380 +       if (dlen > r_len) {
381 +               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
382 +               goto err;
383 +       }
384  
385 -static DSA_SIG *
386 -cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
387 -{
388 -       struct crypt_kop kop;
389 -       BIGNUM *r = NULL, *s = NULL;
390 -       DSA_SIG *dsaret = NULL;
391 +       g_len = q_len;
392 +       /**
393 +        * Get generator into a plain buffer. If length is less than
394 +        * q_len then add leading padding bytes.
395 +        */
396 +       if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
397 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
398 +               goto err;
399 +       }
400  
401 -       if ((r = BN_new()) == NULL)
402 +       priv_key_len = r_len;
403 +       /**
404 +        * Get private key into a plain buffer. If length is less than
405 +        * r_len then add leading padding bytes.
406 +        */
407 +        if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
408 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
409                 goto err;
410 -       if ((s = BN_new()) == NULL) {
411 -               BN_free(r);
412 +       }
413 +
414 +       /* Allocate memory to store hash. */
415 +       f = OPENSSL_malloc (r_len);
416 +       if (!f) {
417 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
418                 goto err;
419         }
420  
421 -       memset(&kop, 0, sizeof kop);
422 +       /* Add padding, since SEC expects hash to of size r_len */
423 +       if (dlen < r_len)
424 +               memset(f, 0, r_len - dlen);
425 +
426 +       /* Skip leading bytes if dgst_len < r_len */
427 +       memcpy(f + r_len - dlen, dgst, dlen);
428 +
429         kop.crk_op = CRK_DSA_SIGN;
430  
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]))
435 -               goto err;
436 -       if (bn2crparam(dsa->q, &kop.crk_param[2]))
437 -               goto err;
438 -       if (bn2crparam(dsa->g, &kop.crk_param[3]))
439 -               goto err;
440 -       if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
441 -               goto err;
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;
452         kop.crk_iparams = 5;
453  
454 -       if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
455 -           BN_num_bytes(dsa->q), s) == 0) {
456 -               dsaret = DSA_SIG_new();
457 -               dsaret->r = r;
458 -               dsaret->s = s;
459 -       } else {
460 -               const DSA_METHOD *meth = DSA_OpenSSL();
461 -               BN_free(r);
462 -               BN_free(s);
463 -               dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
464 +       ret = cryptodev_asym(&kop, r_len, c, r_len, d);
465 +
466 +       if (ret) {
467 +               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DECODE_ERROR);
468 +               goto err;
469         }
470 -err:
471 -       kop.crk_param[0].crp_p = NULL;
472 +
473 +       dsaret = DSA_SIG_new();
474 +       dsaret->r = c;
475 +       dsaret->s = d;
476 +
477         zapparams(&kop);
478         return (dsaret);
479 +err:
480 +       {
481 +               const DSA_METHOD *meth = DSA_OpenSSL();
482 +               if (c)
483 +                       BN_free(c);
484 +               if (d)
485 +                       BN_free(d);
486 +               dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
487 +               return (dsaret);
488 +       }
489  }
490  
491  static int
492 @@ -1441,42 +1580,179 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
493      DSA_SIG *sig, DSA *dsa)
494  {
495         struct crypt_kop kop;
496 -       int dsaret = 1;
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;
501  
502         memset(&kop, 0, sizeof kop);
503         kop.crk_op = CRK_DSA_VERIFY;
504  
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);
511 +               return ret;
512 +       }
513 +
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);
517                 goto err;
518 -       if (bn2crparam(dsa->q, &kop.crk_param[2]))
519 +       }
520 +
521 +       g_len = q_len;
522 +       /**
523 +        * Get generator into a plain buffer. If length is less than
524 +        * q_len then add leading padding bytes.
525 +        */
526 +       if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
527 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
528                 goto err;
529 -       if (bn2crparam(dsa->g, &kop.crk_param[3]))
530 +       }
531 +       w_len = q_len;
532 +       /**
533 +        * Get public key into a plain buffer. If length is less than
534 +        * q_len then add leading padding bytes.
535 +        */
536 +       if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
537 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
538 +               goto err;
539 +       }
540 +       /**
541 +        * Get the 1st part of signature into a flat buffer with
542 +        * appropriate padding
543 +        */
544 +       c_len = r_len;
545 +
546 +       if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
547 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
548                 goto err;
549 -       if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
550 +       }
551 +
552 +       /**
553 +        * Get the 2nd part of signature into a flat buffer with
554 +        * appropriate padding
555 +        */
556 +       d_len = r_len;
557 +
558 +       if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
559 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
560                 goto err;
561 -       if (bn2crparam(sig->r, &kop.crk_param[5]))
562 +       }
563 +
564 +
565 +       /* Sanity test */
566 +       if (dlen > r_len) {
567 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
568                 goto err;
569 -       if (bn2crparam(sig->s, &kop.crk_param[6]))
570 +       }
571 +
572 +       /* Allocate memory to store hash. */
573 +       f = OPENSSL_malloc (r_len);
574 +       if (!f) {
575 +               DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
576                 goto err;
577 +       }
578 +
579 +       /* Add padding, since SEC expects hash to of size r_len */
580 +       if (dlen < r_len)
581 +               memset(f, 0, r_len - dlen);
582 +
583 +       /* Skip leading bytes if dgst_len < r_len */
584 +       memcpy(f + r_len - dlen, dgst, dlen);
585 +
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;
601         kop.crk_iparams = 7;
602  
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;
606 -       } else {
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);
610 +               goto err;
611 +       }
612  
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);
617 +               goto err;
618         }
619 -err:
620 -       kop.crk_param[0].crp_p = NULL;
621 +
622         zapparams(&kop);
623         return (dsaret);
624 +err:
625 +       {
626 +               const DSA_METHOD *meth = DSA_OpenSSL();
627 +
628 +               dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
629 +       }
630 +       return dsaret;
631  }
632  
633 +/* Cryptodev DSA Key Gen routine */
634 +static int cryptodev_dsa_keygen(DSA *dsa)
635 +{
636 +       struct crypt_kop kop;
637 +       int ret = 1, g_len;
638 +       unsigned char *g = NULL;
639 +
640 +       if (dsa->priv_key == NULL)      {
641 +               if ((dsa->priv_key=BN_new()) == NULL)
642 +                       goto sw_try;
643 +       }
644 +
645 +       if (dsa->pub_key == NULL) {
646 +               if ((dsa->pub_key=BN_new()) == NULL)
647 +                       goto sw_try;
648 +       }
649 +
650 +       g_len = BN_num_bytes(dsa->p);
651 +       /**
652 +        * Get generator into a plain buffer. If length is less than
653 +        * p_len then add leading padding bytes.
654 +        */
655 +       if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
656 +               DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
657 +               goto sw_try;
658 +       }
659 +
660 +       memset(&kop, 0, sizeof kop);
661 +
662 +       kop.crk_op = CRK_DSA_GENERATE_KEY;
663 +       if (bn2crparam(dsa->p, &kop.crk_param[0]))
664 +               goto sw_try;
665 +       if (bn2crparam(dsa->q, &kop.crk_param[1]))
666 +               goto sw_try;
667 +       kop.crk_param[2].crp_p = g;
668 +       kop.crk_param[2].crp_nbits = g_len * 8;
669 +       kop.crk_iparams = 3;
670 +
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))
674 +           goto sw_try;
675 +
676 +       return ret;
677 +sw_try:
678 +       {
679 +               const DSA_METHOD *meth = DSA_OpenSSL();
680 +               ret = (meth->dsa_keygen)(dsa);
681 +       }
682 +       return ret;
683 +}
684 +
685 +
686 +
687  static DSA_METHOD cryptodev_dsa = {
688         "cryptodev DSA method",
689         NULL,
690 @@ -1490,12 +1766,543 @@ static DSA_METHOD cryptodev_dsa = {
691         NULL    /* app_data */
692  };
693  
694 -static int
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",
700 +       NULL,
701 +       NULL,                           /* ecdsa_sign_setup */
702 +       NULL,
703 +       NULL,
704 +       0,      /* flags */
705 +       NULL    /* app_data */
706 +};
707 +
708 +typedef enum ec_curve_s
709 +{
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, const BIGNUM *in_r, EC_KEY *eckey)
717  {
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;
732 +
733 +       memset(&kop, 0, sizeof(kop));
734 +       ecdsa = ecdsa_check(eckey);
735 +       if (!ecdsa) {
736 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
737 +               return NULL;
738 +       }
739 +
740 +       group = EC_KEY_get0_group(eckey);
741 +       priv_key = EC_KEY_get0_private_key(eckey);
742 +
743 +       if (!group || !priv_key) {
744 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
745 +               return NULL;
746 +       }
747 +
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);
753 +               goto err;
754 +       }
755 +
756 +       order = &group->order;
757 +       if (!order || BN_is_zero(order)) {
758 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
759 +               goto err;
760 +       }
761 +
762 +       i = BN_num_bits(order);
763 +       /* Need to truncate digest if it is too long: first truncate whole
764 +        bytes */
765 +       if (8 * dgst_len > i)
766 +               dgst_len = (i + 7)/8;
767 +
768 +       if (!BN_bin2bn(dgst, dgst_len, m)) {
769 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
770 +               goto err;
771 +       }
772 +
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);
776 +               goto err;
777 +       }
778 +
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__);
782 +               goto err;
783 +       }
784 +
785 +       ret = ECDSA_SIG_new();
786 +       if  (!ret) {
787 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
788 +               goto err;
789 +       }
790 +
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) {
793 +               ec_crv = EC_PRIME;
794 +               /* get the generator point pair */
795 +               if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group),
796 +                       x, y,ctx)) {
797 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
798 +                       goto err;
799 +               }
800 +
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);
804 +                       goto err;
805 +               }
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);
811 +                       goto err;
812 +               }
813 +
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);
818 +                       goto err;
819 +               }
820 +       } else {
821 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
822 +               goto err;
823 +       }
824 +
825 +       if (spcf_bn2bin(order, &r, &r_len)) {
826 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
827 +               goto err;
828 +       }
829 +
830 +       if (spcf_bn2bin(p, &q, &q_len)) {
831 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
832 +               goto err;
833 +       }
834 +
835 +       priv_key_len = r_len;
836 +
837 +       /**
838 +        * If BN_num_bytes of priv_key returns less then r_len then
839 +        * add padding bytes before the key
840 +        */
841 +       if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len))  {
842 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
843 +               goto err;
844 +       }
845 +
846 +       /* Generation of ECC curve parameters */
847 +       ab_len = 2*q_len;
848 +       ab = eng_copy_curve_points(a, b, ab_len, q_len);
849 +       if (!ab) {
850 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
851 +               goto err;
852 +       }
853 +
854 +       if (ec_crv == EC_BINARY) {
855 +               if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
856 +               {
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);
861 +                       else
862 +                               goto err;
863 +               }
864 +               kop.curve_type = ECC_BINARY;
865 +       }
866 +
867 +       /* Calculation of Generator point */
868 +       g_len = 2*q_len;
869 +       g_xy = eng_copy_curve_points(x, y, g_len, q_len);
870 +       if (!g_xy) {
871 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
872 +               goto err;
873 +       }
874 +
875 +       /* Memory allocation for first part of digital signature */
876 +       c = malloc(r_len);
877 +       if (!c) {
878 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
879 +               goto err;
880 +       }
881 +
882 +       d_len = r_len;
883 +
884 +       /* Memory allocation for second part of digital signature */
885 +       d = malloc(d_len);
886 +       if (!d) {
887 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
888 +               goto err;
889 +       }
890 +
891 +       /* memory for message representative */
892 +       f = malloc(r_len);
893 +       if (!f) {
894 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
895 +               goto err;
896 +       }
897 +
898 +       /* Add padding, since SEC expects hash to of size r_len */
899 +       memset(f, 0, r_len - dgst_len);
900 +
901 +       /* Skip leading bytes if dgst_len < r_len */
902 +       memcpy(f +  r_len - dgst_len, tmp_dgst, dgst_len);
903 +
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;
925 +
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);
930 +       } else {
931 +               const ECDSA_METHOD *meth = ECDSA_OpenSSL();
932 +               ret = (meth->ecdsa_do_sign)(dgst, dgst_len, in_kinv, in_r, eckey);
933 +       }
934 +       kop.crk_param[0].crp_p = NULL;
935 +       zapparams(&kop);
936 +err:
937 +       if (!ret) {
938 +               ECDSA_SIG_free(ret);
939 +               ret = NULL;
940 +       }
941 +       return ret;
942 +}
943 +
944 +static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len,
945 +               ECDSA_SIG *sig, EC_KEY *eckey)
946 +{
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;
960 +
961 +       memset(&kop, 0, sizeof kop);
962 +       ecdsa = ecdsa_check(eckey);
963 +       if (!ecdsa) {
964 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
965 +               return ret;
966 +       }
967 +
968 +       group    = EC_KEY_get0_group(eckey);
969 +       pub_key  = EC_KEY_get0_public_key(eckey);
970 +
971 +       if (!group || !pub_key) {
972 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
973 +               return ret;
974 +       }
975 +
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);
982 +               goto err;
983 +       }
984 +
985 +       order = &group->order;
986 +       if (!order || BN_is_zero(order)) {
987 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
988 +               goto err;
989 +       }
990 +
991 +       i = BN_num_bits(order);
992 +       /* Need to truncate digest if it is too long: first truncate whole
993 +       * bytes */
994 +       if (8 * dgst_len > i)
995 +               dgst_len = (i + 7)/8;
996 +
997 +       if (!BN_bin2bn(dgst, dgst_len, m)) {
998 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
999 +               goto err;
1000 +       }
1001 +
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);
1005 +               goto err;
1006 +       }
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);
1010 +               goto err;
1011 +       }
1012 +
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;
1016 +
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);
1021 +                       goto err;
1022 +               }
1023 +
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);
1028 +                       goto err;
1029 +               }
1030 +
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);
1034 +                       goto err;
1035 +               }
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);
1041 +                       goto err;
1042 +               }
1043 +
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);
1048 +                       goto err;
1049 +               }
1050 +
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);
1055 +                       goto err;
1056 +               }
1057 +       }else {
1058 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1059 +               goto err;
1060 +       }
1061 +
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);
1065 +               goto err;
1066 +       }
1067 +
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);
1071 +               goto err;
1072 +       }
1073 +
1074 +       /* Get the public key into a flat buffer with appropriate padding */
1075 +       pub_key_len = 2 * q_len;
1076 +
1077 +       w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
1078 +       if (!w_xy) {
1079 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1080 +               goto err;
1081 +       }
1082 +
1083 +       /* Generation of ECC curve parameters */
1084 +       ab_len = 2*q_len;
1085 +
1086 +       ab = eng_copy_curve_points (a, b, ab_len, q_len);
1087 +       if (!ab) {
1088 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1089 +               goto err;
1090 +       }
1091 +
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))
1095 +               {
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);
1100 +                       else
1101 +                               goto err;
1102 +               }
1103 +               kop.curve_type = ECC_BINARY;
1104 +       }
1105 +
1106 +       /* Calculation of Generator point */
1107 +       g_len = 2 * q_len;
1108 +
1109 +       g_xy = eng_copy_curve_points (x, y, g_len, q_len);
1110 +       if (!g_xy) {
1111 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1112 +               goto err;
1113 +       }
1114 +
1115 +       /**
1116 +        * Get the 1st part of signature into a flat buffer with
1117 +        * appropriate padding
1118 +        */
1119 +       if (BN_num_bytes(sig->r) < r_len)
1120 +               c_len = r_len;
1121 +
1122 +       if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
1123 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1124 +               goto err;
1125 +       }
1126 +
1127 +       /**
1128 +        * Get the 2nd part of signature into a flat buffer with
1129 +        * appropriate padding
1130 +        */
1131 +       if (BN_num_bytes(sig->s) < r_len)
1132 +               d_len = r_len;
1133 +
1134 +       if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1135 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1136 +               goto err;
1137 +       }
1138 +
1139 +       /* memory for message representative */
1140 +       f = malloc(r_len);
1141 +       if (!f) {
1142 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1143 +               goto err;
1144 +       }
1145 +
1146 +       /* Add padding, since SEC expects hash to of size r_len */
1147 +       memset(f, 0, r_len-dgst_len);
1148 +
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;
1171 +
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)
1175 +                       ret  = 1;
1176 +       } else {
1177 +               const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1178 +
1179 +               ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
1180 +       }
1181 +       kop.crk_param[0].crp_p = NULL;
1182 +       zapparams(&kop);
1183 +
1184 +err:
1185 +       return ret;
1186 +}
1187 +
1188 +static int cryptodev_dh_keygen(DH *dh)
1189 +{
1190 +       struct crypt_kop kop;
1191 +       int ret = 1, g_len;
1192 +       unsigned char *g = NULL;
1193 +
1194 +       if (dh->priv_key == NULL)       {
1195 +               if ((dh->priv_key=BN_new()) == NULL)
1196 +                       goto sw_try;
1197 +       }
1198 +
1199 +       if (dh->pub_key == NULL) {
1200 +               if ((dh->pub_key=BN_new()) == NULL)
1201 +                       goto sw_try;
1202 +       }
1203 +
1204 +       g_len = BN_num_bytes(dh->p);
1205 +       /**
1206 +        * Get generator into a plain buffer. If length is less than
1207 +        * q_len then add leading padding bytes.
1208 +        */
1209 +       if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
1210 +               DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
1211 +               goto sw_try;
1212 +       }
1213 +
1214 +       memset(&kop, 0, sizeof kop);
1215 +       kop.crk_op = CRK_DH_GENERATE_KEY;
1216 +       if (bn2crparam(dh->p, &kop.crk_param[0]))
1217 +               goto sw_try;
1218 +       if (bn2crparam(dh->q, &kop.crk_param[1]))
1219 +               goto sw_try;
1220 +       kop.crk_param[2].crp_p = g;
1221 +       kop.crk_param[2].crp_nbits = g_len * 8;
1222 +       kop.crk_iparams = 3;
1223 +
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))
1227 +           goto sw_try;
1228 +
1229 +       return ret;
1230 +sw_try:
1231 +       {
1232 +               const DH_METHOD *meth = DH_OpenSSL();
1233 +               ret = (meth->generate_key)(dh);
1234 +       }
1235 +       return ret;
1236  }
1237  
1238  static int
1239 @@ -1503,43 +2310,234 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1240  {
1241         struct crypt_kop kop;
1242         int dhret = 1;
1243 -       int fd, keylen;
1244 +       int fd, p_len;
1245 +       BIGNUM *temp = NULL;
1246 +       unsigned char *padded_pub_key = NULL, *p = NULL;
1247 +
1248 +       if ((fd = get_asym_dev_crypto()) < 0)
1249 +               goto sw_try;
1250 +
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]))
1257 +               goto sw_try;
1258 +
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;
1267 +       dhret = p_len;
1268 +
1269 +       if (ioctl(fd, CIOCKEY, &kop))
1270 +               goto sw_try;
1271  
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);
1276 +                       goto sw_try;
1277 +               }
1278 +               if (dhret > BN_num_bytes(temp))
1279 +                       dhret=BN_bn2bin(temp,key);
1280 +               BN_free(temp);
1281 +       }
1282 +
1283 +       kop.crk_param[3].crp_p = NULL;
1284 +       zapparams(&kop);
1285 +       return (dhret);
1286 +sw_try:
1287 +       {
1288                 const DH_METHOD *meth = DH_OpenSSL();
1289  
1290 -               return ((meth->compute_key)(key, pub_key, dh));
1291 +               dhret = (meth->compute_key)(key, pub_key, dh);
1292         }
1293 +       return (dhret);
1294 +}
1295  
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))
1300 +{
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;
1306 +       BN_CTX *ctx;
1307 +       EC_POINT *tmp=NULL;
1308 +       BIGNUM *x=NULL, *y=NULL;
1309 +       const BIGNUM *priv_key;
1310 +       const EC_GROUP* group = NULL;
1311 +       int ret = -1;
1312 +       size_t buflen, len;
1313 +       struct crypt_kop kop;
1314  
1315         memset(&kop, 0, sizeof kop);
1316 -       kop.crk_op = CRK_DH_COMPUTE_KEY;
1317  
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);
1329 +
1330 +       if (!x || !y || !p || !a || !b || !w_x || !w_y) {
1331 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
1332                 goto err;
1333 -       if (bn2crparam(pub_key, &kop.crk_param[1]))
1334 +       }
1335 +
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);
1339                 goto err;
1340 -       if (bn2crparam(dh->p, &kop.crk_param[2]))
1341 +       }
1342 +
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);
1346                 goto err;
1347 -       kop.crk_iparams = 3;
1348 +       }
1349  
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;
1356  
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);
1362 +                       goto err;
1363 +               }
1364  
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);
1369 +                       goto err;
1370 +               }
1371 +
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);
1375 +                       goto err;
1376 +               }
1377 +       } else {
1378 +               ec_crv = EC_BINARY;
1379 +
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);
1383 +                       goto err;
1384 +               }
1385 +
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);
1389 +                       goto err;
1390 +               }
1391 +
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);
1396 +                       goto err;
1397 +               }
1398 +       }
1399 +
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);
1403 +               goto err;
1404 +       }
1405 +
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);
1409 +               goto err;
1410         }
1411 +
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);
1415 +       if (!w_xy) {
1416 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1417 +               goto err;
1418 +       }
1419 +
1420 +       /* Generation of ECC curve parameters */
1421 +       ab_len = 2*q_len;
1422 +       ab = eng_copy_curve_points (a, b, ab_len, q_len);
1423 +       if (!ab) {
1424 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1425 +               goto err;
1426 +       }
1427 +
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))
1431 +               {
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);
1436 +                       else
1437 +                               goto err;
1438 +               }
1439 +               kop.curve_type = ECC_BINARY;
1440 +       } else
1441 +               kop.curve_type = ECC_PRIME;
1442 +
1443 +       priv_key_len = r_len;
1444 +
1445 +       /*
1446 +        * If BN_num_bytes of priv_key returns less then r_len then
1447 +        * add padding bytes before the key
1448 +        */
1449 +       if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
1450 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1451 +               goto err;
1452 +       }
1453 +
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);
1458 +               goto err;
1459 +       }
1460 +
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;
1474 +       ret = q_len;
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);
1478 +       } else
1479 +               ret = q_len;
1480  err:
1481 -       kop.crk_param[3].crp_p = NULL;
1482 +       kop.crk_param[4].crp_p = NULL;
1483         zapparams(&kop);
1484 -       return (dhret);
1485 +       return ret;
1486  }
1487  
1488 +
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 = {
1493         NULL    /* app_data */
1494  };
1495  
1496 +static ECDH_METHOD cryptodev_ecdh = {
1497 +       "cryptodev ECDH method",
1498 +       NULL,   /* cryptodev_ecdh_compute_key */
1499 +       NULL,
1500 +       0,              /* flags */
1501 +       NULL    /* app_data */
1502 +};
1503 +
1504  /*
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;
1514 -               }
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;
1519         }
1520  
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;
1527 +               }
1528 +               if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) {
1529 +                       cryptodev_dh.generate_key =
1530 +                               cryptodev_dh_keygen;
1531 +               }
1532 +       }
1533  
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;
1547 +               }
1548 +               if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
1549 +                       cryptodev_ecdsa.ecdsa_do_verify =
1550 +                               cryptodev_ecdsa_verify;
1551 +               }
1552 +       }
1553 +
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;
1559                 }
1560         }
1561  
1562 -- 
1563 2.3.5
1564