1 From 8e9a39aab2fce48c117460eb1d14bcc02be6de6c 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][fsl 06/15] Initial support for PKC in cryptodev engine
6 Upstream-status: Pending
8 Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
10 crypto/engine/eng_cryptodev.c | 1343 ++++++++++++++++++++++++++++++++++++-----
11 1 file changed, 1183 insertions(+), 160 deletions(-)
13 diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
14 index 123613d..88caec1 100644
15 --- a/crypto/engine/eng_cryptodev.c
16 +++ b/crypto/engine/eng_cryptodev.c
17 @@ -54,11 +54,14 @@ ENGINE_load_cryptodev(void)
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>
33 @@ -68,6 +71,8 @@ ENGINE_load_cryptodev(void)
37 +#include "eng_cryptodev_ec.h"
38 +#include <crypto/cryptodev.h>
40 struct dev_crypto_state {
41 struct session_op d_sess;
42 @@ -116,24 +121,112 @@ 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,
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,
62 void ENGINE_load_cryptodev(void);
64 +inline int spcf_bn2bin(BIGNUM *bn, unsigned char **bin, int *bin_len)
69 + len = BN_num_bytes(bn);
86 +inline int spcf_bn2bin_ex(BIGNUM *bn, unsigned char **bin, int *bin_len)
91 + len = BN_num_bytes(bn);
97 + p = malloc(*bin_len);
104 + if (len < *bin_len) {
105 + /* place padding */
106 + memset(p, 0, (*bin_len - len));
107 + BN_bn2bin(bn,p+(*bin_len-len));
113 + if (len >= *bin_len)
120 + * Convert an ECC F2m 'b' parameter into the 'c' parameter.
122 + * q, the curve's modulus
123 + * b, the curve's b parameter
124 + * (a bignum for b, a buffer for c)
126 + * c, written into bin, right-adjusted to fill q_len bytes.
129 +eng_ec_compute_cparam(const BIGNUM* b, const BIGNUM* q,
130 + unsigned char **bin, int *bin_len)
132 + BIGNUM* c = BN_new();
133 + BIGNUM* exp = BN_new();
134 + BN_CTX *ctx = BN_CTX_new();
135 + int m = BN_num_bits(q) - 1;
138 + if (!c || !exp || !ctx || *bin)
142 + * We have to compute c, where b = c^4, i.e., the fourth root of b.
143 + * The equation for c is c = b^(2^(m-2))
144 + * Compute exp = 2^(m-2)
146 + * and then compute c = b^exp
148 + BN_lshift(exp, BN_value_one(), m-2);
149 + BN_GF2m_mod_exp(c, b, exp, q, ctx);
151 + spcf_bn2bin_ex(c, bin, bin_len);
154 + if (ctx) BN_CTX_free(ctx);
156 + if (exp) BN_free(exp);
160 static const ENGINE_CMD_DEFN cryptodev_defns[] = {
163 @@ -1106,7 +1199,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
165 bn2crparam(const BIGNUM *a, struct crparam *crp)
171 @@ -1123,15 +1215,7 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
173 crp->crp_p = (caddr_t) b;
174 crp->crp_nbits = bits;
176 - for (i = 0, j = 0; i < a->top; i++) {
177 - for (k = 0; k < BN_BITS2 / 8; k++) {
178 - if ((j + k) >= bytes)
180 - b[j + k] = a->d[i] >> (k * 8);
184 + BN_bn2bin(a, crp->crp_p);
188 @@ -1139,22 +1223,14 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
190 crparam2bn(struct crparam *crp, BIGNUM *a)
196 bytes = (crp->crp_nbits + 7) / 8;
201 - if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
204 - for (i = 0; i < bytes; i++)
205 - pd[i] = crp->crp_p[bytes - i - 1];
207 - BN_bin2bn(pd, bytes, a);
209 + BN_bin2bn(crp->crp_p, bytes, a);
213 @@ -1202,6 +1278,32 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
217 +/* Close an opened instance of cryptodev engine */
218 +void cryptodev_close_instance(void *handle)
223 + fd = *(int *)handle;
229 +/* Create an instance of cryptodev for asynchronous interface */
230 +void *cryptodev_init_instance(void)
232 + int *fd = malloc(sizeof(int));
235 + if ((*fd = open("/dev/crypto", O_RDWR, 0)) == -1) {
244 cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
245 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
246 @@ -1217,9 +1319,9 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
250 - memset(&kop, 0, sizeof kop);
251 kop.crk_op = CRK_MOD_EXP;
253 + kop.crk_oparams = 0;
254 + kop.crk_status = 0;
255 /* inputs: a^p % m */
256 if (bn2crparam(a, &kop.crk_param[0]))
258 @@ -1260,28 +1362,38 @@ static int
259 cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
261 struct crypt_kop kop;
263 + int ret = 1, f_len, p_len, q_len;
264 + unsigned char *f = NULL, *p = NULL, *q = NULL, *dp = NULL, *dq = NULL, *c = NULL;
266 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
267 /* XXX 0 means failure?? */
271 - memset(&kop, 0, sizeof kop);
272 + kop.crk_oparams = 0;
273 + kop.crk_status = 0;
274 kop.crk_op = CRK_MOD_EXP_CRT;
275 + f_len = BN_num_bytes(rsa->n);
276 + spcf_bn2bin_ex(I, &f, &f_len);
277 + spcf_bn2bin(rsa->p, &p, &p_len);
278 + spcf_bn2bin(rsa->q, &q, &q_len);
279 + spcf_bn2bin_ex(rsa->dmp1, &dp, &p_len);
280 + spcf_bn2bin_ex(rsa->iqmp, &c, &p_len);
281 + spcf_bn2bin_ex(rsa->dmq1, &dq, &q_len);
282 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
283 - if (bn2crparam(rsa->p, &kop.crk_param[0]))
285 - if (bn2crparam(rsa->q, &kop.crk_param[1]))
287 - if (bn2crparam(I, &kop.crk_param[2]))
289 - if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
291 - if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
293 - if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
295 + kop.crk_param[0].crp_p = p;
296 + kop.crk_param[0].crp_nbits = p_len * 8;
297 + kop.crk_param[1].crp_p = q;
298 + kop.crk_param[1].crp_nbits = q_len * 8;
299 + kop.crk_param[2].crp_p = f;
300 + kop.crk_param[2].crp_nbits = f_len * 8;
301 + kop.crk_param[3].crp_p = dp;
302 + kop.crk_param[3].crp_nbits = p_len * 8;
303 + /* dq must of length q, rest all of length p*/
304 + kop.crk_param[4].crp_p = dq;
305 + kop.crk_param[4].crp_nbits = q_len * 8;
306 + kop.crk_param[5].crp_p = c;
307 + kop.crk_param[5].crp_nbits = p_len * 8;
310 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
311 @@ -1317,90 +1429,117 @@ static RSA_METHOD cryptodev_rsa = {
312 NULL /* rsa_verify */
316 -cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
317 - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
319 - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
323 -cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
324 - BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
325 - BN_CTX *ctx, BN_MONT_CTX *mont)
327 +cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
334 - /* v = ( g^u1 * y^u2 mod p ) mod q */
335 - /* let t1 = g ^ u1 mod p */
337 + struct crypt_kop kop;
338 + BIGNUM *c = NULL, *d = NULL;
339 + DSA_SIG *dsaret = NULL;
340 + int q_len = 0, r_len = 0, g_len = 0;
341 + int priv_key_len = 0, ret;
342 + unsigned char *q = NULL, *r = NULL, *g = NULL, *priv_key = NULL, *f = NULL;
344 - if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
345 + memset(&kop, 0, sizeof kop);
346 + if ((c = BN_new()) == NULL) {
347 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
351 - /* let t2 = y ^ u2 mod p */
352 - if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
353 + if ((d = BN_new()) == NULL) {
355 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
357 - /* let u1 = t1 * t2 mod p */
358 - if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
361 + if (spcf_bn2bin(dsa->p, &q, &q_len)) {
362 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
367 + /* Get order of the field of private keys into plain buffer */
368 + if (spcf_bn2bin (dsa->q, &r, &r_len)) {
369 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
379 + if (dlen > r_len) {
380 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
385 -cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
387 - struct crypt_kop kop;
388 - BIGNUM *r = NULL, *s = NULL;
389 - DSA_SIG *dsaret = NULL;
392 + * Get generator into a plain buffer. If length is less than
393 + * q_len then add leading padding bytes.
395 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
396 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
400 - if ((r = BN_new()) == NULL)
401 + priv_key_len = r_len;
403 + * Get private key into a plain buffer. If length is less than
404 + * r_len then add leading padding bytes.
406 + if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
407 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
409 - if ((s = BN_new()) == NULL) {
413 + /* Allocate memory to store hash. */
414 + f = OPENSSL_malloc (r_len);
416 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
420 - memset(&kop, 0, sizeof kop);
421 + /* Add padding, since SEC expects hash to of size r_len */
423 + memset(f, 0, r_len - dlen);
425 + /* Skip leading bytes if dgst_len < r_len */
426 + memcpy(f + r_len - dlen, dgst, dlen);
428 kop.crk_op = CRK_DSA_SIGN;
430 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
431 - kop.crk_param[0].crp_p = (caddr_t)dgst;
432 - kop.crk_param[0].crp_nbits = dlen * 8;
433 - if (bn2crparam(dsa->p, &kop.crk_param[1]))
435 - if (bn2crparam(dsa->q, &kop.crk_param[2]))
437 - if (bn2crparam(dsa->g, &kop.crk_param[3]))
439 - if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
441 + kop.crk_param[0].crp_p = (void*)f;
442 + kop.crk_param[0].crp_nbits = r_len * 8;
443 + kop.crk_param[1].crp_p = (void*)q;
444 + kop.crk_param[1].crp_nbits = q_len * 8;
445 + kop.crk_param[2].crp_p = (void*)r;
446 + kop.crk_param[2].crp_nbits = r_len * 8;
447 + kop.crk_param[3].crp_p = (void*)g;
448 + kop.crk_param[3].crp_nbits = g_len * 8;
449 + kop.crk_param[4].crp_p = (void*)priv_key;
450 + kop.crk_param[4].crp_nbits = priv_key_len * 8;
453 - if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
454 - BN_num_bytes(dsa->q), s) == 0) {
455 - dsaret = DSA_SIG_new();
459 - const DSA_METHOD *meth = DSA_OpenSSL();
462 - dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
463 + ret = cryptodev_asym(&kop, r_len, c, r_len, d);
466 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DECODE_ERROR);
470 - kop.crk_param[0].crp_p = NULL;
472 + dsaret = DSA_SIG_new();
480 + const DSA_METHOD *meth = DSA_OpenSSL();
485 + dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
491 @@ -1408,42 +1547,179 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
492 DSA_SIG *sig, DSA *dsa)
494 struct crypt_kop kop;
496 + int dsaret = 1, q_len = 0, r_len = 0, g_len = 0;
497 + int w_len = 0 ,c_len = 0, d_len = 0, ret = -1;
498 + unsigned char * q = NULL, * r = NULL, * w = NULL, * g = NULL;
499 + unsigned char * c = NULL, * d = NULL, *f = NULL;
501 memset(&kop, 0, sizeof kop);
502 kop.crk_op = CRK_DSA_VERIFY;
504 - /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
505 - kop.crk_param[0].crp_p = (caddr_t)dgst;
506 - kop.crk_param[0].crp_nbits = dlen * 8;
507 - if (bn2crparam(dsa->p, &kop.crk_param[1]))
508 + if (spcf_bn2bin(dsa->p, &q, &q_len)) {
509 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
513 + /* Get Order of field of private keys */
514 + if (spcf_bn2bin(dsa->q, &r, &r_len)) {
515 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
517 - if (bn2crparam(dsa->q, &kop.crk_param[2]))
522 + * Get generator into a plain buffer. If length is less than
523 + * q_len then add leading padding bytes.
525 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
526 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
528 - if (bn2crparam(dsa->g, &kop.crk_param[3]))
532 + * Get public key into a plain buffer. If length is less than
533 + * q_len then add leading padding bytes.
535 + if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
536 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
540 + * Get the 1st part of signature into a flat buffer with
541 + * appropriate padding
545 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
546 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
548 - if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
552 + * Get the 2nd part of signature into a flat buffer with
553 + * appropriate padding
557 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
558 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
560 - if (bn2crparam(sig->r, &kop.crk_param[5]))
565 + if (dlen > r_len) {
566 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
568 - if (bn2crparam(sig->s, &kop.crk_param[6]))
571 + /* Allocate memory to store hash. */
572 + f = OPENSSL_malloc (r_len);
574 + DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
578 + /* Add padding, since SEC expects hash to of size r_len */
580 + memset(f, 0, r_len - dlen);
582 + /* Skip leading bytes if dgst_len < r_len */
583 + memcpy(f + r_len - dlen, dgst, dlen);
585 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
586 + kop.crk_param[0].crp_p = (void*)f;
587 + kop.crk_param[0].crp_nbits = r_len * 8;
588 + kop.crk_param[1].crp_p = q;
589 + kop.crk_param[1].crp_nbits = q_len * 8;
590 + kop.crk_param[2].crp_p = r;
591 + kop.crk_param[2].crp_nbits = r_len * 8;
592 + kop.crk_param[3].crp_p = g;
593 + kop.crk_param[3].crp_nbits = g_len * 8;
594 + kop.crk_param[4].crp_p = w;
595 + kop.crk_param[4].crp_nbits = w_len * 8;
596 + kop.crk_param[5].crp_p = c;
597 + kop.crk_param[5].crp_nbits = c_len * 8;
598 + kop.crk_param[6].crp_p = d;
599 + kop.crk_param[6].crp_nbits = d_len * 8;
602 - if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
603 -/*OCF success value is 0, if not zero, change dsaret to fail*/
604 - if(0 != kop.crk_status) dsaret = 0;
606 - const DSA_METHOD *meth = DSA_OpenSSL();
607 + if ((cryptodev_asym(&kop, 0, NULL, 0, NULL))) {
608 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
612 - dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
613 + /*OCF success value is 0, if not zero, change dsaret to fail*/
614 + if(0 != kop.crk_status) {
615 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
619 - kop.crk_param[0].crp_p = NULL;
625 + const DSA_METHOD *meth = DSA_OpenSSL();
627 + dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
632 +/* Cryptodev DSA Key Gen routine */
633 +static int cryptodev_dsa_keygen(DSA *dsa)
635 + struct crypt_kop kop;
636 + int ret = 1, g_len;
637 + unsigned char *g = NULL;
639 + if (dsa->priv_key == NULL) {
640 + if ((dsa->priv_key=BN_new()) == NULL)
644 + if (dsa->pub_key == NULL) {
645 + if ((dsa->pub_key=BN_new()) == NULL)
649 + g_len = BN_num_bytes(dsa->p);
651 + * Get generator into a plain buffer. If length is less than
652 + * p_len then add leading padding bytes.
654 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
655 + DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
659 + memset(&kop, 0, sizeof kop);
661 + kop.crk_op = CRK_DSA_GENERATE_KEY;
662 + if (bn2crparam(dsa->p, &kop.crk_param[0]))
664 + if (bn2crparam(dsa->q, &kop.crk_param[1]))
666 + kop.crk_param[2].crp_p = g;
667 + kop.crk_param[2].crp_nbits = g_len * 8;
668 + kop.crk_iparams = 3;
670 + /* pub_key is or prime length while priv key is of length of order */
671 + if (cryptodev_asym(&kop, BN_num_bytes(dsa->p), dsa->pub_key,
672 + BN_num_bytes(dsa->q), dsa->priv_key))
678 + const DSA_METHOD *meth = DSA_OpenSSL();
679 + ret = (meth->dsa_keygen)(dsa);
686 static DSA_METHOD cryptodev_dsa = {
687 "cryptodev DSA method",
689 @@ -1457,12 +1733,543 @@ static DSA_METHOD cryptodev_dsa = {
694 -cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
695 - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
696 - BN_MONT_CTX *m_ctx)
697 +static ECDSA_METHOD cryptodev_ecdsa = {
698 + "cryptodev ECDSA method",
700 + NULL, /* ecdsa_sign_setup */
704 + NULL /* app_data */
707 +typedef enum ec_curve_s
713 +/* ENGINE handler for ECDSA Sign */
714 +static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char *dgst,
715 + int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
717 - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
718 + BIGNUM *m = NULL, *p = NULL, *a = NULL;
719 + BIGNUM *b = NULL, *x = NULL, *y = NULL;
720 + BN_CTX *ctx = NULL;
721 + ECDSA_SIG *ret = NULL;
722 + ECDSA_DATA *ecdsa = NULL;
723 + unsigned char * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
724 + unsigned char * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
725 + int i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
726 + int g_len = 0, d_len = 0, ab_len = 0;
727 + const BIGNUM *order = NULL, *priv_key=NULL;
728 + const EC_GROUP *group = NULL;
729 + struct crypt_kop kop;
730 + ec_curve_t ec_crv = EC_PRIME;
732 + memset(&kop, 0, sizeof(kop));
733 + ecdsa = ecdsa_check(eckey);
735 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
739 + group = EC_KEY_get0_group(eckey);
740 + priv_key = EC_KEY_get0_private_key(eckey);
742 + if (!group || !priv_key) {
743 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
747 + if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
748 + (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
749 + (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
750 + (y = BN_new()) == NULL) {
751 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
755 + order = &group->order;
756 + if (!order || BN_is_zero(order)) {
757 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
761 + i = BN_num_bits(order);
762 + /* Need to truncate digest if it is too long: first truncate whole
764 + if (8 * dgst_len > i)
765 + dgst_len = (i + 7)/8;
767 + if (!BN_bin2bn(dgst, dgst_len, m)) {
768 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
772 + /* If still too long truncate remaining bits with a shift */
773 + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
774 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
778 + /* copy the truncated bits into plain buffer */
779 + if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
780 + fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__);
784 + ret = ECDSA_SIG_new();
786 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
790 + /* check if this is prime or binary EC request */
791 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
793 + /* get the generator point pair */
794 + if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group),
796 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
800 + /* get the ECC curve parameters */
801 + if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) {
802 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
805 + } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) {
806 + ec_crv = EC_BINARY;
807 + /* get the ECC curve parameters */
808 + if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
809 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
813 + /* get the generator point pair */
814 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
815 + EC_GROUP_get0_generator(group), x, y,ctx)) {
816 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
820 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
824 + if (spcf_bn2bin(order, &r, &r_len)) {
825 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
829 + if (spcf_bn2bin(p, &q, &q_len)) {
830 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
834 + priv_key_len = r_len;
837 + * If BN_num_bytes of priv_key returns less then r_len then
838 + * add padding bytes before the key
840 + if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len)) {
841 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
845 + /* Generation of ECC curve parameters */
847 + ab = eng_copy_curve_points(a, b, ab_len, q_len);
849 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
853 + if (ec_crv == EC_BINARY) {
854 + if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
856 + unsigned char *c_temp = NULL;
857 + int c_temp_len = q_len;
858 + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
859 + memcpy(ab+q_len, c_temp, q_len);
863 + kop.curve_type = ECC_BINARY;
866 + /* Calculation of Generator point */
868 + g_xy = eng_copy_curve_points(x, y, g_len, q_len);
870 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
874 + /* Memory allocation for first part of digital signature */
877 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
883 + /* Memory allocation for second part of digital signature */
886 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
890 + /* memory for message representative */
893 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
897 + /* Add padding, since SEC expects hash to of size r_len */
898 + memset(f, 0, r_len - dgst_len);
900 + /* Skip leading bytes if dgst_len < r_len */
901 + memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
903 + dgst_len += r_len - dgst_len;
904 + kop.crk_op = CRK_DSA_SIGN;
905 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
906 + kop.crk_param[0].crp_p = f;
907 + kop.crk_param[0].crp_nbits = dgst_len * 8;
908 + kop.crk_param[1].crp_p = q;
909 + kop.crk_param[1].crp_nbits = q_len * 8;
910 + kop.crk_param[2].crp_p = r;
911 + kop.crk_param[2].crp_nbits = r_len * 8;
912 + kop.crk_param[3].crp_p = g_xy;
913 + kop.crk_param[3].crp_nbits = g_len * 8;
914 + kop.crk_param[4].crp_p = s;
915 + kop.crk_param[4].crp_nbits = priv_key_len * 8;
916 + kop.crk_param[5].crp_p = ab;
917 + kop.crk_param[5].crp_nbits = ab_len * 8;
918 + kop.crk_iparams = 6;
919 + kop.crk_param[6].crp_p = c;
920 + kop.crk_param[6].crp_nbits = d_len * 8;
921 + kop.crk_param[7].crp_p = d;
922 + kop.crk_param[7].crp_nbits = d_len * 8;
923 + kop.crk_oparams = 2;
925 + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
926 + /* Check if ret->r and s needs to allocated */
927 + crparam2bn(&kop.crk_param[6], ret->r);
928 + crparam2bn(&kop.crk_param[7], ret->s);
930 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
931 + ret = (meth->ecdsa_do_sign)(dgst, dgst_len, in_kinv, in_r, eckey);
933 + kop.crk_param[0].crp_p = NULL;
937 + ECDSA_SIG_free(ret);
943 +static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len,
944 + ECDSA_SIG *sig, EC_KEY *eckey)
946 + BIGNUM *m = NULL, *p = NULL, *a = NULL, *b = NULL;
947 + BIGNUM *x = NULL, *y = NULL, *w_x = NULL, *w_y = NULL;
948 + BN_CTX *ctx = NULL;
949 + ECDSA_DATA *ecdsa = NULL;
950 + unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL, *w_xy = NULL;
951 + unsigned char *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
952 + int i = 0, q_len = 0, pub_key_len = 0, r_len = 0, c_len = 0, g_len = 0;
953 + int d_len = 0, ab_len = 0, ret = -1;
954 + const EC_POINT *pub_key = NULL;
955 + const BIGNUM *order = NULL;
956 + const EC_GROUP *group=NULL;
957 + ec_curve_t ec_crv = EC_PRIME;
958 + struct crypt_kop kop;
960 + memset(&kop, 0, sizeof kop);
961 + ecdsa = ecdsa_check(eckey);
963 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
967 + group = EC_KEY_get0_group(eckey);
968 + pub_key = EC_KEY_get0_public_key(eckey);
970 + if (!group || !pub_key) {
971 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
975 + if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
976 + (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
977 + (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
978 + (y = BN_new()) == NULL || (w_x = BN_new()) == NULL ||
979 + (w_y = BN_new()) == NULL) {
980 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
984 + order = &group->order;
985 + if (!order || BN_is_zero(order)) {
986 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
990 + i = BN_num_bits(order);
991 + /* Need to truncate digest if it is too long: first truncate whole
993 + if (8 * dgst_len > i)
994 + dgst_len = (i + 7)/8;
996 + if (!BN_bin2bn(dgst, dgst_len, m)) {
997 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1001 + /* If still too long truncate remaining bits with a shift */
1002 + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
1003 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1006 + /* copy the truncated bits into plain buffer */
1007 + if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
1008 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1012 + /* check if this is prime or binary EC request */
1013 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
1014 + ec_crv = EC_PRIME;
1016 + /* get the generator point pair */
1017 + if (!EC_POINT_get_affine_coordinates_GFp (group,
1018 + EC_GROUP_get0_generator(group), x, y,ctx)) {
1019 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1023 + /* get the public key pair for prime curve */
1024 + if (!EC_POINT_get_affine_coordinates_GFp (group,
1025 + pub_key, w_x, w_y,ctx)) {
1026 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1030 + /* get the ECC curve parameters */
1031 + if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
1032 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1035 + } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field){
1036 + ec_crv = EC_BINARY;
1037 + /* get the ECC curve parameters */
1038 + if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
1039 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1043 + /* get the generator point pair */
1044 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1045 + EC_GROUP_get0_generator(group),x, y,ctx)) {
1046 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1050 + /* get the public key pair for binary curve */
1051 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1052 + pub_key, w_x, w_y,ctx)) {
1053 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1057 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1061 + /* Get the order of the subgroup of private keys */
1062 + if (spcf_bn2bin((BIGNUM*)order, &r, &r_len)) {
1063 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1067 + /* Get the irreducible polynomial that creates the field */
1068 + if (spcf_bn2bin(p, &q, &q_len)) {
1069 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1073 + /* Get the public key into a flat buffer with appropriate padding */
1074 + pub_key_len = 2 * q_len;
1076 + w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
1078 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1082 + /* Generation of ECC curve parameters */
1085 + ab = eng_copy_curve_points (a, b, ab_len, q_len);
1087 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1091 + if (ec_crv == EC_BINARY) {
1092 + /* copy b' i.e c(b), instead of only b */
1093 + if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
1095 + unsigned char *c_temp = NULL;
1096 + int c_temp_len = q_len;
1097 + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1098 + memcpy(ab+q_len, c_temp, q_len);
1102 + kop.curve_type = ECC_BINARY;
1105 + /* Calculation of Generator point */
1106 + g_len = 2 * q_len;
1108 + g_xy = eng_copy_curve_points (x, y, g_len, q_len);
1110 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1115 + * Get the 1st part of signature into a flat buffer with
1116 + * appropriate padding
1118 + if (BN_num_bytes(sig->r) < r_len)
1121 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
1122 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1127 + * Get the 2nd part of signature into a flat buffer with
1128 + * appropriate padding
1130 + if (BN_num_bytes(sig->s) < r_len)
1133 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1134 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1138 + /* memory for message representative */
1139 + f = malloc(r_len);
1141 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1145 + /* Add padding, since SEC expects hash to of size r_len */
1146 + memset(f, 0, r_len-dgst_len);
1148 + /* Skip leading bytes if dgst_len < r_len */
1149 + memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len);
1150 + dgst_len += r_len-dgst_len;
1151 + kop.crk_op = CRK_DSA_VERIFY;
1152 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1153 + kop.crk_param[0].crp_p = f;
1154 + kop.crk_param[0].crp_nbits = dgst_len * 8;
1155 + kop.crk_param[1].crp_p = q;
1156 + kop.crk_param[1].crp_nbits = q_len * 8;
1157 + kop.crk_param[2].crp_p = r;
1158 + kop.crk_param[2].crp_nbits = r_len * 8;
1159 + kop.crk_param[3].crp_p = g_xy;
1160 + kop.crk_param[3].crp_nbits = g_len * 8;
1161 + kop.crk_param[4].crp_p = w_xy;
1162 + kop.crk_param[4].crp_nbits = pub_key_len * 8;
1163 + kop.crk_param[5].crp_p = ab;
1164 + kop.crk_param[5].crp_nbits = ab_len * 8;
1165 + kop.crk_param[6].crp_p = c;
1166 + kop.crk_param[6].crp_nbits = d_len * 8;
1167 + kop.crk_param[7].crp_p = d;
1168 + kop.crk_param[7].crp_nbits = d_len * 8;
1169 + kop.crk_iparams = 8;
1171 + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1172 + /*OCF success value is 0, if not zero, change ret to fail*/
1173 + if(0 == kop.crk_status)
1176 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1178 + ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
1180 + kop.crk_param[0].crp_p = NULL;
1187 +static int cryptodev_dh_keygen(DH *dh)
1189 + struct crypt_kop kop;
1190 + int ret = 1, g_len;
1191 + unsigned char *g = NULL;
1193 + if (dh->priv_key == NULL) {
1194 + if ((dh->priv_key=BN_new()) == NULL)
1198 + if (dh->pub_key == NULL) {
1199 + if ((dh->pub_key=BN_new()) == NULL)
1203 + g_len = BN_num_bytes(dh->p);
1205 + * Get generator into a plain buffer. If length is less than
1206 + * q_len then add leading padding bytes.
1208 + if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
1209 + DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
1213 + memset(&kop, 0, sizeof kop);
1214 + kop.crk_op = CRK_DH_GENERATE_KEY;
1215 + if (bn2crparam(dh->p, &kop.crk_param[0]))
1217 + if (bn2crparam(dh->q, &kop.crk_param[1]))
1219 + kop.crk_param[2].crp_p = g;
1220 + kop.crk_param[2].crp_nbits = g_len * 8;
1221 + kop.crk_iparams = 3;
1223 + /* pub_key is or prime length while priv key is of length of order */
1224 + if (cryptodev_asym(&kop, BN_num_bytes(dh->p), dh->pub_key,
1225 + BN_num_bytes(dh->q), dh->priv_key))
1231 + const DH_METHOD *meth = DH_OpenSSL();
1232 + ret = (meth->generate_key)(dh);
1238 @@ -1470,43 +2277,234 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1240 struct crypt_kop kop;
1244 + BIGNUM *temp = NULL;
1245 + unsigned char *padded_pub_key = NULL, *p = NULL;
1247 + if ((fd = get_asym_dev_crypto()) < 0)
1250 + memset(&kop, 0, sizeof kop);
1251 + kop.crk_op = CRK_DH_COMPUTE_KEY;
1252 + /* inputs: dh->priv_key pub_key dh->p key */
1253 + spcf_bn2bin(dh->p, &p, &p_len);
1254 + spcf_bn2bin_ex(pub_key, &padded_pub_key, &p_len);
1255 + if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1258 + kop.crk_param[1].crp_p = padded_pub_key;
1259 + kop.crk_param[1].crp_nbits = p_len * 8;
1260 + kop.crk_param[2].crp_p = p;
1261 + kop.crk_param[2].crp_nbits = p_len * 8;
1262 + kop.crk_iparams = 3;
1263 + kop.crk_param[3].crp_p = (void*) key;
1264 + kop.crk_param[3].crp_nbits = p_len * 8;
1265 + kop.crk_oparams = 1;
1268 + if (ioctl(fd, CIOCKEY, &kop))
1271 - if ((fd = get_asym_dev_crypto()) < 0) {
1272 + if ((temp = BN_new())) {
1273 + if (!BN_bin2bn(key, p_len, temp)) {
1274 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
1277 + if (dhret > BN_num_bytes(temp))
1278 + dhret=BN_bn2bin(temp,key);
1282 + kop.crk_param[3].crp_p = NULL;
1287 const DH_METHOD *meth = DH_OpenSSL();
1289 - return ((meth->compute_key)(key, pub_key, dh));
1290 + dhret = (meth->compute_key)(key, pub_key, dh);
1295 - keylen = BN_num_bits(dh->p);
1296 +int cryptodev_ecdh_compute_key(void *out, size_t outlen,
1297 + const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen,
1298 + void *out, size_t *outlen))
1300 + ec_curve_t ec_crv = EC_PRIME;
1301 + unsigned char * q = NULL, *w_xy = NULL, *ab = NULL, *s = NULL, *r = NULL;
1302 + BIGNUM * w_x = NULL, *w_y = NULL;
1303 + int q_len = 0, ab_len = 0, pub_key_len = 0, r_len = 0, priv_key_len = 0;
1304 + BIGNUM * p = NULL, *a = NULL, *b = NULL;
1306 + EC_POINT *tmp=NULL;
1307 + BIGNUM *x=NULL, *y=NULL;
1308 + const BIGNUM *priv_key;
1309 + const EC_GROUP* group = NULL;
1311 + size_t buflen, len;
1312 + struct crypt_kop kop;
1314 memset(&kop, 0, sizeof kop);
1315 - kop.crk_op = CRK_DH_COMPUTE_KEY;
1317 - /* inputs: dh->priv_key pub_key dh->p key */
1318 - if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1319 + if ((ctx = BN_CTX_new()) == NULL) goto err;
1320 + BN_CTX_start(ctx);
1321 + x = BN_CTX_get(ctx);
1322 + y = BN_CTX_get(ctx);
1323 + p = BN_CTX_get(ctx);
1324 + a = BN_CTX_get(ctx);
1325 + b = BN_CTX_get(ctx);
1326 + w_x = BN_CTX_get(ctx);
1327 + w_y = BN_CTX_get(ctx);
1329 + if (!x || !y || !p || !a || !b || !w_x || !w_y) {
1330 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
1332 - if (bn2crparam(pub_key, &kop.crk_param[1]))
1335 + priv_key = EC_KEY_get0_private_key(ecdh);
1336 + if (priv_key == NULL) {
1337 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
1339 - if (bn2crparam(dh->p, &kop.crk_param[2]))
1342 + group = EC_KEY_get0_group(ecdh);
1343 + if ((tmp=EC_POINT_new(group)) == NULL) {
1344 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
1346 - kop.crk_iparams = 3;
1349 - kop.crk_param[3].crp_p = (caddr_t) key;
1350 - kop.crk_param[3].crp_nbits = keylen * 8;
1351 - kop.crk_oparams = 1;
1352 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1353 + NID_X9_62_prime_field) {
1354 + ec_crv = EC_PRIME;
1356 - if (ioctl(fd, CIOCKEY, &kop) == -1) {
1357 - const DH_METHOD *meth = DH_OpenSSL();
1358 + if (!EC_POINT_get_affine_coordinates_GFp(group,
1359 + EC_GROUP_get0_generator(group), x, y, ctx)) {
1360 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
1364 - dhret = (meth->compute_key)(key, pub_key, dh);
1365 + /* get the ECC curve parameters */
1366 + if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
1367 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1371 + /* get the public key pair for prime curve */
1372 + if (!EC_POINT_get_affine_coordinates_GFp (group, pub_key, w_x, w_y,ctx)) {
1373 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1377 + ec_crv = EC_BINARY;
1379 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1380 + EC_GROUP_get0_generator(group), x, y, ctx)) {
1381 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
1385 + /* get the ECC curve parameters */
1386 + if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) {
1387 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1391 + /* get the public key pair for binary curve */
1392 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1393 + pub_key, w_x, w_y,ctx)) {
1394 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1399 + /* irreducible polynomial that creates the field */
1400 + if (spcf_bn2bin((BIGNUM*)&group->order, &r, &r_len)) {
1401 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1405 + /* Get the irreducible polynomial that creates the field */
1406 + if (spcf_bn2bin(p, &q, &q_len)) {
1407 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1411 + /* Get the public key into a flat buffer with appropriate padding */
1412 + pub_key_len = 2 * q_len;
1413 + w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
1415 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1419 + /* Generation of ECC curve parameters */
1421 + ab = eng_copy_curve_points (a, b, ab_len, q_len);
1423 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
1427 + if (ec_crv == EC_BINARY) {
1428 + /* copy b' i.e c(b), instead of only b */
1429 + if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
1431 + unsigned char *c_temp = NULL;
1432 + int c_temp_len = q_len;
1433 + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1434 + memcpy(ab+q_len, c_temp, q_len);
1438 + kop.curve_type = ECC_BINARY;
1440 + kop.curve_type = ECC_PRIME;
1442 + priv_key_len = r_len;
1445 + * If BN_num_bytes of priv_key returns less then r_len then
1446 + * add padding bytes before the key
1448 + if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
1449 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1453 + buflen = (EC_GROUP_get_degree(group) + 7)/8;
1454 + len = BN_num_bytes(x);
1455 + if (len > buflen || q_len < buflen) {
1456 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
1460 + kop.crk_op = CRK_DH_COMPUTE_KEY;
1461 + kop.crk_param[0].crp_p = (void*) s;
1462 + kop.crk_param[0].crp_nbits = priv_key_len*8;
1463 + kop.crk_param[1].crp_p = (void*) w_xy;
1464 + kop.crk_param[1].crp_nbits = pub_key_len*8;
1465 + kop.crk_param[2].crp_p = (void*) q;
1466 + kop.crk_param[2].crp_nbits = q_len*8;
1467 + kop.crk_param[3].crp_p = (void*) ab;
1468 + kop.crk_param[3].crp_nbits = ab_len*8;
1469 + kop.crk_iparams = 4;
1470 + kop.crk_param[4].crp_p = (void*) out;
1471 + kop.crk_param[4].crp_nbits = q_len*8;
1472 + kop.crk_oparams = 1;
1474 + if (cryptodev_asym(&kop, 0, NULL, 0, NULL)) {
1475 + const ECDH_METHOD *meth = ECDH_OpenSSL();
1476 + ret = (meth->compute_key)(out, outlen, pub_key, ecdh, KDF);
1480 - kop.crk_param[3].crp_p = NULL;
1481 + kop.crk_param[4].crp_p = NULL;
1488 static DH_METHOD cryptodev_dh = {
1489 "cryptodev DH method",
1490 NULL, /* cryptodev_dh_generate_key */
1491 @@ -1518,6 +2516,14 @@ static DH_METHOD cryptodev_dh = {
1495 +static ECDH_METHOD cryptodev_ecdh = {
1496 + "cryptodev ECDH method",
1497 + NULL, /* cryptodev_ecdh_compute_key */
1500 + NULL /* app_data */
1504 * ctrl right now is just a wrapper that doesn't do much
1505 * but I expect we'll want some options soon.
1506 @@ -1602,25 +2608,42 @@ ENGINE_load_cryptodev(void)
1507 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1508 if (cryptodev_asymfeat & CRF_DSA_SIGN)
1509 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1510 - if (cryptodev_asymfeat & CRF_MOD_EXP) {
1511 - cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1512 - cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1514 if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1515 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1516 + if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY)
1517 + cryptodev_dsa.dsa_keygen = cryptodev_dsa_keygen;
1520 if (ENGINE_set_DH(engine, &cryptodev_dh)){
1521 const DH_METHOD *dh_meth = DH_OpenSSL();
1522 + memcpy(&cryptodev_dh, dh_meth, sizeof(DH_METHOD));
1523 + if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1524 + cryptodev_dh.compute_key =
1525 + cryptodev_dh_compute_key;
1527 + if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) {
1528 + cryptodev_dh.generate_key =
1529 + cryptodev_dh_keygen;
1533 - cryptodev_dh.generate_key = dh_meth->generate_key;
1534 - cryptodev_dh.compute_key = dh_meth->compute_key;
1535 - cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1536 - if (cryptodev_asymfeat & CRF_MOD_EXP) {
1537 - cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1538 - if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1539 - cryptodev_dh.compute_key =
1540 - cryptodev_dh_compute_key;
1541 + if (ENGINE_set_ECDSA(engine, &cryptodev_ecdsa)) {
1542 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1543 + memcpy(&cryptodev_ecdsa, meth, sizeof(ECDSA_METHOD));
1544 + if (cryptodev_asymfeat & CRF_DSA_SIGN) {
1545 + cryptodev_ecdsa.ecdsa_do_sign = cryptodev_ecdsa_do_sign;
1547 + if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
1548 + cryptodev_ecdsa.ecdsa_do_verify =
1549 + cryptodev_ecdsa_verify;
1553 + if (ENGINE_set_ECDH(engine, &cryptodev_ecdh)) {
1554 + const ECDH_METHOD *ecdh_meth = ECDH_OpenSSL();
1555 + memcpy(&cryptodev_ecdh, ecdh_meth, sizeof(ECDH_METHOD));
1556 + if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1557 + cryptodev_ecdh.compute_key = cryptodev_ecdh_compute_key;