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
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 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)
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,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,
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;
65 +inline int spcf_bn2bin(BIGNUM *bn, unsigned char **bin, int *bin_len)
70 + len = BN_num_bytes(bn);
87 +inline int spcf_bn2bin_ex(BIGNUM *bn, unsigned char **bin, int *bin_len)
92 + len = BN_num_bytes(bn);
98 + p = malloc(*bin_len);
105 + if (len < *bin_len) {
106 + /* place padding */
107 + memset(p, 0, (*bin_len - len));
108 + BN_bn2bin(bn,p+(*bin_len-len));
114 + if (len >= *bin_len)
121 + * Convert an ECC F2m 'b' parameter into the 'c' parameter.
123 + * q, the curve's modulus
124 + * b, the curve's b parameter
125 + * (a bignum for b, a buffer for c)
127 + * c, written into bin, right-adjusted to fill q_len bytes.
130 +eng_ec_compute_cparam(const BIGNUM* b, const BIGNUM* q,
131 + unsigned char **bin, int *bin_len)
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;
139 + if (!c || !exp || !ctx || *bin)
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)
147 + * and then compute c = b^exp
149 + BN_lshift(exp, BN_value_one(), m-2);
150 + BN_GF2m_mod_exp(c, b, exp, q, ctx);
152 + spcf_bn2bin_ex(c, bin, bin_len);
155 + if (ctx) BN_CTX_free(ctx);
157 + if (exp) BN_free(exp);
161 static const ENGINE_CMD_DEFN cryptodev_defns[] = {
164 @@ -1139,7 +1232,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
166 bn2crparam(const BIGNUM *a, struct crparam *crp)
172 @@ -1156,15 +1248,7 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
174 crp->crp_p = (caddr_t) b;
175 crp->crp_nbits = bits;
177 - for (i = 0, j = 0; i < a->top; i++) {
178 - for (k = 0; k < BN_BITS2 / 8; k++) {
179 - if ((j + k) >= bytes)
181 - b[j + k] = a->d[i] >> (k * 8);
185 + BN_bn2bin(a, crp->crp_p);
189 @@ -1172,22 +1256,14 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
191 crparam2bn(struct crparam *crp, BIGNUM *a)
197 bytes = (crp->crp_nbits + 7) / 8;
202 - if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
205 - for (i = 0; i < bytes; i++)
206 - pd[i] = crp->crp_p[bytes - i - 1];
208 - BN_bin2bn(pd, bytes, a);
210 + BN_bin2bn(crp->crp_p, bytes, a);
214 @@ -1235,6 +1311,32 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
218 +/* Close an opened instance of cryptodev engine */
219 +void cryptodev_close_instance(void *handle)
224 + fd = *(int *)handle;
230 +/* Create an instance of cryptodev for asynchronous interface */
231 +void *cryptodev_init_instance(void)
233 + int *fd = malloc(sizeof(int));
236 + if ((*fd = open("/dev/crypto", O_RDWR, 0)) == -1) {
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,
251 - memset(&kop, 0, sizeof kop);
252 kop.crk_op = CRK_MOD_EXP;
254 + kop.crk_oparams = 0;
255 + kop.crk_status = 0;
256 /* inputs: a^p % m */
257 if (bn2crparam(a, &kop.crk_param[0]))
259 @@ -1293,28 +1395,38 @@ static int
260 cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
262 struct crypt_kop kop;
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;
267 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
268 /* XXX 0 means failure?? */
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]))
286 - if (bn2crparam(rsa->q, &kop.crk_param[1]))
288 - if (bn2crparam(I, &kop.crk_param[2]))
290 - if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
292 - if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
294 - if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
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;
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 */
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)
320 - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
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)
328 +cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
335 - /* v = ( g^u1 * y^u2 mod p ) mod q */
336 - /* let t1 = g ^ u1 mod p */
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;
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);
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) {
356 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
358 - /* let u1 = t1 * t2 mod p */
359 - if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
362 + if (spcf_bn2bin(dsa->p, &q, &q_len)) {
363 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
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);
380 + if (dlen > r_len) {
381 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
386 -cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
388 - struct crypt_kop kop;
389 - BIGNUM *r = NULL, *s = NULL;
390 - DSA_SIG *dsaret = NULL;
393 + * Get generator into a plain buffer. If length is less than
394 + * q_len then add leading padding bytes.
396 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
397 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
401 - if ((r = BN_new()) == NULL)
402 + priv_key_len = r_len;
404 + * Get private key into a plain buffer. If length is less than
405 + * r_len then add leading padding bytes.
407 + if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) {
408 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
410 - if ((s = BN_new()) == NULL) {
414 + /* Allocate memory to store hash. */
415 + f = OPENSSL_malloc (r_len);
417 + DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
421 - memset(&kop, 0, sizeof kop);
422 + /* Add padding, since SEC expects hash to of size r_len */
424 + memset(f, 0, r_len - dlen);
426 + /* Skip leading bytes if dgst_len < r_len */
427 + memcpy(f + r_len - dlen, dgst, dlen);
429 kop.crk_op = CRK_DSA_SIGN;
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]))
436 - if (bn2crparam(dsa->q, &kop.crk_param[2]))
438 - if (bn2crparam(dsa->g, &kop.crk_param[3]))
440 - if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
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;
454 - if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
455 - BN_num_bytes(dsa->q), s) == 0) {
456 - dsaret = DSA_SIG_new();
460 - const DSA_METHOD *meth = DSA_OpenSSL();
463 - dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
464 + ret = cryptodev_asym(&kop, r_len, c, r_len, d);
467 + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DECODE_ERROR);
471 - kop.crk_param[0].crp_p = NULL;
473 + dsaret = DSA_SIG_new();
481 + const DSA_METHOD *meth = DSA_OpenSSL();
486 + dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
492 @@ -1441,42 +1580,179 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
493 DSA_SIG *sig, DSA *dsa)
495 struct crypt_kop kop;
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;
502 memset(&kop, 0, sizeof kop);
503 kop.crk_op = CRK_DSA_VERIFY;
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);
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);
518 - if (bn2crparam(dsa->q, &kop.crk_param[2]))
523 + * Get generator into a plain buffer. If length is less than
524 + * q_len then add leading padding bytes.
526 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
527 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
529 - if (bn2crparam(dsa->g, &kop.crk_param[3]))
533 + * Get public key into a plain buffer. If length is less than
534 + * q_len then add leading padding bytes.
536 + if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) {
537 + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
541 + * Get the 1st part of signature into a flat buffer with
542 + * appropriate padding
546 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
547 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
549 - if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
553 + * Get the 2nd part of signature into a flat buffer with
554 + * appropriate padding
558 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
559 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
561 - if (bn2crparam(sig->r, &kop.crk_param[5]))
566 + if (dlen > r_len) {
567 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
569 - if (bn2crparam(sig->s, &kop.crk_param[6]))
572 + /* Allocate memory to store hash. */
573 + f = OPENSSL_malloc (r_len);
575 + DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
579 + /* Add padding, since SEC expects hash to of size r_len */
581 + memset(f, 0, r_len - dlen);
583 + /* Skip leading bytes if dgst_len < r_len */
584 + memcpy(f + r_len - dlen, dgst, dlen);
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;
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;
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);
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);
620 - kop.crk_param[0].crp_p = NULL;
626 + const DSA_METHOD *meth = DSA_OpenSSL();
628 + dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
633 +/* Cryptodev DSA Key Gen routine */
634 +static int cryptodev_dsa_keygen(DSA *dsa)
636 + struct crypt_kop kop;
637 + int ret = 1, g_len;
638 + unsigned char *g = NULL;
640 + if (dsa->priv_key == NULL) {
641 + if ((dsa->priv_key=BN_new()) == NULL)
645 + if (dsa->pub_key == NULL) {
646 + if ((dsa->pub_key=BN_new()) == NULL)
650 + g_len = BN_num_bytes(dsa->p);
652 + * Get generator into a plain buffer. If length is less than
653 + * p_len then add leading padding bytes.
655 + if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) {
656 + DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
660 + memset(&kop, 0, sizeof kop);
662 + kop.crk_op = CRK_DSA_GENERATE_KEY;
663 + if (bn2crparam(dsa->p, &kop.crk_param[0]))
665 + if (bn2crparam(dsa->q, &kop.crk_param[1]))
667 + kop.crk_param[2].crp_p = g;
668 + kop.crk_param[2].crp_nbits = g_len * 8;
669 + kop.crk_iparams = 3;
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))
679 + const DSA_METHOD *meth = DSA_OpenSSL();
680 + ret = (meth->dsa_keygen)(dsa);
687 static DSA_METHOD cryptodev_dsa = {
688 "cryptodev DSA method",
690 @@ -1490,12 +1766,543 @@ static DSA_METHOD cryptodev_dsa = {
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",
701 + NULL, /* ecdsa_sign_setup */
705 + NULL /* app_data */
708 +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, const BIGNUM *in_r, EC_KEY *eckey)
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;
733 + memset(&kop, 0, sizeof(kop));
734 + ecdsa = ecdsa_check(eckey);
736 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
740 + group = EC_KEY_get0_group(eckey);
741 + priv_key = EC_KEY_get0_private_key(eckey);
743 + if (!group || !priv_key) {
744 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
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);
756 + order = &group->order;
757 + if (!order || BN_is_zero(order)) {
758 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS);
762 + i = BN_num_bits(order);
763 + /* Need to truncate digest if it is too long: first truncate whole
765 + if (8 * dgst_len > i)
766 + dgst_len = (i + 7)/8;
768 + if (!BN_bin2bn(dgst, dgst_len, m)) {
769 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
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);
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__);
785 + ret = ECDSA_SIG_new();
787 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
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) {
794 + /* get the generator point pair */
795 + if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group),
797 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
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);
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);
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);
821 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
825 + if (spcf_bn2bin(order, &r, &r_len)) {
826 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
830 + if (spcf_bn2bin(p, &q, &q_len)) {
831 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
835 + priv_key_len = r_len;
838 + * If BN_num_bytes of priv_key returns less then r_len then
839 + * add padding bytes before the key
841 + if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len)) {
842 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
846 + /* Generation of ECC curve parameters */
848 + ab = eng_copy_curve_points(a, b, ab_len, q_len);
850 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
854 + if (ec_crv == EC_BINARY) {
855 + if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len))
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);
864 + kop.curve_type = ECC_BINARY;
867 + /* Calculation of Generator point */
869 + g_xy = eng_copy_curve_points(x, y, g_len, q_len);
871 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
875 + /* Memory allocation for first part of digital signature */
878 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
884 + /* Memory allocation for second part of digital signature */
887 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
891 + /* memory for message representative */
894 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
898 + /* Add padding, since SEC expects hash to of size r_len */
899 + memset(f, 0, r_len - dgst_len);
901 + /* Skip leading bytes if dgst_len < r_len */
902 + memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len);
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;
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);
931 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
932 + ret = (meth->ecdsa_do_sign)(dgst, dgst_len, in_kinv, in_r, eckey);
934 + kop.crk_param[0].crp_p = NULL;
938 + ECDSA_SIG_free(ret);
944 +static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len,
945 + ECDSA_SIG *sig, EC_KEY *eckey)
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;
961 + memset(&kop, 0, sizeof kop);
962 + ecdsa = ecdsa_check(eckey);
964 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
968 + group = EC_KEY_get0_group(eckey);
969 + pub_key = EC_KEY_get0_public_key(eckey);
971 + if (!group || !pub_key) {
972 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
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);
985 + order = &group->order;
986 + if (!order || BN_is_zero(order)) {
987 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
991 + i = BN_num_bits(order);
992 + /* Need to truncate digest if it is too long: first truncate whole
994 + if (8 * dgst_len > i)
995 + dgst_len = (i + 7)/8;
997 + if (!BN_bin2bn(dgst, dgst_len, m)) {
998 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
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);
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);
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;
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);
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);
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);
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);
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);
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);
1058 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
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);
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);
1074 + /* Get the public key into a flat buffer with appropriate padding */
1075 + pub_key_len = 2 * q_len;
1077 + w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len);
1079 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1083 + /* Generation of ECC curve parameters */
1086 + ab = eng_copy_curve_points (a, b, ab_len, q_len);
1088 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
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))
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);
1103 + kop.curve_type = ECC_BINARY;
1106 + /* Calculation of Generator point */
1107 + g_len = 2 * q_len;
1109 + g_xy = eng_copy_curve_points (x, y, g_len, q_len);
1111 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1116 + * Get the 1st part of signature into a flat buffer with
1117 + * appropriate padding
1119 + if (BN_num_bytes(sig->r) < r_len)
1122 + if (spcf_bn2bin_ex(sig->r, &c, &c_len)) {
1123 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1128 + * Get the 2nd part of signature into a flat buffer with
1129 + * appropriate padding
1131 + if (BN_num_bytes(sig->s) < r_len)
1134 + if (spcf_bn2bin_ex(sig->s, &d, &d_len)) {
1135 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1139 + /* memory for message representative */
1140 + f = malloc(r_len);
1142 + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
1146 + /* Add padding, since SEC expects hash to of size r_len */
1147 + memset(f, 0, r_len-dgst_len);
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;
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)
1177 + const ECDSA_METHOD *meth = ECDSA_OpenSSL();
1179 + ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey);
1181 + kop.crk_param[0].crp_p = NULL;
1188 +static int cryptodev_dh_keygen(DH *dh)
1190 + struct crypt_kop kop;
1191 + int ret = 1, g_len;
1192 + unsigned char *g = NULL;
1194 + if (dh->priv_key == NULL) {
1195 + if ((dh->priv_key=BN_new()) == NULL)
1199 + if (dh->pub_key == NULL) {
1200 + if ((dh->pub_key=BN_new()) == NULL)
1204 + g_len = BN_num_bytes(dh->p);
1206 + * Get generator into a plain buffer. If length is less than
1207 + * q_len then add leading padding bytes.
1209 + if (spcf_bn2bin_ex(dh->g, &g, &g_len)) {
1210 + DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE);
1214 + memset(&kop, 0, sizeof kop);
1215 + kop.crk_op = CRK_DH_GENERATE_KEY;
1216 + if (bn2crparam(dh->p, &kop.crk_param[0]))
1218 + if (bn2crparam(dh->q, &kop.crk_param[1]))
1220 + kop.crk_param[2].crp_p = g;
1221 + kop.crk_param[2].crp_nbits = g_len * 8;
1222 + kop.crk_iparams = 3;
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))
1232 + const DH_METHOD *meth = DH_OpenSSL();
1233 + ret = (meth->generate_key)(dh);
1239 @@ -1503,43 +2310,234 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1241 struct crypt_kop kop;
1245 + BIGNUM *temp = NULL;
1246 + unsigned char *padded_pub_key = NULL, *p = NULL;
1248 + if ((fd = get_asym_dev_crypto()) < 0)
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]))
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;
1269 + if (ioctl(fd, CIOCKEY, &kop))
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);
1278 + if (dhret > BN_num_bytes(temp))
1279 + dhret=BN_bn2bin(temp,key);
1283 + kop.crk_param[3].crp_p = NULL;
1288 const DH_METHOD *meth = DH_OpenSSL();
1290 - return ((meth->compute_key)(key, pub_key, dh));
1291 + dhret = (meth->compute_key)(key, pub_key, dh);
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))
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;
1307 + EC_POINT *tmp=NULL;
1308 + BIGNUM *x=NULL, *y=NULL;
1309 + const BIGNUM *priv_key;
1310 + const EC_GROUP* group = NULL;
1312 + size_t buflen, len;
1313 + struct crypt_kop kop;
1315 memset(&kop, 0, sizeof kop);
1316 - kop.crk_op = CRK_DH_COMPUTE_KEY;
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);
1330 + if (!x || !y || !p || !a || !b || !w_x || !w_y) {
1331 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
1333 - if (bn2crparam(pub_key, &kop.crk_param[1]))
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);
1340 - if (bn2crparam(dh->p, &kop.crk_param[2]))
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);
1347 - kop.crk_iparams = 3;
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;
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);
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);
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);
1378 + ec_crv = EC_BINARY;
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);
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);
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);
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);
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);
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);
1416 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
1420 + /* Generation of ECC curve parameters */
1422 + ab = eng_copy_curve_points (a, b, ab_len, q_len);
1424 + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
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))
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);
1439 + kop.curve_type = ECC_BINARY;
1441 + kop.curve_type = ECC_PRIME;
1443 + priv_key_len = r_len;
1446 + * If BN_num_bytes of priv_key returns less then r_len then
1447 + * add padding bytes before the key
1449 + if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) {
1450 + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
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);
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;
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);
1481 - kop.crk_param[3].crp_p = NULL;
1482 + kop.crk_param[4].crp_p = NULL;
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 = {
1496 +static ECDH_METHOD cryptodev_ecdh = {
1497 + "cryptodev ECDH method",
1498 + NULL, /* cryptodev_ecdh_compute_key */
1501 + NULL /* app_data */
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;
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;
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;
1528 + if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) {
1529 + cryptodev_dh.generate_key =
1530 + cryptodev_dh_keygen;
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;
1548 + if (cryptodev_asymfeat & CRF_DSA_VERIFY) {
1549 + cryptodev_ecdsa.ecdsa_do_verify =
1550 + cryptodev_ecdsa_verify;
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;