diff options
Diffstat (limited to 'recipes-connectivity/openssl/openssl-qoriq/qoriq/0010-Asynchronous-interface-added-for-PKC-cryptodev-inter.patch')
-rw-r--r-- | recipes-connectivity/openssl/openssl-qoriq/qoriq/0010-Asynchronous-interface-added-for-PKC-cryptodev-inter.patch | 2039 |
1 files changed, 0 insertions, 2039 deletions
diff --git a/recipes-connectivity/openssl/openssl-qoriq/qoriq/0010-Asynchronous-interface-added-for-PKC-cryptodev-inter.patch b/recipes-connectivity/openssl/openssl-qoriq/qoriq/0010-Asynchronous-interface-added-for-PKC-cryptodev-inter.patch deleted file mode 100644 index 0f889c0..0000000 --- a/recipes-connectivity/openssl/openssl-qoriq/qoriq/0010-Asynchronous-interface-added-for-PKC-cryptodev-inter.patch +++ /dev/null @@ -1,2039 +0,0 @@ -From a933e6341fd8989bdd82f8a5446b6f04aa00eef9 Mon Sep 17 00:00:00 2001 -From: Yashpal Dutta <yashpal.dutta@freescale.com> -Date: Tue, 11 Mar 2014 07:14:30 +0545 -Subject: [PATCH 10/26] Asynchronous interface added for PKC cryptodev - interface - -Upstream-status: Pending - -Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com> ---- - crypto/crypto.h | 16 + - crypto/dh/dh.h | 4 +- - crypto/dsa/dsa.h | 5 + - crypto/ecdh/ech_locl.h | 3 + - crypto/ecdsa/ecs_locl.h | 5 + - crypto/engine/eng_cryptodev.c | 1578 +++++++++++++++++++++++++++++++++++++---- - crypto/engine/eng_int.h | 24 +- - crypto/engine/eng_lib.c | 46 ++ - crypto/engine/engine.h | 24 + - crypto/rsa/rsa.h | 23 + - 10 files changed, 1582 insertions(+), 146 deletions(-) - -diff --git a/crypto/crypto.h b/crypto/crypto.h -index f92fc51..ce12731 100644 ---- a/crypto/crypto.h -+++ b/crypto/crypto.h -@@ -605,6 +605,22 @@ void ERR_load_CRYPTO_strings(void); - #define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 - #define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 - -+/* Additions for Asynchronous PKC Infrastructure */ -+struct pkc_cookie_s { -+ void *cookie; /* To be filled by openssl library primitive method function caller */ -+ void *eng_cookie; /* To be filled by Engine */ -+ /* -+ * Callback handler to be provided by caller. Ensure to pass a -+ * handler which takes the crypto operation to completion. -+ * cookie: Container cookie from library -+ * status: Status of the crypto Job completion. -+ * 0: Job handled without any issue -+ * -EINVAL: Parameters Invalid -+ */ -+ void (*pkc_callback)(struct pkc_cookie_s *cookie, int status); -+ void *eng_handle; -+}; -+ - #ifdef __cplusplus - } - #endif -diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h -index ea59e61..20ffad2 100644 ---- a/crypto/dh/dh.h -+++ b/crypto/dh/dh.h -@@ -118,7 +118,9 @@ struct dh_method - int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); /* Can be null */ -- -+ int (*compute_key_async)(unsigned char *key,const BIGNUM *pub_key,DH *dh, -+ struct pkc_cookie_s *cookie); -+ int (*generate_key_async)(DH *dh, struct pkc_cookie_s *cookie); - int (*init)(DH *dh); - int (*finish)(DH *dh); - int flags; -diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h -index a6f6d0b..b04a029 100644 ---- a/crypto/dsa/dsa.h -+++ b/crypto/dsa/dsa.h -@@ -140,6 +140,10 @@ struct dsa_method - int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); /* Can be null */ -+ int (*dsa_do_sign_async)(const unsigned char *dgst, int dlen, DSA *dsa, -+ DSA_SIG *sig, struct pkc_cookie_s *cookie); -+ int (*dsa_do_verify_async)(const unsigned char *dgst, int dgst_len, -+ DSA_SIG *sig, DSA *dsa, struct pkc_cookie_s *cookie); - int (*init)(DSA *dsa); - int (*finish)(DSA *dsa); - int flags; -@@ -151,6 +155,7 @@ struct dsa_method - BN_GENCB *cb); - /* If this is non-NULL, it is used to generate DSA keys */ - int (*dsa_keygen)(DSA *dsa); -+ int (*dsa_keygen_async)(DSA *dsa, struct pkc_cookie_s *cookie); - }; - - struct dsa_st -diff --git a/crypto/ecdh/ech_locl.h b/crypto/ecdh/ech_locl.h -index f6cad6a..adce6b3 100644 ---- a/crypto/ecdh/ech_locl.h -+++ b/crypto/ecdh/ech_locl.h -@@ -67,6 +67,9 @@ struct ecdh_method - const char *name; - int (*compute_key)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, - void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)); -+ int (*compute_key_async)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, -+ void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen), -+ struct pkc_cookie_s *cookie); - #if 0 - int (*init)(EC_KEY *eckey); - int (*finish)(EC_KEY *eckey); -diff --git a/crypto/ecdsa/ecs_locl.h b/crypto/ecdsa/ecs_locl.h -index cb3be13..eb0ebe0 100644 ---- a/crypto/ecdsa/ecs_locl.h -+++ b/crypto/ecdsa/ecs_locl.h -@@ -74,6 +74,11 @@ struct ecdsa_method - BIGNUM **r); - int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len, - const ECDSA_SIG *sig, EC_KEY *eckey); -+ int (*ecdsa_do_sign_async)(const unsigned char *dgst, int dgst_len, -+ const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey, -+ ECDSA_SIG *sig, struct pkc_cookie_s *cookie); -+ int (*ecdsa_do_verify_async)(const unsigned char *dgst, int dgst_len, -+ const ECDSA_SIG *sig, EC_KEY *eckey, struct pkc_cookie_s *cookie); - #if 0 - int (*init)(EC_KEY *eckey); - int (*finish)(EC_KEY *eckey); -diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c -index 7ee314b..9f2416e 100644 ---- a/crypto/engine/eng_cryptodev.c -+++ b/crypto/engine/eng_cryptodev.c -@@ -1281,6 +1281,56 @@ zapparams(struct crypt_kop *kop) - } - } - -+/* Any PKC request has at max 2 output parameters and they are stored here to -+be used while copying in the check availability */ -+struct cryptodev_cookie_s { -+ BIGNUM *r; -+ struct crparam r_param; -+ BIGNUM *s; -+ struct crparam s_param; -+ struct crypt_kop *kop; -+}; -+ -+static int -+cryptodev_asym_async(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, -+ BIGNUM *s) -+{ -+ int fd; -+ struct pkc_cookie_s *cookie = kop->cookie; -+ struct cryptodev_cookie_s *eng_cookie; -+ -+ fd = *(int *)cookie->eng_handle; -+ -+ eng_cookie = malloc(sizeof(struct cryptodev_cookie_s)); -+ -+ if (eng_cookie) { -+ memset(eng_cookie, 0, sizeof(struct cryptodev_cookie_s)); -+ if (r) { -+ kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); -+ if (!kop->crk_param[kop->crk_iparams].crp_p) -+ return -ENOMEM; -+ kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; -+ kop->crk_oparams++; -+ eng_cookie->r = r; -+ eng_cookie->r_param = kop->crk_param[kop->crk_iparams]; -+ } -+ if (s) { -+ kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char)); -+ if (!kop->crk_param[kop->crk_iparams+1].crp_p) -+ return -ENOMEM; -+ kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8; -+ kop->crk_oparams++; -+ eng_cookie->s = s; -+ eng_cookie->s_param = kop->crk_param[kop->crk_iparams + 1]; -+ } -+ } else -+ return -ENOMEM; -+ -+ eng_cookie->kop = kop; -+ cookie->eng_cookie = eng_cookie; -+ return ioctl(fd, CIOCASYMASYNCRYPT, kop); -+} -+ - static int - cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) - { -@@ -1337,6 +1387,44 @@ void *cryptodev_init_instance(void) - return fd; - } - -+#include <poll.h> -+ -+/* Return 0 on success and 1 on failure */ -+int cryptodev_check_availability(void *eng_handle) -+{ -+ int fd = *(int *)eng_handle; -+ struct pkc_cookie_list_s cookie_list; -+ struct pkc_cookie_s *cookie; -+ int i; -+ -+ /* FETCH COOKIE returns number of cookies extracted */ -+ if (ioctl(fd, CIOCASYMFETCHCOOKIE, &cookie_list) <= 0) -+ return 1; -+ -+ for (i = 0; i < cookie_list.cookie_available; i++) { -+ cookie = cookie_list.cookie[i]; -+ if (cookie) { -+ struct cryptodev_cookie_s *eng_cookie = cookie->eng_cookie; -+ if (eng_cookie) { -+ struct crypt_kop *kop = eng_cookie->kop; -+ -+ if (eng_cookie->r) -+ crparam2bn(&eng_cookie->r_param, eng_cookie->r); -+ if (eng_cookie->s) -+ crparam2bn(&eng_cookie->s_param, eng_cookie->s); -+ if (kop->crk_op == CRK_DH_COMPUTE_KEY) -+ kop->crk_oparams = 0; -+ -+ zapparams(eng_cookie->kop); -+ free(eng_cookie->kop); -+ free (eng_cookie); -+ } -+ cookie->pkc_callback(cookie, cookie_list.status[i]); -+ } -+ } -+ return 0; -+} -+ - static int - cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) -@@ -1382,6 +1470,63 @@ err: - } - - static int -+cryptodev_bn_mod_exp_async(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, -+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont, struct pkc_cookie_s *cookie) -+{ -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ int ret = 1; -+ -+ /* Currently, we know we can do mod exp iff we can do any -+ * asymmetric operations at all. -+ */ -+ if (cryptodev_asymfeat == 0 || !kop) { -+ ret = BN_mod_exp(r, a, p, m, ctx); -+ return (ret); -+ } -+ -+ kop->crk_oparams = 0; -+ kop->crk_status = 0; -+ kop->crk_op = CRK_MOD_EXP; -+ kop->cookie = cookie; -+ /* inputs: a^p % m */ -+ if (bn2crparam(a, &kop->crk_param[0])) -+ goto err; -+ if (bn2crparam(p, &kop->crk_param[1])) -+ goto err; -+ if (bn2crparam(m, &kop->crk_param[2])) -+ goto err; -+ -+ kop->crk_iparams = 3; -+ if (cryptodev_asym_async(kop, BN_num_bytes(m), r, 0, NULL)) -+ goto err; -+ -+ return ret; -+err: -+ { -+ const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); -+ -+ if (kop) -+ free(kop); -+ ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); -+ if (ret) -+ /* Call the completion handler immediately */ -+ cookie->pkc_callback(cookie, 0); -+ } -+ return ret; -+} -+ -+static int -+cryptodev_rsa_nocrt_mod_exp_async(BIGNUM *r0, const BIGNUM *I, -+ RSA *rsa, BN_CTX *ctx, struct pkc_cookie_s *cookie) -+{ -+ int r; -+ ctx = BN_CTX_new(); -+ r = cryptodev_bn_mod_exp_async(r0, I, rsa->d, rsa->n, ctx, NULL, cookie); -+ BN_CTX_free(ctx); -+ return r; -+} -+ -+static int - cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) - { - int r; -@@ -1446,6 +1591,62 @@ err: - return (ret); - } - -+static int -+cryptodev_rsa_mod_exp_async(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx, -+ struct pkc_cookie_s *cookie) -+{ -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ int ret = 1, f_len, p_len, q_len; -+ unsigned char *f = NULL, *p = NULL, *q = NULL, *dp = NULL, *dq = NULL, *c = NULL; -+ -+ if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp || !kop) { -+ return (0); -+ } -+ -+ kop->crk_oparams = 0; -+ kop->crk_status = 0; -+ kop->crk_op = CRK_MOD_EXP_CRT; -+ f_len = BN_num_bytes(rsa->n); -+ spcf_bn2bin_ex(I, &f, &f_len); -+ spcf_bn2bin(rsa->p, &p, &p_len); -+ spcf_bn2bin(rsa->q, &q, &q_len); -+ spcf_bn2bin_ex(rsa->dmp1, &dp, &p_len); -+ spcf_bn2bin_ex(rsa->iqmp, &c, &p_len); -+ spcf_bn2bin_ex(rsa->dmq1, &dq, &q_len); -+ /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ -+ kop->crk_param[0].crp_p = p; -+ kop->crk_param[0].crp_nbits = p_len * 8; -+ kop->crk_param[1].crp_p = q; -+ kop->crk_param[1].crp_nbits = q_len * 8; -+ kop->crk_param[2].crp_p = f; -+ kop->crk_param[2].crp_nbits = f_len * 8; -+ kop->crk_param[3].crp_p = dp; -+ kop->crk_param[3].crp_nbits = p_len * 8; -+ /* dq must of length q, rest all of length p*/ -+ kop->crk_param[4].crp_p = dq; -+ kop->crk_param[4].crp_nbits = q_len * 8; -+ kop->crk_param[5].crp_p = c; -+ kop->crk_param[5].crp_nbits = p_len * 8; -+ kop->crk_iparams = 6; -+ kop->cookie = cookie; -+ if (cryptodev_asym_async(kop, BN_num_bytes(rsa->n), r0, 0, NULL)) -+ goto err; -+ -+ return ret; -+err: -+ { -+ const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); -+ -+ if (kop) -+ free(kop); -+ ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); -+ if (ret) -+ /* Call user completion handler immediately */ -+ cookie->pkc_callback(cookie, 0); -+ } -+ return (ret); -+} -+ - static RSA_METHOD cryptodev_rsa = { - "cryptodev RSA method", - NULL, /* rsa_pub_enc */ -@@ -1454,6 +1655,12 @@ static RSA_METHOD cryptodev_rsa = { - NULL, /* rsa_priv_dec */ - NULL, - NULL, -+ NULL, /* rsa_pub_enc */ -+ NULL, /* rsa_pub_dec */ -+ NULL, /* rsa_priv_enc */ -+ NULL, /* rsa_priv_dec */ -+ NULL, -+ NULL, - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ -@@ -1751,126 +1958,424 @@ sw_try: - return ret; - } - -+/* Cryptodev DSA Key Gen routine */ -+static int cryptodev_dsa_keygen_async(DSA *dsa, struct pkc_cookie_s *cookie) -+{ -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ int ret = 1, g_len; -+ unsigned char *g = NULL; - -+ if (!kop) -+ goto sw_try; - --static DSA_METHOD cryptodev_dsa = { -- "cryptodev DSA method", -- NULL, -- NULL, /* dsa_sign_setup */ -- NULL, -- NULL, /* dsa_mod_exp */ -- NULL, -- NULL, /* init */ -- NULL, /* finish */ -- 0, /* flags */ -- NULL /* app_data */ --}; -+ if (dsa->priv_key == NULL) { -+ if ((dsa->priv_key=BN_new()) == NULL) -+ goto sw_try; -+ } - --static ECDSA_METHOD cryptodev_ecdsa = { -- "cryptodev ECDSA method", -- NULL, -- NULL, /* ecdsa_sign_setup */ -- NULL, -- NULL, -- 0, /* flags */ -- NULL /* app_data */ --}; -+ if (dsa->pub_key == NULL) { -+ if ((dsa->pub_key=BN_new()) == NULL) -+ goto sw_try; -+ } - --typedef enum ec_curve_s --{ -- EC_PRIME, -- EC_BINARY --} ec_curve_t; -+ g_len = BN_num_bytes(dsa->p); -+ /** -+ * Get generator into a plain buffer. If length is less than -+ * q_len then add leading padding bytes. -+ */ -+ if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) { -+ DSAerr(DSA_F_DSA_GENERATE_KEY, ERR_R_MALLOC_FAILURE); -+ goto sw_try; -+ } - --/* ENGINE handler for ECDSA Sign */ --static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char *dgst, -- int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) --{ -- BIGNUM *m = NULL, *p = NULL, *a = NULL; -- BIGNUM *b = NULL, *x = NULL, *y = NULL; -- BN_CTX *ctx = NULL; -- ECDSA_SIG *ret = NULL; -- ECDSA_DATA *ecdsa = NULL; -- unsigned char * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL; -- unsigned char * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL; -- int i = 0, q_len = 0, priv_key_len = 0, r_len = 0; -- int g_len = 0, d_len = 0, ab_len = 0; -- const BIGNUM *order = NULL, *priv_key=NULL; -- const EC_GROUP *group = NULL; -- struct crypt_kop kop; -- ec_curve_t ec_crv = EC_PRIME; -+ memset(kop, 0, sizeof(struct crypt_kop)); -+ kop->crk_op = CRK_DSA_GENERATE_KEY; -+ if (bn2crparam(dsa->p, &kop->crk_param[0])) -+ goto sw_try; -+ if (bn2crparam(dsa->q, &kop->crk_param[1])) -+ goto sw_try; -+ kop->crk_param[2].crp_p = g; -+ kop->crk_param[2].crp_nbits = g_len * 8; -+ kop->crk_iparams = 3; -+ kop->cookie = cookie; - -- memset(&kop, 0, sizeof(kop)); -- ecdsa = ecdsa_check(eckey); -- if (!ecdsa) { -- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); -- return NULL; -+ /* pub_key is or prime length while priv key is of length of order */ -+ if (cryptodev_asym_async(kop, BN_num_bytes(dsa->p), dsa->pub_key, -+ BN_num_bytes(dsa->q), dsa->priv_key)) -+ goto sw_try; -+ -+ return ret; -+sw_try: -+ { -+ const DSA_METHOD *meth = DSA_OpenSSL(); -+ -+ if (kop) -+ free(kop); -+ ret = (meth->dsa_keygen)(dsa); -+ cookie->pkc_callback(cookie, 0); - } -+ return ret; -+} - -- group = EC_KEY_get0_group(eckey); -- priv_key = EC_KEY_get0_private_key(eckey); -+static int -+cryptodev_dsa_do_sign_async(const unsigned char *dgst, int dlen, DSA *dsa, -+ DSA_SIG *sig, struct pkc_cookie_s *cookie) -+{ -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ DSA_SIG *dsaret = NULL; -+ int q_len = 0, r_len = 0, g_len = 0; -+ int priv_key_len = 0, ret = 1; -+ unsigned char *q = NULL, *r = NULL, *g = NULL, *priv_key = NULL, *f = NULL; - -- if (!group || !priv_key) { -- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); -- return NULL; -+ if (((sig->r = BN_new()) == NULL) || !kop) { -+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; - } - -- if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL || -- (a = BN_new()) == NULL || (b = BN_new()) == NULL || -- (p = BN_new()) == NULL || (x = BN_new()) == NULL || -- (y = BN_new()) == NULL) { -- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ if ((sig->s = BN_new()) == NULL) { -+ BN_free(sig->r); -+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - -- order = &group->order; -- if (!order || BN_is_zero(order)) { -- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS); -+ if (spcf_bn2bin(dsa->p, &q, &q_len)) { -+ DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - goto err; - } - -- i = BN_num_bits(order); -- /* Need to truncate digest if it is too long: first truncate whole -- bytes */ -- if (8 * dgst_len > i) -- dgst_len = (i + 7)/8; -+ /* Get order of the field of private keys into plain buffer */ -+ if (spcf_bn2bin (dsa->q, &r, &r_len)) { -+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } - -- if (!BN_bin2bn(dgst, dgst_len, m)) { -- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ /* sanity test */ -+ if (dlen > r_len) { -+ DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - goto err; - } - -- /* If still too long truncate remaining bits with a shift */ -- if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { -- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ g_len = q_len; -+ /** -+ * Get generator into a plain buffer. If length is less than -+ * q_len then add leading padding bytes. -+ */ -+ if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) { -+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - -- /* copy the truncated bits into plain buffer */ -- if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) { -- fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__); -+ priv_key_len = r_len; -+ /** -+ * Get private key into a plain buffer. If length is less than -+ * r_len then add leading padding bytes. -+ */ -+ if (spcf_bn2bin_ex(dsa->priv_key, &priv_key, &priv_key_len)) { -+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - -- ret = ECDSA_SIG_new(); -- if (!ret) { -- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ /* Allocate memory to store hash. */ -+ f = OPENSSL_malloc (r_len); -+ if (!f) { -+ DSAerr(DSA_F_DSA_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - -- /* check if this is prime or binary EC request */ -- if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { -- ec_crv = EC_PRIME; -- /* get the generator point pair */ -- if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group), -- x, y,ctx)) { -- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -- goto err; -- } -+ /* Add padding, since SEC expects hash to of size r_len */ -+ if (dlen < r_len) -+ memset(f, 0, r_len - dlen); - -- /* get the ECC curve parameters */ -- if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) { -- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -+ /* Skip leading bytes if dgst_len < r_len */ -+ memcpy(f + r_len - dlen, dgst, dlen); -+ -+ dlen = r_len; -+ -+ memset(kop, 0, sizeof( struct crypt_kop)); -+ kop->crk_op = CRK_DSA_SIGN; -+ -+ /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ -+ kop->crk_param[0].crp_p = (void*)f; -+ kop->crk_param[0].crp_nbits = dlen * 8; -+ kop->crk_param[1].crp_p = (void*)q; -+ kop->crk_param[1].crp_nbits = q_len * 8; -+ kop->crk_param[2].crp_p = (void*)r; -+ kop->crk_param[2].crp_nbits = r_len * 8; -+ kop->crk_param[3].crp_p = (void*)g; -+ kop->crk_param[3].crp_nbits = g_len * 8; -+ kop->crk_param[4].crp_p = (void*)priv_key; -+ kop->crk_param[4].crp_nbits = priv_key_len * 8; -+ kop->crk_iparams = 5; -+ kop->cookie = cookie; -+ -+ if (cryptodev_asym_async(kop, r_len, sig->r, r_len, sig->s)) -+ goto err; -+ -+ return ret; -+err: -+ { -+ const DSA_METHOD *meth = DSA_OpenSSL(); -+ -+ if (kop) -+ free(kop); -+ BN_free(sig->r); -+ BN_free(sig->s); -+ dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); -+ sig->r = dsaret->r; -+ sig->s = dsaret->s; -+ /* Call user callback immediately */ -+ cookie->pkc_callback(cookie, 0); -+ ret = dsaret; -+ } -+ return ret; -+} -+ -+static int -+cryptodev_dsa_verify_async(const unsigned char *dgst, int dlen, -+ DSA_SIG *sig, DSA *dsa, struct pkc_cookie_s *cookie) -+{ -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ int q_len = 0, r_len = 0, g_len = 0; -+ int w_len = 0 ,c_len = 0, d_len = 0, ret = 1; -+ unsigned char * q = NULL, * r = NULL, * w = NULL, * g = NULL; -+ unsigned char *c = NULL, * d = NULL, *f = NULL; -+ -+ if (!kop) -+ goto err; -+ -+ if (spcf_bn2bin(dsa->p, &q, &q_len)) { -+ DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ return ret; -+ } -+ -+ /* Get Order of field of private keys */ -+ if (spcf_bn2bin(dsa->q, &r, &r_len)) { -+ DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ g_len = q_len; -+ /** -+ * Get generator into a plain buffer. If length is less than -+ * q_len then add leading padding bytes. -+ */ -+ if (spcf_bn2bin_ex(dsa->g, &g, &g_len)) { -+ DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ w_len = q_len; -+ /** -+ * Get public key into a plain buffer. If length is less than -+ * q_len then add leading padding bytes. -+ */ -+ if (spcf_bn2bin_ex(dsa->pub_key, &w, &w_len)) { -+ DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ /** -+ * Get the 1st part of signature into a flat buffer with -+ * appropriate padding -+ */ -+ c_len = r_len; -+ -+ if (spcf_bn2bin_ex(sig->r, &c, &c_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /** -+ * Get the 2nd part of signature into a flat buffer with -+ * appropriate padding -+ */ -+ d_len = r_len; -+ -+ if (spcf_bn2bin_ex(sig->s, &d, &d_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ -+ /* Sanity test */ -+ if (dlen > r_len) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Allocate memory to store hash. */ -+ f = OPENSSL_malloc (r_len); -+ if (!f) { -+ DSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Add padding, since SEC expects hash to of size r_len */ -+ if (dlen < r_len) -+ memset(f, 0, r_len - dlen); -+ -+ /* Skip leading bytes if dgst_len < r_len */ -+ memcpy(f + r_len - dlen, dgst, dlen); -+ -+ dlen = r_len; -+ memset(kop, 0, sizeof(struct crypt_kop)); -+ -+ /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ -+ kop->crk_param[0].crp_p = (void*)f; -+ kop->crk_param[0].crp_nbits = dlen * 8; -+ kop->crk_param[1].crp_p = q; -+ kop->crk_param[1].crp_nbits = q_len * 8; -+ kop->crk_param[2].crp_p = r; -+ kop->crk_param[2].crp_nbits = r_len * 8; -+ kop->crk_param[3].crp_p = g; -+ kop->crk_param[3].crp_nbits = g_len * 8; -+ kop->crk_param[4].crp_p = w; -+ kop->crk_param[4].crp_nbits = w_len * 8; -+ kop->crk_param[5].crp_p = c; -+ kop->crk_param[5].crp_nbits = c_len * 8; -+ kop->crk_param[6].crp_p = d; -+ kop->crk_param[6].crp_nbits = d_len * 8; -+ kop->crk_iparams = 7; -+ kop->crk_op = CRK_DSA_VERIFY; -+ kop->cookie = cookie; -+ if (cryptodev_asym_async(kop, 0, NULL, 0, NULL)) -+ goto err; -+ -+ return ret; -+err: -+ { -+ const DSA_METHOD *meth = DSA_OpenSSL(); -+ -+ if (kop) -+ free(kop); -+ -+ ret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa); -+ cookie->pkc_callback(cookie, 0); -+ } -+ return ret; -+} -+ -+static DSA_METHOD cryptodev_dsa = { -+ "cryptodev DSA method", -+ NULL, -+ NULL, /* dsa_sign_setup */ -+ NULL, -+ NULL, /* dsa_mod_exp */ -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, /* init */ -+ NULL, /* finish */ -+ 0, /* flags */ -+ NULL /* app_data */ -+}; -+ -+static ECDSA_METHOD cryptodev_ecdsa = { -+ "cryptodev ECDSA method", -+ NULL, -+ NULL, /* ecdsa_sign_setup */ -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ 0, /* flags */ -+ NULL /* app_data */ -+}; -+ -+typedef enum ec_curve_s -+{ -+ EC_PRIME, -+ EC_BINARY -+} ec_curve_t; -+ -+/* ENGINE handler for ECDSA Sign */ -+static ECDSA_SIG *cryptodev_ecdsa_do_sign( const unsigned char *dgst, -+ int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) -+{ -+ BIGNUM *m = NULL, *p = NULL, *a = NULL; -+ BIGNUM *b = NULL, *x = NULL, *y = NULL; -+ BN_CTX *ctx = NULL; -+ ECDSA_SIG *ret = NULL; -+ ECDSA_DATA *ecdsa = NULL; -+ unsigned char * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL; -+ unsigned char * s = NULL, *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL; -+ int i = 0, q_len = 0, priv_key_len = 0, r_len = 0; -+ int g_len = 0, d_len = 0, ab_len = 0; -+ const BIGNUM *order = NULL, *priv_key=NULL; -+ const EC_GROUP *group = NULL; -+ struct crypt_kop kop; -+ ec_curve_t ec_crv = EC_PRIME; -+ -+ memset(&kop, 0, sizeof(kop)); -+ ecdsa = ecdsa_check(eckey); -+ if (!ecdsa) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); -+ return NULL; -+ } -+ -+ group = EC_KEY_get0_group(eckey); -+ priv_key = EC_KEY_get0_private_key(eckey); -+ -+ if (!group || !priv_key) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); -+ return NULL; -+ } -+ -+ if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL || -+ (a = BN_new()) == NULL || (b = BN_new()) == NULL || -+ (p = BN_new()) == NULL || (x = BN_new()) == NULL || -+ (y = BN_new()) == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ order = &group->order; -+ if (!order || BN_is_zero(order)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS); -+ goto err; -+ } -+ -+ i = BN_num_bits(order); -+ /* Need to truncate digest if it is too long: first truncate whole -+ bytes */ -+ if (8 * dgst_len > i) -+ dgst_len = (i + 7)/8; -+ -+ if (!BN_bin2bn(dgst, dgst_len, m)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* If still too long truncate remaining bits with a shift */ -+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* copy the truncated bits into plain buffer */ -+ if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) { -+ fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__); -+ goto err; -+ } -+ -+ ret = ECDSA_SIG_new(); -+ if (!ret) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* check if this is prime or binary EC request */ -+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { -+ ec_crv = EC_PRIME; -+ /* get the generator point pair */ -+ if (!EC_POINT_get_affine_coordinates_GFp (group, EC_GROUP_get0_generator(group), -+ x, y,ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* get the ECC curve parameters */ -+ if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); - goto err; - } - } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) { -@@ -2195,63 +2700,581 @@ static int cryptodev_ecdsa_verify(const unsigned char *dgst, int dgst_len, - } - - /** -- * Get the 2nd part of signature into a flat buffer with -- * appropriate padding -+ * Get the 2nd part of signature into a flat buffer with -+ * appropriate padding -+ */ -+ if (BN_num_bytes(sig->s) < r_len) -+ d_len = r_len; -+ -+ if (spcf_bn2bin_ex(sig->s, &d, &d_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* memory for message representative */ -+ f = malloc(r_len); -+ if (!f) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Add padding, since SEC expects hash to of size r_len */ -+ memset(f, 0, r_len-dgst_len); -+ -+ /* Skip leading bytes if dgst_len < r_len */ -+ memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len); -+ dgst_len += r_len-dgst_len; -+ kop.crk_op = CRK_DSA_VERIFY; -+ /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ -+ kop.crk_param[0].crp_p = f; -+ kop.crk_param[0].crp_nbits = dgst_len * 8; -+ kop.crk_param[1].crp_p = q; -+ kop.crk_param[1].crp_nbits = q_len * 8; -+ kop.crk_param[2].crp_p = r; -+ kop.crk_param[2].crp_nbits = r_len * 8; -+ kop.crk_param[3].crp_p = g_xy; -+ kop.crk_param[3].crp_nbits = g_len * 8; -+ kop.crk_param[4].crp_p = w_xy; -+ kop.crk_param[4].crp_nbits = pub_key_len * 8; -+ kop.crk_param[5].crp_p = ab; -+ kop.crk_param[5].crp_nbits = ab_len * 8; -+ kop.crk_param[6].crp_p = c; -+ kop.crk_param[6].crp_nbits = d_len * 8; -+ kop.crk_param[7].crp_p = d; -+ kop.crk_param[7].crp_nbits = d_len * 8; -+ kop.crk_iparams = 8; -+ -+ if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { -+ /*OCF success value is 0, if not zero, change ret to fail*/ -+ if(0 == kop.crk_status) -+ ret = 1; -+ } else { -+ const ECDSA_METHOD *meth = ECDSA_OpenSSL(); -+ -+ ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey); -+ } -+ kop.crk_param[0].crp_p = NULL; -+ zapparams(&kop); -+ -+err: -+ return ret; -+} -+ -+static int cryptodev_ecdsa_do_sign_async( const unsigned char *dgst, -+ int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey, -+ ECDSA_SIG *sig, struct pkc_cookie_s *cookie) -+{ -+ BIGNUM *m = NULL, *p = NULL, *a = NULL; -+ BIGNUM *b = NULL, *x = NULL, *y = NULL; -+ BN_CTX *ctx = NULL; -+ ECDSA_SIG *sig_ret = NULL; -+ ECDSA_DATA *ecdsa = NULL; -+ unsigned char * q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL; -+ unsigned char * s = NULL, *f = NULL, *tmp_dgst = NULL; -+ int i = 0, q_len = 0, priv_key_len = 0, r_len = 0; -+ int g_len = 0, ab_len = 0, ret = 1; -+ const BIGNUM *order = NULL, *priv_key=NULL; -+ const EC_GROUP *group = NULL; -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ ec_curve_t ec_crv = EC_PRIME; -+ -+ if (!(sig->r = BN_new()) || !kop) -+ goto err; -+ if ((sig->s = BN_new()) == NULL) { -+ BN_free(r); -+ goto err; -+ } -+ -+ memset(kop, 0, sizeof(struct crypt_kop)); -+ ecdsa = ecdsa_check(eckey); -+ if (!ecdsa) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); -+ goto err; -+ } -+ -+ group = EC_KEY_get0_group(eckey); -+ priv_key = EC_KEY_get0_private_key(eckey); -+ -+ if (!group || !priv_key) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); -+ goto err; -+ } -+ -+ if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL || -+ (a = BN_new()) == NULL || (b = BN_new()) == NULL || -+ (p = BN_new()) == NULL || (x = BN_new()) == NULL || -+ (y = BN_new()) == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ order = &group->order; -+ if (!order || BN_is_zero(order)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_MISSING_PARAMETERS); -+ goto err; -+ } -+ -+ i = BN_num_bits(order); -+ /* Need to truncate digest if it is too long: first truncate whole -+ bytes */ -+ if (8 * dgst_len > i) -+ dgst_len = (i + 7)/8; -+ -+ if (!BN_bin2bn(dgst, dgst_len, m)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* If still too long truncate remaining bits with a shift */ -+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* copy the truncated bits into plain buffer */ -+ if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) { -+ fprintf(stderr, "%s:%d: OPENSSL_malloc failec\n", __FUNCTION__, __LINE__); -+ goto err; -+ } -+ -+ /* check if this is prime or binary EC request */ -+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) -+ == NID_X9_62_prime_field) { -+ ec_crv = EC_PRIME; -+ /* get the generator point pair */ -+ if (!EC_POINT_get_affine_coordinates_GFp (group, -+ EC_GROUP_get0_generator(group), x, y,ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* get the ECC curve parameters */ -+ if (!EC_GROUP_get_curve_GFp(group, p, a, b , ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -+ goto err; -+ } -+ } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field) { -+ ec_crv = EC_BINARY; -+ /* get the ECC curve parameters */ -+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* get the generator point pair */ -+ if (!EC_POINT_get_affine_coordinates_GF2m(group, -+ EC_GROUP_get0_generator(group), x, y,ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -+ goto err; -+ } -+ } else { -+ printf("Unsupported Curve\n"); -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ if (spcf_bn2bin(order, &r, &r_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ if (spcf_bn2bin(p, &q, &q_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ priv_key_len = r_len; -+ -+ /** -+ * If BN_num_bytes of priv_key returns less then r_len then -+ * add padding bytes before the key -+ */ -+ if (spcf_bn2bin_ex(priv_key, &s, &priv_key_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Generation of ECC curve parameters */ -+ ab_len = 2*q_len; -+ ab = eng_copy_curve_points(a, b, ab_len, q_len); -+ if (!ab) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ if (ec_crv == EC_BINARY) { -+ if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len)) -+ { -+ unsigned char *c_temp = NULL; -+ int c_temp_len = q_len; -+ if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len)) -+ memcpy(ab+q_len, c_temp, q_len); -+ else -+ goto err; -+ } -+ kop->curve_type = ECC_BINARY; -+ } -+ -+ /* Calculation of Generator point */ -+ g_len = 2*q_len; -+ g_xy = eng_copy_curve_points(x, y, g_len, q_len); -+ if (!g_xy) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* memory for message representative */ -+ f = malloc(r_len); -+ if (!f) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Add padding, since SEC expects hash to of size r_len */ -+ memset(f, 0, r_len - dgst_len); -+ -+ /* Skip leading bytes if dgst_len < r_len */ -+ memcpy(f + r_len - dgst_len, tmp_dgst, dgst_len); -+ -+ dgst_len += r_len - dgst_len; -+ -+ kop->crk_op = CRK_DSA_SIGN; -+ /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ -+ kop->crk_param[0].crp_p = f; -+ kop->crk_param[0].crp_nbits = dgst_len * 8; -+ kop->crk_param[1].crp_p = q; -+ kop->crk_param[1].crp_nbits = q_len * 8; -+ kop->crk_param[2].crp_p = r; -+ kop->crk_param[2].crp_nbits = r_len * 8; -+ kop->crk_param[3].crp_p = g_xy; -+ kop->crk_param[3].crp_nbits = g_len * 8; -+ kop->crk_param[4].crp_p = s; -+ kop->crk_param[4].crp_nbits = priv_key_len * 8; -+ kop->crk_param[5].crp_p = ab; -+ kop->crk_param[5].crp_nbits = ab_len * 8; -+ kop->crk_iparams = 6; -+ kop->cookie = cookie; -+ -+ if (cryptodev_asym_async(kop, r_len, sig->r , r_len, sig->s)) -+ goto err; -+ -+ return ret; -+err: -+ { -+ const ECDSA_METHOD *meth = ECDSA_OpenSSL(); -+ BN_free(sig->r); -+ BN_free(sig->s); -+ if (kop) -+ free(kop); -+ sig_ret = (meth->ecdsa_do_sign)(dgst, dgst_len, in_kinv, in_r, eckey); -+ sig->r = sig_ret->r; -+ sig->s = sig_ret->s; -+ cookie->pkc_callback(cookie, 0); -+ } -+ return ret; -+} -+ -+static int cryptodev_ecdsa_verify_async(const unsigned char *dgst, int dgst_len, -+ const ECDSA_SIG *sig, EC_KEY *eckey, struct pkc_cookie_s *cookie) -+{ -+ BIGNUM *m = NULL, *p = NULL, *a = NULL, *b = NULL; -+ BIGNUM *x = NULL, *y = NULL, *w_x = NULL, *w_y = NULL; -+ BN_CTX *ctx = NULL; -+ ECDSA_DATA *ecdsa = NULL; -+ unsigned char *q = NULL, *r = NULL, *ab = NULL, *g_xy = NULL, *w_xy = NULL; -+ unsigned char *c = NULL, *d = NULL, *f = NULL, *tmp_dgst = NULL; -+ int i = 0, q_len = 0, pub_key_len = 0, r_len = 0, c_len = 0, g_len = 0; -+ int d_len = 0, ab_len = 0, ret = 1; -+ const EC_POINT *pub_key = NULL; -+ const BIGNUM *order = NULL; -+ const EC_GROUP *group=NULL; -+ ec_curve_t ec_crv = EC_PRIME; -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ -+ if (!kop) -+ goto err; -+ -+ memset(kop, 0, sizeof(struct crypt_kop)); -+ ecdsa = ecdsa_check(eckey); -+ if (!ecdsa) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER); -+ goto err; -+ } -+ -+ group = EC_KEY_get0_group(eckey); -+ pub_key = EC_KEY_get0_public_key(eckey); -+ -+ if (!group || !pub_key) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_PASSED_NULL_PARAMETER); -+ goto err; -+ } -+ -+ if ((ctx = BN_CTX_new()) == NULL || (m = BN_new()) == NULL || -+ (a = BN_new()) == NULL || (b = BN_new()) == NULL || -+ (p = BN_new()) == NULL || (x = BN_new()) == NULL || -+ (y = BN_new()) == NULL || (w_x = BN_new()) == NULL || -+ (w_y = BN_new()) == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ order = &group->order; -+ if (!order || BN_is_zero(order)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); -+ goto err; -+ } -+ -+ i = BN_num_bits(order); -+ /* Need to truncate digest if it is too long: first truncate whole -+ * bytes */ -+ if (8 * dgst_len > i) -+ dgst_len = (i + 7)/8; -+ -+ if (!BN_bin2bn(dgst, dgst_len, m)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* If still too long truncate remaining bits with a shift */ -+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); -+ goto err; -+ } -+ /* copy the truncated bits into plain buffer */ -+ if (spcf_bn2bin(m, &tmp_dgst, &dgst_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* check if this is prime or binary EC request */ -+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { -+ ec_crv = EC_PRIME; -+ -+ /* get the generator point pair */ -+ if (!EC_POINT_get_affine_coordinates_GFp (group, -+ EC_GROUP_get0_generator(group), x, y,ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* get the public key pair for prime curve */ -+ if (!EC_POINT_get_affine_coordinates_GFp (group, -+ pub_key, w_x, w_y,ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* get the ECC curve parameters */ -+ if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ } else if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field){ -+ ec_crv = EC_BINARY; -+ /* get the ECC curve parameters */ -+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* get the generator point pair */ -+ if (!EC_POINT_get_affine_coordinates_GF2m(group, -+ EC_GROUP_get0_generator(group),x, y,ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* get the public key pair for binary curve */ -+ if (!EC_POINT_get_affine_coordinates_GF2m(group, -+ pub_key, w_x, w_y,ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ }else { -+ printf("Unsupported Curve\n"); -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* Get the order of the subgroup of private keys */ -+ if (spcf_bn2bin((BIGNUM*)order, &r, &r_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Get the irreducible polynomial that creates the field */ -+ if (spcf_bn2bin(p, &q, &q_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Get the public key into a flat buffer with appropriate padding */ -+ pub_key_len = 2 * q_len; -+ -+ w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len); -+ if (!w_xy) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Generation of ECC curve parameters */ -+ ab_len = 2*q_len; -+ -+ ab = eng_copy_curve_points (a, b, ab_len, q_len); -+ if (!ab) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ if (ec_crv == EC_BINARY) { -+ /* copy b' i.e c(b), instead of only b */ -+ eng_ec_get_cparam (EC_GROUP_get_curve_name(group), -+ ab+q_len, q_len); -+ kop->curve_type = ECC_BINARY; -+ } -+ -+ /* Calculation of Generator point */ -+ g_len = 2 * q_len; -+ -+ g_xy = eng_copy_curve_points (x, y, g_len, q_len); -+ if (!g_xy) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /** -+ * Get the 1st part of signature into a flat buffer with -+ * appropriate padding -+ */ -+ if (BN_num_bytes(sig->r) < r_len) -+ c_len = r_len; -+ -+ if (spcf_bn2bin_ex(sig->r, &c, &c_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /** -+ * Get the 2nd part of signature into a flat buffer with -+ * appropriate padding -+ */ -+ if (BN_num_bytes(sig->s) < r_len) -+ d_len = r_len; -+ -+ if (spcf_bn2bin_ex(sig->s, &d, &d_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* memory for message representative */ -+ f = malloc(r_len); -+ if (!f) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Add padding, since SEC expects hash to of size r_len */ -+ memset(f, 0, r_len-dgst_len); -+ -+ /* Skip leading bytes if dgst_len < r_len */ -+ memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len); -+ -+ dgst_len += r_len-dgst_len; -+ -+ kop->crk_op = CRK_DSA_VERIFY; -+ /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ -+ kop->crk_param[0].crp_p = f; -+ kop->crk_param[0].crp_nbits = dgst_len * 8; -+ kop->crk_param[1].crp_p = q; -+ kop->crk_param[1].crp_nbits = q_len * 8; -+ kop->crk_param[2].crp_p = r; -+ kop->crk_param[2].crp_nbits = r_len * 8; -+ kop->crk_param[3].crp_p = g_xy; -+ kop->crk_param[3].crp_nbits = g_len * 8; -+ kop->crk_param[4].crp_p = w_xy; -+ kop->crk_param[4].crp_nbits = pub_key_len * 8; -+ kop->crk_param[5].crp_p = ab; -+ kop->crk_param[5].crp_nbits = ab_len * 8; -+ kop->crk_param[6].crp_p = c; -+ kop->crk_param[6].crp_nbits = d_len * 8; -+ kop->crk_param[7].crp_p = d; -+ kop->crk_param[7].crp_nbits = d_len * 8; -+ kop->crk_iparams = 8; -+ kop->cookie = cookie; -+ -+ if (cryptodev_asym_async(kop, 0, NULL, 0, NULL)) -+ goto err; -+ -+ return ret; -+err: -+ { -+ const ECDSA_METHOD *meth = ECDSA_OpenSSL(); -+ -+ if (kop) -+ free(kop); -+ ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey); -+ cookie->pkc_callback(cookie, 0); -+ } -+ -+ return ret; -+} -+ -+/* Cryptodev DH Key Gen routine */ -+static int cryptodev_dh_keygen_async(DH *dh, struct pkc_cookie_s *cookie) -+{ -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ int ret = 1, g_len; -+ unsigned char *g = NULL; -+ -+ if (!kop) -+ goto sw_try; -+ -+ if (dh->priv_key == NULL) { -+ if ((dh->priv_key=BN_new()) == NULL) -+ goto sw_try; -+ } -+ -+ if (dh->pub_key == NULL) { -+ if ((dh->pub_key=BN_new()) == NULL) -+ goto sw_try; -+ } -+ -+ g_len = BN_num_bytes(dh->p); -+ /** -+ * Get generator into a plain buffer. If length is less than -+ * q_len then add leading padding bytes. - */ -- if (BN_num_bytes(sig->s) < r_len) -- d_len = r_len; -- -- if (spcf_bn2bin_ex(sig->s, &d, &d_len)) { -- ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -- goto err; -- } -- -- /* memory for message representative */ -- f = malloc(r_len); -- if (!f) { -- ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -- goto err; -+ if (spcf_bn2bin_ex(dh->g, &g, &g_len)) { -+ DSAerr(DH_F_DH_GENERATE_KEY, ERR_R_MALLOC_FAILURE); -+ goto sw_try; - } - -- /* Add padding, since SEC expects hash to of size r_len */ -- memset(f, 0, r_len-dgst_len); -+ memset(kop, 0, sizeof(struct crypt_kop)); -+ kop->crk_op = CRK_DH_GENERATE_KEY; -+ if (bn2crparam(dh->p, &kop->crk_param[0])) -+ goto sw_try; -+ if (bn2crparam(dh->q, &kop->crk_param[1])) -+ goto sw_try; -+ kop->crk_param[2].crp_p = g; -+ kop->crk_param[2].crp_nbits = g_len * 8; -+ kop->crk_iparams = 3; -+ kop->cookie = cookie; - -- /* Skip leading bytes if dgst_len < r_len */ -- memcpy(f + r_len-dgst_len, tmp_dgst, dgst_len); -- dgst_len += r_len-dgst_len; -- kop.crk_op = CRK_DSA_VERIFY; -- /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ -- kop.crk_param[0].crp_p = f; -- kop.crk_param[0].crp_nbits = dgst_len * 8; -- kop.crk_param[1].crp_p = q; -- kop.crk_param[1].crp_nbits = q_len * 8; -- kop.crk_param[2].crp_p = r; -- kop.crk_param[2].crp_nbits = r_len * 8; -- kop.crk_param[3].crp_p = g_xy; -- kop.crk_param[3].crp_nbits = g_len * 8; -- kop.crk_param[4].crp_p = w_xy; -- kop.crk_param[4].crp_nbits = pub_key_len * 8; -- kop.crk_param[5].crp_p = ab; -- kop.crk_param[5].crp_nbits = ab_len * 8; -- kop.crk_param[6].crp_p = c; -- kop.crk_param[6].crp_nbits = d_len * 8; -- kop.crk_param[7].crp_p = d; -- kop.crk_param[7].crp_nbits = d_len * 8; -- kop.crk_iparams = 8; -+ /* pub_key is or prime length while priv key is of length of order */ -+ if (cryptodev_asym_async(kop, BN_num_bytes(dh->p), dh->pub_key, -+ BN_num_bytes(dh->q), dh->priv_key)) -+ goto sw_try; - -- if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { -- /*OCF success value is 0, if not zero, change ret to fail*/ -- if(0 == kop.crk_status) -- ret = 1; -- } else { -- const ECDSA_METHOD *meth = ECDSA_OpenSSL(); -+ return ret; -+sw_try: -+ { -+ const DH_METHOD *meth = DH_OpenSSL(); - -- ret = (meth->ecdsa_do_verify)(dgst, dgst_len, sig, eckey); -+ if (kop) -+ free(kop); -+ ret = (meth->generate_key)(dh); -+ cookie->pkc_callback(cookie, 0); - } -- kop.crk_param[0].crp_p = NULL; -- zapparams(&kop); -- --err: - return ret; - } - -@@ -2360,6 +3383,54 @@ sw_try: - return (dhret); - } - -+/* Return Length if successful and 0 on failure */ -+static int -+cryptodev_dh_compute_key_async(unsigned char *key, const BIGNUM *pub_key, -+ DH *dh, struct pkc_cookie_s *cookie) -+{ -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ int ret = 1; -+ int fd, p_len; -+ unsigned char *padded_pub_key = NULL, *p = NULL; -+ -+ fd = *(int *)cookie->eng_handle; -+ -+ memset(kop, 0, sizeof(struct crypt_kop)); -+ kop->crk_op = CRK_DH_COMPUTE_KEY; -+ /* inputs: dh->priv_key pub_key dh->p key */ -+ spcf_bn2bin(dh->p, &p, &p_len); -+ spcf_bn2bin_ex(pub_key, &padded_pub_key, &p_len); -+ -+ if (bn2crparam(dh->priv_key, &kop->crk_param[0])) -+ goto err; -+ kop->crk_param[1].crp_p = padded_pub_key; -+ kop->crk_param[1].crp_nbits = p_len * 8; -+ kop->crk_param[2].crp_p = p; -+ kop->crk_param[2].crp_nbits = p_len * 8; -+ kop->crk_iparams = 3; -+ -+ kop->cookie = cookie; -+ kop->crk_param[3].crp_p = (void*) key; -+ kop->crk_param[3].crp_nbits = p_len * 8; -+ kop->crk_oparams = 1; -+ -+ if (cryptodev_asym_async(kop, 0, NULL, 0, NULL)) -+ goto err; -+ -+ return p_len; -+err: -+ { -+ const DH_METHOD *meth = DH_OpenSSL(); -+ -+ if (kop) -+ free(kop); -+ ret = (meth->compute_key)(key, pub_key, dh); -+ /* Call user cookie handler */ -+ cookie->pkc_callback(cookie, 0); -+ } -+ return (ret); -+} -+ - int cryptodev_ecdh_compute_key(void *out, size_t outlen, - const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen, - void *out, size_t *outlen)) -@@ -2537,6 +3608,190 @@ err: - return ret; - } - -+int cryptodev_ecdh_compute_key_async(void *out, size_t outlen, -+ const EC_POINT *pub_key, EC_KEY *ecdh, void *(*KDF)(const void *in, size_t inlen, -+ void *out, size_t *outlen), struct pkc_cookie_s *cookie) -+{ -+ ec_curve_t ec_crv = EC_PRIME; -+ unsigned char * q = NULL, *w_xy = NULL, *ab = NULL, *s = NULL, *r = NULL; -+ BIGNUM * w_x = NULL, *w_y = NULL; -+ int q_len = 0, ab_len = 0, pub_key_len = 0, r_len = 0, priv_key_len = 0; -+ BIGNUM * p = NULL, *a = NULL, *b = NULL; -+ BN_CTX *ctx; -+ EC_POINT *tmp=NULL; -+ BIGNUM *x=NULL, *y=NULL; -+ const BIGNUM *priv_key; -+ const EC_GROUP* group = NULL; -+ int ret = 1; -+ size_t buflen, len; -+ struct crypt_kop *kop = malloc(sizeof(struct crypt_kop)); -+ -+ if (!(ctx = BN_CTX_new()) || !kop) -+ goto err; -+ -+ memset(kop, 0, sizeof(struct crypt_kop)); -+ -+ BN_CTX_start(ctx); -+ x = BN_CTX_get(ctx); -+ y = BN_CTX_get(ctx); -+ p = BN_CTX_get(ctx); -+ a = BN_CTX_get(ctx); -+ b = BN_CTX_get(ctx); -+ w_x = BN_CTX_get(ctx); -+ w_y = BN_CTX_get(ctx); -+ -+ if (!x || !y || !p || !a || !b || !w_x || !w_y) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ priv_key = EC_KEY_get0_private_key(ecdh); -+ if (priv_key == NULL) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE); -+ goto err; -+ } -+ -+ group = EC_KEY_get0_group(ecdh); -+ if ((tmp=EC_POINT_new(group)) == NULL) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == -+ NID_X9_62_prime_field) { -+ ec_crv = EC_PRIME; -+ -+ if (!EC_POINT_get_affine_coordinates_GFp(group, -+ EC_GROUP_get0_generator(group), x, y, ctx)) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE); -+ goto err; -+ } -+ -+ /* get the ECC curve parameters */ -+ if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* get the public key pair for prime curve */ -+ if (!EC_POINT_get_affine_coordinates_GFp (group, pub_key, w_x, w_y,ctx)) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); -+ goto err; -+ } -+ } else { -+ ec_crv = EC_BINARY; -+ -+ if (!EC_POINT_get_affine_coordinates_GF2m(group, -+ EC_GROUP_get0_generator(group), x, y, ctx)) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE); -+ goto err; -+ } -+ -+ /* get the ECC curve parameters */ -+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b , ctx)) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* get the public key pair for binary curve */ -+ if (!EC_POINT_get_affine_coordinates_GF2m(group, -+ pub_key, w_x, w_y,ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+ -+ /* irreducible polynomial that creates the field */ -+ if (spcf_bn2bin((BIGNUM*)&group->order, &r, &r_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Get the irreducible polynomial that creates the field */ -+ if (spcf_bn2bin(p, &q, &q_len)) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* Get the public key into a flat buffer with appropriate padding */ -+ pub_key_len = 2 * q_len; -+ w_xy = eng_copy_curve_points (w_x, w_y, pub_key_len, q_len); -+ if (!w_xy) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* Generation of ECC curve parameters */ -+ ab_len = 2*q_len; -+ ab = eng_copy_curve_points (a, b, ab_len, q_len); -+ if (!ab) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ if (ec_crv == EC_BINARY) { -+ /* copy b' i.e c(b), instead of only b */ -+ if (eng_ec_get_cparam(EC_GROUP_get_curve_name(group), ab+q_len, q_len)) -+ { -+ unsigned char *c_temp = NULL; -+ int c_temp_len = q_len; -+ if (eng_ec_compute_cparam(b, p, &c_temp, &c_temp_len)) -+ memcpy(ab+q_len, c_temp, q_len); -+ else -+ goto err; -+ } -+ kop->curve_type = ECC_BINARY; -+ } else -+ kop->curve_type = ECC_PRIME; -+ -+ priv_key_len = r_len; -+ -+ /* -+ * If BN_num_bytes of priv_key returns less then r_len then -+ * add padding bytes before the key -+ */ -+ if (spcf_bn2bin_ex((BIGNUM *)priv_key, &s, &priv_key_len)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ buflen = (EC_GROUP_get_degree(group) + 7)/8; -+ len = BN_num_bytes(x); -+ if (len > buflen || q_len < buflen) { -+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ kop->crk_op = CRK_DH_COMPUTE_KEY; -+ kop->crk_param[0].crp_p = (void *) s; -+ kop->crk_param[0].crp_nbits = priv_key_len*8; -+ kop->crk_param[1].crp_p = (void *) w_xy; -+ kop->crk_param[1].crp_nbits = pub_key_len*8; -+ kop->crk_param[2].crp_p = (void *) q; -+ kop->crk_param[2].crp_nbits = q_len*8; -+ kop->crk_param[3].crp_p = (void *) ab; -+ kop->crk_param[3].crp_nbits = ab_len*8; -+ kop->crk_iparams = 4; -+ kop->crk_param[4].crp_p = (void *) out; -+ kop->crk_param[4].crp_nbits = q_len*8; -+ kop->crk_oparams = 1; -+ kop->cookie = cookie; -+ if (cryptodev_asym_async(kop, 0, NULL, 0, NULL)) -+ goto err; -+ -+ return q_len; -+err: -+ { -+ const ECDH_METHOD *meth = ECDH_OpenSSL(); -+ -+ if (kop) -+ free(kop); -+ ret = (meth->compute_key)(out, outlen, pub_key, ecdh, KDF); -+ /* Call user cookie handler */ -+ cookie->pkc_callback(cookie, 0); -+ } -+ return ret; -+} - - static DH_METHOD cryptodev_dh = { - "cryptodev DH method", -@@ -2545,6 +3800,8 @@ static DH_METHOD cryptodev_dh = { - NULL, - NULL, - NULL, -+ NULL, -+ NULL, - 0, /* flags */ - NULL /* app_data */ - }; -@@ -2553,6 +3810,7 @@ static ECDH_METHOD cryptodev_ecdh = { - "cryptodev ECDH method", - NULL, /* cryptodev_ecdh_compute_key */ - NULL, -+ NULL, - 0, /* flags */ - NULL /* app_data */ - }; -@@ -2625,12 +3883,19 @@ ENGINE_load_cryptodev(void) - cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; - if (cryptodev_asymfeat & CRF_MOD_EXP) { - cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; -- if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) -+ cryptodev_rsa.bn_mod_exp_async = -+ cryptodev_bn_mod_exp_async; -+ if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) { - cryptodev_rsa.rsa_mod_exp = - cryptodev_rsa_mod_exp; -- else -+ cryptodev_rsa.rsa_mod_exp_async = -+ cryptodev_rsa_mod_exp_async; -+ } else { - cryptodev_rsa.rsa_mod_exp = - cryptodev_rsa_nocrt_mod_exp; -+ cryptodev_rsa.rsa_mod_exp_async = -+ cryptodev_rsa_nocrt_mod_exp_async; -+ } - } - } - -@@ -2638,12 +3903,21 @@ ENGINE_load_cryptodev(void) - const DSA_METHOD *meth = DSA_OpenSSL(); - - memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); -- if (cryptodev_asymfeat & CRF_DSA_SIGN) -+ if (cryptodev_asymfeat & CRF_DSA_SIGN) { - cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; -- if (cryptodev_asymfeat & CRF_DSA_VERIFY) -+ cryptodev_dsa.dsa_do_sign_async = -+ cryptodev_dsa_do_sign_async; -+ } -+ if (cryptodev_asymfeat & CRF_DSA_VERIFY) { - cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; -- if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY) -+ cryptodev_dsa.dsa_do_verify_async = -+ cryptodev_dsa_verify_async; -+ } -+ if (cryptodev_asymfeat & CRF_DSA_GENERATE_KEY) { - cryptodev_dsa.dsa_keygen = cryptodev_dsa_keygen; -+ cryptodev_dsa.dsa_keygen_async = -+ cryptodev_dsa_keygen_async; -+ } - } - - if (ENGINE_set_DH(engine, &cryptodev_dh)){ -@@ -2652,10 +3926,15 @@ ENGINE_load_cryptodev(void) - if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) { - cryptodev_dh.compute_key = - cryptodev_dh_compute_key; -+ cryptodev_dh.compute_key_async = -+ cryptodev_dh_compute_key_async; - } - if (cryptodev_asymfeat & CRF_DH_GENERATE_KEY) { - cryptodev_dh.generate_key = - cryptodev_dh_keygen; -+ cryptodev_dh.generate_key_async = -+ cryptodev_dh_keygen_async; -+ - } - } - -@@ -2664,10 +3943,14 @@ ENGINE_load_cryptodev(void) - memcpy(&cryptodev_ecdsa, meth, sizeof(ECDSA_METHOD)); - if (cryptodev_asymfeat & CRF_DSA_SIGN) { - cryptodev_ecdsa.ecdsa_do_sign = cryptodev_ecdsa_do_sign; -+ cryptodev_ecdsa.ecdsa_do_sign_async = -+ cryptodev_ecdsa_do_sign_async; - } - if (cryptodev_asymfeat & CRF_DSA_VERIFY) { - cryptodev_ecdsa.ecdsa_do_verify = - cryptodev_ecdsa_verify; -+ cryptodev_ecdsa.ecdsa_do_verify_async = -+ cryptodev_ecdsa_verify_async; - } - } - -@@ -2676,9 +3959,16 @@ ENGINE_load_cryptodev(void) - memcpy(&cryptodev_ecdh, ecdh_meth, sizeof(ECDH_METHOD)); - if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) { - cryptodev_ecdh.compute_key = cryptodev_ecdh_compute_key; -+ cryptodev_ecdh.compute_key_async = -+ cryptodev_ecdh_compute_key_async; - } - } - -+ ENGINE_set_check_pkc_availability(engine, cryptodev_check_availability); -+ ENGINE_set_close_instance(engine, cryptodev_close_instance); -+ ENGINE_set_init_instance(engine, cryptodev_init_instance); -+ ENGINE_set_async_map(engine, ENGINE_ALLPKC_ASYNC); -+ - ENGINE_add(engine); - ENGINE_free(engine); - ERR_clear_error(); -diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h -index 451ef8f..8fc3077 100644 ---- a/crypto/engine/eng_int.h -+++ b/crypto/engine/eng_int.h -@@ -181,7 +181,29 @@ struct engine_st - ENGINE_LOAD_KEY_PTR load_pubkey; - - ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert; -- -+ /* -+ * Instantiate Engine handle to be passed in check_pkc_availability -+ * Ensure that Engine is instantiated before any pkc asynchronous call. -+ */ -+ void *(*engine_init_instance)(void); -+ /* -+ * Instantiated Engine handle will be closed with this call. -+ * Ensure that no pkc asynchronous call is made after this call -+ */ -+ void (*engine_close_instance)(void *handle); -+ /* -+ * Check availability will extract the data from kernel. -+ * eng_handle: This is the Engine handle corresponds to which -+ * the cookies needs to be polled. -+ * return 0 if cookie available else 1 -+ */ -+ int (*check_pkc_availability)(void *eng_handle); -+ /* -+ * The following map is used to check if the engine supports asynchronous implementation -+ * ENGINE_ASYNC_FLAG* for available bitmap. Any application checking for asynchronous -+ * implementation need to check this features using "int ENGINE_get_async_map(engine *)"; -+ */ -+ int async_map; - const ENGINE_CMD_DEFN *cmd_defns; - int flags; - /* reference count on the structure itself */ -diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c -index 18a6664..6fa621c 100644 ---- a/crypto/engine/eng_lib.c -+++ b/crypto/engine/eng_lib.c -@@ -98,7 +98,11 @@ void engine_set_all_null(ENGINE *e) - e->ctrl = NULL; - e->load_privkey = NULL; - e->load_pubkey = NULL; -+ e->check_pkc_availability = NULL; -+ e->engine_init_instance = NULL; -+ e->engine_close_instance = NULL; - e->cmd_defns = NULL; -+ e->async_map = 0; - e->flags = 0; - } - -@@ -233,6 +237,48 @@ int ENGINE_set_id(ENGINE *e, const char *id) - return 1; - } - -+void ENGINE_set_init_instance(ENGINE *e, void *(*engine_init_instance)(void)) -+ { -+ e->engine_init_instance = engine_init_instance; -+ } -+ -+void ENGINE_set_close_instance(ENGINE *e, -+ void (*engine_close_instance)(void *)) -+ { -+ e->engine_close_instance = engine_close_instance; -+ } -+ -+void ENGINE_set_async_map(ENGINE *e, int async_map) -+ { -+ e->async_map = async_map; -+ } -+ -+void *ENGINE_init_instance(ENGINE *e) -+ { -+ return e->engine_init_instance(); -+ } -+ -+void ENGINE_close_instance(ENGINE *e, void *eng_handle) -+ { -+ e->engine_close_instance(eng_handle); -+ } -+ -+int ENGINE_get_async_map(ENGINE *e) -+ { -+ return e->async_map; -+ } -+ -+void ENGINE_set_check_pkc_availability(ENGINE *e, -+ int (*check_pkc_availability)(void *eng_handle)) -+ { -+ e->check_pkc_availability = check_pkc_availability; -+ } -+ -+int ENGINE_check_pkc_availability(ENGINE *e, void *eng_handle) -+ { -+ return e->check_pkc_availability(eng_handle); -+ } -+ - int ENGINE_set_name(ENGINE *e, const char *name) - { - if(name == NULL) -diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h -index 237a6c9..ccff86a 100644 ---- a/crypto/engine/engine.h -+++ b/crypto/engine/engine.h -@@ -473,6 +473,30 @@ ENGINE *ENGINE_new(void); - int ENGINE_free(ENGINE *e); - int ENGINE_up_ref(ENGINE *e); - int ENGINE_set_id(ENGINE *e, const char *id); -+void ENGINE_set_init_instance(ENGINE *e, void *(*engine_init_instance)(void)); -+void ENGINE_set_close_instance(ENGINE *e, -+ void (*engine_free_instance)(void *)); -+/* -+ * Following FLAGS are bitmap store in async_map to set asynchronous interface capability -+ *of the engine -+ */ -+#define ENGINE_RSA_ASYNC 0x0001 -+#define ENGINE_DSA_ASYNC 0x0002 -+#define ENGINE_DH_ASYNC 0x0004 -+#define ENGINE_ECDSA_ASYNC 0x0008 -+#define ENGINE_ECDH_ASYNC 0x0010 -+#define ENGINE_ALLPKC_ASYNC 0x001F -+/* Engine implementation will set the bitmap based on above flags using following API */ -+void ENGINE_set_async_map(ENGINE *e, int async_map); -+ /* Application need to check the bitmap based on above flags using following API -+ * to confirm asynchronous methods supported -+ */ -+int ENGINE_get_async_map(ENGINE *e); -+void *ENGINE_init_instance(ENGINE *e); -+void ENGINE_close_instance(ENGINE *e, void *eng_handle); -+void ENGINE_set_check_pkc_availability(ENGINE *e, -+ int (*check_pkc_availability)(void *eng_handle)); -+int ENGINE_check_pkc_availability(ENGINE *e, void *eng_handle); - int ENGINE_set_name(ENGINE *e, const char *name); - int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); - int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); -diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h -index 5f269e5..6ef1b15 100644 ---- a/crypto/rsa/rsa.h -+++ b/crypto/rsa/rsa.h -@@ -101,6 +101,29 @@ struct rsa_meth_st - int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); /* Can be null */ -+ /* -+ * Cookie in the following _async variant must be allocated before -+ * submission and can be freed once its corresponding callback -+ * handler is called -+ */ -+ int (*rsa_pub_enc_asyn)(int flen,const unsigned char *from, -+ unsigned char *to, RSA *rsa, int padding, -+ struct pkc_cookie_s *cookie); -+ int (*rsa_pub_dec_async)(int flen,const unsigned char *from, -+ unsigned char *to, RSA *rsa, int padding, -+ struct pkc_cookie_s *cookie); -+ int (*rsa_priv_enc_async)(int flen,const unsigned char *from, -+ unsigned char *to, RSA *rsa, int padding, -+ struct pkc_cookie_s *cookie); -+ int (*rsa_priv_dec_async)(int flen,const unsigned char *from, -+ unsigned char *to, RSA *rsa, int padding, -+ struct pkc_cookie_s *cookie); -+ int (*rsa_mod_exp_async)(BIGNUM *r0, const BIGNUM *I, RSA *rsa, -+ BN_CTX *ctx, struct pkc_cookie_s *cookie); -+ int (*bn_mod_exp_async)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, -+ const BIGNUM *m, BN_CTX *ctx, -+ BN_MONT_CTX *m_ctx, struct pkc_cookie_s *cookie); -+ - int (*init)(RSA *rsa); /* called at new */ - int (*finish)(RSA *rsa); /* called at free */ - int flags; /* RSA_METHOD_FLAG_* things */ --- -2.3.5 - |