1 From e28df2a5c63dc6195a6065bfd7de9fc860129f56 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 05/48] 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 | 1365 ++++++++++++++++++++++++++++++++++++-----
11 1 file changed, 1202 insertions(+), 163 deletions(-)
13 diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
14 index 3b6515e..0b41bb2 100644
15 --- a/crypto/engine/eng_cryptodev.c
16 +++ b/crypto/engine/eng_cryptodev.c
17 @@ -58,6 +58,10 @@ void ENGINE_load_cryptodev(void)
18 # include <openssl/dsa.h>
19 # include <openssl/err.h>
20 # include <openssl/rsa.h>
21 +# include <crypto/ecdsa/ecs_locl.h>
22 +# include <crypto/ecdh/ech_locl.h>
23 +# include <crypto/ec/ec_lcl.h>
24 +# include <crypto/ec/ec.h>
25 # include <sys/ioctl.h>
28 @@ -67,6 +71,7 @@ void ENGINE_load_cryptodev(void)
32 +# include "eng_cryptodev_ec.h"
34 struct dev_crypto_state {
35 struct session_op d_sess;
36 @@ -115,20 +120,10 @@ static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
38 static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
40 -static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
41 - const BIGNUM *p, const BIGNUM *m,
42 - BN_CTX *ctx, BN_MONT_CTX *m_ctx);
43 -static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
44 - BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2,
45 - BIGNUM *p, BN_CTX *ctx,
47 static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
49 static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
50 DSA_SIG *sig, DSA *dsa);
51 -static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
52 - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
53 - BN_MONT_CTX *m_ctx);
54 static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key,
56 static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
57 @@ -137,6 +132,105 @@ void ENGINE_load_cryptodev(void);
58 const EVP_CIPHER cryptodev_aes_128_cbc_hmac_sha1;
59 const EVP_CIPHER cryptodev_aes_256_cbc_hmac_sha1;
61 +inline int spcf_bn2bin(BIGNUM *bn, unsigned char **bin, int *bin_len)
66 + len = BN_num_bytes(bn);
83 +inline int spcf_bn2bin_ex(BIGNUM *bn, unsigned char **bin, int *bin_len)
88 + len = BN_num_bytes(bn);
94 + p = malloc(*bin_len);
101 + if (len < *bin_len) {
102 + /* place padding */
103 + memset(p, 0, (*bin_len - len));
104 + BN_bn2bin(bn, p + (*bin_len - len));
110 + if (len >= *bin_len)
117 + * Convert an ECC F2m 'b' parameter into the 'c' parameter.
119 + * q, the curve's modulus
120 + * b, the curve's b parameter
121 + * (a bignum for b, a buffer for c)
123 + * c, written into bin, right-adjusted to fill q_len bytes.
126 +eng_ec_compute_cparam(const BIGNUM *b, const BIGNUM *q,
127 + unsigned char **bin, int *bin_len)
129 + BIGNUM *c = BN_new();
130 + BIGNUM *exp = BN_new();
131 + BN_CTX *ctx = BN_CTX_new();
132 + int m = BN_num_bits(q) - 1;
135 + if (!c || !exp || !ctx || *bin)
139 + * We have to compute c, where b = c^4, i.e., the fourth root of b.
140 + * The equation for c is c = b^(2^(m-2))
141 + * Compute exp = 2^(m-2)
143 + * and then compute c = b^exp
145 + BN_lshift(exp, BN_value_one(), m - 2);
146 + BN_GF2m_mod_exp(c, b, exp, q, ctx);
148 + spcf_bn2bin_ex(c, bin, bin_len);
160 static const ENGINE_CMD_DEFN cryptodev_defns[] = {
163 @@ -1225,7 +1319,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
165 static int bn2crparam(const BIGNUM *a, struct crparam *crp)
171 @@ -1243,36 +1336,21 @@ static int bn2crparam(const BIGNUM *a, struct crparam *crp)
172 crp->crp_p = (caddr_t) b;
173 crp->crp_nbits = bits;
175 - for (i = 0, j = 0; i < a->top; i++) {
176 - for (k = 0; k < BN_BITS2 / 8; k++) {
177 - if ((j + k) >= bytes)
179 - b[j + k] = a->d[i] >> (k * 8);
183 + BN_bn2bin(a, crp->crp_p);
187 /* Convert a /dev/crypto parameter to a BIGNUM */
188 static int crparam2bn(struct crparam *crp, BIGNUM *a)
194 bytes = (crp->crp_nbits + 7) / 8;
199 - if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
202 - for (i = 0; i < bytes; i++)
203 - pd[i] = crp->crp_p[bytes - i - 1];
205 - BN_bin2bn(pd, bytes, a);
207 + BN_bin2bn(crp->crp_p, bytes, a);
211 @@ -1321,6 +1399,32 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
215 +/* Close an opened instance of cryptodev engine */
216 +void cryptodev_close_instance(void *handle)
221 + fd = *(int *)handle;
227 +/* Create an instance of cryptodev for asynchronous interface */
228 +void *cryptodev_init_instance(void)
230 + int *fd = malloc(sizeof(int));
233 + if ((*fd = open("/dev/crypto", O_RDWR, 0)) == -1) {
242 cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
243 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
244 @@ -1337,8 +1441,9 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
248 - memset(&kop, 0, sizeof kop);
249 kop.crk_op = CRK_MOD_EXP;
250 + kop.crk_oparams = 0;
251 + kop.crk_status = 0;
253 /* inputs: a^p % m */
254 if (bn2crparam(a, &kop.crk_param[0]))
255 @@ -1381,28 +1486,39 @@ static int
256 cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
258 struct crypt_kop kop;
260 + int ret = 1, f_len, p_len, q_len;
261 + unsigned char *f = NULL, *p = NULL, *q = NULL, *dp = NULL, *dq =
264 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
265 /* XXX 0 means failure?? */
269 - memset(&kop, 0, sizeof kop);
270 + kop.crk_oparams = 0;
271 + kop.crk_status = 0;
272 kop.crk_op = CRK_MOD_EXP_CRT;
273 + f_len = BN_num_bytes(rsa->n);
274 + spcf_bn2bin_ex(I, &f, &f_len);
275 + spcf_bn2bin(rsa->p, &p, &p_len);
276 + spcf_bn2bin(rsa->q, &q, &q_len);
277 + spcf_bn2bin_ex(rsa->dmp1, &dp, &p_len);
278 + spcf_bn2bin_ex(rsa->iqmp, &c, &p_len);
279 + spcf_bn2bin_ex(rsa->dmq1, &dq, &q_len);
280 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
281 - if (bn2crparam(rsa->p, &kop.crk_param[0]))
283 - if (bn2crparam(rsa->q, &kop.crk_param[1]))
285 - if (bn2crparam(I, &kop.crk_param[2]))
287 - if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
289 - if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
291 - if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
293 + kop.crk_param[0].crp_p = p;
294 + kop.crk_param[0].crp_nbits = p_len * 8;
295 + kop.crk_param[1].crp_p = q;
296 + kop.crk_param[1].crp_nbits = q_len * 8;
297 + kop.crk_param[2].crp_p = f;
298 + kop.crk_param[2].crp_nbits = f_len * 8;
299 + kop.crk_param[3].crp_p = dp;
300 + kop.crk_param[3].crp_nbits = p_len * 8;
301 + /* dq must of length q, rest all of length p */
302 + kop.crk_param[4].crp_p = dq;
303 + kop.crk_param[4].crp_nbits = q_len * 8;
304 + kop.crk_param[5].crp_p = c;
305 + kop.crk_param[5].crp_nbits = p_len * 8;
308 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
309 @@ -1438,93 +1554,120 @@ static RSA_METHOD cryptodev_rsa = {
310 NULL /* rsa_verify */
314 -cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
315 - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
317 - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
321 -cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
322 - BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
323 - BN_CTX *ctx, BN_MONT_CTX *mont)
324 +static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
332 - /* v = ( g^u1 * y^u2 mod p ) mod q */
333 - /* let t1 = g ^ u1 mod p */
335 + struct crypt_kop kop;
336 + BIGNUM *c = NULL, *d = NULL;
337 + DSA_SIG *dsaret = NULL;
338 + int q_len = 0, r_len = 0, g_len = 0;
339 + int priv_key_len = 0, ret;
340 + unsigned char *q = NULL, *r = NULL, *g = NULL, *priv_key = NULL, *f =
343 - if (!dsa->meth->bn_mod_exp(dsa, t1, dsa->g, u1, dsa->p, ctx, mont))
344 + memset(&kop, 0, sizeof kop);
345 + if ((c = BN_new()) == NULL) {
346 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
350 - /* let t2 = y ^ u2 mod p */
351 - if (!dsa->meth->bn_mod_exp(dsa, &t2, dsa->pub_key, u2, dsa->p, ctx, mont))
352 + if ((d = BN_new()) == NULL) {
354 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
356 - /* let u1 = t1 * t2 mod p */
357 - if (!BN_mod_mul(u1, t1, &t2, dsa->p, ctx))
360 + if (spcf_bn2bin(dsa->p, &q, &q_len)) {
361 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
366 + /* Get order of the field of private keys into plain buffer */
367 + if (spcf_bn2bin(dsa->q, &r, &r_len)) {
368 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
378 + if (dlen > r_len) {
379 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
383 -static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
386 - struct crypt_kop kop;
387 - BIGNUM *r = NULL, *s = NULL;
388 - DSA_SIG *dsaret = NULL;
391 + * Get generator into a plain buffer. If length is less than
392 + * q_len then add leading padding bytes.
394 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
395 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
399 - if ((r = BN_new()) == NULL)
400 + priv_key_len = r_len;
402 + * Get private key into a plain buffer. If length is less than
403 + * r_len then add leading padding bytes.
405 + if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
406 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
408 - if ((s = BN_new()) == NULL) {
412 + /* Allocate memory to store hash. */
413 + f = OPENSSL_malloc(r_len);
415 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
419 - memset(&kop, 0, sizeof kop);
420 + /* Add padding, since SEC expects hash to of size r_len */
422 + memset(f, 0, r_len - dlen);
424 + /* Skip leading bytes if dgst_len < r_len */
425 + memcpy(f + r_len - dlen, dgst, dlen);
427 kop.crk_op = CRK_DSA_SIGN;
429 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
430 - kop.crk_param[0].crp_p = (caddr_t) dgst;
431 - kop.crk_param[0].crp_nbits = dlen * 8;
432 - if (bn2crparam(dsa->p, &kop.crk_param[1]))
434 - if (bn2crparam(dsa->q, &kop.crk_param[2]))
436 - if (bn2crparam(dsa->g, &kop.crk_param[3]))
437 + kop.crk_param[0].crp_p = (void *)f;
438 + kop.crk_param[0].crp_nbits = r_len * 8;
439 + kop.crk_param[1].crp_p = (void *)q;
440 + kop.crk_param[1].crp_nbits = q_len * 8;
441 + kop.crk_param[2].crp_p = (void *)r;
442 + kop.crk_param[2].crp_nbits = r_len * 8;
443 + kop.crk_param[3].crp_p = (void *)g;
444 + kop.crk_param[3].crp_nbits = g_len * 8;
445 + kop.crk_param[4].crp_p = (void *)priv_key;
446 + kop.crk_param[4].crp_nbits = priv_key_len * 8;
447 + kop.crk_iparams = 5;
449 + ret = cryptodev_asym(&kop, r_len, c, r_len, d);
452 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DECODE_ERROR);
454 - if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
457 + dsaret = DSA_SIG_new();
458 + if (dsaret == NULL)
460 - kop.crk_iparams = 5;
464 - if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
465 - BN_num_bytes(dsa->q), s) == 0) {
466 - dsaret = DSA_SIG_new();
467 - if (dsaret == NULL)
477 const DSA_METHOD *meth = DSA_OpenSSL();
482 dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa);
488 - kop.crk_param[0].crp_p = NULL;
494 @@ -1532,43 +1675,175 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
495 DSA_SIG *sig, DSA *dsa)
497 struct crypt_kop kop;
499 + int dsaret = 1, q_len = 0, r_len = 0, g_len = 0;
500 + int w_len = 0, c_len = 0, d_len = 0, ret = -1;
501 + unsigned char *q = NULL, *r = NULL, *w = NULL, *g = NULL;
502 + unsigned char *c = NULL, *d = NULL, *f = NULL;
504 memset(&kop, 0, sizeof kop);
505 kop.crk_op = CRK_DSA_VERIFY;
507 - /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
508 - kop.crk_param[0].crp_p = (caddr_t) dgst;
509 - kop.crk_param[0].crp_nbits = dlen * 8;
510 - if (bn2crparam(dsa->p, &kop.crk_param[1]))
511 + if (spcf_bn2bin(dsa->p, &q, &q_len)) {
512 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
516 + /* Get Order of field of private keys */
517 + if (spcf_bn2bin(dsa->q, &r, &r_len)) {
518 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
524 + * Get generator into a plain buffer. If length is less than
525 + * q_len then add leading padding bytes.
527 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
528 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
530 - if (bn2crparam(dsa->q, &kop.crk_param[2]))
534 + * Get public key into a plain buffer. If length is less than
535 + * q_len then add leading padding bytes.
537 + if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
538 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
540 - if (bn2crparam(dsa->g, &kop.crk_param[3]))
543 + * Get the 1st part of signature into a flat buffer with
544 + * appropriate padding
548 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
549 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
551 - if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
555 + * Get the 2nd part of signature into a flat buffer with
556 + * appropriate padding
560 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
561 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
563 - if (bn2crparam(sig->r, &kop.crk_param[5]))
567 + if (dlen > r_len) {
568 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
570 - if (bn2crparam(sig->s, &kop.crk_param[6]))
573 + /* Allocate memory to store hash. */
574 + f = OPENSSL_malloc(r_len);
576 + DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
580 + /* Add padding, since SEC expects hash to of size r_len */
582 + memset(f, 0, r_len - dlen);
584 + /* Skip leading bytes if dgst_len < r_len */
585 + memcpy(f + r_len - dlen, dgst, dlen);
587 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
588 + kop.crk_param[0].crp_p = (void *)f;
589 + kop.crk_param[0].crp_nbits = r_len * 8;
590 + kop.crk_param[1].crp_p = q;
591 + kop.crk_param[1].crp_nbits = q_len * 8;
592 + kop.crk_param[2].crp_p = r;
593 + kop.crk_param[2].crp_nbits = r_len * 8;
594 + kop.crk_param[3].crp_p = g;
595 + kop.crk_param[3].crp_nbits = g_len * 8;
596 + kop.crk_param[4].crp_p = w;
597 + kop.crk_param[4].crp_nbits = w_len * 8;
598 + kop.crk_param[5].crp_p = c;
599 + kop.crk_param[5].crp_nbits = c_len * 8;
600 + kop.crk_param[6].crp_p = d;
601 + kop.crk_param[6].crp_nbits = d_len * 8;
604 - if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
606 - * OCF success value is 0, if not zero, change dsaret to fail
608 - if (0 != kop.crk_status)
611 - const DSA_METHOD *meth = DSA_OpenSSL();
612 + if ((cryptodev_asym(&kop, 0, NULL, 0, NULL))) {
613 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
617 - dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa);
619 + * OCF success value is 0, if not zero, change dsaret to fail
621 + if (0 != kop.crk_status) {
622 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, DSA_R_DECODE_ERROR);
626 - kop.crk_param[0].crp_p = NULL;
632 + const DSA_METHOD *meth = DSA_OpenSSL();
633 + dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa);
638 +/* Cryptodev DSA Key Gen routine */
639 +static int cryptodev_dsa_keygen(DSA *dsa)
641 + struct crypt_kop kop;
642 + int ret = 1, g_len;
643 + unsigned char *g = NULL;
645 + if (dsa->priv_key == NULL) {
646 + if ((dsa->priv_key = BN_new()) == NULL)
650 + if (dsa->pub_key == NULL) {
651 + if ((dsa->pub_key = BN_new()) == NULL)
655 + g_len = BN_num_bytes(dsa->p);
657 + * Get generator into a plain buffer. If length is less than
658 + * p_len then add leading padding bytes.
660 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
661 + DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
665 + memset(&kop, 0, sizeof kop);
667 + kop.crk_op = CRK_DSA_GENERATE_KEY;
668 + if (bn2crparam(dsa->p, &kop.crk_param[0]))
670 + if (bn2crparam(dsa->q, &kop.crk_param[1]))
672 + kop.crk_param[2].crp_p = g;
673 + kop.crk_param[2].crp_nbits = g_len * 8;
674 + kop.crk_iparams = 3;
676 + /* pub_key is or prime length while priv key is of length of order */
677 + if (cryptodev_asym(&kop, BN_num_bytes(dsa->p), dsa->pub_key,
678 + BN_num_bytes(dsa->q), dsa->priv_key))
684 + const DSA_METHOD *meth = DSA_OpenSSL();
685 + ret = (meth->dsa_keygen) (dsa);
690 static DSA_METHOD cryptodev_dsa = {
691 @@ -1584,12 +1859,558 @@ static DSA_METHOD cryptodev_dsa = {
696 -cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
697 - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
698 - BN_MONT_CTX *m_ctx)
699 +static ECDSA_METHOD cryptodev_ecdsa = {
700 + "cryptodev ECDSA method",
702 + NULL, /* ecdsa_sign_setup */
706 + NULL /* app_data */
709 +typedef enum ec_curve_s {
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,
717 + const BIGNUM *in_r, EC_KEY *eckey)
719 - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
720 + BIGNUM *m = NULL, *p = NULL, *a = NULL;
721 + BIGNUM *b = NULL, *x = NULL, *y = NULL;
722 + BN_CTX *ctx = NULL;
723 + ECDSA_SIG *ret = NULL;
724 + ECDSA_DATA *ecdsa = NULL;
725 + unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL;
726 + unsigned char *s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst =
728 + int i = 0, q_len = 0, priv_key_len = 0, r_len = 0;
729 + int g_len = 0, d_len = 0, ab_len = 0;
730 + const BIGNUM *order = NULL, *priv_key = NULL;
731 + const EC_GROUP *group = NULL;
732 + struct crypt_kop kop;
733 + ec_curve_t ec_crv = EC_PRIME;
735 + memset(&kop, 0, sizeof(kop));
736 + ecdsa = ecdsa_check(eckey);
738 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
742 + group = EC_KEY_get0_group(eckey);
743 + priv_key = EC_KEY_get0_private_key(eckey);
745 + if (!group || !priv_key) {
746 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
750 + if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
751 + (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
752 + (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
753 + (y = BN_new()) == NULL) {
754 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
758 + order = &group->order;
759 + if (!order || BN_is_zero(order)) {
760 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
764 + i = BN_num_bits(order);
766 + * Need to truncate digest if it is too long: first truncate whole bytes
768 + if (8 * dgst_len > i)
769 + dgst_len = (i + 7) / 8;
771 + if (!BN_bin2bn(dgst, dgst_len, m)) {
772 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
776 + /* If still too long truncate remaining bits with a shift */
777 + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
778 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
782 + /* copy the truncated bits into plain buffer */
783 + if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
784 + fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__,
789 + ret = ECDSA_SIG_new();
791 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
795 + /* check if this is prime or binary EC request */
796 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
797 + NID_X9_62_prime_field) {
799 + /* get the generator point pair */
800 + if (!EC_POINT_get_affine_coordinates_GFp
801 + (group, EC_GROUP_get0_generator(group), x, y, ctx)) {
802 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
806 + /* get the ECC curve parameters */
807 + if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
808 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
811 + } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
812 + NID_X9_62_characteristic_two_field) {
813 + ec_crv = EC_BINARY;
814 + /* get the ECC curve parameters */
815 + if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) {
816 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
820 + /* get the generator point pair */
821 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
822 + EC_GROUP_get0_generator
823 + (group), x, y, ctx)) {
824 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
828 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
832 + if (spcf_bn2bin(order, &r, &r_len)) {
833 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
837 + if (spcf_bn2bin(p, &q, &q_len)) {
838 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
842 + priv_key_len = r_len;
845 + * If BN_num_bytes of priv_key returns less then r_len then
846 + * add padding bytes before the key
848 + if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len)) {
849 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
853 + /* Generation of ECC curve parameters */
854 + ab_len = 2 * q_len;
855 + ab = eng_copy_curve_points(a, b, ab_len, q_len);
857 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
861 + if (ec_crv == EC_BINARY) {
862 + if (eng_ec_get_cparam
863 + (EC_GROUP_get_curve_name(group), ab + q_len, q_len)) {
864 + unsigned char *c_temp = NULL;
865 + int c_temp_len = q_len;
866 + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
867 + memcpy(ab + q_len, c_temp, q_len);
871 + kop.curve_type = ECC_BINARY;
874 + /* Calculation of Generator point */
876 + g_xy = eng_copy_curve_points(x, y, g_len, q_len);
878 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
882 + /* Memory allocation for first part of digital signature */
885 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
891 + /* Memory allocation for second part of digital signature */
894 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
898 + /* memory for message representative */
901 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
905 + /* Add padding, since SEC expects hash to of size r_len */
906 + memset(f, 0, r_len - dgst_len);
908 + /* Skip leading bytes if dgst_len < r_len */
909 + memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
911 + dgst_len += r_len - dgst_len;
912 + kop.crk_op = CRK_DSA_SIGN;
913 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
914 + kop.crk_param[0].crp_p = f;
915 + kop.crk_param[0].crp_nbits = dgst_len * 8;
916 + kop.crk_param[1].crp_p = q;
917 + kop.crk_param[1].crp_nbits = q_len * 8;
918 + kop.crk_param[2].crp_p = r;
919 + kop.crk_param[2].crp_nbits = r_len * 8;
920 + kop.crk_param[3].crp_p = g_xy;
921 + kop.crk_param[3].crp_nbits = g_len * 8;
922 + kop.crk_param[4].crp_p = s;
923 + kop.crk_param[4].crp_nbits = priv_key_len * 8;
924 + kop.crk_param[5].crp_p = ab;
925 + kop.crk_param[5].crp_nbits = ab_len * 8;
926 + kop.crk_iparams = 6;
927 + kop.crk_param[6].crp_p = c;
928 + kop.crk_param[6].crp_nbits = d_len * 8;
929 + kop.crk_param[7].crp_p = d;
930 + kop.crk_param[7].crp_nbits = d_len * 8;
931 + kop.crk_oparams = 2;
933 + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
934 + /* Check if ret->r and s needs to allocated */
935 + crparam2bn(&kop.crk_param[6], ret->r);
936 + crparam2bn(&kop.crk_param[7], ret->s);
938 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
939 + ret = (meth->ecdsa_do_sign) (dgst, dgst_len, in_kinv, in_r, eckey);
941 + kop.crk_param[0].crp_p = NULL;
945 + ECDSA_SIG_free(ret);
951 +static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len,
952 + ECDSA_SIG *sig, EC_KEY *eckey)
954 + BIGNUM *m = NULL, *p = NULL, *a = NULL, *b = NULL;
955 + BIGNUM *x = NULL, *y = NULL, *w_x = NULL, *w_y = NULL;
956 + BN_CTX *ctx = NULL;
957 + ECDSA_DATA *ecdsa = NULL;
958 + unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL, *w_xy =
960 + unsigned char *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL;
961 + int i = 0, q_len = 0, pub_key_len = 0, r_len = 0, c_len = 0, g_len = 0;
962 + int d_len = 0, ab_len = 0, ret = -1;
963 + const EC_POINT *pub_key = NULL;
964 + const BIGNUM *order = NULL;
965 + const EC_GROUP *group = NULL;
966 + ec_curve_t ec_crv = EC_PRIME;
967 + struct crypt_kop kop;
969 + memset(&kop, 0, sizeof kop);
970 + ecdsa = ecdsa_check(eckey);
972 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
976 + group = EC_KEY_get0_group(eckey);
977 + pub_key = EC_KEY_get0_public_key(eckey);
979 + if (!group || !pub_key) {
980 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
984 + if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL ||
985 + (a = BN_new()) == NULL || (b = BN_new()) == NULL ||
986 + (p = BN_new()) == NULL || (x = BN_new()) == NULL ||
987 + (y = BN_new()) == NULL || (w_x = BN_new()) == NULL ||
988 + (w_y = BN_new()) == NULL) {
989 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
993 + order = &group->order;
994 + if (!order || BN_is_zero(order)) {
995 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
999 + i = BN_num_bits(order);
1001 + * Need to truncate digest if it is too long: first truncate whole *
1004 + if (8 * dgst_len > i)
1005 + dgst_len = (i + 7) / 8;
1007 + if (!BN_bin2bn(dgst, dgst_len, m)) {
1008 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1012 + /* If still too long truncate remaining bits with a shift */
1013 + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
1014 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
1017 + /* copy the truncated bits into plain buffer */
1018 + if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) {
1019 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1023 + /* check if this is prime or binary EC request */
1024 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1025 + NID_X9_62_prime_field) {
1026 + ec_crv = EC_PRIME;
1028 + /* get the generator point pair */
1029 + if (!EC_POINT_get_affine_coordinates_GFp(group,
1030 + EC_GROUP_get0_generator
1031 + (group), x, y, ctx)) {
1032 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1036 + /* get the public key pair for prime curve */
1037 + if (!EC_POINT_get_affine_coordinates_GFp(group,
1038 + pub_key, w_x, w_y, ctx)) {
1039 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1043 + /* get the ECC curve parameters */
1044 + if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
1045 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1048 + } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1049 + NID_X9_62_characteristic_two_field) {
1050 + ec_crv = EC_BINARY;
1051 + /* get the ECC curve parameters */
1052 + if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) {
1053 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1057 + /* get the generator point pair */
1058 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1059 + EC_GROUP_get0_generator
1060 + (group), x, y, ctx)) {
1061 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1065 + /* get the public key pair for binary curve */
1066 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1067 + pub_key, w_x, w_y, ctx)) {
1068 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1072 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
1076 + /* Get the order of the subgroup of private keys */
1077 + if (spcf_bn2bin((BIGNUM *)order, &r, &r_len)) {
1078 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1082 + /* Get the irreducible polynomial that creates the field */
1083 + if (spcf_bn2bin(p, &q, &q_len)) {
1084 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1088 + /* Get the public key into a flat buffer with appropriate padding */
1089 + pub_key_len = 2 * q_len;
1091 + w_xy = eng_copy_curve_points(w_x, w_y, pub_key_len, q_len);
1093 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1097 + /* Generation of ECC curve parameters */
1098 + ab_len = 2 * q_len;
1100 + ab = eng_copy_curve_points(a, b, ab_len, q_len);
1102 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1106 + if (ec_crv == EC_BINARY) {
1107 + /* copy b' i.e c(b), instead of only b */
1108 + if (eng_ec_get_cparam
1109 + (EC_GROUP_get_curve_name(group), ab + q_len, q_len)) {
1110 + unsigned char *c_temp = NULL;
1111 + int c_temp_len = q_len;
1112 + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1113 + memcpy(ab + q_len, c_temp, q_len);
1117 + kop.curve_type = ECC_BINARY;
1120 + /* Calculation of Generator point */
1121 + g_len = 2 * q_len;
1123 + g_xy = eng_copy_curve_points(x, y, g_len, q_len);
1125 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1130 + * Get the 1st part of signature into a flat buffer with
1131 + * appropriate padding
1133 + if (BN_num_bytes(sig->r) < r_len)
1136 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
1137 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1142 + * Get the 2nd part of signature into a flat buffer with
1143 + * appropriate padding
1145 + if (BN_num_bytes(sig->s) < r_len)
1148 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1149 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1153 + /* memory for message representative */
1154 + f = malloc(r_len);
1156 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1160 + /* Add padding, since SEC expects hash to of size r_len */
1161 + memset(f, 0, r_len - dgst_len);
1163 + /* Skip leading bytes if dgst_len < r_len */
1164 + memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
1165 + dgst_len += r_len - dgst_len;
1166 + kop.crk_op = CRK_DSA_VERIFY;
1167 + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1168 + kop.crk_param[0].crp_p = f;
1169 + kop.crk_param[0].crp_nbits = dgst_len * 8;
1170 + kop.crk_param[1].crp_p = q;
1171 + kop.crk_param[1].crp_nbits = q_len * 8;
1172 + kop.crk_param[2].crp_p = r;
1173 + kop.crk_param[2].crp_nbits = r_len * 8;
1174 + kop.crk_param[3].crp_p = g_xy;
1175 + kop.crk_param[3].crp_nbits = g_len * 8;
1176 + kop.crk_param[4].crp_p = w_xy;
1177 + kop.crk_param[4].crp_nbits = pub_key_len * 8;
1178 + kop.crk_param[5].crp_p = ab;
1179 + kop.crk_param[5].crp_nbits = ab_len * 8;
1180 + kop.crk_param[6].crp_p = c;
1181 + kop.crk_param[6].crp_nbits = d_len * 8;
1182 + kop.crk_param[7].crp_p = d;
1183 + kop.crk_param[7].crp_nbits = d_len * 8;
1184 + kop.crk_iparams = 8;
1186 + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1188 + * OCF success value is 0, if not zero, change ret to fail
1190 + if (0 == kop.crk_status)
1193 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1195 + ret = (meth->ecdsa_do_verify) (dgst, dgst_len, sig, eckey);
1197 + kop.crk_param[0].crp_p = NULL;
1204 +static int cryptodev_dh_keygen(DH *dh)
1206 + struct crypt_kop kop;
1207 + int ret = 1, g_len;
1208 + unsigned char *g = NULL;
1210 + if (dh->priv_key == NULL) {
1211 + if ((dh->priv_key = BN_new()) == NULL)
1215 + if (dh->pub_key == NULL) {
1216 + if ((dh->pub_key = BN_new()) == NULL)
1220 + g_len = BN_num_bytes(dh->p);
1222 + * Get generator into a plain buffer. If length is less than
1223 + * q_len then add leading padding bytes.
1225 + if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
1226 + DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
1230 + memset(&kop, 0, sizeof kop);
1231 + kop.crk_op = CRK_DH_GENERATE_KEY;
1232 + if (bn2crparam(dh->p, &kop.crk_param[0]))
1234 + if (bn2crparam(dh->q, &kop.crk_param[1]))
1236 + kop.crk_param[2].crp_p = g;
1237 + kop.crk_param[2].crp_nbits = g_len * 8;
1238 + kop.crk_iparams = 3;
1240 + /* pub_key is or prime length while priv key is of length of order */
1241 + if (cryptodev_asym(&kop, BN_num_bytes(dh->p), dh->pub_key,
1242 + BN_num_bytes(dh->q), dh->priv_key))
1248 + const DH_METHOD *meth = DH_OpenSSL();
1249 + ret = (meth->generate_key) (dh);
1255 @@ -1597,41 +2418,236 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1257 struct crypt_kop kop;
1261 + BIGNUM *temp = NULL;
1262 + unsigned char *padded_pub_key = NULL, *p = NULL;
1264 + if ((fd = get_asym_dev_crypto()) < 0)
1267 + memset(&kop, 0, sizeof kop);
1268 + kop.crk_op = CRK_DH_COMPUTE_KEY;
1269 + /* inputs: dh->priv_key pub_key dh->p key */
1270 + spcf_bn2bin(dh->p, &p, &p_len);
1271 + spcf_bn2bin_ex(pub_key, &padded_pub_key, &p_len);
1272 + if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1275 + kop.crk_param[1].crp_p = padded_pub_key;
1276 + kop.crk_param[1].crp_nbits = p_len * 8;
1277 + kop.crk_param[2].crp_p = p;
1278 + kop.crk_param[2].crp_nbits = p_len * 8;
1279 + kop.crk_iparams = 3;
1280 + kop.crk_param[3].crp_p = (void *)key;
1281 + kop.crk_param[3].crp_nbits = p_len * 8;
1282 + kop.crk_oparams = 1;
1285 + if (ioctl(fd, CIOCKEY, &kop))
1288 + if ((temp = BN_new())) {
1289 + if (!BN_bin2bn(key, p_len, temp)) {
1290 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
1293 + if (dhret > BN_num_bytes(temp))
1294 + dhret = BN_bn2bin(temp, key);
1298 - if ((fd = get_asym_dev_crypto()) < 0) {
1299 + kop.crk_param[3].crp_p = NULL;
1304 const DH_METHOD *meth = DH_OpenSSL();
1306 - return ((meth->compute_key) (key, pub_key, dh));
1307 + dhret = (meth->compute_key) (key, pub_key, dh);
1312 - keylen = BN_num_bits(dh->p);
1313 +int cryptodev_ecdh_compute_key(void *out, size_t outlen,
1314 + const EC_POINT *pub_key, EC_KEY *ecdh,
1315 + void *(*KDF) (const void *in, size_t inlen,
1316 + void *out, size_t *outlen))
1318 + ec_curve_t ec_crv = EC_PRIME;
1319 + unsigned char *q = NULL, *w_xy = NULL, *ab = NULL, *s = NULL, *r = NULL;
1320 + BIGNUM *w_x = NULL, *w_y = NULL;
1321 + int q_len = 0, ab_len = 0, pub_key_len = 0, r_len = 0, priv_key_len = 0;
1322 + BIGNUM *p = NULL, *a = NULL, *b = NULL;
1324 + EC_POINT *tmp = NULL;
1325 + BIGNUM *x = NULL, *y = NULL;
1326 + const BIGNUM *priv_key;
1327 + const EC_GROUP *group = NULL;
1329 + size_t buflen, len;
1330 + struct crypt_kop kop;
1332 memset(&kop, 0, sizeof kop);
1333 - kop.crk_op = CRK_DH_COMPUTE_KEY;
1335 - /* inputs: dh->priv_key pub_key dh->p key */
1336 - if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1337 + if ((ctx = BN_CTX_new()) == NULL)
1339 - if (bn2crparam(pub_key, &kop.crk_param[1]))
1340 + BN_CTX_start(ctx);
1341 + x = BN_CTX_get(ctx);
1342 + y = BN_CTX_get(ctx);
1343 + p = BN_CTX_get(ctx);
1344 + a = BN_CTX_get(ctx);
1345 + b = BN_CTX_get(ctx);
1346 + w_x = BN_CTX_get(ctx);
1347 + w_y = BN_CTX_get(ctx);
1349 + if (!x || !y || !p || !a || !b || !w_x || !w_y) {
1350 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
1352 - if (bn2crparam(dh->p, &kop.crk_param[2]))
1355 + priv_key = EC_KEY_get0_private_key(ecdh);
1356 + if (priv_key == NULL) {
1357 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_NO_PRIVATE_VALUE);
1359 - kop.crk_iparams = 3;
1362 - kop.crk_param[3].crp_p = (caddr_t) key;
1363 - kop.crk_param[3].crp_nbits = keylen * 8;
1364 - kop.crk_oparams = 1;
1365 + group = EC_KEY_get0_group(ecdh);
1366 + if ((tmp = EC_POINT_new(group)) == NULL) {
1367 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
1371 - if (ioctl(fd, CIOCKEY, &kop) == -1) {
1372 - const DH_METHOD *meth = DH_OpenSSL();
1373 + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
1374 + NID_X9_62_prime_field) {
1375 + ec_crv = EC_PRIME;
1377 - dhret = (meth->compute_key) (key, pub_key, dh);
1378 + if (!EC_POINT_get_affine_coordinates_GFp(group,
1379 + EC_GROUP_get0_generator
1380 + (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_GFp(group, p, a, b, ctx)) {
1387 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1391 + /* get the public key pair for prime curve */
1392 + if (!EC_POINT_get_affine_coordinates_GFp
1393 + (group, pub_key, w_x, w_y, ctx)) {
1394 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1398 + ec_crv = EC_BINARY;
1400 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1401 + EC_GROUP_get0_generator
1402 + (group), x, y, ctx)) {
1403 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE);
1407 + /* get the ECC curve parameters */
1408 + if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) {
1409 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1413 + /* get the public key pair for binary curve */
1414 + if (!EC_POINT_get_affine_coordinates_GF2m(group,
1415 + pub_key, w_x, w_y, ctx)) {
1416 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
1421 + /* irreducible polynomial that creates the field */
1422 + if (spcf_bn2bin((BIGNUM *)&group->order, &r, &r_len)) {
1423 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1427 + /* Get the irreducible polynomial that creates the field */
1428 + if (spcf_bn2bin(p, &q, &q_len)) {
1429 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1433 + /* Get the public key into a flat buffer with appropriate padding */
1434 + pub_key_len = 2 * q_len;
1435 + w_xy = eng_copy_curve_points(w_x, w_y, pub_key_len, q_len);
1437 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1441 + /* Generation of ECC curve parameters */
1442 + ab_len = 2 * q_len;
1443 + ab = eng_copy_curve_points(a, b, ab_len, q_len);
1445 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
1449 + if (ec_crv == EC_BINARY) {
1450 + /* copy b' i.e c(b), instead of only b */
1451 + if (eng_ec_get_cparam
1452 + (EC_GROUP_get_curve_name(group), ab + q_len, q_len)) {
1453 + unsigned char *c_temp = NULL;
1454 + int c_temp_len = q_len;
1455 + if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len))
1456 + memcpy(ab + q_len, c_temp, q_len);
1460 + kop.curve_type = ECC_BINARY;
1462 + kop.curve_type = ECC_PRIME;
1464 + priv_key_len = r_len;
1467 + * If BN_num_bytes of priv_key returns less then r_len then
1468 + * add padding bytes before the key
1470 + if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
1471 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1475 + buflen = (EC_GROUP_get_degree(group) + 7) / 8;
1476 + len = BN_num_bytes(x);
1477 + if (len > buflen || q_len < buflen) {
1478 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
1482 + kop.crk_op = CRK_DH_COMPUTE_KEY;
1483 + kop.crk_param[0].crp_p = (void *)s;
1484 + kop.crk_param[0].crp_nbits = priv_key_len * 8;
1485 + kop.crk_param[1].crp_p = (void *)w_xy;
1486 + kop.crk_param[1].crp_nbits = pub_key_len * 8;
1487 + kop.crk_param[2].crp_p = (void *)q;
1488 + kop.crk_param[2].crp_nbits = q_len * 8;
1489 + kop.crk_param[3].crp_p = (void *)ab;
1490 + kop.crk_param[3].crp_nbits = ab_len * 8;
1491 + kop.crk_iparams = 4;
1492 + kop.crk_param[4].crp_p = (void *)out;
1493 + kop.crk_param[4].crp_nbits = q_len * 8;
1494 + kop.crk_oparams = 1;
1496 + if (cryptodev_asym(&kop, 0, NULL, 0, NULL)) {
1497 + const ECDH_METHOD *meth = ECDH_OpenSSL();
1498 + ret = (meth->compute_key) (out, outlen, pub_key, ecdh, KDF);
1502 - kop.crk_param[3].crp_p = NULL;
1503 + kop.crk_param[4].crp_p = NULL;
1509 static DH_METHOD cryptodev_dh = {
1510 @@ -1645,6 +2661,14 @@ static DH_METHOD cryptodev_dh = {
1514 +static ECDH_METHOD cryptodev_ecdh = {
1515 + "cryptodev ECDH method",
1516 + NULL, /* cryptodev_ecdh_compute_key */
1519 + NULL /* app_data */
1523 * ctrl right now is just a wrapper that doesn't do much
1524 * but I expect we'll want some options soon.
1525 @@ -1724,24 +2748,39 @@ void ENGINE_load_cryptodev(void)
1526 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1527 if (cryptodev_asymfeat & CRF_DSA_SIGN)
1528 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1529 - if (cryptodev_asymfeat & CRF_MOD_EXP) {
1530 - cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1531 - cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1533 if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1534 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1535 + if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY)
1536 + cryptodev_dsa.dsa_keygen = cryptodev_dsa_keygen;
1539 if (ENGINE_set_DH(engine, &cryptodev_dh)) {
1540 const DH_METHOD *dh_meth = DH_OpenSSL();
1541 + memcpy(&cryptodev_dh, dh_meth, sizeof(DH_METHOD));
1542 + if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1543 + cryptodev_dh.compute_key = cryptodev_dh_compute_key;
1545 + if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) {
1546 + cryptodev_dh.generate_key = cryptodev_dh_keygen;
1550 - cryptodev_dh.generate_key = dh_meth->generate_key;
1551 - cryptodev_dh.compute_key = dh_meth->compute_key;
1552 - cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1553 - if (cryptodev_asymfeat & CRF_MOD_EXP) {
1554 - cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1555 - if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1556 - cryptodev_dh.compute_key = cryptodev_dh_compute_key;
1557 + if (ENGINE_set_ECDSA(engine, &cryptodev_ecdsa)) {
1558 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1559 + memcpy(&cryptodev_ecdsa, meth, sizeof(ECDSA_METHOD));
1560 + if (cryptodev_asymfeat & CRF_DSA_SIGN) {
1561 + cryptodev_ecdsa.ecdsa_do_sign = cryptodev_ecdsa_do_sign;
1563 + if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
1564 + cryptodev_ecdsa.ecdsa_do_verify = cryptodev_ecdsa_verify;
1568 + if (ENGINE_set_ECDH(engine, &cryptodev_ecdh)) {
1569 + const ECDH_METHOD *ecdh_meth = ECDH_OpenSSL();
1570 + memcpy(&cryptodev_ecdh, ecdh_meth, sizeof(ECDH_METHOD));
1571 + if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) {
1572 + cryptodev_ecdh.compute_key = cryptodev_ecdh_compute_key;