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
7 Upstream-status: Pending
9 Change-Id: Ia8974f793dc18a959ed6798dcdd7d3fad81cb7da
10 Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
12 crypto/crypto.h | 16 +
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(-)
24 diff --git a/crypto/crypto.h b/crypto/crypto.h
25 index 6c644ce..2b4ec59 100644
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
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 */
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
44 + void (*pkc_callback)(struct pkc_cookie_s *cookie, int status);
51 diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
52 index a5bd901..31dd762 100644
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,
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);
63 int (*finish) (DH *dh);
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 {
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);
80 @@ -150,6 +154,7 @@ struct dsa_method {
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);
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,
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);
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 {
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);
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)
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
130 +struct cryptodev_cookie_s {
132 + struct crparam r_param;
134 + struct crparam s_param;
135 + struct crypt_kop *kop;
139 +cryptodev_asym_async(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
143 + struct pkc_cookie_s *cookie = kop->cookie;
144 + struct cryptodev_cookie_s *eng_cookie;
146 + fd = *(int *)cookie->eng_handle;
148 + eng_cookie = malloc(sizeof(struct cryptodev_cookie_s));
151 + memset(eng_cookie, 0, sizeof(struct cryptodev_cookie_s));
153 + kop->crk_param[kop->crk_iparams].crp_p =
154 + calloc(rlen, sizeof(char));
155 + if (!kop->crk_param[kop->crk_iparams].crp_p)
157 + kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
158 + kop->crk_oparams++;
160 + eng_cookie->r_param = kop->crk_param[kop->crk_iparams];
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)
167 + kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8;
168 + kop->crk_oparams++;
170 + eng_cookie->s_param = kop->crk_param[kop->crk_iparams + 1];
175 + eng_cookie->kop = kop;
176 + cookie->eng_cookie = eng_cookie;
177 + return ioctl(fd, CIOCASYMASYNCRYPT, kop);
181 cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
183 @@ -1425,6 +1479,44 @@ void *cryptodev_init_instance(void)
189 +/* Return 0 on success and 1 on failure */
190 +int cryptodev_check_availability(void *eng_handle)
192 + int fd = *(int *)eng_handle;
193 + struct pkc_cookie_list_s cookie_list;
194 + struct pkc_cookie_s *cookie;
197 + /* FETCH COOKIE returns number of cookies extracted */
198 + if (ioctl(fd, CIOCASYMFETCHCOOKIE, &cookie_list) <= 0)
201 + for (i = 0; i < cookie_list.cookie_available; i++) {
202 + cookie = cookie_list.cookie[i];
204 + struct cryptodev_cookie_s *eng_cookie = cookie->eng_cookie;
206 + struct crypt_kop *kop = eng_cookie->kop;
209 + crparam2bn(&eng_cookie->r_param, eng_cookie->r);
211 + crparam2bn(&eng_cookie->s_param, eng_cookie->s);
212 + if (kop->crk_op == CRK_DH_COMPUTE_KEY)
213 + kop->crk_oparams = 0;
215 + zapparams(eng_cookie->kop);
216 + free(eng_cookie->kop);
219 + cookie->pkc_callback(cookie, cookie_list.status[i]);
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,
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)
236 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
240 + * Currently, we know we can do mod exp iff we can do any asymmetric
241 + * operations at all.
243 + if (cryptodev_asymfeat == 0 || !kop) {
244 + ret = BN_mod_exp(r, a, p, m, ctx);
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]))
255 + if (bn2crparam(p, &kop->crk_param[1]))
257 + if (bn2crparam(m, &kop->crk_param[2]))
260 + kop->crk_iparams = 3;
261 + if (cryptodev_asym_async(kop, BN_num_bytes(m), r, 0, NULL))
267 + const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
271 + ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
273 + /* Call the completion handler immediately */
274 + cookie->pkc_callback(cookie, 0);
280 +cryptodev_rsa_nocrt_mod_exp_async(BIGNUM *r0, const BIGNUM *I,
281 + RSA *rsa, BN_CTX *ctx,
282 + struct pkc_cookie_s *cookie)
285 + ctx = BN_CTX_new();
286 + r = cryptodev_bn_mod_exp_async(r0, I, rsa->d, rsa->n, ctx, NULL, cookie);
292 cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
295 @@ -1538,6 +1690,63 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
300 +cryptodev_rsa_mod_exp_async(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
301 + BN_CTX *ctx, struct pkc_cookie_s *cookie)
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 =
308 + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp || !kop) {
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))
344 + const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
348 + ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx);
350 + /* Call user completion handler immediately */
351 + cookie->pkc_callback(cookie, 0);
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 */
363 + NULL, /* rsa_pub_enc */
364 + NULL, /* rsa_pub_dec */
365 + NULL, /* rsa_priv_enc */
366 + NULL, /* rsa_priv_dec */
372 @@ -1846,128 +2061,428 @@ static int cryptodev_dsa_keygen(DSA *dsa)
376 -static DSA_METHOD cryptodev_dsa = {
377 - "cryptodev DSA method",
379 - NULL, /* dsa_sign_setup */
381 - NULL, /* dsa_mod_exp */
386 - NULL /* app_data */
388 +/* Cryptodev DSA Key Gen routine */
389 +static int cryptodev_dsa_keygen_async(DSA *dsa, struct pkc_cookie_s *cookie)
391 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
392 + int ret = 1, g_len;
393 + unsigned char *g = NULL;
395 -static ECDSA_METHOD cryptodev_ecdsa = {
396 - "cryptodev ECDSA method",
398 - NULL, /* ecdsa_sign_setup */
402 - NULL /* app_data */
407 -typedef enum ec_curve_s {
411 + if (dsa->priv_key == NULL) {
412 + if ((dsa->priv_key = BN_new()) == NULL)
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)
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 =
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)
440 - memset(&kop, 0, sizeof(kop));
441 - ecdsa = ecdsa_check(eckey);
443 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
445 + g_len = BN_num_bytes(dsa->p);
447 + * Get generator into a plain buffer. If length is less than
448 + * q_len then add leading padding bytes.
450 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
451 + DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
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]))
461 + if (bn2crparam(dsa->q, &kop->crk_param[1]))
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;
468 - if (!group || !priv_key) {
469 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
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))
479 + const DSA_METHOD *meth = DSA_OpenSSL();
483 + ret = (meth->dsa_keygen) (dsa);
484 + cookie->pkc_callback(cookie, 0);
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);
495 +cryptodev_dsa_do_sign_async(const unsigned char *dgst, int dlen, DSA *dsa,
496 + DSA_SIG *sig, struct pkc_cookie_s *cookie)
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 =
504 + if (((sig->r = BN_new()) == NULL) || !kop) {
505 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
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) {
514 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
518 - i = BN_num_bits(order);
520 - * Need to truncate digest if it is too long: first truncate whole bytes
522 - if (8 * dgst_len > i)
523 - dgst_len = (i + 7) / 8;
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);
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);
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__,
546 + if (dlen > r_len) {
547 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
551 - ret = ECDSA_SIG_new();
553 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
556 + * Get generator into a plain buffer. If length is less than
557 + * q_len then add leading padding bytes.
559 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
560 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
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) {
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);
574 + priv_key_len = r_len;
576 + * Get private key into a plain buffer. If length is less than
577 + * r_len then add leading padding bytes.
579 + if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
580 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
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);
590 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
594 + /* Add padding, since SEC expects hash to of size r_len */
596 + memset(f, 0, r_len - dlen);
598 + /* Skip leading bytes if dgst_len < r_len */
599 + memcpy(f + r_len - dlen, dgst, dlen);
603 + memset(kop, 0, sizeof(struct crypt_kop));
604 + kop->crk_op = CRK_DSA_SIGN;
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;
620 + if (cryptodev_asym_async(kop, r_len, sig->r, r_len, sig->s))
626 + const DSA_METHOD *meth = DSA_OpenSSL();
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);
643 +cryptodev_dsa_verify_async(const unsigned char *dgst, int dlen,
644 + DSA_SIG *sig, DSA *dsa,
645 + struct pkc_cookie_s *cookie)
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;
656 + if (spcf_bn2bin(dsa->p, &q, &q_len)) {
657 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
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);
669 + * Get generator into a plain buffer. If length is less than
670 + * q_len then add leading padding bytes.
672 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
673 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
678 + * Get public key into a plain buffer. If length is less than
679 + * q_len then add leading padding bytes.
681 + if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
682 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
686 + * Get the 1st part of signature into a flat buffer with
687 + * appropriate padding
691 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
692 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
697 + * Get the 2nd part of signature into a flat buffer with
698 + * appropriate padding
702 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
703 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
708 + if (dlen > r_len) {
709 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
713 + /* Allocate memory to store hash. */
714 + f = OPENSSL_malloc(r_len);
716 + DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
720 + /* Add padding, since SEC expects hash to of size r_len */
722 + memset(f, 0, r_len - dlen);
724 + /* Skip leading bytes if dgst_len < r_len */
725 + memcpy(f + r_len - dlen, dgst, dlen);
728 + memset(kop, 0, sizeof(struct crypt_kop));
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))
754 + const DSA_METHOD *meth = DSA_OpenSSL();
759 + ret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa);
760 + cookie->pkc_callback(cookie, 0);
765 +static DSA_METHOD cryptodev_dsa = {
766 + "cryptodev DSA method",
768 + NULL, /* dsa_sign_setup */
770 + NULL, /* dsa_mod_exp */
778 + NULL /* app_data */
781 +static ECDSA_METHOD cryptodev_ecdsa = {
782 + "cryptodev ECDSA method",
784 + NULL, /* ecdsa_sign_setup */
790 + NULL /* app_data */
793 +typedef enum ec_curve_s {
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)
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 =
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;
818 + memset(&kop, 0, sizeof(kop));
819 + ecdsa = ecdsa_check(eckey);
821 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
825 + group = EC_KEY_get0_group(eckey);
826 + priv_key = EC_KEY_get0_private_key(eckey);
828 + if (!group || !priv_key) {
829 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
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);
841 + order = &group->order;
842 + if (!order || BN_is_zero(order)) {
843 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
847 + i = BN_num_bits(order);
849 + * Need to truncate digest if it is too long: first truncate whole bytes
851 + if (8 * dgst_len > i)
852 + dgst_len = (i + 7) / 8;
854 + if (!BN_bin2bn(dgst, dgst_len, m)) {
855 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
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);
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__,
872 + ret = ECDSA_SIG_new();
874 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
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) {
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);
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);
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,
899 - /* memory for message representative */
902 - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
904 + /* memory for message representative */
907 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
911 + /* Add padding, since SEC expects hash to of size r_len */
912 + memset(f, 0, r_len - dgst_len);
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;
937 + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
939 + * OCF success value is 0, if not zero, change ret to fail
941 + if (0 == kop.crk_status)
944 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
946 + ret = (meth->ecdsa_do_verify) (dgst, dgst_len, sig, eckey);
948 + kop.crk_param[0].crp_p = NULL;
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,
959 + struct pkc_cookie_s *cookie)
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;
975 + if (!(sig->r = BN_new()) || !kop)
977 + if ((sig->s = BN_new()) == NULL) {
982 + memset(kop, 0, sizeof(struct crypt_kop));
983 + ecdsa = ecdsa_check(eckey);
985 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
989 + group = EC_KEY_get0_group(eckey);
990 + priv_key = EC_KEY_get0_private_key(eckey);
992 + if (!group || !priv_key) {
993 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
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);
1005 + order = &group->order;
1006 + if (!order || BN_is_zero(order)) {
1007 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
1011 + i = BN_num_bits(order);
1013 + * Need to truncate digest if it is too long: first truncate whole bytes
1015 + if (8 * dgst_len > i)
1016 + dgst_len = (i + 7) / 8;
1018 + if (!BN_bin2bn(dgst, dgst_len, m)) {
1019 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
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);
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__,
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);
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);
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);
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);
1070 + printf("Unsupported Curve\n");
1071 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1075 + if (spcf_bn2bin(order, &r, &r_len)) {
1076 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1080 + if (spcf_bn2bin(p, &q, &q_len)) {
1081 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1085 + priv_key_len = r_len;
1088 + * If BN_num_bytes of priv_key returns less then r_len then
1089 + * add padding bytes before the key
1091 + if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len)) {
1092 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1096 + /* Generation of ECC curve parameters */
1097 + ab_len = 2 * q_len;
1098 + ab = eng_copy_curve_points(a, b, ab_len, q_len);
1100 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
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);
1114 + kop->curve_type = ECC_BINARY;
1117 + /* Calculation of Generator point */
1118 + g_len = 2 * q_len;
1119 + g_xy = eng_copy_curve_points(x, y, g_len, q_len);
1121 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1125 + /* memory for message representative */
1126 + f = malloc(r_len);
1128 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1132 + /* Add padding, since SEC expects hash to of size r_len */
1133 + memset(f, 0, r_len - dgst_len);
1135 + /* Skip leading bytes if dgst_len < r_len */
1136 + memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
1138 + dgst_len += r_len - dgst_len;
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;
1157 + if (cryptodev_asym_async(kop, r_len, sig->r, r_len, sig->s))
1163 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
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);
1177 +static int cryptodev_ecdsa_verify_async(const unsigned char *dgst,
1178 + int dgst_len, const ECDSA_SIG *sig,
1180 + struct pkc_cookie_s *cookie)
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 =
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));
1200 + memset(kop, 0, sizeof(struct crypt_kop));
1201 + ecdsa = ecdsa_check(eckey);
1203 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
1207 + group = EC_KEY_get0_group(eckey);
1208 + pub_key = EC_KEY_get0_public_key(eckey);
1210 + if (!group || !pub_key) {
1211 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
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);
1224 + order = &group->order;
1225 + if (!order || BN_is_zero(order)) {
1226 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
1230 + i = BN_num_bits(order);
1232 + * Need to truncate digest if it is too long: first truncate whole *
1235 + if (8 * dgst_len > i)
1236 + dgst_len = (i + 7) / 8;
1238 + if (!BN_bin2bn(dgst, dgst_len, m)) {
1239 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
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);
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);
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;
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);
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);
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);
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);
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);
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);
1303 + printf("Unsupported Curve\n");
1304 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
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);
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);
1320 + /* Get the public key into a flat buffer with appropriate padding */
1321 + pub_key_len = 2 * q_len;
1323 + w_xy = eng_copy_curve_points(w_x, w_y, pub_key_len, q_len);
1325 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1329 + /* Generation of ECC curve parameters */
1330 + ab_len = 2 * q_len;
1332 + ab = eng_copy_curve_points(a, b, ab_len, q_len);
1334 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
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;
1344 + /* Calculation of Generator point */
1345 + g_len = 2 * q_len;
1347 + g_xy = eng_copy_curve_points(x, y, g_len, q_len);
1349 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1354 + * Get the 1st part of signature into a flat buffer with
1355 + * appropriate padding
1357 + if (BN_num_bytes(sig->r) < r_len)
1360 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
1361 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1366 + * Get the 2nd part of signature into a flat buffer with
1367 + * appropriate padding
1369 + if (BN_num_bytes(sig->s) < r_len)
1372 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1373 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1377 + /* memory for message representative */
1378 + f = malloc(r_len);
1380 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1384 + /* Add padding, since SEC expects hash to of size r_len */
1385 + memset(f, 0, r_len - dgst_len);
1387 + /* Skip leading bytes if dgst_len < r_len */
1388 + memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
1390 + dgst_len += r_len - dgst_len;
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;
1413 + if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
1419 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1423 + ret = (meth->ecdsa_do_verify) (dgst, dgst_len, sig, eckey);
1424 + cookie->pkc_callback(cookie, 0);
1430 +/* Cryptodev DH Key Gen routine */
1431 +static int cryptodev_dh_keygen_async(DH *dh, struct pkc_cookie_s *cookie)
1433 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1434 + int ret = 1, g_len;
1435 + unsigned char *g = NULL;
1440 + if (dh->priv_key == NULL) {
1441 + if ((dh->priv_key = BN_new()) == NULL)
1445 + if (dh->pub_key == NULL) {
1446 + if ((dh->pub_key = BN_new()) == NULL)
1450 + g_len = BN_num_bytes(dh->p);
1452 + * Get generator into a plain buffer. If length is less than
1453 + * q_len then add leading padding bytes.
1455 + if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
1456 + DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
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]))
1466 + if (bn2crparam(dh->q, &kop->crk_param[1]))
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;
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))
1500 - if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1502 - * OCF success value is 0, if not zero, change ret to fail
1504 - if (0 == kop.crk_status)
1507 - const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1511 + const DH_METHOD *meth = DH_OpenSSL();
1513 - ret = (meth->ecdsa_do_verify) (dgst, dgst_len, sig, eckey);
1516 + ret = (meth->generate_key) (dh);
1517 + cookie->pkc_callback(cookie, 0);
1519 - kop.crk_param[0].crp_p = NULL;
1526 @@ -2468,6 +3517,54 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1530 +/* Return Length if successful and 0 on failure */
1532 +cryptodev_dh_compute_key_async(unsigned char *key, const BIGNUM *pub_key,
1533 + DH *dh, struct pkc_cookie_s *cookie)
1535 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1538 + unsigned char *padded_pub_key = NULL, *p = NULL;
1540 + fd = *(int *)cookie->eng_handle;
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);
1548 + if (bn2crparam(dh->priv_key, &kop->crk_param[0]))
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;
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;
1561 + if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
1567 + const DH_METHOD *meth = DH_OpenSSL();
1571 + ret = (meth->compute_key) (key, pub_key, dh);
1572 + /* Call user cookie handler */
1573 + cookie->pkc_callback(cookie, 0);
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,
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,
1590 + struct pkc_cookie_s *cookie)
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;
1598 + EC_POINT *tmp = NULL;
1599 + BIGNUM *x = NULL, *y = NULL;
1600 + const BIGNUM *priv_key;
1601 + const EC_GROUP *group = NULL;
1603 + size_t buflen, len;
1604 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1606 + if (!(ctx = BN_CTX_new()) || !kop)
1609 + memset(kop, 0, sizeof(struct crypt_kop));
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);
1620 + if (!x || !y || !p || !a || !b || !w_x || !w_y) {
1621 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
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);
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);
1637 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1638 + NID_X9_62_prime_field) {
1639 + ec_crv = EC_PRIME;
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);
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);
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);
1661 + ec_crv = EC_BINARY;
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);
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);
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);
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);
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);
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);
1700 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1704 + /* Generation of ECC curve parameters */
1705 + ab_len = 2 * q_len;
1706 + ab = eng_copy_curve_points(a, b, ab_len, q_len);
1708 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
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);
1723 + kop->curve_type = ECC_BINARY;
1725 + kop->curve_type = ECC_PRIME;
1727 + priv_key_len = r_len;
1730 + * If BN_num_bytes of priv_key returns less then r_len then
1731 + * add padding bytes before the key
1733 + if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
1734 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
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);
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))
1765 + const ECDH_METHOD *meth = ECDH_OpenSSL();
1769 + ret = (meth->compute_key) (out, outlen, pub_key, ecdh, KDF);
1770 + /* Call user cookie handler */
1771 + cookie->pkc_callback(cookie, 0);
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 = {
1788 @@ -2665,6 +3955,7 @@ static ECDH_METHOD cryptodev_ecdh = {
1789 "cryptodev ECDH method",
1790 NULL, /* cryptodev_ecdh_compute_key */
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;
1805 + cryptodev_rsa.rsa_mod_exp_async = cryptodev_rsa_mod_exp_async;
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;
1814 @@ -2746,12 +4042,18 @@ void ENGINE_load_cryptodev(void)
1815 const DSA_METHOD *meth = DSA_OpenSSL();
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;
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;
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;
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;
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;
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;
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;
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;
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);
1878 ENGINE_free(engine);
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;
1889 + * Instantiate Engine handle to be passed in check_pkc_availability
1890 + * Ensure that Engine is instantiated before any pkc asynchronous call.
1892 + void *(*engine_init_instance)(void);
1894 + * Instantiated Engine handle will be closed with this call.
1895 + * Ensure that no pkc asynchronous call is made after this call
1897 + void (*engine_close_instance)(void *handle);
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
1904 + int (*check_pkc_availability)(void *eng_handle);
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 *)";
1911 const ENGINE_CMD_DEFN *cmd_defns;
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)
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;
1930 @@ -246,6 +250,48 @@ int ENGINE_set_id(ENGINE *e, const char *id)
1936 +void ENGINE_set_init_instance(ENGINE *e, void *(*engine_init_instance)(void))
1938 + e->engine_init_instance = engine_init_instance;
1941 +void ENGINE_set_close_instance(ENGINE *e,
1942 + void (*engine_close_instance)(void *))
1944 + e->engine_close_instance = engine_close_instance;
1947 +void ENGINE_set_async_map(ENGINE *e, int async_map)
1949 + e->async_map = async_map;
1952 +void *ENGINE_init_instance(ENGINE *e)
1954 + return e->engine_init_instance();
1957 +void ENGINE_close_instance(ENGINE *e, void *eng_handle)
1959 + e->engine_close_instance(eng_handle);
1962 +int ENGINE_get_async_map(ENGINE *e)
1964 + return e->async_map;
1967 +void ENGINE_set_check_pkc_availability(ENGINE *e,
1968 + int (*check_pkc_availability)(void *eng_handle))
1970 + e->check_pkc_availability = check_pkc_availability;
1973 +int ENGINE_check_pkc_availability(ENGINE *e, void *eng_handle)
1975 + return e->check_pkc_availability(eng_handle);
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 *));
1991 + * Following FLAGS are bitmap store in async_map to set asynchronous interface capability
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
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 {
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);
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
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);
2046 int (*init) (RSA *rsa);
2047 /* called at free */