diff options
author | Ting Liu <ting.liu@nxp.com> | 2015-07-29 18:11:18 -0300 |
---|---|---|
committer | Zhenhua Luo <zhenhua.luo@nxp.com> | 2016-06-23 10:58:51 +0800 |
commit | 4cc0cf8255a3726fe3f6cbbe1a877fe2fab7edc6 (patch) | |
tree | ed1a4cf255057afd5556c1f60fd63b7f1b414f6a /recipes-connectivity/openssl/openssl-fsl/0008-Initial-support-for-PKC-in-cryptodev-engine.patch | |
parent | 41d1478e1294d06f0cce58fe847c0b0f1706b808 (diff) | |
download | meta-fsl-ppc-4cc0cf8255a3726fe3f6cbbe1a877fe2fab7edc6.tar.gz |
openssl: rename to openssl-qoriq
The QorIQ version of openssl needs to use another recipe name and have
a common provider, which is than choosen for QorIQ-based machines.
The recipe is now called 'openssl-qoriq' and it provides openssl so
the preferrence is set just for QorIQ based machines.
Signed-off-by: Ting Liu <ting.liu@nxp.com>
Diffstat (limited to 'recipes-connectivity/openssl/openssl-fsl/0008-Initial-support-for-PKC-in-cryptodev-engine.patch')
-rw-r--r-- | recipes-connectivity/openssl/openssl-fsl/0008-Initial-support-for-PKC-in-cryptodev-engine.patch | 1564 |
1 files changed, 0 insertions, 1564 deletions
diff --git a/recipes-connectivity/openssl/openssl-fsl/0008-Initial-support-for-PKC-in-cryptodev-engine.patch b/recipes-connectivity/openssl/openssl-fsl/0008-Initial-support-for-PKC-in-cryptodev-engine.patch deleted file mode 100644 index 98272ab..0000000 --- a/recipes-connectivity/openssl/openssl-fsl/0008-Initial-support-for-PKC-in-cryptodev-engine.patch +++ /dev/null | |||
@@ -1,1564 +0,0 @@ | |||
1 | From 107a10d45db0f2e58482f698add04ed9183f7268 Mon Sep 17 00:00:00 2001 | ||
2 | From: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
3 | Date: Tue, 11 Mar 2014 06:29:52 +0545 | ||
4 | Subject: [PATCH 08/26] Initial support for PKC in cryptodev engine | ||
5 | |||
6 | Upstream-status: Pending | ||
7 | |||
8 | Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
9 | --- | ||
10 | crypto/engine/eng_cryptodev.c | 1343 ++++++++++++++++++++++++++++++++++++----- | ||
11 | 1 file changed, 1183 insertions(+), 160 deletions(-) | ||
12 | |||
13 | diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c | ||
14 | index e3eb98b..7ee314b 100644 | ||
15 | --- a/crypto/engine/eng_cryptodev.c | ||
16 | +++ b/crypto/engine/eng_cryptodev.c | ||
17 | @@ -54,11 +54,14 @@ ENGINE_load_cryptodev(void) | ||
18 | #else | ||
19 | |||
20 | #include <sys/types.h> | ||
21 | -#include <crypto/cryptodev.h> | ||
22 | #include <crypto/dh/dh.h> | ||
23 | #include <crypto/dsa/dsa.h> | ||
24 | #include <crypto/err/err.h> | ||
25 | #include <crypto/rsa/rsa.h> | ||
26 | +#include <crypto/ecdsa/ecs_locl.h> | ||
27 | +#include <crypto/ecdh/ech_locl.h> | ||
28 | +#include <crypto/ec/ec_lcl.h> | ||
29 | +#include <crypto/ec/ec.h> | ||
30 | #include <sys/ioctl.h> | ||
31 | #include <errno.h> | ||
32 | #include <stdio.h> | ||
33 | @@ -68,6 +71,8 @@ ENGINE_load_cryptodev(void) | ||
34 | #include <syslog.h> | ||
35 | #include <errno.h> | ||
36 | #include <string.h> | ||
37 | +#include "eng_cryptodev_ec.h" | ||
38 | +#include <crypto/cryptodev.h> | ||
39 | |||
40 | struct dev_crypto_state { | ||
41 | struct session_op d_sess; | ||
42 | @@ -116,18 +121,10 @@ static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, | ||
43 | static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, | ||
44 | RSA *rsa, BN_CTX *ctx); | ||
45 | static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); | ||
46 | -static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, | ||
47 | - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
48 | -static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, | ||
49 | - BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, | ||
50 | - BN_CTX *ctx, BN_MONT_CTX *mont); | ||
51 | static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, | ||
52 | int dlen, DSA *dsa); | ||
53 | static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, | ||
54 | DSA_SIG *sig, DSA *dsa); | ||
55 | -static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, | ||
56 | - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, | ||
57 | - BN_MONT_CTX *m_ctx); | ||
58 | static int cryptodev_dh_compute_key(unsigned char *key, | ||
59 | const BIGNUM *pub_key, DH *dh); | ||
60 | static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, | ||
61 | @@ -136,6 +133,102 @@ void ENGINE_load_cryptodev(void); | ||
62 | const EVP_CIPHER cryptodev_aes_128_cbc_hmac_sha1; | ||
63 | const EVP_CIPHER cryptodev_aes_256_cbc_hmac_sha1; | ||
64 | |||
65 | +static int spcf_bn2bin(BIGNUM *bn, unsigned char **bin, int *bin_len) | ||
66 | +{ | ||
67 | + int len; | ||
68 | + unsigned char *p; | ||
69 | + | ||
70 | + len = BN_num_bytes(bn); | ||
71 | + | ||
72 | + if (!len) | ||
73 | + return -1; | ||
74 | + | ||
75 | + p = malloc(len); | ||
76 | + if (!p) | ||
77 | + return -1; | ||
78 | + | ||
79 | + BN_bn2bin(bn,p); | ||
80 | + | ||
81 | + *bin = p; | ||
82 | + *bin_len = len; | ||
83 | + | ||
84 | + return 0; | ||
85 | +} | ||
86 | + | ||
87 | +static int spcf_bn2bin_ex(BIGNUM *bn, unsigned char **bin, int *bin_len) | ||
88 | +{ | ||
89 | + int len; | ||
90 | + unsigned char *p; | ||
91 | + | ||
92 | + len = BN_num_bytes(bn); | ||
93 | + | ||
94 | + if (!len) | ||
95 | + return -1; | ||
96 | + | ||
97 | + if (len < *bin_len) | ||
98 | + p = malloc(*bin_len); | ||
99 | + else | ||
100 | + p = malloc(len); | ||
101 | + | ||
102 | + if (!p) | ||
103 | + return -ENOMEM; | ||
104 | + | ||
105 | + if (len < *bin_len) { | ||
106 | + /* place padding */ | ||
107 | + memset(p, 0, (*bin_len - len)); | ||
108 | + BN_bn2bin(bn,p+(*bin_len-len)); | ||
109 | + } else { | ||
110 | + BN_bn2bin(bn,p); | ||
111 | + } | ||
112 | + | ||
113 | + *bin = p; | ||
114 | + if (len >= *bin_len) | ||
115 | + *bin_len = len; | ||
116 | + | ||
117 | + return 0; | ||
118 | +} | ||
119 | + | ||
120 | +/** | ||
121 | + * Convert an ECC F2m 'b' parameter into the 'c' parameter. | ||
122 | + *Inputs: | ||
123 | + * q, the curve's modulus | ||
124 | + * b, the curve's b parameter | ||
125 | + * (a bignum for b, a buffer for c) | ||
126 | + * Output: | ||
127 | + * c, written into bin, right-adjusted to fill q_len bytes. | ||
128 | + */ | ||
129 | +static int | ||
130 | +eng_ec_compute_cparam(const BIGNUM* b, const BIGNUM* q, | ||
131 | + unsigned char **bin, int *bin_len) | ||
132 | +{ | ||
133 | + BIGNUM* c = BN_new(); | ||
134 | + BIGNUM* exp = BN_new(); | ||
135 | + BN_CTX *ctx = BN_CTX_new(); | ||
136 | + int m = BN_num_bits(q) - 1; | ||
137 | + int ok = 0; | ||
138 | + | ||
139 | + if (!c || !exp || !ctx || *bin) | ||
140 | + goto err; | ||
141 | + | ||
142 | + /* | ||
143 | + * We have to compute c, where b = c^4, i.e., the fourth root of b. | ||
144 | + * The equation for c is c = b^(2^(m-2)) | ||
145 | + * Compute exp = 2^(m-2) | ||
146 | + * (1 << x) == 2^x | ||
147 | + * and then compute c = b^exp | ||
148 | + */ | ||
149 | + BN_lshift(exp, BN_value_one(), m-2); | ||
150 | + BN_GF2m_mod_exp(c, b, exp, q, ctx); | ||
151 | + /* Store c */ | ||
152 | + spcf_bn2bin_ex(c, bin, bin_len); | ||
153 | + ok = 1; | ||
154 | +err: | ||
155 | + if (ctx) BN_CTX_free(ctx); | ||
156 | + if (c) BN_free(c); | ||
157 | + if (exp) BN_free(exp); | ||
158 | + return ok; | ||
159 | +} | ||
160 | + | ||
161 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { | ||
162 | { 0, NULL, NULL, 0 } | ||
163 | }; | ||
164 | @@ -1139,7 +1232,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | ||
165 | static int | ||
166 | bn2crparam(const BIGNUM *a, struct crparam *crp) | ||
167 | { | ||
168 | - int i, j, k; | ||
169 | ssize_t bytes, bits; | ||
170 | u_char *b; | ||
171 | |||
172 | @@ -1156,15 +1248,7 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) | ||
173 | |||
174 | crp->crp_p = (caddr_t) b; | ||
175 | crp->crp_nbits = bits; | ||
176 | - | ||
177 | - for (i = 0, j = 0; i < a->top; i++) { | ||
178 | - for (k = 0; k < BN_BITS2 / 8; k++) { | ||
179 | - if ((j + k) >= bytes) | ||
180 | - return (0); | ||
181 | - b[j + k] = a->d[i] >> (k * 8); | ||
182 | - } | ||
183 | - j += BN_BITS2 / 8; | ||
184 | - } | ||
185 | + BN_bn2bin(a, crp->crp_p); | ||
186 | return (0); | ||
187 | } | ||
188 | |||
189 | @@ -1172,22 +1256,14 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) | ||
190 | static int | ||
191 | crparam2bn(struct crparam *crp, BIGNUM *a) | ||
192 | { | ||
193 | - u_int8_t *pd; | ||
194 | - int i, bytes; | ||
195 | + int bytes; | ||
196 | |||
197 | bytes = (crp->crp_nbits + 7) / 8; | ||
198 | |||
199 | if (bytes == 0) | ||
200 | return (-1); | ||
201 | |||
202 | - if ((pd = (u_int8_t *) malloc(bytes)) == NULL) | ||
203 | - return (-1); | ||
204 | - | ||
205 | - for (i = 0; i < bytes; i++) | ||
206 | - pd[i] = crp->crp_p[bytes - i - 1]; | ||
207 | - | ||
208 | - BN_bin2bn(pd, bytes, a); | ||
209 | - free(pd); | ||
210 | + BN_bin2bn(crp->crp_p, bytes, a); | ||
211 | |||
212 | return (0); | ||
213 | } | ||
214 | @@ -1235,6 +1311,32 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) | ||
215 | return (ret); | ||
216 | } | ||
217 | |||
218 | +/* Close an opened instance of cryptodev engine */ | ||
219 | +void cryptodev_close_instance(void *handle) | ||
220 | +{ | ||
221 | + int fd; | ||
222 | + | ||
223 | + if (handle) { | ||
224 | + fd = *(int *)handle; | ||
225 | + close(fd); | ||
226 | + free(handle); | ||
227 | + } | ||
228 | +} | ||
229 | + | ||
230 | +/* Create an instance of cryptodev for asynchronous interface */ | ||
231 | +void *cryptodev_init_instance(void) | ||
232 | +{ | ||
233 | + int *fd = malloc(sizeof(int)); | ||
234 | + | ||
235 | + if (fd) { | ||
236 | + if ((*fd = open("/dev/crypto", O_RDWR, 0)) == -1) { | ||
237 | + free(fd); | ||
238 | + return NULL; | ||
239 | + } | ||
240 | + } | ||
241 | + return fd; | ||
242 | +} | ||
243 | + | ||
244 | static int | ||
245 | cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | ||
246 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) | ||
247 | @@ -1250,9 +1352,9 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | ||
248 | return (ret); | ||
249 | } | ||
250 | |||
251 | - memset(&kop, 0, sizeof kop); | ||
252 | kop.crk_op = CRK_MOD_EXP; | ||
253 | - | ||
254 | + kop.crk_oparams = 0; | ||
255 | + kop.crk_status = 0; | ||
256 | /* inputs: a^p % m */ | ||
257 | if (bn2crparam(a, &kop.crk_param[0])) | ||
258 | goto err; | ||
259 | @@ -1293,28 +1395,38 @@ static int | ||
260 | cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) | ||
261 | { | ||
262 | struct crypt_kop kop; | ||
263 | - int ret = 1; | ||
264 | + int ret = 1, f_len, p_len, q_len; | ||
265 | + unsigned char *f = NULL, *p = NULL, *q = NULL, *dp = NULL, *dq = NULL, *c = NULL; | ||
266 | |||
267 | if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { | ||
268 | /* XXX 0 means failure?? */ | ||
269 | return (0); | ||
270 | } | ||
271 | |||
272 | - memset(&kop, 0, sizeof kop); | ||
273 | + kop.crk_oparams = 0; | ||
274 | + kop.crk_status = 0; | ||
275 | kop.crk_op = CRK_MOD_EXP_CRT; | ||
276 | + f_len = BN_num_bytes(rsa->n); | ||
277 | + spcf_bn2bin_ex(I, &f, &f_len); | ||
278 | + spcf_bn2bin(rsa->p, &p, &p_len); | ||
279 | + spcf_bn2bin(rsa->q, &q, &q_len); | ||
280 | + spcf_bn2bin_ex(rsa->dmp1, &dp, &p_len); | ||
281 | + spcf_bn2bin_ex(rsa->iqmp, &c, &p_len); | ||
282 | + spcf_bn2bin_ex(rsa->dmq1, &dq, &q_len); | ||
283 | /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ | ||
284 | - if (bn2crparam(rsa->p, &kop.crk_param[0])) | ||
285 | - goto err; | ||
286 | - if (bn2crparam(rsa->q, &kop.crk_param[1])) | ||
287 | - goto err; | ||
288 | - if (bn2crparam(I, &kop.crk_param[2])) | ||
289 | - goto err; | ||
290 | - if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) | ||
291 | - goto err; | ||
292 | - if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) | ||
293 | - goto err; | ||
294 | - if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) | ||
295 | - goto err; | ||
296 | + kop.crk_param[0].crp_p = p; | ||
297 | + kop.crk_param[0].crp_nbits = p_len * 8; | ||
298 | + kop.crk_param[1].crp_p = q; | ||
299 | + kop.crk_param[1].crp_nbits = q_len * 8; | ||
300 | + kop.crk_param[2].crp_p = f; | ||
301 | + kop.crk_param[2].crp_nbits = f_len * 8; | ||
302 | + kop.crk_param[3].crp_p = dp; | ||
303 | + kop.crk_param[3].crp_nbits = p_len * 8; | ||
304 | + /* dq must of length q, rest all of length p*/ | ||
305 | + kop.crk_param[4].crp_p = dq; | ||
306 | + kop.crk_param[4].crp_nbits = q_len * 8; | ||
307 | + kop.crk_param[5].crp_p = c; | ||
308 | + kop.crk_param[5].crp_nbits = p_len * 8; | ||
309 | kop.crk_iparams = 6; | ||
310 | |||
311 | if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { | ||
312 | @@ -1350,90 +1462,117 @@ static RSA_METHOD cryptodev_rsa = { | ||
313 | NULL /* rsa_verify */ | ||
314 | }; | ||
315 | |||
316 | -static int | ||
317 | -cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
318 | - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) | ||
319 | -{ | ||
320 | - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); | ||
321 | -} | ||
322 | - | ||
323 | -static int | ||
324 | -cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, | ||
325 | - BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, | ||
326 | - BN_CTX *ctx, BN_MONT_CTX *mont) | ||
327 | +static DSA_SIG * | ||
328 | +cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | ||
329 | { | ||
330 | - BIGNUM t2; | ||
331 | - int ret = 0; | ||
332 | - | ||
333 | - BN_init(&t2); | ||
334 | - | ||
335 | - /* v = ( g^u1 * y^u2 mod p ) mod q */ | ||
336 | - /* let t1 = g ^ u1 mod p */ | ||
337 | - ret = 0; | ||
338 | + struct crypt_kop kop; | ||
339 | + BIGNUM *c = NULL, *d = NULL; | ||
340 | + DSA_SIG *dsaret = NULL; | ||
341 | + int q_len = 0, r_len = 0, g_len = 0; | ||
342 | + int priv_key_len = 0, ret; | ||
343 | + unsigned char *q = NULL, *r = NULL, *g = NULL, *priv_key = NULL, *f = NULL; | ||
344 | |||
345 | - if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont)) | ||
346 | + memset(&kop, 0, sizeof kop); | ||
347 | + if ((c = BN_new()) == NULL) { | ||
348 | + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
349 | goto err; | ||
350 | + } | ||
351 | |||
352 | - /* let t2 = y ^ u2 mod p */ | ||
353 | - if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont)) | ||
354 | + if ((d = BN_new()) == NULL) { | ||
355 | + BN_free(c); | ||
356 | + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
357 | goto err; | ||
358 | - /* let u1 = t1 * t2 mod p */ | ||
359 | - if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx)) | ||
360 | + } | ||
361 | + | ||
362 | + if (spcf_bn2bin(dsa->p, &q, &q_len)) { | ||
363 | + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); | ||
364 | goto err; | ||
365 | + } | ||
366 | |||
367 | - BN_copy(t1,u1); | ||
368 | + /* Get order of the field of private keys into plain buffer */ | ||
369 | + if (spcf_bn2bin (dsa->q, &r, &r_len)) { | ||
370 | + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
371 | + goto err; | ||
372 | + } | ||
373 | |||
374 | - ret = 1; | ||
375 | -err: | ||
376 | - BN_free(&t2); | ||
377 | - return(ret); | ||
378 | -} | ||
379 | + /* sanity test */ | ||
380 | + if (dlen > r_len) { | ||
381 | + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); | ||
382 | + goto err; | ||
383 | + } | ||
384 | |||
385 | -static DSA_SIG * | ||
386 | -cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | ||
387 | -{ | ||
388 | - struct crypt_kop kop; | ||
389 | - BIGNUM *r = NULL, *s = NULL; | ||
390 | - DSA_SIG *dsaret = NULL; | ||
391 | + g_len = q_len; | ||
392 | + /** | ||
393 | + * Get generator into a plain buffer. If length is less than | ||
394 | + * q_len then add leading padding bytes. | ||
395 | + */ | ||
396 | + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) { | ||
397 | + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
398 | + goto err; | ||
399 | + } | ||
400 | |||
401 | - if ((r = BN_new()) == NULL) | ||
402 | + priv_key_len = r_len; | ||
403 | + /** | ||
404 | + * Get private key into a plain buffer. If length is less than | ||
405 | + * r_len then add leading padding bytes. | ||
406 | + */ | ||
407 | + if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) { | ||
408 | + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
409 | goto err; | ||
410 | - if ((s = BN_new()) == NULL) { | ||
411 | - BN_free(r); | ||
412 | + } | ||
413 | + | ||
414 | + /* Allocate memory to store hash. */ | ||
415 | + f = OPENSSL_malloc (r_len); | ||
416 | + if (!f) { | ||
417 | + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
418 | goto err; | ||
419 | } | ||
420 | |||
421 | - memset(&kop, 0, sizeof kop); | ||
422 | + /* Add padding, since SEC expects hash to of size r_len */ | ||
423 | + if (dlen < r_len) | ||
424 | + memset(f, 0, r_len - dlen); | ||
425 | + | ||
426 | + /* Skip leading bytes if dgst_len < r_len */ | ||
427 | + memcpy(f + r_len - dlen, dgst, dlen); | ||
428 | + | ||
429 | kop.crk_op = CRK_DSA_SIGN; | ||
430 | |||
431 | /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ | ||
432 | - kop.crk_param[0].crp_p = (caddr_t)dgst; | ||
433 | - kop.crk_param[0].crp_nbits = dlen * 8; | ||
434 | - if (bn2crparam(dsa->p, &kop.crk_param[1])) | ||
435 | - goto err; | ||
436 | - if (bn2crparam(dsa->q, &kop.crk_param[2])) | ||
437 | - goto err; | ||
438 | - if (bn2crparam(dsa->g, &kop.crk_param[3])) | ||
439 | - goto err; | ||
440 | - if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) | ||
441 | - goto err; | ||
442 | + kop.crk_param[0].crp_p = (void*)f; | ||
443 | + kop.crk_param[0].crp_nbits = r_len * 8; | ||
444 | + kop.crk_param[1].crp_p = (void*)q; | ||
445 | + kop.crk_param[1].crp_nbits = q_len * 8; | ||
446 | + kop.crk_param[2].crp_p = (void*)r; | ||
447 | + kop.crk_param[2].crp_nbits = r_len * 8; | ||
448 | + kop.crk_param[3].crp_p = (void*)g; | ||
449 | + kop.crk_param[3].crp_nbits = g_len * 8; | ||
450 | + kop.crk_param[4].crp_p = (void*)priv_key; | ||
451 | + kop.crk_param[4].crp_nbits = priv_key_len * 8; | ||
452 | kop.crk_iparams = 5; | ||
453 | |||
454 | - if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, | ||
455 | - BN_num_bytes(dsa->q), s) == 0) { | ||
456 | - dsaret = DSA_SIG_new(); | ||
457 | - dsaret->r = r; | ||
458 | - dsaret->s = s; | ||
459 | - } else { | ||
460 | - const DSA_METHOD *meth = DSA_OpenSSL(); | ||
461 | - BN_free(r); | ||
462 | - BN_free(s); | ||
463 | - dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); | ||
464 | + ret = cryptodev_asym(&kop, r_len, c, r_len, d); | ||
465 | + | ||
466 | + if (ret) { | ||
467 | + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DECODE_ERROR); | ||
468 | + goto err; | ||
469 | } | ||
470 | -err: | ||
471 | - kop.crk_param[0].crp_p = NULL; | ||
472 | + | ||
473 | + dsaret = DSA_SIG_new(); | ||
474 | + dsaret->r = c; | ||
475 | + dsaret->s = d; | ||
476 | + | ||
477 | zapparams(&kop); | ||
478 | return (dsaret); | ||
479 | +err: | ||
480 | + { | ||
481 | + const DSA_METHOD *meth = DSA_OpenSSL(); | ||
482 | + if (c) | ||
483 | + BN_free(c); | ||
484 | + if (d) | ||
485 | + BN_free(d); | ||
486 | + dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); | ||
487 | + return (dsaret); | ||
488 | + } | ||
489 | } | ||
490 | |||
491 | static int | ||
492 | @@ -1441,42 +1580,179 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, | ||
493 | DSA_SIG *sig, DSA *dsa) | ||
494 | { | ||
495 | struct crypt_kop kop; | ||
496 | - int dsaret = 1; | ||
497 | + int dsaret = 1, q_len = 0, r_len = 0, g_len = 0; | ||
498 | + int w_len = 0 ,c_len = 0, d_len = 0, ret = -1; | ||
499 | + unsigned char * q = NULL, * r = NULL, * w = NULL, * g = NULL; | ||
500 | + unsigned char * c = NULL, * d = NULL, *f = NULL; | ||
501 | |||
502 | memset(&kop, 0, sizeof kop); | ||
503 | kop.crk_op = CRK_DSA_VERIFY; | ||
504 | |||
505 | - /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ | ||
506 | - kop.crk_param[0].crp_p = (caddr_t)dgst; | ||
507 | - kop.crk_param[0].crp_nbits = dlen * 8; | ||
508 | - if (bn2crparam(dsa->p, &kop.crk_param[1])) | ||
509 | + if (spcf_bn2bin(dsa->p, &q, &q_len)) { | ||
510 | + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
511 | + return ret; | ||
512 | + } | ||
513 | + | ||
514 | + /* Get Order of field of private keys */ | ||
515 | + if (spcf_bn2bin(dsa->q, &r, &r_len)) { | ||
516 | + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
517 | goto err; | ||
518 | - if (bn2crparam(dsa->q, &kop.crk_param[2])) | ||
519 | + } | ||
520 | + | ||
521 | + g_len = q_len; | ||
522 | + /** | ||
523 | + * Get generator into a plain buffer. If length is less than | ||
524 | + * q_len then add leading padding bytes. | ||
525 | + */ | ||
526 | + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) { | ||
527 | + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
528 | goto err; | ||
529 | - if (bn2crparam(dsa->g, &kop.crk_param[3])) | ||
530 | + } | ||
531 | + w_len = q_len; | ||
532 | + /** | ||
533 | + * Get public key into a plain buffer. If length is less than | ||
534 | + * q_len then add leading padding bytes. | ||
535 | + */ | ||
536 | + if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) { | ||
537 | + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
538 | + goto err; | ||
539 | + } | ||
540 | + /** | ||
541 | + * Get the 1st part of signature into a flat buffer with | ||
542 | + * appropriate padding | ||
543 | + */ | ||
544 | + c_len = r_len; | ||
545 | + | ||
546 | + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) { | ||
547 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
548 | goto err; | ||
549 | - if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) | ||
550 | + } | ||
551 | + | ||
552 | + /** | ||
553 | + * Get the 2nd part of signature into a flat buffer with | ||
554 | + * appropriate padding | ||
555 | + */ | ||
556 | + d_len = r_len; | ||
557 | + | ||
558 | + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) { | ||
559 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
560 | goto err; | ||
561 | - if (bn2crparam(sig->r, &kop.crk_param[5])) | ||
562 | + } | ||
563 | + | ||
564 | + | ||
565 | + /* Sanity test */ | ||
566 | + if (dlen > r_len) { | ||
567 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
568 | goto err; | ||
569 | - if (bn2crparam(sig->s, &kop.crk_param[6])) | ||
570 | + } | ||
571 | + | ||
572 | + /* Allocate memory to store hash. */ | ||
573 | + f = OPENSSL_malloc (r_len); | ||
574 | + if (!f) { | ||
575 | + DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
576 | goto err; | ||
577 | + } | ||
578 | + | ||
579 | + /* Add padding, since SEC expects hash to of size r_len */ | ||
580 | + if (dlen < r_len) | ||
581 | + memset(f, 0, r_len - dlen); | ||
582 | + | ||
583 | + /* Skip leading bytes if dgst_len < r_len */ | ||
584 | + memcpy(f + r_len - dlen, dgst, dlen); | ||
585 | + | ||
586 | + /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ | ||
587 | + kop.crk_param[0].crp_p = (void*)f; | ||
588 | + kop.crk_param[0].crp_nbits = r_len * 8; | ||
589 | + kop.crk_param[1].crp_p = q; | ||
590 | + kop.crk_param[1].crp_nbits = q_len * 8; | ||
591 | + kop.crk_param[2].crp_p = r; | ||
592 | + kop.crk_param[2].crp_nbits = r_len * 8; | ||
593 | + kop.crk_param[3].crp_p = g; | ||
594 | + kop.crk_param[3].crp_nbits = g_len * 8; | ||
595 | + kop.crk_param[4].crp_p = w; | ||
596 | + kop.crk_param[4].crp_nbits = w_len * 8; | ||
597 | + kop.crk_param[5].crp_p = c; | ||
598 | + kop.crk_param[5].crp_nbits = c_len * 8; | ||
599 | + kop.crk_param[6].crp_p = d; | ||
600 | + kop.crk_param[6].crp_nbits = d_len * 8; | ||
601 | kop.crk_iparams = 7; | ||
602 | |||
603 | - if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { | ||
604 | -/*OCF success value is 0, if not zero, change dsaret to fail*/ | ||
605 | - if(0 != kop.crk_status) dsaret = 0; | ||
606 | - } else { | ||
607 | - const DSA_METHOD *meth = DSA_OpenSSL(); | ||
608 | + if ((cryptodev_asym(&kop, 0, NULL, 0, NULL))) { | ||
609 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR); | ||
610 | + goto err; | ||
611 | + } | ||
612 | |||
613 | - dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa); | ||
614 | + /*OCF success value is 0, if not zero, change dsaret to fail*/ | ||
615 | + if(0 != kop.crk_status) { | ||
616 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR); | ||
617 | + goto err; | ||
618 | } | ||
619 | -err: | ||
620 | - kop.crk_param[0].crp_p = NULL; | ||
621 | + | ||
622 | zapparams(&kop); | ||
623 | return (dsaret); | ||
624 | +err: | ||
625 | + { | ||
626 | + const DSA_METHOD *meth = DSA_OpenSSL(); | ||
627 | + | ||
628 | + dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa); | ||
629 | + } | ||
630 | + return dsaret; | ||
631 | } | ||
632 | |||
633 | +/* Cryptodev DSA Key Gen routine */ | ||
634 | +static int cryptodev_dsa_keygen(DSA *dsa) | ||
635 | +{ | ||
636 | + struct crypt_kop kop; | ||
637 | + int ret = 1, g_len; | ||
638 | + unsigned char *g = NULL; | ||
639 | + | ||
640 | + if (dsa->priv_key == NULL) { | ||
641 | + if ((dsa->priv_key=BN_new()) == NULL) | ||
642 | + goto sw_try; | ||
643 | + } | ||
644 | + | ||
645 | + if (dsa->pub_key == NULL) { | ||
646 | + if ((dsa->pub_key=BN_new()) == NULL) | ||
647 | + goto sw_try; | ||
648 | + } | ||
649 | + | ||
650 | + g_len = BN_num_bytes(dsa->p); | ||
651 | + /** | ||
652 | + * Get generator into a plain buffer. If length is less than | ||
653 | + * p_len then add leading padding bytes. | ||
654 | + */ | ||
655 | + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) { | ||
656 | + DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE); | ||
657 | + goto sw_try; | ||
658 | + } | ||
659 | + | ||
660 | + memset(&kop, 0, sizeof kop); | ||
661 | + | ||
662 | + kop.crk_op = CRK_DSA_GENERATE_KEY; | ||
663 | + if (bn2crparam(dsa->p, &kop.crk_param[0])) | ||
664 | + goto sw_try; | ||
665 | + if (bn2crparam(dsa->q, &kop.crk_param[1])) | ||
666 | + goto sw_try; | ||
667 | + kop.crk_param[2].crp_p = g; | ||
668 | + kop.crk_param[2].crp_nbits = g_len * 8; | ||
669 | + kop.crk_iparams = 3; | ||
670 | + | ||
671 | + /* pub_key is or prime length while priv key is of length of order */ | ||
672 | + if (cryptodev_asym(&kop, BN_num_bytes(dsa->p), dsa->pub_key, | ||
673 | + BN_num_bytes(dsa->q), dsa->priv_key)) | ||
674 | + goto sw_try; | ||
675 | + | ||
676 | + return ret; | ||
677 | +sw_try: | ||
678 | + { | ||
679 | + const DSA_METHOD *meth = DSA_OpenSSL(); | ||
680 | + ret = (meth->dsa_keygen)(dsa); | ||
681 | + } | ||
682 | + return ret; | ||
683 | +} | ||
684 | + | ||
685 | + | ||
686 | + | ||
687 | static DSA_METHOD cryptodev_dsa = { | ||
688 | "cryptodev DSA method", | ||
689 | NULL, | ||
690 | @@ -1490,12 +1766,543 @@ static DSA_METHOD cryptodev_dsa = { | ||
691 | NULL /* app_data */ | ||
692 | }; | ||
693 | |||
694 | -static int | ||
695 | -cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, | ||
696 | - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, | ||
697 | - BN_MONT_CTX *m_ctx) | ||
698 | +static ECDSA_METHOD cryptodev_ecdsa = { | ||
699 | + "cryptodev ECDSA method", | ||
700 | + NULL, | ||
701 | + NULL, /* ecdsa_sign_setup */ | ||
702 | + NULL, | ||
703 | + NULL, | ||
704 | + 0, /* flags */ | ||
705 | + NULL /* app_data */ | ||
706 | +}; | ||
707 | + | ||
708 | +typedef enum ec_curve_s | ||
709 | +{ | ||
710 | + EC_PRIME, | ||
711 | + EC_BINARY | ||
712 | +} ec_curve_t; | ||
713 | + | ||
714 | +/* ENGINE handler for ECDSA Sign */ | ||
715 | +static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char *dgst, | ||
716 | + int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) | ||
717 | { | ||
718 | - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); | ||
719 | + BIGNUM *m = NULL, *p = NULL, *a = NULL; | ||
720 | + BIGNUM *b = NULL, *x = NULL, *y = NULL; | ||
721 | + BN_CTX *ctx = NULL; | ||
722 | + ECDSA_SIG *ret = NULL; | ||
723 | + ECDSA_DATA *ecdsa = NULL; | ||
724 | + unsigned char * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL; | ||
725 | + unsigned char * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL; | ||
726 | + int i = 0, q_len = 0, priv_key_len = 0, r_len = 0; | ||
727 | + int g_len = 0, d_len = 0, ab_len = 0; | ||
728 | + const BIGNUM *order = NULL, *priv_key=NULL; | ||
729 | + const EC_GROUP *group = NULL; | ||
730 | + struct crypt_kop kop; | ||
731 | + ec_curve_t ec_crv = EC_PRIME; | ||
732 | + | ||
733 | + memset(&kop, 0, sizeof(kop)); | ||
734 | + ecdsa = ecdsa_check(eckey); | ||
735 | + if (!ecdsa) { | ||
736 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); | ||
737 | + return NULL; | ||
738 | + } | ||
739 | + | ||
740 | + group = EC_KEY_get0_group(eckey); | ||
741 | + priv_key = EC_KEY_get0_private_key(eckey); | ||
742 | + | ||
743 | + if (!group || !priv_key) { | ||
744 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); | ||
745 | + return NULL; | ||
746 | + } | ||
747 | + | ||
748 | + if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL || | ||
749 | + (a = BN_new()) == NULL || (b = BN_new()) == NULL || | ||
750 | + (p = BN_new()) == NULL || (x = BN_new()) == NULL || | ||
751 | + (y = BN_new()) == NULL) { | ||
752 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
753 | + goto err; | ||
754 | + } | ||
755 | + | ||
756 | + order = &group->order; | ||
757 | + if (!order || BN_is_zero(order)) { | ||
758 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS); | ||
759 | + goto err; | ||
760 | + } | ||
761 | + | ||
762 | + i = BN_num_bits(order); | ||
763 | + /* Need to truncate digest if it is too long: first truncate whole | ||
764 | + bytes */ | ||
765 | + if (8 * dgst_len > i) | ||
766 | + dgst_len = (i + 7)/8; | ||
767 | + | ||
768 | + if (!BN_bin2bn(dgst, dgst_len, m)) { | ||
769 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); | ||
770 | + goto err; | ||
771 | + } | ||
772 | + | ||
773 | + /* If still too long truncate remaining bits with a shift */ | ||
774 | + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { | ||
775 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); | ||
776 | + goto err; | ||
777 | + } | ||
778 | + | ||
779 | + /* copy the truncated bits into plain buffer */ | ||
780 | + if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) { | ||
781 | + fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__); | ||
782 | + goto err; | ||
783 | + } | ||
784 | + | ||
785 | + ret = ECDSA_SIG_new(); | ||
786 | + if (!ret) { | ||
787 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); | ||
788 | + goto err; | ||
789 | + } | ||
790 | + | ||
791 | + /* check if this is prime or binary EC request */ | ||
792 | + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { | ||
793 | + ec_crv = EC_PRIME; | ||
794 | + /* get the generator point pair */ | ||
795 | + if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group), | ||
796 | + x, y,ctx)) { | ||
797 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); | ||
798 | + goto err; | ||
799 | + } | ||
800 | + | ||
801 | + /* get the ECC curve parameters */ | ||
802 | + if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) { | ||
803 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); | ||
804 | + goto err; | ||
805 | + } | ||
806 | + } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) { | ||
807 | + ec_crv = EC_BINARY; | ||
808 | + /* get the ECC curve parameters */ | ||
809 | + if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) { | ||
810 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); | ||
811 | + goto err; | ||
812 | + } | ||
813 | + | ||
814 | + /* get the generator point pair */ | ||
815 | + if (!EC_POINT_get_affine_coordinates_GF2m(group, | ||
816 | + EC_GROUP_get0_generator(group), x, y,ctx)) { | ||
817 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); | ||
818 | + goto err; | ||
819 | + } | ||
820 | + } else { | ||
821 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); | ||
822 | + goto err; | ||
823 | + } | ||
824 | + | ||
825 | + if (spcf_bn2bin(order, &r, &r_len)) { | ||
826 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
827 | + goto err; | ||
828 | + } | ||
829 | + | ||
830 | + if (spcf_bn2bin(p, &q, &q_len)) { | ||
831 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
832 | + goto err; | ||
833 | + } | ||
834 | + | ||
835 | + priv_key_len = r_len; | ||
836 | + | ||
837 | + /** | ||
838 | + * If BN_num_bytes of priv_key returns less then r_len then | ||
839 | + * add padding bytes before the key | ||
840 | + */ | ||
841 | + if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len)) { | ||
842 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
843 | + goto err; | ||
844 | + } | ||
845 | + | ||
846 | + /* Generation of ECC curve parameters */ | ||
847 | + ab_len = 2*q_len; | ||
848 | + ab = eng_copy_curve_points(a, b, ab_len, q_len); | ||
849 | + if (!ab) { | ||
850 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
851 | + goto err; | ||
852 | + } | ||
853 | + | ||
854 | + if (ec_crv == EC_BINARY) { | ||
855 | + if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len)) | ||
856 | + { | ||
857 | + unsigned char *c_temp = NULL; | ||
858 | + int c_temp_len = q_len; | ||
859 | + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len)) | ||
860 | + memcpy(ab+q_len, c_temp, q_len); | ||
861 | + else | ||
862 | + goto err; | ||
863 | + } | ||
864 | + kop.curve_type = ECC_BINARY; | ||
865 | + } | ||
866 | + | ||
867 | + /* Calculation of Generator point */ | ||
868 | + g_len = 2*q_len; | ||
869 | + g_xy = eng_copy_curve_points(x, y, g_len, q_len); | ||
870 | + if (!g_xy) { | ||
871 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
872 | + goto err; | ||
873 | + } | ||
874 | + | ||
875 | + /* Memory allocation for first part of digital signature */ | ||
876 | + c = malloc(r_len); | ||
877 | + if (!c) { | ||
878 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
879 | + goto err; | ||
880 | + } | ||
881 | + | ||
882 | + d_len = r_len; | ||
883 | + | ||
884 | + /* Memory allocation for second part of digital signature */ | ||
885 | + d = malloc(d_len); | ||
886 | + if (!d) { | ||
887 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
888 | + goto err; | ||
889 | + } | ||
890 | + | ||
891 | + /* memory for message representative */ | ||
892 | + f = malloc(r_len); | ||
893 | + if (!f) { | ||
894 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
895 | + goto err; | ||
896 | + } | ||
897 | + | ||
898 | + /* Add padding, since SEC expects hash to of size r_len */ | ||
899 | + memset(f, 0, r_len - dgst_len); | ||
900 | + | ||
901 | + /* Skip leading bytes if dgst_len < r_len */ | ||
902 | + memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len); | ||
903 | + | ||
904 | + dgst_len += r_len - dgst_len; | ||
905 | + kop.crk_op = CRK_DSA_SIGN; | ||
906 | + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ | ||
907 | + kop.crk_param[0].crp_p = f; | ||
908 | + kop.crk_param[0].crp_nbits = dgst_len * 8; | ||
909 | + kop.crk_param[1].crp_p = q; | ||
910 | + kop.crk_param[1].crp_nbits = q_len * 8; | ||
911 | + kop.crk_param[2].crp_p = r; | ||
912 | + kop.crk_param[2].crp_nbits = r_len * 8; | ||
913 | + kop.crk_param[3].crp_p = g_xy; | ||
914 | + kop.crk_param[3].crp_nbits = g_len * 8; | ||
915 | + kop.crk_param[4].crp_p = s; | ||
916 | + kop.crk_param[4].crp_nbits = priv_key_len * 8; | ||
917 | + kop.crk_param[5].crp_p = ab; | ||
918 | + kop.crk_param[5].crp_nbits = ab_len * 8; | ||
919 | + kop.crk_iparams = 6; | ||
920 | + kop.crk_param[6].crp_p = c; | ||
921 | + kop.crk_param[6].crp_nbits = d_len * 8; | ||
922 | + kop.crk_param[7].crp_p = d; | ||
923 | + kop.crk_param[7].crp_nbits = d_len * 8; | ||
924 | + kop.crk_oparams = 2; | ||
925 | + | ||
926 | + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { | ||
927 | + /* Check if ret->r and s needs to allocated */ | ||
928 | + crparam2bn(&kop.crk_param[6], ret->r); | ||
929 | + crparam2bn(&kop.crk_param[7], ret->s); | ||
930 | + } else { | ||
931 | + const ECDSA_METHOD *meth = ECDSA_OpenSSL(); | ||
932 | + ret = (meth->ecdsa_do_sign)(dgst, dgst_len, in_kinv, in_r, eckey); | ||
933 | + } | ||
934 | + kop.crk_param[0].crp_p = NULL; | ||
935 | + zapparams(&kop); | ||
936 | +err: | ||
937 | + if (!ret) { | ||
938 | + ECDSA_SIG_free(ret); | ||
939 | + ret = NULL; | ||
940 | + } | ||
941 | + return ret; | ||
942 | +} | ||
943 | + | ||
944 | +static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len, | ||
945 | + ECDSA_SIG *sig, EC_KEY *eckey) | ||
946 | +{ | ||
947 | + BIGNUM *m = NULL, *p = NULL, *a = NULL, *b = NULL; | ||
948 | + BIGNUM *x = NULL, *y = NULL, *w_x = NULL, *w_y = NULL; | ||
949 | + BN_CTX *ctx = NULL; | ||
950 | + ECDSA_DATA *ecdsa = NULL; | ||
951 | + unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL, *w_xy = NULL; | ||
952 | + unsigned char *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL; | ||
953 | + int i = 0, q_len = 0, pub_key_len = 0, r_len = 0, c_len = 0, g_len = 0; | ||
954 | + int d_len = 0, ab_len = 0, ret = -1; | ||
955 | + const EC_POINT *pub_key = NULL; | ||
956 | + const BIGNUM *order = NULL; | ||
957 | + const EC_GROUP *group=NULL; | ||
958 | + ec_curve_t ec_crv = EC_PRIME; | ||
959 | + struct crypt_kop kop; | ||
960 | + | ||
961 | + memset(&kop, 0, sizeof kop); | ||
962 | + ecdsa = ecdsa_check(eckey); | ||
963 | + if (!ecdsa) { | ||
964 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER); | ||
965 | + return ret; | ||
966 | + } | ||
967 | + | ||
968 | + group = EC_KEY_get0_group(eckey); | ||
969 | + pub_key = EC_KEY_get0_public_key(eckey); | ||
970 | + | ||
971 | + if (!group || !pub_key) { | ||
972 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER); | ||
973 | + return ret; | ||
974 | + } | ||
975 | + | ||
976 | + if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL || | ||
977 | + (a = BN_new()) == NULL || (b = BN_new()) == NULL || | ||
978 | + (p = BN_new()) == NULL || (x = BN_new()) == NULL || | ||
979 | + (y = BN_new()) == NULL || (w_x = BN_new()) == NULL || | ||
980 | + (w_y = BN_new()) == NULL) { | ||
981 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
982 | + goto err; | ||
983 | + } | ||
984 | + | ||
985 | + order = &group->order; | ||
986 | + if (!order || BN_is_zero(order)) { | ||
987 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); | ||
988 | + goto err; | ||
989 | + } | ||
990 | + | ||
991 | + i = BN_num_bits(order); | ||
992 | + /* Need to truncate digest if it is too long: first truncate whole | ||
993 | + * bytes */ | ||
994 | + if (8 * dgst_len > i) | ||
995 | + dgst_len = (i + 7)/8; | ||
996 | + | ||
997 | + if (!BN_bin2bn(dgst, dgst_len, m)) { | ||
998 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | ||
999 | + goto err; | ||
1000 | + } | ||
1001 | + | ||
1002 | + /* If still too long truncate remaining bits with a shift */ | ||
1003 | + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { | ||
1004 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | ||
1005 | + goto err; | ||
1006 | + } | ||
1007 | + /* copy the truncated bits into plain buffer */ | ||
1008 | + if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) { | ||
1009 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
1010 | + goto err; | ||
1011 | + } | ||
1012 | + | ||
1013 | + /* check if this is prime or binary EC request */ | ||
1014 | + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { | ||
1015 | + ec_crv = EC_PRIME; | ||
1016 | + | ||
1017 | + /* get the generator point pair */ | ||
1018 | + if (!EC_POINT_get_affine_coordinates_GFp (group, | ||
1019 | + EC_GROUP_get0_generator(group), x, y,ctx)) { | ||
1020 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
1021 | + goto err; | ||
1022 | + } | ||
1023 | + | ||
1024 | + /* get the public key pair for prime curve */ | ||
1025 | + if (!EC_POINT_get_affine_coordinates_GFp (group, | ||
1026 | + pub_key, w_x, w_y,ctx)) { | ||
1027 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
1028 | + goto err; | ||
1029 | + } | ||
1030 | + | ||
1031 | + /* get the ECC curve parameters */ | ||
1032 | + if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) { | ||
1033 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
1034 | + goto err; | ||
1035 | + } | ||
1036 | + } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field){ | ||
1037 | + ec_crv = EC_BINARY; | ||
1038 | + /* get the ECC curve parameters */ | ||
1039 | + if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) { | ||
1040 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
1041 | + goto err; | ||
1042 | + } | ||
1043 | + | ||
1044 | + /* get the generator point pair */ | ||
1045 | + if (!EC_POINT_get_affine_coordinates_GF2m(group, | ||
1046 | + EC_GROUP_get0_generator(group),x, y,ctx)) { | ||
1047 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
1048 | + goto err; | ||
1049 | + } | ||
1050 | + | ||
1051 | + /* get the public key pair for binary curve */ | ||
1052 | + if (!EC_POINT_get_affine_coordinates_GF2m(group, | ||
1053 | + pub_key, w_x, w_y,ctx)) { | ||
1054 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
1055 | + goto err; | ||
1056 | + } | ||
1057 | + }else { | ||
1058 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
1059 | + goto err; | ||
1060 | + } | ||
1061 | + | ||
1062 | + /* Get the order of the subgroup of private keys */ | ||
1063 | + if (spcf_bn2bin((BIGNUM*)order, &r, &r_len)) { | ||
1064 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
1065 | + goto err; | ||
1066 | + } | ||
1067 | + | ||
1068 | + /* Get the irreducible polynomial that creates the field */ | ||
1069 | + if (spcf_bn2bin(p, &q, &q_len)) { | ||
1070 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
1071 | + goto err; | ||
1072 | + } | ||
1073 | + | ||
1074 | + /* Get the public key into a flat buffer with appropriate padding */ | ||
1075 | + pub_key_len = 2 * q_len; | ||
1076 | + | ||
1077 | + w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len); | ||
1078 | + if (!w_xy) { | ||
1079 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
1080 | + goto err; | ||
1081 | + } | ||
1082 | + | ||
1083 | + /* Generation of ECC curve parameters */ | ||
1084 | + ab_len = 2*q_len; | ||
1085 | + | ||
1086 | + ab = eng_copy_curve_points (a, b, ab_len, q_len); | ||
1087 | + if (!ab) { | ||
1088 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
1089 | + goto err; | ||
1090 | + } | ||
1091 | + | ||
1092 | + if (ec_crv == EC_BINARY) { | ||
1093 | + /* copy b' i.e c(b), instead of only b */ | ||
1094 | + if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len)) | ||
1095 | + { | ||
1096 | + unsigned char *c_temp = NULL; | ||
1097 | + int c_temp_len = q_len; | ||
1098 | + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len)) | ||
1099 | + memcpy(ab+q_len, c_temp, q_len); | ||
1100 | + else | ||
1101 | + goto err; | ||
1102 | + } | ||
1103 | + kop.curve_type = ECC_BINARY; | ||
1104 | + } | ||
1105 | + | ||
1106 | + /* Calculation of Generator point */ | ||
1107 | + g_len = 2 * q_len; | ||
1108 | + | ||
1109 | + g_xy = eng_copy_curve_points (x, y, g_len, q_len); | ||
1110 | + if (!g_xy) { | ||
1111 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
1112 | + goto err; | ||
1113 | + } | ||
1114 | + | ||
1115 | + /** | ||
1116 | + * Get the 1st part of signature into a flat buffer with | ||
1117 | + * appropriate padding | ||
1118 | + */ | ||
1119 | + if (BN_num_bytes(sig->r) < r_len) | ||
1120 | + c_len = r_len; | ||
1121 | + | ||
1122 | + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) { | ||
1123 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
1124 | + goto err; | ||
1125 | + } | ||
1126 | + | ||
1127 | + /** | ||
1128 | + * Get the 2nd part of signature into a flat buffer with | ||
1129 | + * appropriate padding | ||
1130 | + */ | ||
1131 | + if (BN_num_bytes(sig->s) < r_len) | ||
1132 | + d_len = r_len; | ||
1133 | + | ||
1134 | + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) { | ||
1135 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
1136 | + goto err; | ||
1137 | + } | ||
1138 | + | ||
1139 | + /* memory for message representative */ | ||
1140 | + f = malloc(r_len); | ||
1141 | + if (!f) { | ||
1142 | + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
1143 | + goto err; | ||
1144 | + } | ||
1145 | + | ||
1146 | + /* Add padding, since SEC expects hash to of size r_len */ | ||
1147 | + memset(f, 0, r_len-dgst_len); | ||
1148 | + | ||
1149 | + /* Skip leading bytes if dgst_len < r_len */ | ||
1150 | + memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len); | ||
1151 | + dgst_len += r_len-dgst_len; | ||
1152 | + kop.crk_op = CRK_DSA_VERIFY; | ||
1153 | + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ | ||
1154 | + kop.crk_param[0].crp_p = f; | ||
1155 | + kop.crk_param[0].crp_nbits = dgst_len * 8; | ||
1156 | + kop.crk_param[1].crp_p = q; | ||
1157 | + kop.crk_param[1].crp_nbits = q_len * 8; | ||
1158 | + kop.crk_param[2].crp_p = r; | ||
1159 | + kop.crk_param[2].crp_nbits = r_len * 8; | ||
1160 | + kop.crk_param[3].crp_p = g_xy; | ||
1161 | + kop.crk_param[3].crp_nbits = g_len * 8; | ||
1162 | + kop.crk_param[4].crp_p = w_xy; | ||
1163 | + kop.crk_param[4].crp_nbits = pub_key_len * 8; | ||
1164 | + kop.crk_param[5].crp_p = ab; | ||
1165 | + kop.crk_param[5].crp_nbits = ab_len * 8; | ||
1166 | + kop.crk_param[6].crp_p = c; | ||
1167 | + kop.crk_param[6].crp_nbits = d_len * 8; | ||
1168 | + kop.crk_param[7].crp_p = d; | ||
1169 | + kop.crk_param[7].crp_nbits = d_len * 8; | ||
1170 | + kop.crk_iparams = 8; | ||
1171 | + | ||
1172 | + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { | ||
1173 | + /*OCF success value is 0, if not zero, change ret to fail*/ | ||
1174 | + if(0 == kop.crk_status) | ||
1175 | + ret = 1; | ||
1176 | + } else { | ||
1177 | + const ECDSA_METHOD *meth = ECDSA_OpenSSL(); | ||
1178 | + | ||
1179 | + ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey); | ||
1180 | + } | ||
1181 | + kop.crk_param[0].crp_p = NULL; | ||
1182 | + zapparams(&kop); | ||
1183 | + | ||
1184 | +err: | ||
1185 | + return ret; | ||
1186 | +} | ||
1187 | + | ||
1188 | +static int cryptodev_dh_keygen(DH *dh) | ||
1189 | +{ | ||
1190 | + struct crypt_kop kop; | ||
1191 | + int ret = 1, g_len; | ||
1192 | + unsigned char *g = NULL; | ||
1193 | + | ||
1194 | + if (dh->priv_key == NULL) { | ||
1195 | + if ((dh->priv_key=BN_new()) == NULL) | ||
1196 | + goto sw_try; | ||
1197 | + } | ||
1198 | + | ||
1199 | + if (dh->pub_key == NULL) { | ||
1200 | + if ((dh->pub_key=BN_new()) == NULL) | ||
1201 | + goto sw_try; | ||
1202 | + } | ||
1203 | + | ||
1204 | + g_len = BN_num_bytes(dh->p); | ||
1205 | + /** | ||
1206 | + * Get generator into a plain buffer. If length is less than | ||
1207 | + * q_len then add leading padding bytes. | ||
1208 | + */ | ||
1209 | + if (spcf_bn2bin_ex(dh->g, &g, &g_len)) { | ||
1210 | + DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE); | ||
1211 | + goto sw_try; | ||
1212 | + } | ||
1213 | + | ||
1214 | + memset(&kop, 0, sizeof kop); | ||
1215 | + kop.crk_op = CRK_DH_GENERATE_KEY; | ||
1216 | + if (bn2crparam(dh->p, &kop.crk_param[0])) | ||
1217 | + goto sw_try; | ||
1218 | + if (bn2crparam(dh->q, &kop.crk_param[1])) | ||
1219 | + goto sw_try; | ||
1220 | + kop.crk_param[2].crp_p = g; | ||
1221 | + kop.crk_param[2].crp_nbits = g_len * 8; | ||
1222 | + kop.crk_iparams = 3; | ||
1223 | + | ||
1224 | + /* pub_key is or prime length while priv key is of length of order */ | ||
1225 | + if (cryptodev_asym(&kop, BN_num_bytes(dh->p), dh->pub_key, | ||
1226 | + BN_num_bytes(dh->q), dh->priv_key)) | ||
1227 | + goto sw_try; | ||
1228 | + | ||
1229 | + return ret; | ||
1230 | +sw_try: | ||
1231 | + { | ||
1232 | + const DH_METHOD *meth = DH_OpenSSL(); | ||
1233 | + ret = (meth->generate_key)(dh); | ||
1234 | + } | ||
1235 | + return ret; | ||
1236 | } | ||
1237 | |||
1238 | static int | ||
1239 | @@ -1503,43 +2310,234 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | ||
1240 | { | ||
1241 | struct crypt_kop kop; | ||
1242 | int dhret = 1; | ||
1243 | - int fd, keylen; | ||
1244 | + int fd, p_len; | ||
1245 | + BIGNUM *temp = NULL; | ||
1246 | + unsigned char *padded_pub_key = NULL, *p = NULL; | ||
1247 | + | ||
1248 | + if ((fd = get_asym_dev_crypto()) < 0) | ||
1249 | + goto sw_try; | ||
1250 | + | ||
1251 | + memset(&kop, 0, sizeof kop); | ||
1252 | + kop.crk_op = CRK_DH_COMPUTE_KEY; | ||
1253 | + /* inputs: dh->priv_key pub_key dh->p key */ | ||
1254 | + spcf_bn2bin(dh->p, &p, &p_len); | ||
1255 | + spcf_bn2bin_ex(pub_key, &padded_pub_key, &p_len); | ||
1256 | + if (bn2crparam(dh->priv_key, &kop.crk_param[0])) | ||
1257 | + goto sw_try; | ||
1258 | + | ||
1259 | + kop.crk_param[1].crp_p = padded_pub_key; | ||
1260 | + kop.crk_param[1].crp_nbits = p_len * 8; | ||
1261 | + kop.crk_param[2].crp_p = p; | ||
1262 | + kop.crk_param[2].crp_nbits = p_len * 8; | ||
1263 | + kop.crk_iparams = 3; | ||
1264 | + kop.crk_param[3].crp_p = (void*) key; | ||
1265 | + kop.crk_param[3].crp_nbits = p_len * 8; | ||
1266 | + kop.crk_oparams = 1; | ||
1267 | + dhret = p_len; | ||
1268 | + | ||
1269 | + if (ioctl(fd, CIOCKEY, &kop)) | ||
1270 | + goto sw_try; | ||
1271 | |||
1272 | - if ((fd = get_asym_dev_crypto()) < 0) { | ||
1273 | + if ((temp = BN_new())) { | ||
1274 | + if (!BN_bin2bn(key, p_len, temp)) { | ||
1275 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); | ||
1276 | + goto sw_try; | ||
1277 | + } | ||
1278 | + if (dhret > BN_num_bytes(temp)) | ||
1279 | + dhret=BN_bn2bin(temp,key); | ||
1280 | + BN_free(temp); | ||
1281 | + } | ||
1282 | + | ||
1283 | + kop.crk_param[3].crp_p = NULL; | ||
1284 | + zapparams(&kop); | ||
1285 | + return (dhret); | ||
1286 | +sw_try: | ||
1287 | + { | ||
1288 | const DH_METHOD *meth = DH_OpenSSL(); | ||
1289 | |||
1290 | - return ((meth->compute_key)(key, pub_key, dh)); | ||
1291 | + dhret = (meth->compute_key)(key, pub_key, dh); | ||
1292 | } | ||
1293 | + return (dhret); | ||
1294 | +} | ||
1295 | |||
1296 | - keylen = BN_num_bits(dh->p); | ||
1297 | +int cryptodev_ecdh_compute_key(void *out, size_t outlen, | ||
1298 | + const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen, | ||
1299 | + void *out, size_t *outlen)) | ||
1300 | +{ | ||
1301 | + ec_curve_t ec_crv = EC_PRIME; | ||
1302 | + unsigned char * q = NULL, *w_xy = NULL, *ab = NULL, *s = NULL, *r = NULL; | ||
1303 | + BIGNUM * w_x = NULL, *w_y = NULL; | ||
1304 | + int q_len = 0, ab_len = 0, pub_key_len = 0, r_len = 0, priv_key_len = 0; | ||
1305 | + BIGNUM * p = NULL, *a = NULL, *b = NULL; | ||
1306 | + BN_CTX *ctx; | ||
1307 | + EC_POINT *tmp=NULL; | ||
1308 | + BIGNUM *x=NULL, *y=NULL; | ||
1309 | + const BIGNUM *priv_key; | ||
1310 | + const EC_GROUP* group = NULL; | ||
1311 | + int ret = -1; | ||
1312 | + size_t buflen, len; | ||
1313 | + struct crypt_kop kop; | ||
1314 | |||
1315 | memset(&kop, 0, sizeof kop); | ||
1316 | - kop.crk_op = CRK_DH_COMPUTE_KEY; | ||
1317 | |||
1318 | - /* inputs: dh->priv_key pub_key dh->p key */ | ||
1319 | - if (bn2crparam(dh->priv_key, &kop.crk_param[0])) | ||
1320 | + if ((ctx = BN_CTX_new()) == NULL) goto err; | ||
1321 | + BN_CTX_start(ctx); | ||
1322 | + x = BN_CTX_get(ctx); | ||
1323 | + y = BN_CTX_get(ctx); | ||
1324 | + p = BN_CTX_get(ctx); | ||
1325 | + a = BN_CTX_get(ctx); | ||
1326 | + b = BN_CTX_get(ctx); | ||
1327 | + w_x = BN_CTX_get(ctx); | ||
1328 | + w_y = BN_CTX_get(ctx); | ||
1329 | + | ||
1330 | + if (!x || !y || !p || !a || !b || !w_x || !w_y) { | ||
1331 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); | ||
1332 | goto err; | ||
1333 | - if (bn2crparam(pub_key, &kop.crk_param[1])) | ||
1334 | + } | ||
1335 | + | ||
1336 | + priv_key = EC_KEY_get0_private_key(ecdh); | ||
1337 | + if (priv_key == NULL) { | ||
1338 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE); | ||
1339 | goto err; | ||
1340 | - if (bn2crparam(dh->p, &kop.crk_param[2])) | ||
1341 | + } | ||
1342 | + | ||
1343 | + group = EC_KEY_get0_group(ecdh); | ||
1344 | + if ((tmp=EC_POINT_new(group)) == NULL) { | ||
1345 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); | ||
1346 | goto err; | ||
1347 | - kop.crk_iparams = 3; | ||
1348 | + } | ||
1349 | |||
1350 | - kop.crk_param[3].crp_p = (caddr_t) key; | ||
1351 | - kop.crk_param[3].crp_nbits = keylen * 8; | ||
1352 | - kop.crk_oparams = 1; | ||
1353 | + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == | ||
1354 | + NID_X9_62_prime_field) { | ||
1355 | + ec_crv = EC_PRIME; | ||
1356 | |||
1357 | - if (ioctl(fd, CIOCKEY, &kop) == -1) { | ||
1358 | - const DH_METHOD *meth = DH_OpenSSL(); | ||
1359 | + if (!EC_POINT_get_affine_coordinates_GFp(group, | ||
1360 | + EC_GROUP_get0_generator(group), x, y, ctx)) { | ||
1361 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE); | ||
1362 | + goto err; | ||
1363 | + } | ||
1364 | |||
1365 | - dhret = (meth->compute_key)(key, pub_key, dh); | ||
1366 | + /* get the ECC curve parameters */ | ||
1367 | + if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) { | ||
1368 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); | ||
1369 | + goto err; | ||
1370 | + } | ||
1371 | + | ||
1372 | + /* get the public key pair for prime curve */ | ||
1373 | + if (!EC_POINT_get_affine_coordinates_GFp (group, pub_key, w_x, w_y,ctx)) { | ||
1374 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); | ||
1375 | + goto err; | ||
1376 | + } | ||
1377 | + } else { | ||
1378 | + ec_crv = EC_BINARY; | ||
1379 | + | ||
1380 | + if (!EC_POINT_get_affine_coordinates_GF2m(group, | ||
1381 | + EC_GROUP_get0_generator(group), x, y, ctx)) { | ||
1382 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE); | ||
1383 | + goto err; | ||
1384 | + } | ||
1385 | + | ||
1386 | + /* get the ECC curve parameters */ | ||
1387 | + if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) { | ||
1388 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); | ||
1389 | + goto err; | ||
1390 | + } | ||
1391 | + | ||
1392 | + /* get the public key pair for binary curve */ | ||
1393 | + if (!EC_POINT_get_affine_coordinates_GF2m(group, | ||
1394 | + pub_key, w_x, w_y,ctx)) { | ||
1395 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); | ||
1396 | + goto err; | ||
1397 | + } | ||
1398 | + } | ||
1399 | + | ||
1400 | + /* irreducible polynomial that creates the field */ | ||
1401 | + if (spcf_bn2bin((BIGNUM*)&group->order, &r, &r_len)) { | ||
1402 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
1403 | + goto err; | ||
1404 | + } | ||
1405 | + | ||
1406 | + /* Get the irreducible polynomial that creates the field */ | ||
1407 | + if (spcf_bn2bin(p, &q, &q_len)) { | ||
1408 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); | ||
1409 | + goto err; | ||
1410 | } | ||
1411 | + | ||
1412 | + /* Get the public key into a flat buffer with appropriate padding */ | ||
1413 | + pub_key_len = 2 * q_len; | ||
1414 | + w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len); | ||
1415 | + if (!w_xy) { | ||
1416 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
1417 | + goto err; | ||
1418 | + } | ||
1419 | + | ||
1420 | + /* Generation of ECC curve parameters */ | ||
1421 | + ab_len = 2*q_len; | ||
1422 | + ab = eng_copy_curve_points (a, b, ab_len, q_len); | ||
1423 | + if (!ab) { | ||
1424 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); | ||
1425 | + goto err; | ||
1426 | + } | ||
1427 | + | ||
1428 | + if (ec_crv == EC_BINARY) { | ||
1429 | + /* copy b' i.e c(b), instead of only b */ | ||
1430 | + if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len)) | ||
1431 | + { | ||
1432 | + unsigned char *c_temp = NULL; | ||
1433 | + int c_temp_len = q_len; | ||
1434 | + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len)) | ||
1435 | + memcpy(ab+q_len, c_temp, q_len); | ||
1436 | + else | ||
1437 | + goto err; | ||
1438 | + } | ||
1439 | + kop.curve_type = ECC_BINARY; | ||
1440 | + } else | ||
1441 | + kop.curve_type = ECC_PRIME; | ||
1442 | + | ||
1443 | + priv_key_len = r_len; | ||
1444 | + | ||
1445 | + /* | ||
1446 | + * If BN_num_bytes of priv_key returns less then r_len then | ||
1447 | + * add padding bytes before the key | ||
1448 | + */ | ||
1449 | + if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) { | ||
1450 | + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
1451 | + goto err; | ||
1452 | + } | ||
1453 | + | ||
1454 | + buflen = (EC_GROUP_get_degree(group) + 7)/8; | ||
1455 | + len = BN_num_bytes(x); | ||
1456 | + if (len > buflen || q_len < buflen) { | ||
1457 | + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR); | ||
1458 | + goto err; | ||
1459 | + } | ||
1460 | + | ||
1461 | + kop.crk_op = CRK_DH_COMPUTE_KEY; | ||
1462 | + kop.crk_param[0].crp_p = (void*) s; | ||
1463 | + kop.crk_param[0].crp_nbits = priv_key_len*8; | ||
1464 | + kop.crk_param[1].crp_p = (void*) w_xy; | ||
1465 | + kop.crk_param[1].crp_nbits = pub_key_len*8; | ||
1466 | + kop.crk_param[2].crp_p = (void*) q; | ||
1467 | + kop.crk_param[2].crp_nbits = q_len*8; | ||
1468 | + kop.crk_param[3].crp_p = (void*) ab; | ||
1469 | + kop.crk_param[3].crp_nbits = ab_len*8; | ||
1470 | + kop.crk_iparams = 4; | ||
1471 | + kop.crk_param[4].crp_p = (void*) out; | ||
1472 | + kop.crk_param[4].crp_nbits = q_len*8; | ||
1473 | + kop.crk_oparams = 1; | ||
1474 | + ret = q_len; | ||
1475 | + if (cryptodev_asym(&kop, 0, NULL, 0, NULL)) { | ||
1476 | + const ECDH_METHOD *meth = ECDH_OpenSSL(); | ||
1477 | + ret = (meth->compute_key)(out, outlen, pub_key, ecdh, KDF); | ||
1478 | + } else | ||
1479 | + ret = q_len; | ||
1480 | err: | ||
1481 | - kop.crk_param[3].crp_p = NULL; | ||
1482 | + kop.crk_param[4].crp_p = NULL; | ||
1483 | zapparams(&kop); | ||
1484 | - return (dhret); | ||
1485 | + return ret; | ||
1486 | } | ||
1487 | |||
1488 | + | ||
1489 | static DH_METHOD cryptodev_dh = { | ||
1490 | "cryptodev DH method", | ||
1491 | NULL, /* cryptodev_dh_generate_key */ | ||
1492 | @@ -1551,6 +2549,14 @@ static DH_METHOD cryptodev_dh = { | ||
1493 | NULL /* app_data */ | ||
1494 | }; | ||
1495 | |||
1496 | +static ECDH_METHOD cryptodev_ecdh = { | ||
1497 | + "cryptodev ECDH method", | ||
1498 | + NULL, /* cryptodev_ecdh_compute_key */ | ||
1499 | + NULL, | ||
1500 | + 0, /* flags */ | ||
1501 | + NULL /* app_data */ | ||
1502 | +}; | ||
1503 | + | ||
1504 | /* | ||
1505 | * ctrl right now is just a wrapper that doesn't do much | ||
1506 | * but I expect we'll want some options soon. | ||
1507 | @@ -1634,25 +2640,42 @@ ENGINE_load_cryptodev(void) | ||
1508 | memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); | ||
1509 | if (cryptodev_asymfeat & CRF_DSA_SIGN) | ||
1510 | cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; | ||
1511 | - if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
1512 | - cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; | ||
1513 | - cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; | ||
1514 | - } | ||
1515 | if (cryptodev_asymfeat & CRF_DSA_VERIFY) | ||
1516 | cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; | ||
1517 | + if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY) | ||
1518 | + cryptodev_dsa.dsa_keygen = cryptodev_dsa_keygen; | ||
1519 | } | ||
1520 | |||
1521 | if (ENGINE_set_DH(engine, &cryptodev_dh)){ | ||
1522 | const DH_METHOD *dh_meth = DH_OpenSSL(); | ||
1523 | + memcpy(&cryptodev_dh, dh_meth, sizeof(DH_METHOD)); | ||
1524 | + if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) { | ||
1525 | + cryptodev_dh.compute_key = | ||
1526 | + cryptodev_dh_compute_key; | ||
1527 | + } | ||
1528 | + if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) { | ||
1529 | + cryptodev_dh.generate_key = | ||
1530 | + cryptodev_dh_keygen; | ||
1531 | + } | ||
1532 | + } | ||
1533 | |||
1534 | - cryptodev_dh.generate_key = dh_meth->generate_key; | ||
1535 | - cryptodev_dh.compute_key = dh_meth->compute_key; | ||
1536 | - cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; | ||
1537 | - if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
1538 | - cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; | ||
1539 | - if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) | ||
1540 | - cryptodev_dh.compute_key = | ||
1541 | - cryptodev_dh_compute_key; | ||
1542 | + if (ENGINE_set_ECDSA(engine, &cryptodev_ecdsa)) { | ||
1543 | + const ECDSA_METHOD *meth = ECDSA_OpenSSL(); | ||
1544 | + memcpy(&cryptodev_ecdsa, meth, sizeof(ECDSA_METHOD)); | ||
1545 | + if (cryptodev_asymfeat & CRF_DSA_SIGN) { | ||
1546 | + cryptodev_ecdsa.ecdsa_do_sign = cryptodev_ecdsa_do_sign; | ||
1547 | + } | ||
1548 | + if (cryptodev_asymfeat & CRF_DSA_VERIFY) { | ||
1549 | + cryptodev_ecdsa.ecdsa_do_verify = | ||
1550 | + cryptodev_ecdsa_verify; | ||
1551 | + } | ||
1552 | + } | ||
1553 | + | ||
1554 | + if (ENGINE_set_ECDH(engine, &cryptodev_ecdh)) { | ||
1555 | + const ECDH_METHOD *ecdh_meth = ECDH_OpenSSL(); | ||
1556 | + memcpy(&cryptodev_ecdh, ecdh_meth, sizeof(ECDH_METHOD)); | ||
1557 | + if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) { | ||
1558 | + cryptodev_ecdh.compute_key = cryptodev_ecdh_compute_key; | ||
1559 | } | ||
1560 | } | ||
1561 | |||
1562 | -- | ||
1563 | 2.3.5 | ||
1564 | |||