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