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