/* * 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); }
/* * 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); }