]> code.ossystems Code Review - meta-freescale.git/blob
b7702d1008178907dc1f7bcd12a5c5e640605d10
[meta-freescale.git] /
1 From a933e6341fd8989bdd82f8a5446b6f04aa00eef9 Mon Sep 17 00:00:00 2001
2 From: Yashpal Dutta <yashpal.dutta@freescale.com>
3 Date: Tue, 11 Mar 2014 07:14:30 +0545
4 Subject: [PATCH 10/17] Asynchronous interface added for PKC cryptodev
5  interface
6
7 Upstream-status: Pending
8
9 Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
10 ---
11  crypto/crypto.h               |   16 +
12  crypto/dh/dh.h                |    4 +-
13  crypto/dsa/dsa.h              |    5 +
14  crypto/ecdh/ech_locl.h        |    3 +
15  crypto/ecdsa/ecs_locl.h       |    5 +
16  crypto/engine/eng_cryptodev.c | 1578 +++++++++++++++++++++++++++++++++++++----
17  crypto/engine/eng_int.h       |   24 +-
18  crypto/engine/eng_lib.c       |   46 ++
19  crypto/engine/engine.h        |   24 +
20  crypto/rsa/rsa.h              |   23 +
21  10 files changed, 1582 insertions(+), 146 deletions(-)
22
23 diff --git a/crypto/crypto.h b/crypto/crypto.h
24 index f92fc51..ce12731 100644
25 --- a/crypto/crypto.h
26 +++ b/crypto/crypto.h
27 @@ -605,6 +605,22 @@ void ERR_load_CRYPTO_strings(void);
28  #define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED                101
29  #define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK             100
30  
31 +/* Additions for Asynchronous PKC Infrastructure */
32 +struct pkc_cookie_s {
33 +       void *cookie; /* To be filled by openssl library primitive method function caller */
34 +       void *eng_cookie; /* To be filled by Engine */
35 +        /*
36 +          * Callback handler to be provided by caller. Ensure to pass a
37 +          * handler which takes the crypto operation to completion.
38 +          * cookie: Container cookie from library
39 +          * status: Status of the crypto Job completion.
40 +          *            0: Job handled without any issue
41 +          *            -EINVAL: Parameters Invalid
42 +          */
43 +       void (*pkc_callback)(struct pkc_cookie_s *cookie, int status);
44 +       void *eng_handle;
45 +};
46 +
47  #ifdef  __cplusplus
48  }
49  #endif
50 diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
51 index ea59e61..20ffad2 100644
52 --- a/crypto/dh/dh.h
53 +++ b/crypto/dh/dh.h
54 @@ -118,7 +118,9 @@ struct dh_method
55         int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a,
56                                 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
57                                 BN_MONT_CTX *m_ctx); /* Can be null */
58 -
59 +       int (*compute_key_async)(unsigned char *key,const BIGNUM *pub_key,DH *dh,
60 +                               struct pkc_cookie_s *cookie);
61 +       int (*generate_key_async)(DH *dh, struct pkc_cookie_s *cookie);
62         int (*init)(DH *dh);
63         int (*finish)(DH *dh);
64         int flags;
65 diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h
66 index a6f6d0b..b04a029 100644
67 --- a/crypto/dsa/dsa.h
68 +++ b/crypto/dsa/dsa.h
69 @@ -140,6 +140,10 @@ struct dsa_method
70         int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
71                                 const BIGNUM *m, BN_CTX *ctx,
72                                 BN_MONT_CTX *m_ctx); /* Can be null */
73 +       int (*dsa_do_sign_async)(const unsigned char *dgst, int dlen, DSA *dsa,
74 +                               DSA_SIG *sig, struct pkc_cookie_s *cookie);
75 +       int (*dsa_do_verify_async)(const unsigned char *dgst, int dgst_len,
76 +                            DSA_SIG *sig, DSA *dsa, struct pkc_cookie_s *cookie);
77         int (*init)(DSA *dsa);
78         int (*finish)(DSA *dsa);
79         int flags;
80 @@ -151,6 +155,7 @@ struct dsa_method
81                         BN_GENCB *cb);
82         /* If this is non-NULL, it is used to generate DSA keys */
83         int (*dsa_keygen)(DSA *dsa);
84 +       int (*dsa_keygen_async)(DSA *dsa, struct pkc_cookie_s *cookie);
85         };
86  
87  struct dsa_st
88 diff --git a/crypto/ecdh/ech_locl.h b/crypto/ecdh/ech_locl.h
89 index f6cad6a..adce6b3 100644
90 --- a/crypto/ecdh/ech_locl.h
91 +++ b/crypto/ecdh/ech_locl.h
92 @@ -67,6 +67,9 @@ struct ecdh_method
93         const char *name;
94         int (*compute_key)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
95                            void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
96 +       int (*compute_key_async)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
97 +                          void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen),
98 +                          struct pkc_cookie_s *cookie);
99  #if 0
100         int (*init)(EC_KEY *eckey);
101         int (*finish)(EC_KEY *eckey);
102 diff --git a/crypto/ecdsa/ecs_locl.h b/crypto/ecdsa/ecs_locl.h
103 index cb3be13..eb0ebe0 100644
104 --- a/crypto/ecdsa/ecs_locl.h
105 +++ b/crypto/ecdsa/ecs_locl.h
106 @@ -74,6 +74,11 @@ struct ecdsa_method
107                         BIGNUM **r);
108         int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len, 
109                         const ECDSA_SIG *sig, EC_KEY *eckey);
110 +        int (*ecdsa_do_sign_async)(const unsigned char *dgst, int dgst_len,
111 +                       const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey,
112 +                       ECDSA_SIG *sig, struct pkc_cookie_s *cookie);
113 +       int (*ecdsa_do_verify_async)(const unsigned char *dgst, int dgst_len,
114 +                       const ECDSA_SIG *sig, EC_KEY *eckey, struct pkc_cookie_s *cookie);
115  #if 0
116         int (*init)(EC_KEY *eckey);
117         int (*finish)(EC_KEY *eckey);
118 diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
119 index 7ee314b..9f2416e 100644
120 --- a/crypto/engine/eng_cryptodev.c
121 +++ b/crypto/engine/eng_cryptodev.c
122 @@ -1281,6 +1281,56 @@ zapparams(struct crypt_kop *kop)
123         }
124  }
125  
126 +/* Any PKC request has at max 2 output parameters and they are stored here to
127 +be used while copying in the check availability */
128 +struct cryptodev_cookie_s {
129 +       BIGNUM *r;
130 +       struct crparam r_param;
131 +       BIGNUM *s;
132 +       struct crparam s_param;
133 +       struct crypt_kop *kop;
134 +};
135 +
136 +static int
137 +cryptodev_asym_async(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
138 +                                       BIGNUM *s)
139 +{
140 +       int fd;
141 +       struct pkc_cookie_s *cookie = kop->cookie;
142 +       struct cryptodev_cookie_s *eng_cookie;
143 +
144 +       fd = *(int *)cookie->eng_handle;
145 +
146 +       eng_cookie = malloc(sizeof(struct cryptodev_cookie_s));
147 +
148 +       if (eng_cookie) {
149 +               memset(eng_cookie, 0, sizeof(struct cryptodev_cookie_s));
150 +               if (r) {
151 +                       kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
152 +                       if (!kop->crk_param[kop->crk_iparams].crp_p)
153 +                               return -ENOMEM;
154 +                       kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
155 +                       kop->crk_oparams++;
156 +                       eng_cookie->r = r;
157 +                       eng_cookie->r_param = kop->crk_param[kop->crk_iparams];
158 +               }
159 +               if (s) {
160 +                       kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
161 +                       if (!kop->crk_param[kop->crk_iparams+1].crp_p)
162 +                               return -ENOMEM;
163 +                       kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
164 +                       kop->crk_oparams++;
165 +                       eng_cookie->s = s;
166 +                       eng_cookie->s_param = kop->crk_param[kop->crk_iparams + 1];
167 +               }
168 +       } else
169 +               return -ENOMEM;
170 +
171 +       eng_cookie->kop = kop;
172 +       cookie->eng_cookie = eng_cookie;
173 +       return ioctl(fd, CIOCASYMASYNCRYPT, kop);
174 +}
175 +
176  static int
177  cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
178  {
179 @@ -1337,6 +1387,44 @@ void *cryptodev_init_instance(void)
180         return fd;
181  }
182  
183 +#include <poll.h>
184 +
185 +/* Return 0 on success and 1 on failure */
186 +int cryptodev_check_availability(void *eng_handle)
187 +{
188 +       int fd = *(int *)eng_handle;
189 +       struct pkc_cookie_list_s cookie_list;
190 +       struct pkc_cookie_s *cookie;
191 +       int i;
192 +
193 +       /* FETCH COOKIE returns number of cookies extracted */
194 +       if (ioctl(fd, CIOCASYMFETCHCOOKIE, &cookie_list) <= 0)
195 +               return 1;
196 +
197 +       for (i = 0; i < cookie_list.cookie_available; i++) {
198 +               cookie = cookie_list.cookie[i];
199 +               if (cookie) {
200 +                       struct cryptodev_cookie_s *eng_cookie = cookie->eng_cookie;
201 +                       if (eng_cookie) {
202 +                               struct crypt_kop *kop = eng_cookie->kop;
203 +
204 +                               if (eng_cookie->r)
205 +                                       crparam2bn(&eng_cookie->r_param, eng_cookie->r);
206 +                               if (eng_cookie->s)
207 +                                       crparam2bn(&eng_cookie->s_param, eng_cookie->s);
208 +                               if (kop->crk_op == CRK_DH_COMPUTE_KEY)
209 +                                       kop->crk_oparams = 0;
210 +
211 +                               zapparams(eng_cookie->kop);
212 +                               free(eng_cookie->kop);
213 +                               free (eng_cookie);
214 +                       }
215 +                       cookie->pkc_callback(cookie, cookie_list.status[i]);
216 +               }
217 +       }
218 +       return 0;
219 +}
220 +
221  static int
222  cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
223      const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
224 @@ -1382,6 +1470,63 @@ err:
225  }
226  
227  static int
228 +cryptodev_bn_mod_exp_async(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
229 +    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont, struct pkc_cookie_s *cookie)
230 +{
231 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
232 +       int ret = 1;
233 +
234 +       /* Currently, we know we can do mod exp iff we can do any
235 +        * asymmetric operations at all.
236 +        */
237 +       if (cryptodev_asymfeat == 0 || !kop) {
238 +               ret = BN_mod_exp(r, a, p, m, ctx);
239 +               return (ret);
240 +       }
241 +
242 +       kop->crk_oparams = 0;
243 +       kop->crk_status = 0;
244 +       kop->crk_op = CRK_MOD_EXP;
245 +       kop->cookie = cookie;
246 +       /* inputs: a^p % m */
247 +       if (bn2crparam(a, &kop->crk_param[0]))
248 +               goto err;
249 +       if (bn2crparam(p, &kop->crk_param[1]))
250 +               goto err;
251 +       if (bn2crparam(m, &kop->crk_param[2]))
252 +               goto err;
253 +
254 +       kop->crk_iparams = 3;
255 +       if (cryptodev_asym_async(kop, BN_num_bytes(m), r, 0, NULL))
256 +               goto err;
257 +
258 +       return ret;
259 +err:
260 +       {
261 +               const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
262 +
263 +               if (kop)
264 +                       free(kop);
265 +               ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
266 +               if (ret)
267 +                       /* Call the completion handler immediately */
268 +                       cookie->pkc_callback(cookie, 0);
269 +       }
270 +       return ret;
271 +}
272 +
273 +static int
274 +cryptodev_rsa_nocrt_mod_exp_async(BIGNUM *r0, const BIGNUM *I,
275 +               RSA *rsa, BN_CTX *ctx, struct pkc_cookie_s *cookie)
276 +{
277 +       int r;
278 +       ctx = BN_CTX_new();
279 +       r = cryptodev_bn_mod_exp_async(r0, I, rsa->d, rsa->n, ctx, NULL, cookie);
280 +       BN_CTX_free(ctx);
281 +       return r;
282 +}
283 +
284 +static int
285  cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
286  {
287         int r;
288 @@ -1446,6 +1591,62 @@ err:
289         return (ret);
290  }
291  
292 +static int
293 +cryptodev_rsa_mod_exp_async(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx,
294 +                               struct pkc_cookie_s *cookie)
295 +{
296 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
297 +       int ret = 1, f_len, p_len, q_len;
298 +       unsigned char *f = NULL, *p = NULL, *q = NULL, *dp = NULL, *dq = NULL, *c = NULL;
299 +
300 +       if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp || !kop) {
301 +               return (0);
302 +       }
303 +
304 +       kop->crk_oparams = 0;
305 +       kop->crk_status = 0;
306 +       kop->crk_op = CRK_MOD_EXP_CRT;
307 +       f_len = BN_num_bytes(rsa->n);
308 +       spcf_bn2bin_ex(I, &f, &f_len);
309 +       spcf_bn2bin(rsa->p, &p, &p_len);
310 +       spcf_bn2bin(rsa->q, &q, &q_len);
311 +       spcf_bn2bin_ex(rsa->dmp1, &dp, &p_len);
312 +       spcf_bn2bin_ex(rsa->iqmp, &c, &p_len);
313 +       spcf_bn2bin_ex(rsa->dmq1, &dq, &q_len);
314 +       /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
315 +       kop->crk_param[0].crp_p = p;
316 +       kop->crk_param[0].crp_nbits = p_len * 8;
317 +       kop->crk_param[1].crp_p = q;
318 +       kop->crk_param[1].crp_nbits = q_len * 8;
319 +       kop->crk_param[2].crp_p = f;
320 +       kop->crk_param[2].crp_nbits = f_len * 8;
321 +       kop->crk_param[3].crp_p = dp;
322 +       kop->crk_param[3].crp_nbits = p_len * 8;
323 +       /* dq must of length q, rest all of length p*/
324 +       kop->crk_param[4].crp_p = dq;
325 +       kop->crk_param[4].crp_nbits = q_len * 8;
326 +       kop->crk_param[5].crp_p = c;
327 +       kop->crk_param[5].crp_nbits = p_len * 8;
328 +       kop->crk_iparams = 6;
329 +       kop->cookie = cookie;
330 +       if (cryptodev_asym_async(kop, BN_num_bytes(rsa->n), r0, 0, NULL))
331 +               goto err;
332 +
333 +       return ret;
334 +err:
335 +       {
336 +               const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
337 +
338 +               if (kop)
339 +                       free(kop);
340 +               ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
341 +               if (ret)
342 +                       /* Call user completion handler immediately */
343 +                       cookie->pkc_callback(cookie, 0);
344 +       }
345 +       return (ret);
346 +}
347 +
348  static RSA_METHOD cryptodev_rsa = {
349         "cryptodev RSA method",
350         NULL,                           /* rsa_pub_enc */
351 @@ -1454,6 +1655,12 @@ static RSA_METHOD cryptodev_rsa = {
352         NULL,                           /* rsa_priv_dec */
353         NULL,
354         NULL,
355 +       NULL,                           /* rsa_pub_enc */
356 +       NULL,                           /* rsa_pub_dec */
357 +       NULL,                           /* rsa_priv_enc */
358 +       NULL,                           /* rsa_priv_dec */
359 +       NULL,
360 +       NULL,
361         NULL,                           /* init */
362         NULL,                           /* finish */
363         0,                              /* flags */
364 @@ -1751,126 +1958,424 @@ sw_try:
365         return ret;
366  }
367  
368 +/* Cryptodev DSA Key Gen routine */
369 +static int cryptodev_dsa_keygen_async(DSA *dsa,  struct pkc_cookie_s *cookie)
370 +{
371 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
372 +       int ret = 1, g_len;
373 +       unsigned char *g = NULL;
374  
375 +       if (!kop)
376 +               goto sw_try;
377  
378 -static DSA_METHOD cryptodev_dsa = {
379 -       "cryptodev DSA method",
380 -       NULL,
381 -       NULL,                           /* dsa_sign_setup */
382 -       NULL,
383 -       NULL,                           /* dsa_mod_exp */
384 -       NULL,
385 -       NULL,                           /* init */
386 -       NULL,                           /* finish */
387 -       0,      /* flags */
388 -       NULL    /* app_data */
389 -};
390 +       if (dsa->priv_key == NULL)      {
391 +               if ((dsa->priv_key=BN_new()) == NULL)
392 +                       goto sw_try;
393 +       }
394  
395 -static ECDSA_METHOD cryptodev_ecdsa = {
396 -       "cryptodev ECDSA method",
397 -       NULL,
398 -       NULL,                           /* ecdsa_sign_setup */
399 -       NULL,
400 -       NULL,
401 -       0,      /* flags */
402 -       NULL    /* app_data */
403 -};
404 +       if (dsa->pub_key == NULL) {
405 +               if ((dsa->pub_key=BN_new()) == NULL)
406 +                       goto sw_try;
407 +       }
408  
409 -typedef enum ec_curve_s
410 -{
411 -       EC_PRIME,
412 -       EC_BINARY
413 -} ec_curve_t;
414 +       g_len = BN_num_bytes(dsa->p);
415 +       /**
416 +        * Get generator into a plain buffer. If length is less than
417 +        * q_len then add leading padding bytes.
418 +        */
419 +       if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
420 +               DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
421 +               goto sw_try;
422 +       }
423  
424 -/* ENGINE handler for ECDSA Sign */
425 -static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char  *dgst,
426 -       int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
427 -{
428 -       BIGNUM  *m = NULL, *p = NULL, *a = NULL;
429 -       BIGNUM  *b = NULL, *x = NULL, *y = NULL;
430 -       BN_CTX  *ctx = NULL;
431 -       ECDSA_SIG *ret = NULL;
432 -       ECDSA_DATA *ecdsa = NULL;
433 -       unsigned char  * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
434 -       unsigned char  * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
435 -       int     i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
436 -       int     g_len = 0, d_len = 0, ab_len = 0;
437 -       const BIGNUM   *order = NULL, *priv_key=NULL;
438 -       const EC_GROUP *group = NULL;
439 -       struct crypt_kop kop;
440 -       ec_curve_t ec_crv = EC_PRIME;
441 +       memset(kop, 0, sizeof(struct crypt_kop));
442 +       kop->crk_op = CRK_DSA_GENERATE_KEY;
443 +       if (bn2crparam(dsa->p, &kop->crk_param[0]))
444 +               goto sw_try;
445 +       if (bn2crparam(dsa->q, &kop->crk_param[1]))
446 +               goto sw_try;
447 +       kop->crk_param[2].crp_p = g;
448 +       kop->crk_param[2].crp_nbits = g_len * 8;
449 +       kop->crk_iparams = 3;
450 +       kop->cookie = cookie;
451  
452 -       memset(&kop, 0, sizeof(kop));
453 -       ecdsa = ecdsa_check(eckey);
454 -       if (!ecdsa) {
455 -               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
456 -               return NULL;
457 +       /* pub_key is or prime length while priv key is of length of order */
458 +       if (cryptodev_asym_async(kop, BN_num_bytes(dsa->p), dsa->pub_key,
459 +           BN_num_bytes(dsa->q), dsa->priv_key))
460 +           goto sw_try;
461 +
462 +       return ret;
463 +sw_try:
464 +       {
465 +               const DSA_METHOD *meth = DSA_OpenSSL();
466 +
467 +               if (kop)
468 +                       free(kop);
469 +               ret = (meth->dsa_keygen)(dsa);
470 +               cookie->pkc_callback(cookie, 0);
471         }
472 +       return ret;
473 +}
474  
475 -       group = EC_KEY_get0_group(eckey);
476 -       priv_key = EC_KEY_get0_private_key(eckey);
477 +static int
478 +cryptodev_dsa_do_sign_async(const unsigned char *dgst, int dlen, DSA *dsa,
479 +                       DSA_SIG *sig, struct pkc_cookie_s *cookie)
480 +{
481 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
482 +       DSA_SIG *dsaret = NULL;
483 +       int q_len = 0, r_len = 0, g_len = 0;
484 +       int priv_key_len = 0, ret = 1;
485 +       unsigned char *q = NULL, *r = NULL, *g = NULL, *priv_key = NULL, *f = NULL;
486  
487 -       if (!group || !priv_key) {
488 -               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
489 -               return NULL;
490 +       if (((sig->r = BN_new()) == NULL) || !kop) {
491 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
492 +               goto err;
493         }
494  
495 -       if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
496 -               (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
497 -               (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
498 -               (y = BN_new()) == NULL) {
499 -               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
500 +       if ((sig->s = BN_new()) == NULL) {
501 +               BN_free(sig->r);
502 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
503                 goto err;
504         }
505  
506 -       order = &group->order;
507 -       if (!order || BN_is_zero(order)) {
508 -               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
509 +       if (spcf_bn2bin(dsa->p, &q, &q_len)) {
510 +               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
511                 goto err;
512         }
513  
514 -       i = BN_num_bits(order);
515 -       /* Need to truncate digest if it is too long: first truncate whole
516 -        bytes */
517 -       if (8 * dgst_len > i)
518 -               dgst_len = (i + 7)/8;
519 +       /* Get order of the field of private keys into plain buffer */
520 +       if (spcf_bn2bin (dsa->q, &r, &r_len)) {
521 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
522 +               goto err;
523 +       }
524  
525 -       if (!BN_bin2bn(dgst, dgst_len, m)) {
526 -               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
527 +       /* sanity test */
528 +       if (dlen > r_len) {
529 +               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
530                 goto err;
531         }
532  
533 -       /* If still too long truncate remaining bits with a shift */
534 -       if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
535 -               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
536 +       g_len = q_len;
537 +       /**
538 +        * Get generator into a plain buffer. If length is less than
539 +        * q_len then add leading padding bytes.
540 +        */
541 +       if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
542 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
543                 goto err;
544         }
545  
546 -       /* copy the truncated bits into plain buffer */
547 -       if (spcf_bn2bin(m, &tmp_dgst, &dgst_len))  {
548 -               fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__);
549 +       priv_key_len = r_len;
550 +       /**
551 +        * Get private key into a plain buffer. If length is less than
552 +        * r_len then add leading padding bytes.
553 +        */
554 +        if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
555 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
556                 goto err;
557         }
558  
559 -       ret = ECDSA_SIG_new();
560 -       if  (!ret) {
561 -               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
562 +       /* Allocate memory to store hash. */
563 +       f = OPENSSL_malloc (r_len);
564 +       if (!f) {
565 +               DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
566                 goto err;
567         }
568  
569 -       /* check if this is prime or binary EC request */
570 -       if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
571 -               ec_crv = EC_PRIME;
572 -               /* get the generator point pair */
573 -               if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group),
574 -                       x, y,ctx)) {
575 -                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
576 -                       goto err;
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 -               /* get the ECC curve parameters */
583 -               if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) {
584 -                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
585 +       /* Skip leading bytes if dgst_len < r_len */
586 +       memcpy(f + r_len - dlen, dgst, dlen);
587 +
588 +       dlen = r_len;
589 +
590 +       memset(kop, 0, sizeof( struct crypt_kop));
591 +       kop->crk_op = CRK_DSA_SIGN;
592 +
593 +       /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
594 +       kop->crk_param[0].crp_p = (void*)f;
595 +       kop->crk_param[0].crp_nbits = dlen * 8;
596 +       kop->crk_param[1].crp_p = (void*)q;
597 +       kop->crk_param[1].crp_nbits = q_len * 8;
598 +       kop->crk_param[2].crp_p = (void*)r;
599 +       kop->crk_param[2].crp_nbits = r_len * 8;
600 +       kop->crk_param[3].crp_p = (void*)g;
601 +       kop->crk_param[3].crp_nbits = g_len * 8;
602 +       kop->crk_param[4].crp_p = (void*)priv_key;
603 +       kop->crk_param[4].crp_nbits = priv_key_len * 8;
604 +       kop->crk_iparams = 5;
605 +       kop->cookie = cookie;
606 +
607 +       if (cryptodev_asym_async(kop, r_len, sig->r, r_len, sig->s))
608 +           goto err;
609 +
610 +       return ret;
611 +err:
612 +       {
613 +               const DSA_METHOD *meth = DSA_OpenSSL();
614 +
615 +               if (kop)
616 +                       free(kop);
617 +               BN_free(sig->r);
618 +               BN_free(sig->s);
619 +               dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
620 +               sig->r = dsaret->r;
621 +               sig->s = dsaret->s;
622 +               /* Call user callback immediately */
623 +               cookie->pkc_callback(cookie, 0);
624 +               ret = dsaret;
625 +       }
626 +       return ret;
627 +}
628 +
629 +static int
630 +cryptodev_dsa_verify_async(const unsigned char *dgst, int dlen,
631 +    DSA_SIG *sig, DSA *dsa, struct pkc_cookie_s *cookie)
632 +{
633 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
634 +       int q_len = 0, r_len = 0, g_len = 0;
635 +       int w_len = 0 ,c_len = 0, d_len = 0, ret = 1;
636 +       unsigned char   * q = NULL, * r = NULL, * w = NULL, * g = NULL;
637 +       unsigned char   *c = NULL, * d = NULL, *f = NULL;
638 +
639 +       if (!kop)
640 +               goto err;
641 +
642 +       if (spcf_bn2bin(dsa->p, &q, &q_len)) {
643 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
644 +               return ret;
645 +       }
646 +
647 +       /* Get Order of field of private keys */
648 +       if (spcf_bn2bin(dsa->q, &r, &r_len)) {
649 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
650 +               goto err;
651 +       }
652 +
653 +       g_len = q_len;
654 +       /**
655 +        * Get generator into a plain buffer. If length is less than
656 +        * q_len then add leading padding bytes.
657 +        */
658 +       if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
659 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
660 +               goto err;
661 +       }
662 +       w_len = q_len;
663 +       /**
664 +        * Get public key into a plain buffer. If length is less than
665 +        * q_len then add leading padding bytes.
666 +        */
667 +       if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
668 +               DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
669 +               goto err;
670 +       }
671 +       /**
672 +        * Get the 1st part of signature into a flat buffer with
673 +        * appropriate padding
674 +        */
675 +       c_len = r_len;
676 +
677 +       if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
678 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
679 +               goto err;
680 +       }
681 +
682 +       /**
683 +        * Get the 2nd part of signature into a flat buffer with
684 +        * appropriate padding
685 +        */
686 +       d_len = r_len;
687 +
688 +       if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
689 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
690 +               goto err;
691 +       }
692 +
693 +
694 +       /* Sanity test */
695 +       if (dlen > r_len) {
696 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
697 +               goto err;
698 +       }
699 +
700 +       /* Allocate memory to store hash. */
701 +       f = OPENSSL_malloc (r_len);
702 +       if (!f) {
703 +               DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
704 +               goto err;
705 +       }
706 +
707 +       /* Add padding, since SEC expects hash to of size r_len */
708 +       if (dlen < r_len)
709 +               memset(f, 0, r_len - dlen);
710 +
711 +       /* Skip leading bytes if dgst_len < r_len */
712 +       memcpy(f + r_len - dlen, dgst, dlen);
713 +
714 +       dlen = r_len;
715 +       memset(kop, 0, sizeof(struct crypt_kop));
716 +
717 +       /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
718 +       kop->crk_param[0].crp_p = (void*)f;
719 +       kop->crk_param[0].crp_nbits = dlen * 8;
720 +       kop->crk_param[1].crp_p = q;
721 +       kop->crk_param[1].crp_nbits = q_len * 8;
722 +       kop->crk_param[2].crp_p = r;
723 +       kop->crk_param[2].crp_nbits = r_len * 8;
724 +       kop->crk_param[3].crp_p = g;
725 +       kop->crk_param[3].crp_nbits = g_len * 8;
726 +       kop->crk_param[4].crp_p = w;
727 +       kop->crk_param[4].crp_nbits = w_len * 8;
728 +       kop->crk_param[5].crp_p = c;
729 +       kop->crk_param[5].crp_nbits = c_len * 8;
730 +       kop->crk_param[6].crp_p = d;
731 +       kop->crk_param[6].crp_nbits = d_len * 8;
732 +       kop->crk_iparams = 7;
733 +       kop->crk_op = CRK_DSA_VERIFY;
734 +       kop->cookie = cookie;
735 +       if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
736 +               goto err;
737 +
738 +       return ret;
739 +err:
740 +       {
741 +               const DSA_METHOD *meth = DSA_OpenSSL();
742 +
743 +               if (kop)
744 +                       free(kop);
745 +
746 +               ret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
747 +               cookie->pkc_callback(cookie, 0);
748 +       }
749 +       return ret;
750 +}
751 +
752 +static DSA_METHOD cryptodev_dsa = {
753 +       "cryptodev DSA method",
754 +       NULL,
755 +       NULL,                           /* dsa_sign_setup */
756 +       NULL,
757 +       NULL,                           /* dsa_mod_exp */
758 +       NULL,
759 +       NULL,
760 +       NULL,
761 +       NULL,
762 +       NULL,                           /* init */
763 +       NULL,                           /* finish */
764 +       0,      /* flags */
765 +       NULL    /* app_data */
766 +};
767 +
768 +static ECDSA_METHOD cryptodev_ecdsa = {
769 +       "cryptodev ECDSA method",
770 +       NULL,
771 +       NULL,                           /* ecdsa_sign_setup */
772 +       NULL,
773 +       NULL,
774 +       NULL,
775 +       NULL,
776 +       0,      /* flags */
777 +       NULL    /* app_data */
778 +};
779 +
780 +typedef enum ec_curve_s
781 +{
782 +       EC_PRIME,
783 +       EC_BINARY
784 +} ec_curve_t;
785 +
786 +/* ENGINE handler for ECDSA Sign */
787 +static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char  *dgst,
788 +       int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
789 +{
790 +       BIGNUM  *m = NULL, *p = NULL, *a = NULL;
791 +       BIGNUM  *b = NULL, *x = NULL, *y = NULL;
792 +       BN_CTX  *ctx = NULL;
793 +       ECDSA_SIG *ret = NULL;
794 +       ECDSA_DATA *ecdsa = NULL;
795 +       unsigned char  * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
796 +       unsigned char  * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
797 +       int     i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
798 +       int     g_len = 0, d_len = 0, ab_len = 0;
799 +       const BIGNUM   *order = NULL, *priv_key=NULL;
800 +       const EC_GROUP *group = NULL;
801 +       struct crypt_kop kop;
802 +       ec_curve_t ec_crv = EC_PRIME;
803 +
804 +       memset(&kop, 0, sizeof(kop));
805 +       ecdsa = ecdsa_check(eckey);
806 +       if (!ecdsa) {
807 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
808 +               return NULL;
809 +       }
810 +
811 +       group = EC_KEY_get0_group(eckey);
812 +       priv_key = EC_KEY_get0_private_key(eckey);
813 +
814 +       if (!group || !priv_key) {
815 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
816 +               return NULL;
817 +       }
818 +
819 +       if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
820 +               (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
821 +               (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
822 +               (y = BN_new()) == NULL) {
823 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
824 +               goto err;
825 +       }
826 +
827 +       order = &group->order;
828 +       if (!order || BN_is_zero(order)) {
829 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
830 +               goto err;
831 +       }
832 +
833 +       i = BN_num_bits(order);
834 +       /* Need to truncate digest if it is too long: first truncate whole
835 +        bytes */
836 +       if (8 * dgst_len > i)
837 +               dgst_len = (i + 7)/8;
838 +
839 +       if (!BN_bin2bn(dgst, dgst_len, m)) {
840 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
841 +               goto err;
842 +       }
843 +
844 +       /* If still too long truncate remaining bits with a shift */
845 +       if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
846 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
847 +               goto err;
848 +       }
849 +
850 +       /* copy the truncated bits into plain buffer */
851 +       if (spcf_bn2bin(m, &tmp_dgst, &dgst_len))  {
852 +               fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__);
853 +               goto err;
854 +       }
855 +
856 +       ret = ECDSA_SIG_new();
857 +       if  (!ret) {
858 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
859 +               goto err;
860 +       }
861 +
862 +       /* check if this is prime or binary EC request */
863 +       if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
864 +               ec_crv = EC_PRIME;
865 +               /* get the generator point pair */
866 +               if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group),
867 +                       x, y,ctx)) {
868 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
869 +                       goto err;
870 +               }
871 +
872 +               /* get the ECC curve parameters */
873 +               if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) {
874 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
875                         goto err;
876                 }
877         } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) {
878 @@ -2195,63 +2700,581 @@ static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len,
879         }
880  
881         /**
882 -        * Get the 2nd part of signature into a flat buffer with
883 -        * appropriate padding
884 +        * Get the 2nd part of signature into a flat buffer with
885 +        * appropriate padding
886 +        */
887 +       if (BN_num_bytes(sig->s) < r_len)
888 +               d_len = r_len;
889 +
890 +       if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
891 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
892 +               goto err;
893 +       }
894 +
895 +       /* memory for message representative */
896 +       f = malloc(r_len);
897 +       if (!f) {
898 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
899 +               goto err;
900 +       }
901 +
902 +       /* Add padding, since SEC expects hash to of size r_len */
903 +       memset(f, 0, r_len-dgst_len);
904 +
905 +       /* Skip leading bytes if dgst_len < r_len */
906 +       memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len);
907 +       dgst_len += r_len-dgst_len;
908 +       kop.crk_op = CRK_DSA_VERIFY;
909 +       /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
910 +       kop.crk_param[0].crp_p = f;
911 +       kop.crk_param[0].crp_nbits = dgst_len * 8;
912 +       kop.crk_param[1].crp_p = q;
913 +       kop.crk_param[1].crp_nbits = q_len * 8;
914 +       kop.crk_param[2].crp_p = r;
915 +       kop.crk_param[2].crp_nbits = r_len * 8;
916 +       kop.crk_param[3].crp_p = g_xy;
917 +       kop.crk_param[3].crp_nbits = g_len * 8;
918 +       kop.crk_param[4].crp_p = w_xy;
919 +       kop.crk_param[4].crp_nbits = pub_key_len * 8;
920 +       kop.crk_param[5].crp_p = ab;
921 +       kop.crk_param[5].crp_nbits = ab_len * 8;
922 +       kop.crk_param[6].crp_p = c;
923 +       kop.crk_param[6].crp_nbits = d_len * 8;
924 +       kop.crk_param[7].crp_p = d;
925 +       kop.crk_param[7].crp_nbits = d_len * 8;
926 +       kop.crk_iparams = 8;
927 +
928 +       if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
929 +               /*OCF success value is 0, if not zero, change ret to fail*/
930 +               if(0 == kop.crk_status)
931 +                       ret  = 1;
932 +       } else {
933 +               const ECDSA_METHOD *meth = ECDSA_OpenSSL();
934 +
935 +               ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
936 +       }
937 +       kop.crk_param[0].crp_p = NULL;
938 +       zapparams(&kop);
939 +
940 +err:
941 +       return ret;
942 +}
943 +
944 +static int cryptodev_ecdsa_do_sign_async( const unsigned char  *dgst,
945 +       int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey,
946 +       ECDSA_SIG *sig, struct pkc_cookie_s *cookie)
947 +{
948 +       BIGNUM  *m = NULL, *p = NULL, *a = NULL;
949 +       BIGNUM  *b = NULL, *x = NULL, *y = NULL;
950 +       BN_CTX  *ctx = NULL;
951 +       ECDSA_SIG *sig_ret = NULL;
952 +       ECDSA_DATA *ecdsa = NULL;
953 +       unsigned char  * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
954 +       unsigned char  * s = NULL, *f = NULL, *tmp_dgst = NULL;
955 +       int     i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
956 +       int     g_len = 0, ab_len = 0, ret = 1;
957 +       const BIGNUM   *order = NULL, *priv_key=NULL;
958 +       const EC_GROUP *group = NULL;
959 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
960 +       ec_curve_t ec_crv = EC_PRIME;
961 +
962 +       if (!(sig->r = BN_new()) || !kop)
963 +               goto err;
964 +       if ((sig->s = BN_new()) == NULL) {
965 +               BN_free(r);
966 +               goto err;
967 +       }
968 +
969 +       memset(kop, 0, sizeof(struct crypt_kop));
970 +       ecdsa = ecdsa_check(eckey);
971 +       if (!ecdsa) {
972 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
973 +               goto err;
974 +       }
975 +
976 +       group = EC_KEY_get0_group(eckey);
977 +       priv_key = EC_KEY_get0_private_key(eckey);
978 +
979 +       if (!group || !priv_key) {
980 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
981 +               goto err;
982 +       }
983 +
984 +       if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
985 +               (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
986 +               (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
987 +               (y = BN_new()) == NULL) {
988 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
989 +               goto err;
990 +       }
991 +
992 +       order = &group->order;
993 +       if (!order || BN_is_zero(order)) {
994 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
995 +               goto err;
996 +       }
997 +
998 +       i = BN_num_bits(order);
999 +       /* Need to truncate digest if it is too long: first truncate whole
1000 +        bytes */
1001 +       if (8 * dgst_len > i)
1002 +               dgst_len = (i + 7)/8;
1003 +
1004 +       if (!BN_bin2bn(dgst, dgst_len, m)) {
1005 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
1006 +               goto err;
1007 +       }
1008 +
1009 +       /* If still too long truncate remaining bits with a shift */
1010 +       if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
1011 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
1012 +               goto err;
1013 +       }
1014 +
1015 +       /* copy the truncated bits into plain buffer */
1016 +       if (spcf_bn2bin(m, &tmp_dgst, &dgst_len))  {
1017 +               fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__);
1018 +               goto err;
1019 +       }
1020 +
1021 +       /* check if this is prime or binary EC request */
1022 +       if (EC_METHOD_get_field_type(EC_GROUP_method_of(group))
1023 +                               == NID_X9_62_prime_field) {
1024 +               ec_crv = EC_PRIME;
1025 +               /* get the generator point pair */
1026 +               if (!EC_POINT_get_affine_coordinates_GFp (group,
1027 +                       EC_GROUP_get0_generator(group), x, y,ctx)) {
1028 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1029 +                       goto err;
1030 +               }
1031 +
1032 +               /* get the ECC curve parameters */
1033 +               if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) {
1034 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1035 +                       goto err;
1036 +               }
1037 +       } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) {
1038 +               ec_crv = EC_BINARY;
1039 +               /* get the ECC curve parameters */
1040 +               if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
1041 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1042 +                       goto err;
1043 +               }
1044 +
1045 +               /* get the generator point pair */
1046 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
1047 +                       EC_GROUP_get0_generator(group), x, y,ctx)) {
1048 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1049 +                       goto err;
1050 +               }
1051 +       } else {
1052 +               printf("Unsupported Curve\n");
1053 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1054 +               goto err;
1055 +       }
1056 +
1057 +       if (spcf_bn2bin(order, &r, &r_len)) {
1058 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1059 +               goto err;
1060 +       }
1061 +
1062 +       if (spcf_bn2bin(p, &q, &q_len)) {
1063 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1064 +               goto err;
1065 +       }
1066 +
1067 +       priv_key_len = r_len;
1068 +
1069 +       /**
1070 +        * If BN_num_bytes of priv_key returns less then r_len then
1071 +        * add padding bytes before the key
1072 +        */
1073 +       if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len))  {
1074 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1075 +               goto err;
1076 +       }
1077 +
1078 +       /* Generation of ECC curve parameters */
1079 +       ab_len = 2*q_len;
1080 +       ab = eng_copy_curve_points(a, b, ab_len, q_len);
1081 +       if (!ab) {
1082 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1083 +               goto err;
1084 +       }
1085 +
1086 +       if (ec_crv == EC_BINARY) {
1087 +               if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
1088 +               {
1089 +                       unsigned char *c_temp = NULL;
1090 +                       int c_temp_len = q_len;
1091 +                       if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1092 +                               memcpy(ab+q_len, c_temp, q_len);
1093 +                       else
1094 +                               goto err;
1095 +               }
1096 +               kop->curve_type = ECC_BINARY;
1097 +       }
1098 +
1099 +       /* Calculation of Generator point */
1100 +       g_len = 2*q_len;
1101 +       g_xy = eng_copy_curve_points(x, y, g_len, q_len);
1102 +       if (!g_xy) {
1103 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1104 +               goto err;
1105 +       }
1106 +
1107 +       /* memory for message representative */
1108 +       f = malloc(r_len);
1109 +       if (!f) {
1110 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1111 +               goto err;
1112 +       }
1113 +
1114 +       /* Add padding, since SEC expects hash to of size r_len */
1115 +       memset(f, 0, r_len - dgst_len);
1116 +
1117 +       /* Skip leading bytes if dgst_len < r_len */
1118 +       memcpy(f +  r_len - dgst_len, tmp_dgst, dgst_len);
1119 +
1120 +       dgst_len +=  r_len - dgst_len;
1121 +
1122 +       kop->crk_op = CRK_DSA_SIGN;
1123 +       /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1124 +       kop->crk_param[0].crp_p = f;
1125 +       kop->crk_param[0].crp_nbits = dgst_len * 8;
1126 +       kop->crk_param[1].crp_p = q;
1127 +       kop->crk_param[1].crp_nbits = q_len * 8;
1128 +       kop->crk_param[2].crp_p = r;
1129 +       kop->crk_param[2].crp_nbits = r_len * 8;
1130 +       kop->crk_param[3].crp_p = g_xy;
1131 +       kop->crk_param[3].crp_nbits = g_len * 8;
1132 +       kop->crk_param[4].crp_p = s;
1133 +       kop->crk_param[4].crp_nbits = priv_key_len * 8;
1134 +       kop->crk_param[5].crp_p = ab;
1135 +       kop->crk_param[5].crp_nbits = ab_len * 8;
1136 +       kop->crk_iparams = 6;
1137 +       kop->cookie = cookie;
1138 +
1139 +       if (cryptodev_asym_async(kop, r_len, sig->r , r_len, sig->s))
1140 +               goto err;
1141 +
1142 +       return ret;
1143 +err:
1144 +       {
1145 +               const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1146 +               BN_free(sig->r);
1147 +               BN_free(sig->s);
1148 +               if (kop)
1149 +                       free(kop);
1150 +               sig_ret = (meth->ecdsa_do_sign)(dgst, dgst_len, in_kinv, in_r, eckey);
1151 +               sig->r = sig_ret->r;
1152 +               sig->s = sig_ret->s;
1153 +               cookie->pkc_callback(cookie, 0);
1154 +       }
1155 +       return ret;
1156 +}
1157 +
1158 +static int cryptodev_ecdsa_verify_async(const unsigned char *dgst, int dgst_len,
1159 +               const ECDSA_SIG *sig, EC_KEY *eckey, struct pkc_cookie_s *cookie)
1160 +{
1161 +       BIGNUM  *m = NULL, *p = NULL, *a = NULL, *b = NULL;
1162 +       BIGNUM  *x = NULL, *y = NULL, *w_x = NULL, *w_y = NULL;
1163 +       BN_CTX  *ctx = NULL;
1164 +       ECDSA_DATA      *ecdsa = NULL;
1165 +       unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL, *w_xy = NULL;
1166 +       unsigned char *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
1167 +       int     i = 0, q_len = 0, pub_key_len = 0, r_len = 0, c_len = 0, g_len = 0;
1168 +       int     d_len = 0, ab_len = 0, ret = 1;
1169 +       const EC_POINT *pub_key = NULL;
1170 +       const BIGNUM   *order = NULL;
1171 +       const EC_GROUP *group=NULL;
1172 +       ec_curve_t       ec_crv = EC_PRIME;
1173 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1174 +
1175 +       if (!kop)
1176 +               goto err;
1177 +
1178 +       memset(kop, 0, sizeof(struct crypt_kop));
1179 +       ecdsa = ecdsa_check(eckey);
1180 +       if (!ecdsa) {
1181 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
1182 +               goto err;
1183 +       }
1184 +
1185 +       group    = EC_KEY_get0_group(eckey);
1186 +       pub_key  = EC_KEY_get0_public_key(eckey);
1187 +
1188 +       if (!group || !pub_key) {
1189 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
1190 +               goto err;
1191 +       }
1192 +
1193 +       if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
1194 +               (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
1195 +               (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
1196 +               (y = BN_new()) == NULL || (w_x = BN_new()) == NULL ||
1197 +               (w_y = BN_new()) == NULL) {
1198 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1199 +               goto err;
1200 +       }
1201 +
1202 +       order = &group->order;
1203 +       if (!order || BN_is_zero(order)) {
1204 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
1205 +               goto err;
1206 +       }
1207 +
1208 +       i = BN_num_bits(order);
1209 +       /* Need to truncate digest if it is too long: first truncate whole
1210 +       * bytes */
1211 +       if (8 * dgst_len > i)
1212 +               dgst_len = (i + 7)/8;
1213 +
1214 +       if (!BN_bin2bn(dgst, dgst_len, m)) {
1215 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1216 +               goto err;
1217 +       }
1218 +
1219 +       /* If still too long truncate remaining bits with a shift */
1220 +       if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
1221 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1222 +               goto err;
1223 +       }
1224 +       /* copy the truncated bits into plain buffer */
1225 +       if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
1226 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1227 +               goto err;
1228 +       }
1229 +
1230 +       /* check if this is prime or binary EC request */
1231 +       if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
1232 +               ec_crv = EC_PRIME;
1233 +
1234 +               /* get the generator point pair */
1235 +               if (!EC_POINT_get_affine_coordinates_GFp (group,
1236 +                       EC_GROUP_get0_generator(group), x, y,ctx)) {
1237 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1238 +                       goto err;
1239 +               }
1240 +
1241 +               /* get the public key pair for prime curve */
1242 +               if (!EC_POINT_get_affine_coordinates_GFp (group,
1243 +                       pub_key, w_x, w_y,ctx)) {
1244 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1245 +                       goto err;
1246 +               }
1247 +
1248 +               /* get the ECC curve parameters */
1249 +               if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
1250 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1251 +                       goto err;
1252 +               }
1253 +       } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field){
1254 +               ec_crv = EC_BINARY;
1255 +               /* get the ECC curve parameters */
1256 +               if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
1257 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1258 +                       goto err;
1259 +               }
1260 +
1261 +               /* get the generator point pair */
1262 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
1263 +                       EC_GROUP_get0_generator(group),x, y,ctx)) {
1264 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1265 +                       goto err;
1266 +               }
1267 +
1268 +               /* get the public key pair for binary curve */
1269 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
1270 +                       pub_key, w_x, w_y,ctx)) {
1271 +                       ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1272 +                       goto err;
1273 +               }
1274 +       }else {
1275 +               printf("Unsupported Curve\n");
1276 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1277 +               goto err;
1278 +       }
1279 +
1280 +       /* Get the order of the subgroup of private keys */
1281 +       if (spcf_bn2bin((BIGNUM*)order, &r, &r_len)) {
1282 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1283 +               goto err;
1284 +       }
1285 +
1286 +       /* Get the irreducible polynomial that creates the field */
1287 +       if (spcf_bn2bin(p, &q, &q_len)) {
1288 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1289 +               goto err;
1290 +       }
1291 +
1292 +       /* Get the public key into a flat buffer with appropriate padding */
1293 +       pub_key_len = 2 * q_len;
1294 +
1295 +       w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
1296 +       if (!w_xy) {
1297 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1298 +               goto err;
1299 +       }
1300 +
1301 +       /* Generation of ECC curve parameters */
1302 +       ab_len = 2*q_len;
1303 +
1304 +       ab = eng_copy_curve_points (a, b, ab_len, q_len);
1305 +       if (!ab) {
1306 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1307 +               goto err;
1308 +       }
1309 +
1310 +       if (ec_crv == EC_BINARY) {
1311 +               /* copy b' i.e c(b), instead of only b */
1312 +               eng_ec_get_cparam (EC_GROUP_get_curve_name(group),
1313 +                       ab+q_len, q_len);
1314 +               kop->curve_type = ECC_BINARY;
1315 +       }
1316 +
1317 +       /* Calculation of Generator point */
1318 +       g_len = 2 * q_len;
1319 +
1320 +       g_xy = eng_copy_curve_points (x, y, g_len, q_len);
1321 +       if (!g_xy) {
1322 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1323 +               goto err;
1324 +       }
1325 +
1326 +       /**
1327 +        * Get the 1st part of signature into a flat buffer with
1328 +        * appropriate padding
1329 +        */
1330 +       if (BN_num_bytes(sig->r) < r_len)
1331 +               c_len = r_len;
1332 +
1333 +       if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
1334 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1335 +               goto err;
1336 +       }
1337 +
1338 +       /**
1339 +        * Get the 2nd part of signature into a flat buffer with
1340 +        * appropriate padding
1341 +        */
1342 +       if (BN_num_bytes(sig->s) < r_len)
1343 +               d_len = r_len;
1344 +
1345 +       if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1346 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1347 +               goto err;
1348 +       }
1349 +
1350 +       /* memory for message representative */
1351 +       f = malloc(r_len);
1352 +       if (!f) {
1353 +               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1354 +               goto err;
1355 +       }
1356 +
1357 +       /* Add padding, since SEC expects hash to of size r_len */
1358 +       memset(f, 0, r_len-dgst_len);
1359 +
1360 +       /* Skip leading bytes if dgst_len < r_len */
1361 +       memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len);
1362 +
1363 +       dgst_len += r_len-dgst_len;
1364 +
1365 +       kop->crk_op = CRK_DSA_VERIFY;
1366 +       /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1367 +       kop->crk_param[0].crp_p = f;
1368 +       kop->crk_param[0].crp_nbits = dgst_len * 8;
1369 +       kop->crk_param[1].crp_p = q;
1370 +       kop->crk_param[1].crp_nbits = q_len * 8;
1371 +       kop->crk_param[2].crp_p = r;
1372 +       kop->crk_param[2].crp_nbits = r_len * 8;
1373 +       kop->crk_param[3].crp_p = g_xy;
1374 +       kop->crk_param[3].crp_nbits = g_len * 8;
1375 +       kop->crk_param[4].crp_p = w_xy;
1376 +       kop->crk_param[4].crp_nbits = pub_key_len * 8;
1377 +       kop->crk_param[5].crp_p = ab;
1378 +       kop->crk_param[5].crp_nbits = ab_len * 8;
1379 +       kop->crk_param[6].crp_p = c;
1380 +       kop->crk_param[6].crp_nbits = d_len * 8;
1381 +       kop->crk_param[7].crp_p = d;
1382 +       kop->crk_param[7].crp_nbits = d_len * 8;
1383 +       kop->crk_iparams = 8;
1384 +       kop->cookie = cookie;
1385 +
1386 +       if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
1387 +               goto err;
1388 +
1389 +       return ret;
1390 +err:
1391 +       {
1392 +               const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1393 +
1394 +               if (kop)
1395 +                       free(kop);
1396 +               ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
1397 +               cookie->pkc_callback(cookie, 0);
1398 +       }
1399 +
1400 +       return ret;
1401 +}
1402 +
1403 +/* Cryptodev DH Key Gen routine */
1404 +static int cryptodev_dh_keygen_async(DH *dh,  struct pkc_cookie_s *cookie)
1405 +{
1406 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1407 +       int ret = 1, g_len;
1408 +       unsigned char *g = NULL;
1409 +
1410 +       if (!kop)
1411 +               goto sw_try;
1412 +
1413 +       if (dh->priv_key == NULL)       {
1414 +               if ((dh->priv_key=BN_new()) == NULL)
1415 +                       goto sw_try;
1416 +       }
1417 +
1418 +       if (dh->pub_key == NULL) {
1419 +               if ((dh->pub_key=BN_new()) == NULL)
1420 +                       goto sw_try;
1421 +       }
1422 +
1423 +       g_len = BN_num_bytes(dh->p);
1424 +       /**
1425 +        * Get generator into a plain buffer. If length is less than
1426 +        * q_len then add leading padding bytes.
1427          */
1428 -       if (BN_num_bytes(sig->s) < r_len)
1429 -               d_len = r_len;
1430 -
1431 -       if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1432 -               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1433 -               goto err;
1434 -       }
1435 -
1436 -       /* memory for message representative */
1437 -       f = malloc(r_len);
1438 -       if (!f) {
1439 -               ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1440 -               goto err;
1441 +       if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
1442 +               DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
1443 +               goto sw_try;
1444         }
1445  
1446 -       /* Add padding, since SEC expects hash to of size r_len */
1447 -       memset(f, 0, r_len-dgst_len);
1448 +       memset(kop, 0, sizeof(struct crypt_kop));
1449 +       kop->crk_op = CRK_DH_GENERATE_KEY;
1450 +       if (bn2crparam(dh->p, &kop->crk_param[0]))
1451 +               goto sw_try;
1452 +       if (bn2crparam(dh->q, &kop->crk_param[1]))
1453 +               goto sw_try;
1454 +       kop->crk_param[2].crp_p = g;
1455 +       kop->crk_param[2].crp_nbits = g_len * 8;
1456 +       kop->crk_iparams = 3;
1457 +       kop->cookie = cookie;
1458  
1459 -       /* Skip leading bytes if dgst_len < r_len */
1460 -       memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len);
1461 -       dgst_len += r_len-dgst_len;
1462 -       kop.crk_op = CRK_DSA_VERIFY;
1463 -       /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1464 -       kop.crk_param[0].crp_p = f;
1465 -       kop.crk_param[0].crp_nbits = dgst_len * 8;
1466 -       kop.crk_param[1].crp_p = q;
1467 -       kop.crk_param[1].crp_nbits = q_len * 8;
1468 -       kop.crk_param[2].crp_p = r;
1469 -       kop.crk_param[2].crp_nbits = r_len * 8;
1470 -       kop.crk_param[3].crp_p = g_xy;
1471 -       kop.crk_param[3].crp_nbits = g_len * 8;
1472 -       kop.crk_param[4].crp_p = w_xy;
1473 -       kop.crk_param[4].crp_nbits = pub_key_len * 8;
1474 -       kop.crk_param[5].crp_p = ab;
1475 -       kop.crk_param[5].crp_nbits = ab_len * 8;
1476 -       kop.crk_param[6].crp_p = c;
1477 -       kop.crk_param[6].crp_nbits = d_len * 8;
1478 -       kop.crk_param[7].crp_p = d;
1479 -       kop.crk_param[7].crp_nbits = d_len * 8;
1480 -       kop.crk_iparams = 8;
1481 +       /* pub_key is or prime length while priv key is of length of order */
1482 +       if (cryptodev_asym_async(kop, BN_num_bytes(dh->p), dh->pub_key,
1483 +           BN_num_bytes(dh->q), dh->priv_key))
1484 +           goto sw_try;
1485  
1486 -       if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1487 -               /*OCF success value is 0, if not zero, change ret to fail*/
1488 -               if(0 == kop.crk_status)
1489 -                       ret  = 1;
1490 -       } else {
1491 -               const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1492 +       return ret;
1493 +sw_try:
1494 +       {
1495 +               const DH_METHOD *meth = DH_OpenSSL();
1496  
1497 -               ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
1498 +               if (kop)
1499 +                       free(kop);
1500 +               ret = (meth->generate_key)(dh);
1501 +               cookie->pkc_callback(cookie, 0);
1502         }
1503 -       kop.crk_param[0].crp_p = NULL;
1504 -       zapparams(&kop);
1505 -
1506 -err:
1507         return ret;
1508  }
1509  
1510 @@ -2360,6 +3383,54 @@ sw_try:
1511         return (dhret);
1512  }
1513  
1514 +/* Return Length if successful and 0 on failure */
1515 +static int
1516 +cryptodev_dh_compute_key_async(unsigned char *key, const BIGNUM *pub_key,
1517 +               DH *dh, struct pkc_cookie_s *cookie)
1518 +{
1519 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1520 +       int ret = 1;
1521 +       int fd, p_len;
1522 +       unsigned char *padded_pub_key = NULL, *p = NULL;
1523 +
1524 +       fd = *(int *)cookie->eng_handle;
1525 +
1526 +       memset(kop, 0, sizeof(struct crypt_kop));
1527 +       kop->crk_op = CRK_DH_COMPUTE_KEY;
1528 +       /* inputs: dh->priv_key pub_key dh->p key */
1529 +       spcf_bn2bin(dh->p, &p, &p_len);
1530 +       spcf_bn2bin_ex(pub_key, &padded_pub_key, &p_len);
1531 +
1532 +       if (bn2crparam(dh->priv_key, &kop->crk_param[0]))
1533 +               goto err;
1534 +       kop->crk_param[1].crp_p = padded_pub_key;
1535 +       kop->crk_param[1].crp_nbits = p_len * 8;
1536 +       kop->crk_param[2].crp_p = p;
1537 +       kop->crk_param[2].crp_nbits = p_len * 8;
1538 +       kop->crk_iparams = 3;
1539 +
1540 +       kop->cookie = cookie;
1541 +       kop->crk_param[3].crp_p = (void*) key;
1542 +       kop->crk_param[3].crp_nbits = p_len * 8;
1543 +       kop->crk_oparams = 1;
1544 +
1545 +       if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
1546 +               goto err;
1547 +
1548 +       return p_len;
1549 +err:
1550 +       {
1551 +               const DH_METHOD *meth = DH_OpenSSL();
1552 +
1553 +               if (kop)
1554 +                       free(kop);
1555 +               ret = (meth->compute_key)(key, pub_key, dh);
1556 +               /* Call user cookie handler */
1557 +               cookie->pkc_callback(cookie, 0);
1558 +       }
1559 +       return (ret);
1560 +}
1561 +
1562  int cryptodev_ecdh_compute_key(void *out, size_t outlen,
1563         const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen,
1564         void *out, size_t *outlen))
1565 @@ -2537,6 +3608,190 @@ err:
1566         return ret;
1567  }
1568  
1569 +int cryptodev_ecdh_compute_key_async(void *out, size_t outlen,
1570 +       const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen,
1571 +       void *out, size_t *outlen), struct pkc_cookie_s *cookie)
1572 +{
1573 +       ec_curve_t       ec_crv = EC_PRIME;
1574 +       unsigned char * q = NULL, *w_xy = NULL, *ab = NULL, *s = NULL, *r = NULL;
1575 +       BIGNUM         * w_x = NULL, *w_y = NULL;
1576 +       int q_len = 0, ab_len = 0, pub_key_len = 0, r_len = 0, priv_key_len = 0;
1577 +       BIGNUM * p = NULL, *a = NULL, *b = NULL;
1578 +       BN_CTX *ctx;
1579 +       EC_POINT *tmp=NULL;
1580 +       BIGNUM *x=NULL, *y=NULL;
1581 +       const BIGNUM *priv_key;
1582 +       const EC_GROUP* group = NULL;
1583 +       int ret = 1;
1584 +       size_t buflen, len;
1585 +       struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1586 +
1587 +       if (!(ctx = BN_CTX_new()) || !kop)
1588 +                goto err;
1589 +
1590 +       memset(kop, 0, sizeof(struct crypt_kop));
1591 +
1592 +       BN_CTX_start(ctx);
1593 +       x = BN_CTX_get(ctx);
1594 +       y = BN_CTX_get(ctx);
1595 +       p = BN_CTX_get(ctx);
1596 +       a = BN_CTX_get(ctx);
1597 +       b = BN_CTX_get(ctx);
1598 +       w_x = BN_CTX_get(ctx);
1599 +       w_y = BN_CTX_get(ctx);
1600 +
1601 +       if (!x || !y || !p || !a || !b || !w_x || !w_y) {
1602 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
1603 +               goto err;
1604 +       }
1605 +
1606 +       priv_key = EC_KEY_get0_private_key(ecdh);
1607 +       if (priv_key == NULL) {
1608 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
1609 +               goto err;
1610 +       }
1611 +
1612 +       group = EC_KEY_get0_group(ecdh);
1613 +       if ((tmp=EC_POINT_new(group)) == NULL) {
1614 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
1615 +               goto err;
1616 +       }
1617 +
1618 +       if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1619 +               NID_X9_62_prime_field) {
1620 +               ec_crv = EC_PRIME;
1621 +
1622 +               if (!EC_POINT_get_affine_coordinates_GFp(group,
1623 +                       EC_GROUP_get0_generator(group), x, y, ctx)) {
1624 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
1625 +                       goto err;
1626 +               }
1627 +
1628 +               /* get the ECC curve parameters */
1629 +               if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
1630 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1631 +                       goto err;
1632 +               }
1633 +
1634 +               /* get the public key pair for prime curve */
1635 +               if (!EC_POINT_get_affine_coordinates_GFp (group, pub_key, w_x, w_y,ctx)) {
1636 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1637 +                       goto err;
1638 +               }
1639 +       } else {
1640 +               ec_crv = EC_BINARY;
1641 +
1642 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
1643 +                       EC_GROUP_get0_generator(group), x, y, ctx)) {
1644 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
1645 +                       goto err;
1646 +               }
1647 +
1648 +               /* get the ECC curve parameters */
1649 +               if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
1650 +                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1651 +                       goto err;
1652 +               }
1653 +
1654 +               /* get the public key pair for binary curve */
1655 +               if (!EC_POINT_get_affine_coordinates_GF2m(group,
1656 +                       pub_key, w_x, w_y,ctx)) {
1657 +                       ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1658 +                       goto err;
1659 +               }
1660 +       }
1661 +
1662 +       /* irreducible polynomial that creates the field */
1663 +       if (spcf_bn2bin((BIGNUM*)&group->order, &r, &r_len)) {
1664 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1665 +               goto err;
1666 +       }
1667 +
1668 +       /* Get the irreducible polynomial that creates the field */
1669 +       if (spcf_bn2bin(p, &q, &q_len)) {
1670 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1671 +               goto err;
1672 +       }
1673 +
1674 +       /* Get the public key into a flat buffer with appropriate padding */
1675 +       pub_key_len = 2 * q_len;
1676 +       w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
1677 +       if (!w_xy) {
1678 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1679 +               goto err;
1680 +       }
1681 +
1682 +       /* Generation of ECC curve parameters */
1683 +       ab_len = 2*q_len;
1684 +       ab = eng_copy_curve_points (a, b, ab_len, q_len);
1685 +       if (!ab) {
1686 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1687 +               goto err;
1688 +       }
1689 +
1690 +       if (ec_crv == EC_BINARY) {
1691 +               /* copy b' i.e c(b), instead of only b */
1692 +               if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
1693 +               {
1694 +                       unsigned char *c_temp = NULL;
1695 +                       int c_temp_len = q_len;
1696 +                       if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1697 +                               memcpy(ab+q_len, c_temp, q_len);
1698 +                       else
1699 +                               goto err;
1700 +               }
1701 +               kop->curve_type = ECC_BINARY;
1702 +       } else
1703 +               kop->curve_type = ECC_PRIME;
1704 +
1705 +       priv_key_len = r_len;
1706 +
1707 +       /*
1708 +        * If BN_num_bytes of priv_key returns less then r_len then
1709 +        * add padding bytes before the key
1710 +        */
1711 +       if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
1712 +               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1713 +               goto err;
1714 +       }
1715 +
1716 +       buflen = (EC_GROUP_get_degree(group) + 7)/8;
1717 +       len = BN_num_bytes(x);
1718 +       if (len > buflen || q_len < buflen) {
1719 +               ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
1720 +               goto err;
1721 +       }
1722 +
1723 +       kop->crk_op = CRK_DH_COMPUTE_KEY;
1724 +       kop->crk_param[0].crp_p = (void *) s;
1725 +       kop->crk_param[0].crp_nbits = priv_key_len*8;
1726 +       kop->crk_param[1].crp_p = (void *) w_xy;
1727 +       kop->crk_param[1].crp_nbits = pub_key_len*8;
1728 +       kop->crk_param[2].crp_p = (void *) q;
1729 +       kop->crk_param[2].crp_nbits = q_len*8;
1730 +       kop->crk_param[3].crp_p = (void *) ab;
1731 +       kop->crk_param[3].crp_nbits = ab_len*8;
1732 +       kop->crk_iparams = 4;
1733 +       kop->crk_param[4].crp_p = (void *) out;
1734 +       kop->crk_param[4].crp_nbits = q_len*8;
1735 +       kop->crk_oparams = 1;
1736 +       kop->cookie = cookie;
1737 +       if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
1738 +               goto err;
1739 +
1740 +       return q_len;
1741 +err:
1742 +       {
1743 +               const ECDH_METHOD *meth = ECDH_OpenSSL();
1744 +
1745 +               if (kop)
1746 +                       free(kop);
1747 +               ret = (meth->compute_key)(out, outlen, pub_key, ecdh, KDF);
1748 +               /* Call user cookie handler */
1749 +               cookie->pkc_callback(cookie, 0);
1750 +       }
1751 +       return ret;
1752 +}
1753  
1754  static DH_METHOD cryptodev_dh = {
1755         "cryptodev DH method",
1756 @@ -2545,6 +3800,8 @@ static DH_METHOD cryptodev_dh = {
1757         NULL,
1758         NULL,
1759         NULL,
1760 +       NULL,
1761 +       NULL,
1762         0,      /* flags */
1763         NULL    /* app_data */
1764  };
1765 @@ -2553,6 +3810,7 @@ static ECDH_METHOD cryptodev_ecdh = {
1766         "cryptodev ECDH method",
1767         NULL,   /* cryptodev_ecdh_compute_key */
1768         NULL,
1769 +       NULL,
1770         0,              /* flags */
1771         NULL    /* app_data */
1772  };
1773 @@ -2625,12 +3883,19 @@ ENGINE_load_cryptodev(void)
1774                 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
1775                 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1776                         cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
1777 -                       if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
1778 +                       cryptodev_rsa.bn_mod_exp_async =
1779 +                                cryptodev_bn_mod_exp_async;
1780 +                       if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) {
1781                                 cryptodev_rsa.rsa_mod_exp =
1782                                     cryptodev_rsa_mod_exp;
1783 -                       else
1784 +                               cryptodev_rsa.rsa_mod_exp_async =
1785 +                                   cryptodev_rsa_mod_exp_async;
1786 +                       } else {
1787                                 cryptodev_rsa.rsa_mod_exp =
1788                                     cryptodev_rsa_nocrt_mod_exp;
1789 +                               cryptodev_rsa.rsa_mod_exp_async =
1790 +                                   cryptodev_rsa_nocrt_mod_exp_async;
1791 +                       }
1792                 }
1793         }
1794  
1795 @@ -2638,12 +3903,21 @@ ENGINE_load_cryptodev(void)
1796                 const DSA_METHOD *meth = DSA_OpenSSL();
1797  
1798                 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1799 -               if (cryptodev_asymfeat & CRF_DSA_SIGN)
1800 +               if (cryptodev_asymfeat & CRF_DSA_SIGN) {
1801                         cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1802 -               if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1803 +                       cryptodev_dsa.dsa_do_sign_async =
1804 +                                cryptodev_dsa_do_sign_async;
1805 +               }
1806 +               if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
1807                         cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1808 -               if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY)
1809 +                       cryptodev_dsa.dsa_do_verify_async =
1810 +                                cryptodev_dsa_verify_async;
1811 +               }
1812 +               if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY) {
1813                         cryptodev_dsa.dsa_keygen = cryptodev_dsa_keygen;
1814 +                       cryptodev_dsa.dsa_keygen_async =
1815 +                                cryptodev_dsa_keygen_async;
1816 +               }
1817         }
1818  
1819         if (ENGINE_set_DH(engine, &cryptodev_dh)){
1820 @@ -2652,10 +3926,15 @@ ENGINE_load_cryptodev(void)
1821                 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1822                         cryptodev_dh.compute_key =
1823                                 cryptodev_dh_compute_key;
1824 +                       cryptodev_dh.compute_key_async =
1825 +                               cryptodev_dh_compute_key_async;
1826                 }
1827                 if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) {
1828                         cryptodev_dh.generate_key =
1829                                 cryptodev_dh_keygen;
1830 +                       cryptodev_dh.generate_key_async =
1831 +                               cryptodev_dh_keygen_async;
1832 +
1833                 }
1834         }
1835  
1836 @@ -2664,10 +3943,14 @@ ENGINE_load_cryptodev(void)
1837                 memcpy(&cryptodev_ecdsa, meth, sizeof(ECDSA_METHOD));
1838                 if (cryptodev_asymfeat & CRF_DSA_SIGN) {
1839                         cryptodev_ecdsa.ecdsa_do_sign = cryptodev_ecdsa_do_sign;
1840 +                       cryptodev_ecdsa.ecdsa_do_sign_async =
1841 +                               cryptodev_ecdsa_do_sign_async;
1842                 }
1843                 if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
1844                         cryptodev_ecdsa.ecdsa_do_verify =
1845                                 cryptodev_ecdsa_verify;
1846 +                       cryptodev_ecdsa.ecdsa_do_verify_async =
1847 +                               cryptodev_ecdsa_verify_async;
1848                 }
1849         }
1850  
1851 @@ -2676,9 +3959,16 @@ ENGINE_load_cryptodev(void)
1852                 memcpy(&cryptodev_ecdh, ecdh_meth, sizeof(ECDH_METHOD));
1853                 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1854                         cryptodev_ecdh.compute_key = cryptodev_ecdh_compute_key;
1855 +                       cryptodev_ecdh.compute_key_async =
1856 +                                cryptodev_ecdh_compute_key_async;
1857                 }
1858         }
1859  
1860 +       ENGINE_set_check_pkc_availability(engine, cryptodev_check_availability);
1861 +       ENGINE_set_close_instance(engine, cryptodev_close_instance);
1862 +       ENGINE_set_init_instance(engine, cryptodev_init_instance);
1863 +       ENGINE_set_async_map(engine, ENGINE_ALLPKC_ASYNC);
1864 +
1865         ENGINE_add(engine);
1866         ENGINE_free(engine);
1867         ERR_clear_error();
1868 diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h
1869 index 451ef8f..8fc3077 100644
1870 --- a/crypto/engine/eng_int.h
1871 +++ b/crypto/engine/eng_int.h
1872 @@ -181,7 +181,29 @@ struct engine_st
1873         ENGINE_LOAD_KEY_PTR load_pubkey;
1874  
1875         ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
1876 -
1877 +       /*
1878 +        * Instantiate Engine handle to be passed in check_pkc_availability
1879 +        * Ensure that Engine is instantiated before any pkc asynchronous call.
1880 +        */
1881 +       void *(*engine_init_instance)(void);
1882 +       /*
1883 +        * Instantiated Engine handle will be closed with this call.
1884 +        * Ensure that no pkc asynchronous call is made after this call
1885 +        */
1886 +       void (*engine_close_instance)(void *handle);
1887 +       /*
1888 +        * Check availability will extract the data from kernel.
1889 +        * eng_handle: This is the Engine handle corresponds to which
1890 +        * the cookies needs to be polled.
1891 +        * return 0 if cookie available else 1
1892 +        */
1893 +       int (*check_pkc_availability)(void *eng_handle);
1894 +       /*
1895 +        * The following map is used to check if the engine supports asynchronous implementation
1896 +        * ENGINE_ASYNC_FLAG* for available bitmap. Any application checking for asynchronous
1897 +        * implementation need to check this features using "int ENGINE_get_async_map(engine *)";
1898 +        */
1899 +       int async_map;
1900         const ENGINE_CMD_DEFN *cmd_defns;
1901         int flags;
1902         /* reference count on the structure itself */
1903 diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c
1904 index 18a6664..6fa621c 100644
1905 --- a/crypto/engine/eng_lib.c
1906 +++ b/crypto/engine/eng_lib.c
1907 @@ -98,7 +98,11 @@ void engine_set_all_null(ENGINE *e)
1908         e->ctrl = NULL;
1909         e->load_privkey = NULL;
1910         e->load_pubkey = NULL;
1911 +       e->check_pkc_availability = NULL;
1912 +       e->engine_init_instance = NULL;
1913 +       e->engine_close_instance = NULL;
1914         e->cmd_defns = NULL;
1915 +       e->async_map = 0;
1916         e->flags = 0;
1917         }
1918  
1919 @@ -233,6 +237,48 @@ int ENGINE_set_id(ENGINE *e, const char *id)
1920         return 1;
1921         }
1922  
1923 +void ENGINE_set_init_instance(ENGINE *e, void *(*engine_init_instance)(void))
1924 +       {
1925 +               e->engine_init_instance = engine_init_instance;
1926 +       }
1927 +
1928 +void ENGINE_set_close_instance(ENGINE *e,
1929 +       void (*engine_close_instance)(void *))
1930 +       {
1931 +               e->engine_close_instance = engine_close_instance;
1932 +       }
1933 +
1934 +void ENGINE_set_async_map(ENGINE *e, int async_map)
1935 +       {
1936 +               e->async_map = async_map;
1937 +       }
1938 +
1939 +void *ENGINE_init_instance(ENGINE *e)
1940 +       {
1941 +               return e->engine_init_instance();
1942 +       }
1943 +
1944 +void ENGINE_close_instance(ENGINE *e, void *eng_handle)
1945 +       {
1946 +               e->engine_close_instance(eng_handle);
1947 +       }
1948 +
1949 +int ENGINE_get_async_map(ENGINE *e)
1950 +       {
1951 +               return e->async_map;
1952 +       }
1953 +
1954 +void ENGINE_set_check_pkc_availability(ENGINE *e,
1955 +       int (*check_pkc_availability)(void *eng_handle))
1956 +       {
1957 +               e->check_pkc_availability = check_pkc_availability;
1958 +       }
1959 +
1960 +int ENGINE_check_pkc_availability(ENGINE *e, void *eng_handle)
1961 +       {
1962 +               return e->check_pkc_availability(eng_handle);
1963 +       }
1964 +
1965  int ENGINE_set_name(ENGINE *e, const char *name)
1966         {
1967         if(name == NULL)
1968 diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h
1969 index 237a6c9..ccff86a 100644
1970 --- a/crypto/engine/engine.h
1971 +++ b/crypto/engine/engine.h
1972 @@ -473,6 +473,30 @@ ENGINE *ENGINE_new(void);
1973  int ENGINE_free(ENGINE *e);
1974  int ENGINE_up_ref(ENGINE *e);
1975  int ENGINE_set_id(ENGINE *e, const char *id);
1976 +void ENGINE_set_init_instance(ENGINE *e, void *(*engine_init_instance)(void));
1977 +void ENGINE_set_close_instance(ENGINE *e,
1978 +       void (*engine_free_instance)(void *));
1979 +/*
1980 + * Following FLAGS are bitmap store in async_map to set asynchronous interface capability
1981 + *of the engine
1982 + */
1983 +#define ENGINE_RSA_ASYNC 0x0001
1984 +#define ENGINE_DSA_ASYNC 0x0002
1985 +#define ENGINE_DH_ASYNC 0x0004
1986 +#define ENGINE_ECDSA_ASYNC 0x0008
1987 +#define ENGINE_ECDH_ASYNC 0x0010
1988 +#define ENGINE_ALLPKC_ASYNC 0x001F
1989 +/* Engine implementation will set the bitmap based on above flags using following API */
1990 +void ENGINE_set_async_map(ENGINE *e, int async_map);
1991 + /* Application need to check the bitmap based on above flags using following API
1992 +  * to confirm asynchronous methods supported
1993 +  */
1994 +int ENGINE_get_async_map(ENGINE *e);
1995 +void *ENGINE_init_instance(ENGINE *e);
1996 +void ENGINE_close_instance(ENGINE *e, void *eng_handle);
1997 +void ENGINE_set_check_pkc_availability(ENGINE *e,
1998 +       int (*check_pkc_availability)(void *eng_handle));
1999 +int ENGINE_check_pkc_availability(ENGINE *e, void *eng_handle);
2000  int ENGINE_set_name(ENGINE *e, const char *name);
2001  int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
2002  int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
2003 diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
2004 index 5f269e5..6ef1b15 100644
2005 --- a/crypto/rsa/rsa.h
2006 +++ b/crypto/rsa/rsa.h
2007 @@ -101,6 +101,29 @@ struct rsa_meth_st
2008         int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
2009                           const BIGNUM *m, BN_CTX *ctx,
2010                           BN_MONT_CTX *m_ctx); /* Can be null */
2011 +       /*
2012 +        * Cookie in the following _async variant must be allocated before
2013 +        * submission and can be freed once its corresponding callback
2014 +        * handler is called
2015 +        */
2016 +       int (*rsa_pub_enc_asyn)(int flen,const unsigned char *from,
2017 +                          unsigned char *to, RSA *rsa, int padding,
2018 +                          struct pkc_cookie_s *cookie);
2019 +       int (*rsa_pub_dec_async)(int flen,const unsigned char *from,
2020 +                          unsigned char *to, RSA *rsa, int padding,
2021 +                          struct pkc_cookie_s *cookie);
2022 +       int (*rsa_priv_enc_async)(int flen,const unsigned char *from,
2023 +                           unsigned char *to, RSA *rsa, int padding,
2024 +                           struct pkc_cookie_s *cookie);
2025 +       int (*rsa_priv_dec_async)(int flen,const unsigned char *from,
2026 +                           unsigned char *to, RSA *rsa, int padding,
2027 +                           struct pkc_cookie_s *cookie);
2028 +       int (*rsa_mod_exp_async)(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
2029 +                           BN_CTX *ctx, struct pkc_cookie_s *cookie);
2030 +       int (*bn_mod_exp_async)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
2031 +                         const BIGNUM *m, BN_CTX *ctx,
2032 +                         BN_MONT_CTX *m_ctx, struct pkc_cookie_s *cookie);
2033 +
2034         int (*init)(RSA *rsa);          /* called at new */
2035         int (*finish)(RSA *rsa);        /* called at free */
2036         int flags;                      /* RSA_METHOD_FLAG_* things */
2037 -- 
2038 1.8.3.1
2039