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