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) { struct crypt_kop 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) { ret = BN_mod_exp(r, a, p, m, ctx); return (ret); } memset(&kop, 0, sizeof kop); kop.crk_op = CRK_MOD_EXP; /* 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(&kop, BN_num_bytes(m), r, 0, NULL) == -1) { const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); } err: zapparams(&kop); return (ret); }
static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { struct crypt_kop kop; BIGNUM *r = NULL, *s = NULL; DSA_SIG *dsaret = NULL; if ((r = BN_new()) == NULL) goto err; if ((s = BN_new()) == NULL) { BN_free(r); goto err; } memset(&kop, 0, sizeof kop); kop.crk_op = CRK_DSA_SIGN; /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ kop.crk_param[0].crp_p = (caddr_t) dgst; kop.crk_param[0].crp_nbits = dlen * 8; if (bn2crparam(dsa->p, &kop.crk_param[1])) goto err; if (bn2crparam(dsa->q, &kop.crk_param[2])) goto err; if (bn2crparam(dsa->g, &kop.crk_param[3])) goto err; if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) goto err; kop.crk_iparams = 5; if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, BN_num_bytes(dsa->q), s) == 0) { dsaret = DSA_SIG_new(); if (dsaret == NULL) goto err; dsaret->r = r; dsaret->s = s; r = s = NULL; } else { const DSA_METHOD *meth = DSA_OpenSSL(); dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa); } err: BN_free(r); BN_free(s); kop.crk_param[0].crp_p = NULL; zapparams(&kop); return (dsaret); }
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) { struct crypt_kop 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) { ret = BN_mod_exp(r, a, p, m, ctx); return (ret); } memset(&kop, 0, sizeof(kop)); kop.crk_op = CRK_MOD_EXP; /* 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(&kop, BN_num_bytes(m), r, 0, NULL)) { const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); printf("OCF asym process failed, Running in software\n"); ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); } else if (ECANCELED == kop.crk_status) { const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); printf("OCF hardware operation cancelled. Running in Software\n"); ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); } /* else cryptodev operation worked ok ==> ret = 1 */ err: zapparams(&kop); return (ret); }
/* * Compute mod exp in hardware */ static void cryptodev_mod_exp(mpz_t dst, const mpz_t mp_g, const mpz_t secret, const mpz_t modulus) { struct crypt_kop kop; BIGNUM r0, a, p, m; BN_CTX *ctx; memset(&kop, 0, sizeof kop); kop.crk_op = CRK_MOD_EXP; ctx = BN_CTX_new(); mp2bn(mp_g, &a); mp2bn(secret, &p); mp2bn(modulus, &m); mp2bn(dst, &r0); /* 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(&kop, BN_num_bytes(&m), &r0, 0, NULL) == -1) { openswan_log("OCF CRK_MOD_EXP failed %d, using SW\n", errno); goto err; } bn2mp(&r0, dst); zapparams(&kop); BN_CTX_free(ctx); return; err: zapparams(&kop); BN_CTX_free(ctx); soft_meth.mod_exp(dst, mp_g, secret, modulus); }
static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) { struct crypt_kop kop; int dhret = 1; int fd, keylen; if ((fd = get_asym_dev_crypto()) < 0) { const DH_METHOD *meth = DH_OpenSSL(); return ((meth->compute_key)(key, pub_key, dh)); } keylen = BN_num_bits(dh->p); memset(&kop, 0, sizeof kop); kop.crk_op = CRK_DH_COMPUTE_KEY; /* inputs: dh->priv_key pub_key dh->p key */ if (bn2crparam(dh->priv_key, &kop.crk_param[0])) goto err; if (bn2crparam(pub_key, &kop.crk_param[1])) goto err; if (bn2crparam(dh->p, &kop.crk_param[2])) goto err; kop.crk_iparams = 3; kop.crk_param[3].crp_p = key; kop.crk_param[3].crp_nbits = keylen * 8; kop.crk_oparams = 1; if (ioctl(fd, CIOCKEY, &kop) == -1) { const DH_METHOD *meth = DH_OpenSSL(); dhret = (meth->compute_key)(key, pub_key, dh); } err: kop.crk_param[3].crp_p = NULL; zapparams(&kop); return (dhret); }
/* * Do the modular exponentiation without Chinese Remainder Theorem in hardware */ static void cryptodev_rsa_mod_exp_crt(mpz_t dst, const mpz_t src, const mpz_t p, const mpz_t dP, const mpz_t q, const mpz_t dQ, const mpz_t qInv) { struct crypt_kop kop; BIGNUM D, S, P, DP, Q, DQ, QI; BN_CTX *ctx; memset(&kop, 0, sizeof kop); kop.crk_op = CRK_MOD_EXP; ctx = BN_CTX_new(); mp2bn(dst, &D); mp2bn(src, &S); mp2bn(p, &P); mp2bn(dP, &DP); mp2bn(q, &Q); mp2bn(dQ, &DQ); mp2bn(qInv, &QI); /* inputs: a^p % m */ if (bn2crparam(&P, &kop.crk_param[0])) goto err; if (bn2crparam(&Q, &kop.crk_param[1])) goto err; if (bn2crparam(&S, &kop.crk_param[2])) goto err; if (bn2crparam(&DP, &kop.crk_param[3])) goto err; if (bn2crparam(&DQ, &kop.crk_param[4])) goto err; if (bn2crparam(&QI, &kop.crk_param[5])) goto err; kop.crk_iparams = 6; if (cryptodev_asym(&kop, BN_num_bytes(&D), &D, 0, NULL) == -1) { libreswan_log("OCF CRK_MOD_EXP_CRT failed %d, using SW\n", errno); goto err; } bn2mp(&D, dst); zapparams(&kop); BN_CTX_free(ctx); return; err: zapparams(&kop); BN_CTX_free(ctx); soft_meth.rsa_mod_exp_crt(dst, src, p, dP, q, dQ, qInv); }
static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { struct crypt_kop kop; int ret = 1; if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { /* XXX 0 means failure?? */ return (0); } memset(&kop, 0, sizeof(kop)); kop.crk_op = CRK_MOD_EXP_CRT; /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ if (bn2crparam(rsa->p, &kop.crk_param[0])) goto err; if (bn2crparam(rsa->q, &kop.crk_param[1])) goto err; if (bn2crparam(I, &kop.crk_param[2])) goto err; if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) goto err; if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) goto err; if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) goto err; kop.crk_iparams = 6; if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); printf("OCF asym process failed, running in Software\n"); ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); } else if (ECANCELED == kop.crk_status) { const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); printf("OCF hardware operation cancelled. Running in Software\n"); ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); } /* else cryptodev operation worked ok ==> ret = 1 */ err: zapparams(&kop); return (ret); }
static int cryptodev_dsa_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig, DSA *dsa) { struct crypt_kop kop; int dsaret = 1; memset(&kop, 0, sizeof(kop)); kop.crk_op = CRK_DSA_VERIFY; /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ kop.crk_param[0].crp_p = (caddr_t) dgst; kop.crk_param[0].crp_nbits = dlen * 8; if (bn2crparam(dsa->p, &kop.crk_param[1])) goto err; if (bn2crparam(dsa->q, &kop.crk_param[2])) goto err; if (bn2crparam(dsa->g, &kop.crk_param[3])) goto err; if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) goto err; if (bn2crparam(sig->r, &kop.crk_param[5])) goto err; if (bn2crparam(sig->s, &kop.crk_param[6])) goto err; kop.crk_iparams = 7; if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { /* * OCF success value is 0, if not zero, change dsaret to fail */ if (0 != kop.crk_status) dsaret = 0; } else { const DSA_METHOD *meth = DSA_OpenSSL(); dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa); } err: kop.crk_param[0].crp_p = NULL; zapparams(&kop); return (dsaret); }
static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { struct crypt_kop kop; int ret = 1; if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { /* XXX 0 means failure?? */ return (0); } memset(&kop, 0, sizeof kop); kop.crk_op = CRK_MOD_EXP_CRT; /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ if (bn2crparam(rsa->p, &kop.crk_param[0])) goto err; if (bn2crparam(rsa->q, &kop.crk_param[1])) goto err; if (bn2crparam(I, &kop.crk_param[2])) goto err; if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) goto err; if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) goto err; if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) goto err; kop.crk_iparams = 6; if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) { const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); } err: zapparams(&kop); return (ret); }