1 From a933e6341fd8989bdd82f8a5446b6f04aa00eef9 Mon Sep 17 00:00:00 2001
2 From: Yashpal Dutta <yashpal.dutta@freescale.com>
3 Date: Tue, 11 Mar 2014 07:14:30 +0545
4 Subject: [PATCH 10/17] Asynchronous interface added for PKC cryptodev
7 Upstream-status: Pending
9 Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
11 crypto/crypto.h | 16 +
13 crypto/dsa/dsa.h | 5 +
14 crypto/ecdh/ech_locl.h | 3 +
15 crypto/ecdsa/ecs_locl.h | 5 +
16 crypto/engine/eng_cryptodev.c | 1578 +++++++++++++++++++++++++++++++++++++----
17 crypto/engine/eng_int.h | 24 +-
18 crypto/engine/eng_lib.c | 46 ++
19 crypto/engine/engine.h | 24 +
20 crypto/rsa/rsa.h | 23 +
21 10 files changed, 1582 insertions(+), 146 deletions(-)
23 diff --git a/crypto/crypto.h b/crypto/crypto.h
24 index f92fc51..ce12731 100644
27 @@ -605,6 +605,22 @@ void ERR_load_CRYPTO_strings(void);
28 #define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101
29 #define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100
31 +/* Additions for Asynchronous PKC Infrastructure */
32 +struct pkc_cookie_s {
33 + void *cookie; /* To be filled by openssl library primitive method function caller */
34 + void *eng_cookie; /* To be filled by Engine */
36 + * Callback handler to be provided by caller. Ensure to pass a
37 + * handler which takes the crypto operation to completion.
38 + * cookie: Container cookie from library
39 + * status: Status of the crypto Job completion.
40 + * 0: Job handled without any issue
41 + * -EINVAL: Parameters Invalid
43 + void (*pkc_callback)(struct pkc_cookie_s *cookie, int status);
50 diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
51 index ea59e61..20ffad2 100644
54 @@ -118,7 +118,9 @@ struct dh_method
55 int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a,
56 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
57 BN_MONT_CTX *m_ctx); /* Can be null */
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 a6f6d0b..b04a029 100644
67 --- a/crypto/dsa/dsa.h
68 +++ b/crypto/dsa/dsa.h
69 @@ -140,6 +140,10 @@ struct dsa_method
70 int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
71 const BIGNUM *m, BN_CTX *ctx,
72 BN_MONT_CTX *m_ctx); /* Can be null */
73 + int (*dsa_do_sign_async)(const unsigned char *dgst, int dlen, DSA *dsa,
74 + DSA_SIG *sig, struct pkc_cookie_s *cookie);
75 + int (*dsa_do_verify_async)(const unsigned char *dgst, int dgst_len,
76 + DSA_SIG *sig, DSA *dsa, struct pkc_cookie_s *cookie);
77 int (*init)(DSA *dsa);
78 int (*finish)(DSA *dsa);
80 @@ -151,6 +155,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 f6cad6a..adce6b3 100644
90 --- a/crypto/ecdh/ech_locl.h
91 +++ b/crypto/ecdh/ech_locl.h
92 @@ -67,6 +67,9 @@ struct ecdh_method
94 int (*compute_key)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
95 void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
96 + int (*compute_key_async)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
97 + void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen),
98 + struct pkc_cookie_s *cookie);
100 int (*init)(EC_KEY *eckey);
101 int (*finish)(EC_KEY *eckey);
102 diff --git a/crypto/ecdsa/ecs_locl.h b/crypto/ecdsa/ecs_locl.h
103 index cb3be13..eb0ebe0 100644
104 --- a/crypto/ecdsa/ecs_locl.h
105 +++ b/crypto/ecdsa/ecs_locl.h
106 @@ -74,6 +74,11 @@ struct ecdsa_method
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 7ee314b..9f2416e 100644
120 --- a/crypto/engine/eng_cryptodev.c
121 +++ b/crypto/engine/eng_cryptodev.c
122 @@ -1281,6 +1281,56 @@ zapparams(struct crypt_kop *kop)
126 +/* Any PKC request has at max 2 output parameters and they are stored here to
127 +be used while copying in the check availability */
128 +struct cryptodev_cookie_s {
130 + struct crparam r_param;
132 + struct crparam s_param;
133 + struct crypt_kop *kop;
137 +cryptodev_asym_async(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
141 + struct pkc_cookie_s *cookie = kop->cookie;
142 + struct cryptodev_cookie_s *eng_cookie;
144 + fd = *(int *)cookie->eng_handle;
146 + eng_cookie = malloc(sizeof(struct cryptodev_cookie_s));
149 + memset(eng_cookie, 0, sizeof(struct cryptodev_cookie_s));
151 + kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
152 + if (!kop->crk_param[kop->crk_iparams].crp_p)
154 + kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
155 + kop->crk_oparams++;
157 + eng_cookie->r_param = kop->crk_param[kop->crk_iparams];
160 + kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
161 + if (!kop->crk_param[kop->crk_iparams+1].crp_p)
163 + kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
164 + kop->crk_oparams++;
166 + eng_cookie->s_param = kop->crk_param[kop->crk_iparams + 1];
171 + eng_cookie->kop = kop;
172 + cookie->eng_cookie = eng_cookie;
173 + return ioctl(fd, CIOCASYMASYNCRYPT, kop);
177 cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
179 @@ -1337,6 +1387,44 @@ void *cryptodev_init_instance(void)
185 +/* Return 0 on success and 1 on failure */
186 +int cryptodev_check_availability(void *eng_handle)
188 + int fd = *(int *)eng_handle;
189 + struct pkc_cookie_list_s cookie_list;
190 + struct pkc_cookie_s *cookie;
193 + /* FETCH COOKIE returns number of cookies extracted */
194 + if (ioctl(fd, CIOCASYMFETCHCOOKIE, &cookie_list) <= 0)
197 + for (i = 0; i < cookie_list.cookie_available; i++) {
198 + cookie = cookie_list.cookie[i];
200 + struct cryptodev_cookie_s *eng_cookie = cookie->eng_cookie;
202 + struct crypt_kop *kop = eng_cookie->kop;
205 + crparam2bn(&eng_cookie->r_param, eng_cookie->r);
207 + crparam2bn(&eng_cookie->s_param, eng_cookie->s);
208 + if (kop->crk_op == CRK_DH_COMPUTE_KEY)
209 + kop->crk_oparams = 0;
211 + zapparams(eng_cookie->kop);
212 + free(eng_cookie->kop);
215 + cookie->pkc_callback(cookie, cookie_list.status[i]);
222 cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
223 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
224 @@ -1382,6 +1470,63 @@ err:
228 +cryptodev_bn_mod_exp_async(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
229 + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont, struct pkc_cookie_s *cookie)
231 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
234 + /* Currently, we know we can do mod exp iff we can do any
235 + * asymmetric operations at all.
237 + if (cryptodev_asymfeat == 0 || !kop) {
238 + ret = BN_mod_exp(r, a, p, m, ctx);
242 + kop->crk_oparams = 0;
243 + kop->crk_status = 0;
244 + kop->crk_op = CRK_MOD_EXP;
245 + kop->cookie = cookie;
246 + /* inputs: a^p % m */
247 + if (bn2crparam(a, &kop->crk_param[0]))
249 + if (bn2crparam(p, &kop->crk_param[1]))
251 + if (bn2crparam(m, &kop->crk_param[2]))
254 + kop->crk_iparams = 3;
255 + if (cryptodev_asym_async(kop, BN_num_bytes(m), r, 0, NULL))
261 + const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
265 + ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
267 + /* Call the completion handler immediately */
268 + cookie->pkc_callback(cookie, 0);
274 +cryptodev_rsa_nocrt_mod_exp_async(BIGNUM *r0, const BIGNUM *I,
275 + RSA *rsa, BN_CTX *ctx, struct pkc_cookie_s *cookie)
278 + ctx = BN_CTX_new();
279 + r = cryptodev_bn_mod_exp_async(r0, I, rsa->d, rsa->n, ctx, NULL, cookie);
285 cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
288 @@ -1446,6 +1591,62 @@ err:
293 +cryptodev_rsa_mod_exp_async(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx,
294 + struct pkc_cookie_s *cookie)
296 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
297 + int ret = 1, f_len, p_len, q_len;
298 + unsigned char *f = NULL, *p = NULL, *q = NULL, *dp = NULL, *dq = NULL, *c = NULL;
300 + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp || !kop) {
304 + kop->crk_oparams = 0;
305 + kop->crk_status = 0;
306 + kop->crk_op = CRK_MOD_EXP_CRT;
307 + f_len = BN_num_bytes(rsa->n);
308 + spcf_bn2bin_ex(I, &f, &f_len);
309 + spcf_bn2bin(rsa->p, &p, &p_len);
310 + spcf_bn2bin(rsa->q, &q, &q_len);
311 + spcf_bn2bin_ex(rsa->dmp1, &dp, &p_len);
312 + spcf_bn2bin_ex(rsa->iqmp, &c, &p_len);
313 + spcf_bn2bin_ex(rsa->dmq1, &dq, &q_len);
314 + /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
315 + kop->crk_param[0].crp_p = p;
316 + kop->crk_param[0].crp_nbits = p_len * 8;
317 + kop->crk_param[1].crp_p = q;
318 + kop->crk_param[1].crp_nbits = q_len * 8;
319 + kop->crk_param[2].crp_p = f;
320 + kop->crk_param[2].crp_nbits = f_len * 8;
321 + kop->crk_param[3].crp_p = dp;
322 + kop->crk_param[3].crp_nbits = p_len * 8;
323 + /* dq must of length q, rest all of length p*/
324 + kop->crk_param[4].crp_p = dq;
325 + kop->crk_param[4].crp_nbits = q_len * 8;
326 + kop->crk_param[5].crp_p = c;
327 + kop->crk_param[5].crp_nbits = p_len * 8;
328 + kop->crk_iparams = 6;
329 + kop->cookie = cookie;
330 + if (cryptodev_asym_async(kop, BN_num_bytes(rsa->n), r0, 0, NULL))
336 + const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
340 + ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
342 + /* Call user completion handler immediately */
343 + cookie->pkc_callback(cookie, 0);
348 static RSA_METHOD cryptodev_rsa = {
349 "cryptodev RSA method",
350 NULL, /* rsa_pub_enc */
351 @@ -1454,6 +1655,12 @@ static RSA_METHOD cryptodev_rsa = {
352 NULL, /* rsa_priv_dec */
355 + NULL, /* rsa_pub_enc */
356 + NULL, /* rsa_pub_dec */
357 + NULL, /* rsa_priv_enc */
358 + NULL, /* rsa_priv_dec */
364 @@ -1751,126 +1958,424 @@ sw_try:
368 +/* Cryptodev DSA Key Gen routine */
369 +static int cryptodev_dsa_keygen_async(DSA *dsa, struct pkc_cookie_s *cookie)
371 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
372 + int ret = 1, g_len;
373 + unsigned char *g = NULL;
378 -static DSA_METHOD cryptodev_dsa = {
379 - "cryptodev DSA method",
381 - NULL, /* dsa_sign_setup */
383 - NULL, /* dsa_mod_exp */
388 - NULL /* app_data */
390 + if (dsa->priv_key == NULL) {
391 + if ((dsa->priv_key=BN_new()) == NULL)
395 -static ECDSA_METHOD cryptodev_ecdsa = {
396 - "cryptodev ECDSA method",
398 - NULL, /* ecdsa_sign_setup */
402 - NULL /* app_data */
404 + if (dsa->pub_key == NULL) {
405 + if ((dsa->pub_key=BN_new()) == NULL)
409 -typedef enum ec_curve_s
414 + g_len = BN_num_bytes(dsa->p);
416 + * Get generator into a plain buffer. If length is less than
417 + * q_len then add leading padding bytes.
419 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
420 + DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
424 -/* ENGINE handler for ECDSA Sign */
425 -static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char *dgst,
426 - int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
428 - BIGNUM *m = NULL, *p = NULL, *a = NULL;
429 - BIGNUM *b = NULL, *x = NULL, *y = NULL;
430 - BN_CTX *ctx = NULL;
431 - ECDSA_SIG *ret = NULL;
432 - ECDSA_DATA *ecdsa = NULL;
433 - unsigned char * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
434 - unsigned char * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
435 - int i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
436 - int g_len = 0, d_len = 0, ab_len = 0;
437 - const BIGNUM *order = NULL, *priv_key=NULL;
438 - const EC_GROUP *group = NULL;
439 - struct crypt_kop kop;
440 - ec_curve_t ec_crv = EC_PRIME;
441 + memset(kop, 0, sizeof(struct crypt_kop));
442 + kop->crk_op = CRK_DSA_GENERATE_KEY;
443 + if (bn2crparam(dsa->p, &kop->crk_param[0]))
445 + if (bn2crparam(dsa->q, &kop->crk_param[1]))
447 + kop->crk_param[2].crp_p = g;
448 + kop->crk_param[2].crp_nbits = g_len * 8;
449 + kop->crk_iparams = 3;
450 + kop->cookie = cookie;
452 - memset(&kop, 0, sizeof(kop));
453 - ecdsa = ecdsa_check(eckey);
455 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
457 + /* pub_key is or prime length while priv key is of length of order */
458 + if (cryptodev_asym_async(kop, BN_num_bytes(dsa->p), dsa->pub_key,
459 + BN_num_bytes(dsa->q), dsa->priv_key))
465 + const DSA_METHOD *meth = DSA_OpenSSL();
469 + ret = (meth->dsa_keygen)(dsa);
470 + cookie->pkc_callback(cookie, 0);
475 - group = EC_KEY_get0_group(eckey);
476 - priv_key = EC_KEY_get0_private_key(eckey);
478 +cryptodev_dsa_do_sign_async(const unsigned char *dgst, int dlen, DSA *dsa,
479 + DSA_SIG *sig, struct pkc_cookie_s *cookie)
481 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
482 + DSA_SIG *dsaret = NULL;
483 + int q_len = 0, r_len = 0, g_len = 0;
484 + int priv_key_len = 0, ret = 1;
485 + unsigned char *q = NULL, *r = NULL, *g = NULL, *priv_key = NULL, *f = NULL;
487 - if (!group || !priv_key) {
488 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
490 + if (((sig->r = BN_new()) == NULL) || !kop) {
491 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
495 - if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
496 - (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
497 - (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
498 - (y = BN_new()) == NULL) {
499 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
500 + if ((sig->s = BN_new()) == NULL) {
502 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
506 - order = &group->order;
507 - if (!order || BN_is_zero(order)) {
508 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
509 + if (spcf_bn2bin(dsa->p, &q, &q_len)) {
510 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
514 - i = BN_num_bits(order);
515 - /* Need to truncate digest if it is too long: first truncate whole
517 - if (8 * dgst_len > i)
518 - dgst_len = (i + 7)/8;
519 + /* Get order of the field of private keys into plain buffer */
520 + if (spcf_bn2bin (dsa->q, &r, &r_len)) {
521 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
525 - if (!BN_bin2bn(dgst, dgst_len, m)) {
526 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
528 + if (dlen > r_len) {
529 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
533 - /* If still too long truncate remaining bits with a shift */
534 - if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
535 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
538 + * Get generator into a plain buffer. If length is less than
539 + * q_len then add leading padding bytes.
541 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
542 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
546 - /* copy the truncated bits into plain buffer */
547 - if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
548 - fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__);
549 + priv_key_len = r_len;
551 + * Get private key into a plain buffer. If length is less than
552 + * r_len then add leading padding bytes.
554 + if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
555 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
559 - ret = ECDSA_SIG_new();
561 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
562 + /* Allocate memory to store hash. */
563 + f = OPENSSL_malloc (r_len);
565 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
569 - /* check if this is prime or binary EC request */
570 - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
572 - /* get the generator point pair */
573 - if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group),
575 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
578 + /* Add padding, since SEC expects hash to of size r_len */
580 + memset(f, 0, r_len - dlen);
582 - /* get the ECC curve parameters */
583 - if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) {
584 - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
585 + /* Skip leading bytes if dgst_len < r_len */
586 + memcpy(f + r_len - dlen, dgst, dlen);
590 + memset(kop, 0, sizeof( struct crypt_kop));
591 + kop->crk_op = CRK_DSA_SIGN;
593 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
594 + kop->crk_param[0].crp_p = (void*)f;
595 + kop->crk_param[0].crp_nbits = dlen * 8;
596 + kop->crk_param[1].crp_p = (void*)q;
597 + kop->crk_param[1].crp_nbits = q_len * 8;
598 + kop->crk_param[2].crp_p = (void*)r;
599 + kop->crk_param[2].crp_nbits = r_len * 8;
600 + kop->crk_param[3].crp_p = (void*)g;
601 + kop->crk_param[3].crp_nbits = g_len * 8;
602 + kop->crk_param[4].crp_p = (void*)priv_key;
603 + kop->crk_param[4].crp_nbits = priv_key_len * 8;
604 + kop->crk_iparams = 5;
605 + kop->cookie = cookie;
607 + if (cryptodev_asym_async(kop, r_len, sig->r, r_len, sig->s))
613 + const DSA_METHOD *meth = DSA_OpenSSL();
619 + dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
620 + sig->r = dsaret->r;
621 + sig->s = dsaret->s;
622 + /* Call user callback immediately */
623 + cookie->pkc_callback(cookie, 0);
630 +cryptodev_dsa_verify_async(const unsigned char *dgst, int dlen,
631 + DSA_SIG *sig, DSA *dsa, struct pkc_cookie_s *cookie)
633 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
634 + int q_len = 0, r_len = 0, g_len = 0;
635 + int w_len = 0 ,c_len = 0, d_len = 0, ret = 1;
636 + unsigned char * q = NULL, * r = NULL, * w = NULL, * g = NULL;
637 + unsigned char *c = NULL, * d = NULL, *f = NULL;
642 + if (spcf_bn2bin(dsa->p, &q, &q_len)) {
643 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
647 + /* Get Order of field of private keys */
648 + if (spcf_bn2bin(dsa->q, &r, &r_len)) {
649 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
655 + * Get generator into a plain buffer. If length is less than
656 + * q_len then add leading padding bytes.
658 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
659 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
664 + * Get public key into a plain buffer. If length is less than
665 + * q_len then add leading padding bytes.
667 + if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
668 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
672 + * Get the 1st part of signature into a flat buffer with
673 + * appropriate padding
677 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
678 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
683 + * Get the 2nd part of signature into a flat buffer with
684 + * appropriate padding
688 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
689 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
695 + if (dlen > r_len) {
696 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
700 + /* Allocate memory to store hash. */
701 + f = OPENSSL_malloc (r_len);
703 + DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
707 + /* Add padding, since SEC expects hash to of size r_len */
709 + memset(f, 0, r_len - dlen);
711 + /* Skip leading bytes if dgst_len < r_len */
712 + memcpy(f + r_len - dlen, dgst, dlen);
715 + memset(kop, 0, sizeof(struct crypt_kop));
717 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
718 + kop->crk_param[0].crp_p = (void*)f;
719 + kop->crk_param[0].crp_nbits = dlen * 8;
720 + kop->crk_param[1].crp_p = q;
721 + kop->crk_param[1].crp_nbits = q_len * 8;
722 + kop->crk_param[2].crp_p = r;
723 + kop->crk_param[2].crp_nbits = r_len * 8;
724 + kop->crk_param[3].crp_p = g;
725 + kop->crk_param[3].crp_nbits = g_len * 8;
726 + kop->crk_param[4].crp_p = w;
727 + kop->crk_param[4].crp_nbits = w_len * 8;
728 + kop->crk_param[5].crp_p = c;
729 + kop->crk_param[5].crp_nbits = c_len * 8;
730 + kop->crk_param[6].crp_p = d;
731 + kop->crk_param[6].crp_nbits = d_len * 8;
732 + kop->crk_iparams = 7;
733 + kop->crk_op = CRK_DSA_VERIFY;
734 + kop->cookie = cookie;
735 + if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
741 + const DSA_METHOD *meth = DSA_OpenSSL();
746 + ret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
747 + cookie->pkc_callback(cookie, 0);
752 +static DSA_METHOD cryptodev_dsa = {
753 + "cryptodev DSA method",
755 + NULL, /* dsa_sign_setup */
757 + NULL, /* dsa_mod_exp */
765 + NULL /* app_data */
768 +static ECDSA_METHOD cryptodev_ecdsa = {
769 + "cryptodev ECDSA method",
771 + NULL, /* ecdsa_sign_setup */
777 + NULL /* app_data */
780 +typedef enum ec_curve_s
786 +/* ENGINE handler for ECDSA Sign */
787 +static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char *dgst,
788 + int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
790 + BIGNUM *m = NULL, *p = NULL, *a = NULL;
791 + BIGNUM *b = NULL, *x = NULL, *y = NULL;
792 + BN_CTX *ctx = NULL;
793 + ECDSA_SIG *ret = NULL;
794 + ECDSA_DATA *ecdsa = NULL;
795 + unsigned char * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
796 + unsigned char * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
797 + int i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
798 + int g_len = 0, d_len = 0, ab_len = 0;
799 + const BIGNUM *order = NULL, *priv_key=NULL;
800 + const EC_GROUP *group = NULL;
801 + struct crypt_kop kop;
802 + ec_curve_t ec_crv = EC_PRIME;
804 + memset(&kop, 0, sizeof(kop));
805 + ecdsa = ecdsa_check(eckey);
807 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
811 + group = EC_KEY_get0_group(eckey);
812 + priv_key = EC_KEY_get0_private_key(eckey);
814 + if (!group || !priv_key) {
815 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
819 + if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
820 + (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
821 + (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
822 + (y = BN_new()) == NULL) {
823 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
827 + order = &group->order;
828 + if (!order || BN_is_zero(order)) {
829 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
833 + i = BN_num_bits(order);
834 + /* Need to truncate digest if it is too long: first truncate whole
836 + if (8 * dgst_len > i)
837 + dgst_len = (i + 7)/8;
839 + if (!BN_bin2bn(dgst, dgst_len, m)) {
840 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
844 + /* If still too long truncate remaining bits with a shift */
845 + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
846 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
850 + /* copy the truncated bits into plain buffer */
851 + if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
852 + fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__);
856 + ret = ECDSA_SIG_new();
858 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
862 + /* check if this is prime or binary EC request */
863 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
865 + /* get the generator point pair */
866 + if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group),
868 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
872 + /* get the ECC curve parameters */
873 + if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) {
874 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
877 } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) {
878 @@ -2195,63 +2700,581 @@ static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len,
882 - * Get the 2nd part of signature into a flat buffer with
883 - * appropriate padding
884 + * Get the 2nd part of signature into a flat buffer with
885 + * appropriate padding
887 + if (BN_num_bytes(sig->s) < r_len)
890 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
891 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
895 + /* memory for message representative */
898 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
902 + /* Add padding, since SEC expects hash to of size r_len */
903 + memset(f, 0, r_len-dgst_len);
905 + /* Skip leading bytes if dgst_len < r_len */
906 + memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len);
907 + dgst_len += r_len-dgst_len;
908 + kop.crk_op = CRK_DSA_VERIFY;
909 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
910 + kop.crk_param[0].crp_p = f;
911 + kop.crk_param[0].crp_nbits = dgst_len * 8;
912 + kop.crk_param[1].crp_p = q;
913 + kop.crk_param[1].crp_nbits = q_len * 8;
914 + kop.crk_param[2].crp_p = r;
915 + kop.crk_param[2].crp_nbits = r_len * 8;
916 + kop.crk_param[3].crp_p = g_xy;
917 + kop.crk_param[3].crp_nbits = g_len * 8;
918 + kop.crk_param[4].crp_p = w_xy;
919 + kop.crk_param[4].crp_nbits = pub_key_len * 8;
920 + kop.crk_param[5].crp_p = ab;
921 + kop.crk_param[5].crp_nbits = ab_len * 8;
922 + kop.crk_param[6].crp_p = c;
923 + kop.crk_param[6].crp_nbits = d_len * 8;
924 + kop.crk_param[7].crp_p = d;
925 + kop.crk_param[7].crp_nbits = d_len * 8;
926 + kop.crk_iparams = 8;
928 + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
929 + /*OCF success value is 0, if not zero, change ret to fail*/
930 + if(0 == kop.crk_status)
933 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
935 + ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
937 + kop.crk_param[0].crp_p = NULL;
944 +static int cryptodev_ecdsa_do_sign_async( const unsigned char *dgst,
945 + int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey,
946 + ECDSA_SIG *sig, struct pkc_cookie_s *cookie)
948 + BIGNUM *m = NULL, *p = NULL, *a = NULL;
949 + BIGNUM *b = NULL, *x = NULL, *y = NULL;
950 + BN_CTX *ctx = NULL;
951 + ECDSA_SIG *sig_ret = NULL;
952 + ECDSA_DATA *ecdsa = NULL;
953 + unsigned char * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
954 + unsigned char * s = NULL, *f = NULL, *tmp_dgst = NULL;
955 + int i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
956 + int g_len = 0, ab_len = 0, ret = 1;
957 + const BIGNUM *order = NULL, *priv_key=NULL;
958 + const EC_GROUP *group = NULL;
959 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
960 + ec_curve_t ec_crv = EC_PRIME;
962 + if (!(sig->r = BN_new()) || !kop)
964 + if ((sig->s = BN_new()) == NULL) {
969 + memset(kop, 0, sizeof(struct crypt_kop));
970 + ecdsa = ecdsa_check(eckey);
972 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
976 + group = EC_KEY_get0_group(eckey);
977 + priv_key = EC_KEY_get0_private_key(eckey);
979 + if (!group || !priv_key) {
980 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
984 + if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
985 + (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
986 + (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
987 + (y = BN_new()) == NULL) {
988 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
992 + order = &group->order;
993 + if (!order || BN_is_zero(order)) {
994 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
998 + i = BN_num_bits(order);
999 + /* Need to truncate digest if it is too long: first truncate whole
1001 + if (8 * dgst_len > i)
1002 + dgst_len = (i + 7)/8;
1004 + if (!BN_bin2bn(dgst, dgst_len, m)) {
1005 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
1009 + /* If still too long truncate remaining bits with a shift */
1010 + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
1011 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
1015 + /* copy the truncated bits into plain buffer */
1016 + if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
1017 + fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__);
1021 + /* check if this is prime or binary EC request */
1022 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group))
1023 + == NID_X9_62_prime_field) {
1024 + ec_crv = EC_PRIME;
1025 + /* get the generator point pair */
1026 + if (!EC_POINT_get_affine_coordinates_GFp (group,
1027 + EC_GROUP_get0_generator(group), x, y,ctx)) {
1028 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1032 + /* get the ECC curve parameters */
1033 + if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) {
1034 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1037 + } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) {
1038 + ec_crv = EC_BINARY;
1039 + /* get the ECC curve parameters */
1040 + if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
1041 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1045 + /* get the generator point pair */
1046 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1047 + EC_GROUP_get0_generator(group), x, y,ctx)) {
1048 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1052 + printf("Unsupported Curve\n");
1053 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1057 + if (spcf_bn2bin(order, &r, &r_len)) {
1058 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1062 + if (spcf_bn2bin(p, &q, &q_len)) {
1063 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1067 + priv_key_len = r_len;
1070 + * If BN_num_bytes of priv_key returns less then r_len then
1071 + * add padding bytes before the key
1073 + if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len)) {
1074 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1078 + /* Generation of ECC curve parameters */
1080 + ab = eng_copy_curve_points(a, b, ab_len, q_len);
1082 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1086 + if (ec_crv == EC_BINARY) {
1087 + if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
1089 + unsigned char *c_temp = NULL;
1090 + int c_temp_len = q_len;
1091 + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1092 + memcpy(ab+q_len, c_temp, q_len);
1096 + kop->curve_type = ECC_BINARY;
1099 + /* Calculation of Generator point */
1101 + g_xy = eng_copy_curve_points(x, y, g_len, q_len);
1103 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1107 + /* memory for message representative */
1108 + f = malloc(r_len);
1110 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1114 + /* Add padding, since SEC expects hash to of size r_len */
1115 + memset(f, 0, r_len - dgst_len);
1117 + /* Skip leading bytes if dgst_len < r_len */
1118 + memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
1120 + dgst_len += r_len - dgst_len;
1122 + kop->crk_op = CRK_DSA_SIGN;
1123 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1124 + kop->crk_param[0].crp_p = f;
1125 + kop->crk_param[0].crp_nbits = dgst_len * 8;
1126 + kop->crk_param[1].crp_p = q;
1127 + kop->crk_param[1].crp_nbits = q_len * 8;
1128 + kop->crk_param[2].crp_p = r;
1129 + kop->crk_param[2].crp_nbits = r_len * 8;
1130 + kop->crk_param[3].crp_p = g_xy;
1131 + kop->crk_param[3].crp_nbits = g_len * 8;
1132 + kop->crk_param[4].crp_p = s;
1133 + kop->crk_param[4].crp_nbits = priv_key_len * 8;
1134 + kop->crk_param[5].crp_p = ab;
1135 + kop->crk_param[5].crp_nbits = ab_len * 8;
1136 + kop->crk_iparams = 6;
1137 + kop->cookie = cookie;
1139 + if (cryptodev_asym_async(kop, r_len, sig->r , r_len, sig->s))
1145 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1150 + sig_ret = (meth->ecdsa_do_sign)(dgst, dgst_len, in_kinv, in_r, eckey);
1151 + sig->r = sig_ret->r;
1152 + sig->s = sig_ret->s;
1153 + cookie->pkc_callback(cookie, 0);
1158 +static int cryptodev_ecdsa_verify_async(const unsigned char *dgst, int dgst_len,
1159 + const ECDSA_SIG *sig, EC_KEY *eckey, struct pkc_cookie_s *cookie)
1161 + BIGNUM *m = NULL, *p = NULL, *a = NULL, *b = NULL;
1162 + BIGNUM *x = NULL, *y = NULL, *w_x = NULL, *w_y = NULL;
1163 + BN_CTX *ctx = NULL;
1164 + ECDSA_DATA *ecdsa = NULL;
1165 + unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL, *w_xy = NULL;
1166 + unsigned char *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
1167 + int i = 0, q_len = 0, pub_key_len = 0, r_len = 0, c_len = 0, g_len = 0;
1168 + int d_len = 0, ab_len = 0, ret = 1;
1169 + const EC_POINT *pub_key = NULL;
1170 + const BIGNUM *order = NULL;
1171 + const EC_GROUP *group=NULL;
1172 + ec_curve_t ec_crv = EC_PRIME;
1173 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1178 + memset(kop, 0, sizeof(struct crypt_kop));
1179 + ecdsa = ecdsa_check(eckey);
1181 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
1185 + group = EC_KEY_get0_group(eckey);
1186 + pub_key = EC_KEY_get0_public_key(eckey);
1188 + if (!group || !pub_key) {
1189 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
1193 + if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
1194 + (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
1195 + (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
1196 + (y = BN_new()) == NULL || (w_x = BN_new()) == NULL ||
1197 + (w_y = BN_new()) == NULL) {
1198 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1202 + order = &group->order;
1203 + if (!order || BN_is_zero(order)) {
1204 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
1208 + i = BN_num_bits(order);
1209 + /* Need to truncate digest if it is too long: first truncate whole
1211 + if (8 * dgst_len > i)
1212 + dgst_len = (i + 7)/8;
1214 + if (!BN_bin2bn(dgst, dgst_len, m)) {
1215 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1219 + /* If still too long truncate remaining bits with a shift */
1220 + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
1221 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1224 + /* copy the truncated bits into plain buffer */
1225 + if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
1226 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1230 + /* check if this is prime or binary EC request */
1231 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
1232 + ec_crv = EC_PRIME;
1234 + /* get the generator point pair */
1235 + if (!EC_POINT_get_affine_coordinates_GFp (group,
1236 + EC_GROUP_get0_generator(group), x, y,ctx)) {
1237 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1241 + /* get the public key pair for prime curve */
1242 + if (!EC_POINT_get_affine_coordinates_GFp (group,
1243 + pub_key, w_x, w_y,ctx)) {
1244 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1248 + /* get the ECC curve parameters */
1249 + if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
1250 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1253 + } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field){
1254 + ec_crv = EC_BINARY;
1255 + /* get the ECC curve parameters */
1256 + if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
1257 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1261 + /* get the generator point pair */
1262 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1263 + EC_GROUP_get0_generator(group),x, y,ctx)) {
1264 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1268 + /* get the public key pair for binary curve */
1269 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1270 + pub_key, w_x, w_y,ctx)) {
1271 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1275 + printf("Unsupported Curve\n");
1276 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1280 + /* Get the order of the subgroup of private keys */
1281 + if (spcf_bn2bin((BIGNUM*)order, &r, &r_len)) {
1282 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1286 + /* Get the irreducible polynomial that creates the field */
1287 + if (spcf_bn2bin(p, &q, &q_len)) {
1288 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1292 + /* Get the public key into a flat buffer with appropriate padding */
1293 + pub_key_len = 2 * q_len;
1295 + w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
1297 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1301 + /* Generation of ECC curve parameters */
1304 + ab = eng_copy_curve_points (a, b, ab_len, q_len);
1306 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1310 + if (ec_crv == EC_BINARY) {
1311 + /* copy b' i.e c(b), instead of only b */
1312 + eng_ec_get_cparam (EC_GROUP_get_curve_name(group),
1314 + kop->curve_type = ECC_BINARY;
1317 + /* Calculation of Generator point */
1318 + g_len = 2 * q_len;
1320 + g_xy = eng_copy_curve_points (x, y, g_len, q_len);
1322 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1327 + * Get the 1st part of signature into a flat buffer with
1328 + * appropriate padding
1330 + if (BN_num_bytes(sig->r) < r_len)
1333 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
1334 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1339 + * Get the 2nd part of signature into a flat buffer with
1340 + * appropriate padding
1342 + if (BN_num_bytes(sig->s) < r_len)
1345 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1346 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1350 + /* memory for message representative */
1351 + f = malloc(r_len);
1353 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1357 + /* Add padding, since SEC expects hash to of size r_len */
1358 + memset(f, 0, r_len-dgst_len);
1360 + /* Skip leading bytes if dgst_len < r_len */
1361 + memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len);
1363 + dgst_len += r_len-dgst_len;
1365 + kop->crk_op = CRK_DSA_VERIFY;
1366 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1367 + kop->crk_param[0].crp_p = f;
1368 + kop->crk_param[0].crp_nbits = dgst_len * 8;
1369 + kop->crk_param[1].crp_p = q;
1370 + kop->crk_param[1].crp_nbits = q_len * 8;
1371 + kop->crk_param[2].crp_p = r;
1372 + kop->crk_param[2].crp_nbits = r_len * 8;
1373 + kop->crk_param[3].crp_p = g_xy;
1374 + kop->crk_param[3].crp_nbits = g_len * 8;
1375 + kop->crk_param[4].crp_p = w_xy;
1376 + kop->crk_param[4].crp_nbits = pub_key_len * 8;
1377 + kop->crk_param[5].crp_p = ab;
1378 + kop->crk_param[5].crp_nbits = ab_len * 8;
1379 + kop->crk_param[6].crp_p = c;
1380 + kop->crk_param[6].crp_nbits = d_len * 8;
1381 + kop->crk_param[7].crp_p = d;
1382 + kop->crk_param[7].crp_nbits = d_len * 8;
1383 + kop->crk_iparams = 8;
1384 + kop->cookie = cookie;
1386 + if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
1392 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1396 + ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
1397 + cookie->pkc_callback(cookie, 0);
1403 +/* Cryptodev DH Key Gen routine */
1404 +static int cryptodev_dh_keygen_async(DH *dh, struct pkc_cookie_s *cookie)
1406 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1407 + int ret = 1, g_len;
1408 + unsigned char *g = NULL;
1413 + if (dh->priv_key == NULL) {
1414 + if ((dh->priv_key=BN_new()) == NULL)
1418 + if (dh->pub_key == NULL) {
1419 + if ((dh->pub_key=BN_new()) == NULL)
1423 + g_len = BN_num_bytes(dh->p);
1425 + * Get generator into a plain buffer. If length is less than
1426 + * q_len then add leading padding bytes.
1428 - if (BN_num_bytes(sig->s) < r_len)
1431 - if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1432 - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1436 - /* memory for message representative */
1437 - f = malloc(r_len);
1439 - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1441 + if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
1442 + DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
1446 - /* Add padding, since SEC expects hash to of size r_len */
1447 - memset(f, 0, r_len-dgst_len);
1448 + memset(kop, 0, sizeof(struct crypt_kop));
1449 + kop->crk_op = CRK_DH_GENERATE_KEY;
1450 + if (bn2crparam(dh->p, &kop->crk_param[0]))
1452 + if (bn2crparam(dh->q, &kop->crk_param[1]))
1454 + kop->crk_param[2].crp_p = g;
1455 + kop->crk_param[2].crp_nbits = g_len * 8;
1456 + kop->crk_iparams = 3;
1457 + kop->cookie = cookie;
1459 - /* Skip leading bytes if dgst_len < r_len */
1460 - memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len);
1461 - dgst_len += r_len-dgst_len;
1462 - kop.crk_op = CRK_DSA_VERIFY;
1463 - /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1464 - kop.crk_param[0].crp_p = f;
1465 - kop.crk_param[0].crp_nbits = dgst_len * 8;
1466 - kop.crk_param[1].crp_p = q;
1467 - kop.crk_param[1].crp_nbits = q_len * 8;
1468 - kop.crk_param[2].crp_p = r;
1469 - kop.crk_param[2].crp_nbits = r_len * 8;
1470 - kop.crk_param[3].crp_p = g_xy;
1471 - kop.crk_param[3].crp_nbits = g_len * 8;
1472 - kop.crk_param[4].crp_p = w_xy;
1473 - kop.crk_param[4].crp_nbits = pub_key_len * 8;
1474 - kop.crk_param[5].crp_p = ab;
1475 - kop.crk_param[5].crp_nbits = ab_len * 8;
1476 - kop.crk_param[6].crp_p = c;
1477 - kop.crk_param[6].crp_nbits = d_len * 8;
1478 - kop.crk_param[7].crp_p = d;
1479 - kop.crk_param[7].crp_nbits = d_len * 8;
1480 - kop.crk_iparams = 8;
1481 + /* pub_key is or prime length while priv key is of length of order */
1482 + if (cryptodev_asym_async(kop, BN_num_bytes(dh->p), dh->pub_key,
1483 + BN_num_bytes(dh->q), dh->priv_key))
1486 - if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1487 - /*OCF success value is 0, if not zero, change ret to fail*/
1488 - if(0 == kop.crk_status)
1491 - const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1495 + const DH_METHOD *meth = DH_OpenSSL();
1497 - ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
1500 + ret = (meth->generate_key)(dh);
1501 + cookie->pkc_callback(cookie, 0);
1503 - kop.crk_param[0].crp_p = NULL;
1510 @@ -2360,6 +3383,54 @@ sw_try:
1514 +/* Return Length if successful and 0 on failure */
1516 +cryptodev_dh_compute_key_async(unsigned char *key, const BIGNUM *pub_key,
1517 + DH *dh, struct pkc_cookie_s *cookie)
1519 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1522 + unsigned char *padded_pub_key = NULL, *p = NULL;
1524 + fd = *(int *)cookie->eng_handle;
1526 + memset(kop, 0, sizeof(struct crypt_kop));
1527 + kop->crk_op = CRK_DH_COMPUTE_KEY;
1528 + /* inputs: dh->priv_key pub_key dh->p key */
1529 + spcf_bn2bin(dh->p, &p, &p_len);
1530 + spcf_bn2bin_ex(pub_key, &padded_pub_key, &p_len);
1532 + if (bn2crparam(dh->priv_key, &kop->crk_param[0]))
1534 + kop->crk_param[1].crp_p = padded_pub_key;
1535 + kop->crk_param[1].crp_nbits = p_len * 8;
1536 + kop->crk_param[2].crp_p = p;
1537 + kop->crk_param[2].crp_nbits = p_len * 8;
1538 + kop->crk_iparams = 3;
1540 + kop->cookie = cookie;
1541 + kop->crk_param[3].crp_p = (void*) key;
1542 + kop->crk_param[3].crp_nbits = p_len * 8;
1543 + kop->crk_oparams = 1;
1545 + if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
1551 + const DH_METHOD *meth = DH_OpenSSL();
1555 + ret = (meth->compute_key)(key, pub_key, dh);
1556 + /* Call user cookie handler */
1557 + cookie->pkc_callback(cookie, 0);
1562 int cryptodev_ecdh_compute_key(void *out, size_t outlen,
1563 const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen,
1564 void *out, size_t *outlen))
1565 @@ -2537,6 +3608,190 @@ err:
1569 +int cryptodev_ecdh_compute_key_async(void *out, size_t outlen,
1570 + const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen,
1571 + void *out, size_t *outlen), struct pkc_cookie_s *cookie)
1573 + ec_curve_t ec_crv = EC_PRIME;
1574 + unsigned char * q = NULL, *w_xy = NULL, *ab = NULL, *s = NULL, *r = NULL;
1575 + BIGNUM * w_x = NULL, *w_y = NULL;
1576 + int q_len = 0, ab_len = 0, pub_key_len = 0, r_len = 0, priv_key_len = 0;
1577 + BIGNUM * p = NULL, *a = NULL, *b = NULL;
1579 + EC_POINT *tmp=NULL;
1580 + BIGNUM *x=NULL, *y=NULL;
1581 + const BIGNUM *priv_key;
1582 + const EC_GROUP* group = NULL;
1584 + size_t buflen, len;
1585 + struct crypt_kop *kop = malloc(sizeof(struct crypt_kop));
1587 + if (!(ctx = BN_CTX_new()) || !kop)
1590 + memset(kop, 0, sizeof(struct crypt_kop));
1592 + BN_CTX_start(ctx);
1593 + x = BN_CTX_get(ctx);
1594 + y = BN_CTX_get(ctx);
1595 + p = BN_CTX_get(ctx);
1596 + a = BN_CTX_get(ctx);
1597 + b = BN_CTX_get(ctx);
1598 + w_x = BN_CTX_get(ctx);
1599 + w_y = BN_CTX_get(ctx);
1601 + if (!x || !y || !p || !a || !b || !w_x || !w_y) {
1602 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
1606 + priv_key = EC_KEY_get0_private_key(ecdh);
1607 + if (priv_key == NULL) {
1608 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
1612 + group = EC_KEY_get0_group(ecdh);
1613 + if ((tmp=EC_POINT_new(group)) == NULL) {
1614 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
1618 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1619 + NID_X9_62_prime_field) {
1620 + ec_crv = EC_PRIME;
1622 + if (!EC_POINT_get_affine_coordinates_GFp(group,
1623 + EC_GROUP_get0_generator(group), x, y, ctx)) {
1624 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
1628 + /* get the ECC curve parameters */
1629 + if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
1630 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1634 + /* get the public key pair for prime curve */
1635 + if (!EC_POINT_get_affine_coordinates_GFp (group, pub_key, w_x, w_y,ctx)) {
1636 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1640 + ec_crv = EC_BINARY;
1642 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1643 + EC_GROUP_get0_generator(group), x, y, ctx)) {
1644 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
1648 + /* get the ECC curve parameters */
1649 + if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
1650 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1654 + /* get the public key pair for binary curve */
1655 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1656 + pub_key, w_x, w_y,ctx)) {
1657 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1662 + /* irreducible polynomial that creates the field */
1663 + if (spcf_bn2bin((BIGNUM*)&group->order, &r, &r_len)) {
1664 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1668 + /* Get the irreducible polynomial that creates the field */
1669 + if (spcf_bn2bin(p, &q, &q_len)) {
1670 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1674 + /* Get the public key into a flat buffer with appropriate padding */
1675 + pub_key_len = 2 * q_len;
1676 + w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
1678 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1682 + /* Generation of ECC curve parameters */
1684 + ab = eng_copy_curve_points (a, b, ab_len, q_len);
1686 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1690 + if (ec_crv == EC_BINARY) {
1691 + /* copy b' i.e c(b), instead of only b */
1692 + if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
1694 + unsigned char *c_temp = NULL;
1695 + int c_temp_len = q_len;
1696 + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1697 + memcpy(ab+q_len, c_temp, q_len);
1701 + kop->curve_type = ECC_BINARY;
1703 + kop->curve_type = ECC_PRIME;
1705 + priv_key_len = r_len;
1708 + * If BN_num_bytes of priv_key returns less then r_len then
1709 + * add padding bytes before the key
1711 + if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
1712 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1716 + buflen = (EC_GROUP_get_degree(group) + 7)/8;
1717 + len = BN_num_bytes(x);
1718 + if (len > buflen || q_len < buflen) {
1719 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
1723 + kop->crk_op = CRK_DH_COMPUTE_KEY;
1724 + kop->crk_param[0].crp_p = (void *) s;
1725 + kop->crk_param[0].crp_nbits = priv_key_len*8;
1726 + kop->crk_param[1].crp_p = (void *) w_xy;
1727 + kop->crk_param[1].crp_nbits = pub_key_len*8;
1728 + kop->crk_param[2].crp_p = (void *) q;
1729 + kop->crk_param[2].crp_nbits = q_len*8;
1730 + kop->crk_param[3].crp_p = (void *) ab;
1731 + kop->crk_param[3].crp_nbits = ab_len*8;
1732 + kop->crk_iparams = 4;
1733 + kop->crk_param[4].crp_p = (void *) out;
1734 + kop->crk_param[4].crp_nbits = q_len*8;
1735 + kop->crk_oparams = 1;
1736 + kop->cookie = cookie;
1737 + if (cryptodev_asym_async(kop, 0, NULL, 0, NULL))
1743 + const ECDH_METHOD *meth = ECDH_OpenSSL();
1747 + ret = (meth->compute_key)(out, outlen, pub_key, ecdh, KDF);
1748 + /* Call user cookie handler */
1749 + cookie->pkc_callback(cookie, 0);
1754 static DH_METHOD cryptodev_dh = {
1755 "cryptodev DH method",
1756 @@ -2545,6 +3800,8 @@ static DH_METHOD cryptodev_dh = {
1765 @@ -2553,6 +3810,7 @@ static ECDH_METHOD cryptodev_ecdh = {
1766 "cryptodev ECDH method",
1767 NULL, /* cryptodev_ecdh_compute_key */
1773 @@ -2625,12 +3883,19 @@ ENGINE_load_cryptodev(void)
1774 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
1775 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1776 cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
1777 - if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
1778 + cryptodev_rsa.bn_mod_exp_async =
1779 + cryptodev_bn_mod_exp_async;
1780 + if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) {
1781 cryptodev_rsa.rsa_mod_exp =
1782 cryptodev_rsa_mod_exp;
1784 + cryptodev_rsa.rsa_mod_exp_async =
1785 + cryptodev_rsa_mod_exp_async;
1787 cryptodev_rsa.rsa_mod_exp =
1788 cryptodev_rsa_nocrt_mod_exp;
1789 + cryptodev_rsa.rsa_mod_exp_async =
1790 + cryptodev_rsa_nocrt_mod_exp_async;
1795 @@ -2638,12 +3903,21 @@ ENGINE_load_cryptodev(void)
1796 const DSA_METHOD *meth = DSA_OpenSSL();
1798 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1799 - if (cryptodev_asymfeat & CRF_DSA_SIGN)
1800 + if (cryptodev_asymfeat & CRF_DSA_SIGN) {
1801 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1802 - if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1803 + cryptodev_dsa.dsa_do_sign_async =
1804 + cryptodev_dsa_do_sign_async;
1806 + if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
1807 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1808 - if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY)
1809 + cryptodev_dsa.dsa_do_verify_async =
1810 + cryptodev_dsa_verify_async;
1812 + if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY) {
1813 cryptodev_dsa.dsa_keygen = cryptodev_dsa_keygen;
1814 + cryptodev_dsa.dsa_keygen_async =
1815 + cryptodev_dsa_keygen_async;
1819 if (ENGINE_set_DH(engine, &cryptodev_dh)){
1820 @@ -2652,10 +3926,15 @@ ENGINE_load_cryptodev(void)
1821 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1822 cryptodev_dh.compute_key =
1823 cryptodev_dh_compute_key;
1824 + cryptodev_dh.compute_key_async =
1825 + cryptodev_dh_compute_key_async;
1827 if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) {
1828 cryptodev_dh.generate_key =
1829 cryptodev_dh_keygen;
1830 + cryptodev_dh.generate_key_async =
1831 + cryptodev_dh_keygen_async;
1836 @@ -2664,10 +3943,14 @@ ENGINE_load_cryptodev(void)
1837 memcpy(&cryptodev_ecdsa, meth, sizeof(ECDSA_METHOD));
1838 if (cryptodev_asymfeat & CRF_DSA_SIGN) {
1839 cryptodev_ecdsa.ecdsa_do_sign = cryptodev_ecdsa_do_sign;
1840 + cryptodev_ecdsa.ecdsa_do_sign_async =
1841 + cryptodev_ecdsa_do_sign_async;
1843 if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
1844 cryptodev_ecdsa.ecdsa_do_verify =
1845 cryptodev_ecdsa_verify;
1846 + cryptodev_ecdsa.ecdsa_do_verify_async =
1847 + cryptodev_ecdsa_verify_async;
1851 @@ -2676,9 +3959,16 @@ ENGINE_load_cryptodev(void)
1852 memcpy(&cryptodev_ecdh, ecdh_meth, sizeof(ECDH_METHOD));
1853 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1854 cryptodev_ecdh.compute_key = cryptodev_ecdh_compute_key;
1855 + cryptodev_ecdh.compute_key_async =
1856 + cryptodev_ecdh_compute_key_async;
1860 + ENGINE_set_check_pkc_availability(engine, cryptodev_check_availability);
1861 + ENGINE_set_close_instance(engine, cryptodev_close_instance);
1862 + ENGINE_set_init_instance(engine, cryptodev_init_instance);
1863 + ENGINE_set_async_map(engine, ENGINE_ALLPKC_ASYNC);
1866 ENGINE_free(engine);
1868 diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h
1869 index 451ef8f..8fc3077 100644
1870 --- a/crypto/engine/eng_int.h
1871 +++ b/crypto/engine/eng_int.h
1872 @@ -181,7 +181,29 @@ struct engine_st
1873 ENGINE_LOAD_KEY_PTR load_pubkey;
1875 ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
1878 + * Instantiate Engine handle to be passed in check_pkc_availability
1879 + * Ensure that Engine is instantiated before any pkc asynchronous call.
1881 + void *(*engine_init_instance)(void);
1883 + * Instantiated Engine handle will be closed with this call.
1884 + * Ensure that no pkc asynchronous call is made after this call
1886 + void (*engine_close_instance)(void *handle);
1888 + * Check availability will extract the data from kernel.
1889 + * eng_handle: This is the Engine handle corresponds to which
1890 + * the cookies needs to be polled.
1891 + * return 0 if cookie available else 1
1893 + int (*check_pkc_availability)(void *eng_handle);
1895 + * The following map is used to check if the engine supports asynchronous implementation
1896 + * ENGINE_ASYNC_FLAG* for available bitmap. Any application checking for asynchronous
1897 + * implementation need to check this features using "int ENGINE_get_async_map(engine *)";
1900 const ENGINE_CMD_DEFN *cmd_defns;
1902 /* reference count on the structure itself */
1903 diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c
1904 index 18a6664..6fa621c 100644
1905 --- a/crypto/engine/eng_lib.c
1906 +++ b/crypto/engine/eng_lib.c
1907 @@ -98,7 +98,11 @@ void engine_set_all_null(ENGINE *e)
1909 e->load_privkey = NULL;
1910 e->load_pubkey = NULL;
1911 + e->check_pkc_availability = NULL;
1912 + e->engine_init_instance = NULL;
1913 + e->engine_close_instance = NULL;
1914 e->cmd_defns = NULL;
1919 @@ -233,6 +237,48 @@ int ENGINE_set_id(ENGINE *e, const char *id)
1923 +void ENGINE_set_init_instance(ENGINE *e, void *(*engine_init_instance)(void))
1925 + e->engine_init_instance = engine_init_instance;
1928 +void ENGINE_set_close_instance(ENGINE *e,
1929 + void (*engine_close_instance)(void *))
1931 + e->engine_close_instance = engine_close_instance;
1934 +void ENGINE_set_async_map(ENGINE *e, int async_map)
1936 + e->async_map = async_map;
1939 +void *ENGINE_init_instance(ENGINE *e)
1941 + return e->engine_init_instance();
1944 +void ENGINE_close_instance(ENGINE *e, void *eng_handle)
1946 + e->engine_close_instance(eng_handle);
1949 +int ENGINE_get_async_map(ENGINE *e)
1951 + return e->async_map;
1954 +void ENGINE_set_check_pkc_availability(ENGINE *e,
1955 + int (*check_pkc_availability)(void *eng_handle))
1957 + e->check_pkc_availability = check_pkc_availability;
1960 +int ENGINE_check_pkc_availability(ENGINE *e, void *eng_handle)
1962 + return e->check_pkc_availability(eng_handle);
1965 int ENGINE_set_name(ENGINE *e, const char *name)
1968 diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h
1969 index 237a6c9..ccff86a 100644
1970 --- a/crypto/engine/engine.h
1971 +++ b/crypto/engine/engine.h
1972 @@ -473,6 +473,30 @@ ENGINE *ENGINE_new(void);
1973 int ENGINE_free(ENGINE *e);
1974 int ENGINE_up_ref(ENGINE *e);
1975 int ENGINE_set_id(ENGINE *e, const char *id);
1976 +void ENGINE_set_init_instance(ENGINE *e, void *(*engine_init_instance)(void));
1977 +void ENGINE_set_close_instance(ENGINE *e,
1978 + void (*engine_free_instance)(void *));
1980 + * Following FLAGS are bitmap store in async_map to set asynchronous interface capability
1983 +#define ENGINE_RSA_ASYNC 0x0001
1984 +#define ENGINE_DSA_ASYNC 0x0002
1985 +#define ENGINE_DH_ASYNC 0x0004
1986 +#define ENGINE_ECDSA_ASYNC 0x0008
1987 +#define ENGINE_ECDH_ASYNC 0x0010
1988 +#define ENGINE_ALLPKC_ASYNC 0x001F
1989 +/* Engine implementation will set the bitmap based on above flags using following API */
1990 +void ENGINE_set_async_map(ENGINE *e, int async_map);
1991 + /* Application need to check the bitmap based on above flags using following API
1992 + * to confirm asynchronous methods supported
1994 +int ENGINE_get_async_map(ENGINE *e);
1995 +void *ENGINE_init_instance(ENGINE *e);
1996 +void ENGINE_close_instance(ENGINE *e, void *eng_handle);
1997 +void ENGINE_set_check_pkc_availability(ENGINE *e,
1998 + int (*check_pkc_availability)(void *eng_handle));
1999 +int ENGINE_check_pkc_availability(ENGINE *e, void *eng_handle);
2000 int ENGINE_set_name(ENGINE *e, const char *name);
2001 int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
2002 int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
2003 diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
2004 index 5f269e5..6ef1b15 100644
2005 --- a/crypto/rsa/rsa.h
2006 +++ b/crypto/rsa/rsa.h
2007 @@ -101,6 +101,29 @@ struct rsa_meth_st
2008 int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
2009 const BIGNUM *m, BN_CTX *ctx,
2010 BN_MONT_CTX *m_ctx); /* Can be null */
2012 + * Cookie in the following _async variant must be allocated before
2013 + * submission and can be freed once its corresponding callback
2014 + * handler is called
2016 + int (*rsa_pub_enc_asyn)(int flen,const unsigned char *from,
2017 + unsigned char *to, RSA *rsa, int padding,
2018 + struct pkc_cookie_s *cookie);
2019 + int (*rsa_pub_dec_async)(int flen,const unsigned char *from,
2020 + unsigned char *to, RSA *rsa, int padding,
2021 + struct pkc_cookie_s *cookie);
2022 + int (*rsa_priv_enc_async)(int flen,const unsigned char *from,
2023 + unsigned char *to, RSA *rsa, int padding,
2024 + struct pkc_cookie_s *cookie);
2025 + int (*rsa_priv_dec_async)(int flen,const unsigned char *from,
2026 + unsigned char *to, RSA *rsa, int padding,
2027 + struct pkc_cookie_s *cookie);
2028 + int (*rsa_mod_exp_async)(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
2029 + BN_CTX *ctx, struct pkc_cookie_s *cookie);
2030 + int (*bn_mod_exp_async)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
2031 + const BIGNUM *m, BN_CTX *ctx,
2032 + BN_MONT_CTX *m_ctx, struct pkc_cookie_s *cookie);
2034 int (*init)(RSA *rsa); /* called at new */
2035 int (*finish)(RSA *rsa); /* called at free */
2036 int flags; /* RSA_METHOD_FLAG_* things */