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