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