コード例 #1
0
static int
cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
    const unsigned char *iv, int enc)
{
	struct dev_crypto_state *state = ctx->cipher_data;
	struct session_op *sess = &state->d_sess;
	struct dev_crypto_cipher *cipher;

	if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NULL)
		return (0);

	if (ctx->cipher->iv_len > cipher->c_ivmax)
		return (0);

	if (ctx->key_len != cipher->c_keylen)
		return (0);

	memset(sess, 0, sizeof(struct session_op));

	if ((state->d_fd = get_dev_crypto()) < 0)
		return (0);

	sess->key = (unsigned char *)key;
	sess->keylen = ctx->key_len;
	sess->cipher = cipher->c_id;

	if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
		close(state->d_fd);
		state->d_fd = -1;
		return (0);
	}
	return (1);
}
コード例 #2
0
ファイル: eng_cryptodev.c プロジェクト: AndreV84/openssl
static int cryptodev_digest_init(EVP_MD_CTX *ctx)
{
    struct dev_crypto_state *state = ctx->md_data;
    struct session_op *sess = &state->d_sess;
    int digest;

    if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef) {
        printf("cryptodev_digest_init: Can't get digest \n");
        return (0);
    }

    memset(state, 0, sizeof(*state));

    if ((state->d_fd = get_dev_crypto()) < 0) {
        printf("cryptodev_digest_init: Can't get Dev \n");
        return (0);
    }

    sess->mackey = state->dummy_mac_key;
    sess->mackeylen = digest_key_length(ctx->digest->type);
    sess->mac = digest;

    if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
        put_dev_crypto(state->d_fd);
        state->d_fd = -1;
        printf("cryptodev_digest_init: Open session failed\n");
        return (0);
    }

    return (1);
}
コード例 #3
0
/*
 * Find out what digests /dev/crypto will let us have a session for.
 * XXX note, that some of these openssl doesn't deal with yet!
 * returning them here is harmless, as long as we return NULL
 * when asked for a handler in the cryptodev_engine_digests routine
 */
#if 0 /* UNUSED */
static int
get_cryptodev_digests(const int **cnids)
{
	static int nids[CRYPTO_ALGORITHM_MAX];
	struct session_op sess;
	int fd, i, count = 0;

	if ((fd = get_dev_crypto()) < 0) {
		*cnids = NULL;
		return (0);
	}
	memset(&sess, 0, sizeof(sess));
	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
		if (digests[i].nid == NID_undef)
			continue;
		sess.mac = digests[i].id;
		sess.cipher = 0;
		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
			nids[count++] = digests[i].nid;
	}
	close(fd);

	if (count > 0)
		*cnids = nids;
	else
		*cnids = NULL;
	return (count);
}
コード例 #4
0
ファイル: eng_cryptodev.c プロジェクト: AndreV84/openssl
/*
 * Find out what ciphers /dev/crypto will let us have a session for.
 * XXX note, that some of these openssl doesn't deal with yet!
 * returning them here is harmless, as long as we return NULL
 * when asked for a handler in the cryptodev_engine_ciphers routine
 */
static int get_cryptodev_ciphers(const int **cnids)
{
    static int nids[CRYPTO_ALGORITHM_MAX];
    struct session_op sess;
    int fd, i, count = 0;

    if ((fd = get_dev_crypto()) < 0) {
        *cnids = NULL;
        return (0);
    }
    memset(&sess, 0, sizeof(sess));
    sess.key = (caddr_t) "123456789abcdefghijklmno";

    for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
        if (ciphers[i].nid == NID_undef)
            continue;
        sess.cipher = ciphers[i].id;
        sess.keylen = ciphers[i].keylen;
        sess.mac = 0;
        if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
            ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
            nids[count++] = ciphers[i].nid;
    }
    put_dev_crypto(fd);

    if (count > 0)
        *cnids = nids;
    else
        *cnids = NULL;
    return (count);
}
コード例 #5
0
/*
 * Find out what ciphers /dev/crypto will let us have a session for.
 * XXX note, that some of these openssl doesn't deal with yet!
 * returning them here is harmless, as long as we return NULL
 * when asked for a handler in the cryptodev_engine_ciphers routine
 */
static int
get_cryptodev_ciphers(const int **cnids)
{
	static int nids[CRYPTO_ALGORITHM_MAX];
	struct session_op sess;
	int fd, i, count = 0;

	if ((fd = get_dev_crypto()) < 0) {
		*cnids = NULL;
		return (0);
	}
	memset(&sess, 0, sizeof(sess));
	sess.key = (caddr_t)"123456781234567812345678";

	for (i = 0; ciphers[i].c_id && count < CRYPTO_ALGORITHM_MAX; i++) {
		if (ciphers[i].c_nid == NID_undef)
			continue;
		sess.cipher = ciphers[i].c_id;
		sess.keylen = ciphers[i].c_keylen;
		sess.mac = 0;
		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
			nids[count++] = ciphers[i].c_nid;
	}
	close(fd);

#if defined(__i386__)
	/*
	 * On i386, always check for the VIA C3 AES instructions;
	 * even if /dev/crypto is disabled.
	 */
	if (check_viac3aes() >= 1) {
		int have_NID_aes_128_cbc = 0;
		int have_NID_aes_192_cbc = 0;
		int have_NID_aes_256_cbc = 0;

		for (i = 0; i < count; i++) {
			if (nids[i] == NID_aes_128_cbc)
				have_NID_aes_128_cbc = 1;
			if (nids[i] == NID_aes_192_cbc)
				have_NID_aes_192_cbc = 1;
			if (nids[i] == NID_aes_256_cbc)
				have_NID_aes_256_cbc = 1;
		}
		if (!have_NID_aes_128_cbc)
			nids[count++] = NID_aes_128_cbc;
		if (!have_NID_aes_192_cbc)
			nids[count++] = NID_aes_192_cbc;
		if (!have_NID_aes_256_cbc)
			nids[count++] = NID_aes_256_cbc;
	}
#endif

	if (count > 0)
		*cnids = nids;
	else
		*cnids = NULL;
	return (count);
}
コード例 #6
0
ファイル: eng_cryptodev.c プロジェクト: AndreV84/openssl
/* Caching version for asym operations */
static int get_asym_dev_crypto(void)
{
    static int fd = -1;

    if (fd == -1)
        fd = get_dev_crypto();
    return fd;
}
コード例 #7
0
ファイル: eng_cryptodev.c プロジェクト: AndreV84/openssl
static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
{
    struct dev_crypto_state *fstate = from->md_data;
    struct dev_crypto_state *dstate = to->md_data;
    struct session_op *sess;
    int digest;

    if (dstate == NULL || fstate == NULL)
        return 1;

    memcpy(dstate, fstate, sizeof(struct dev_crypto_state));

    sess = &dstate->d_sess;

    digest = digest_nid_to_cryptodev(to->digest->type);

    sess->mackey = dstate->dummy_mac_key;
    sess->mackeylen = digest_key_length(to->digest->type);
    sess->mac = digest;

    dstate->d_fd = get_dev_crypto();

    if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
        put_dev_crypto(dstate->d_fd);
        dstate->d_fd = -1;
        printf("cryptodev_digest_copy: Open session failed\n");
        return (0);
    }

    if (fstate->mac_len != 0) {
        if (fstate->mac_data != NULL) {
            dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
            if (dstate->mac_data == NULL) {
                printf("cryptodev_digest_copy: mac_data allocation failed\n");
                return (0);
            }
            memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
            dstate->mac_len = fstate->mac_len;
        }
    }

    return 1;
}
コード例 #8
0
ファイル: eng_cryptodev.c プロジェクト: AndreV84/openssl
static int
cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                   const unsigned char *iv, int enc)
{
    struct dev_crypto_state *state = ctx->cipher_data;
    struct session_op *sess = &state->d_sess;
    int cipher = -1, i;

    for (i = 0; ciphers[i].id; i++)
        if (ctx->cipher->nid == ciphers[i].nid &&
            ctx->cipher->iv_len <= ciphers[i].ivmax &&
            ctx->key_len == ciphers[i].keylen) {
            cipher = ciphers[i].id;
            break;
        }

    if (!ciphers[i].id) {
        state->d_fd = -1;
        return (0);
    }

    memset(sess, 0, sizeof(*sess));

    if ((state->d_fd = get_dev_crypto()) < 0)
        return (0);

    sess->key = (caddr_t) key;
    sess->keylen = ctx->key_len;
    sess->cipher = cipher;

    if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
        put_dev_crypto(state->d_fd);
        state->d_fd = -1;
        return (0);
    }
    return (1);
}
コード例 #9
0
void
ENGINE_load_cryptodev(void)
{
	ENGINE *engine = ENGINE_new();
	int fd;

	if (engine == NULL)
		return;
	if ((fd = get_dev_crypto()) < 0) {
		ENGINE_free(engine);
		return;
	}

	/*
	 * find out what asymmetric crypto algorithms we support
	 */
	if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
		close(fd);
		ENGINE_free(engine);
		return;
	}
	close(fd);

	if (!ENGINE_set_id(engine, "cryptodev") ||
	    !ENGINE_set_name(engine, "BSD cryptodev engine") ||
	    !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
	    !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
	    !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
	    !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
		ENGINE_free(engine);
		return;
	}

	if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
		const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();

		cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
		cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
		cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
		cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
		cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
		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.rsa_mod_exp =
				    cryptodev_rsa_mod_exp;
			else
				cryptodev_rsa.rsa_mod_exp =
				    cryptodev_rsa_nocrt_mod_exp;
		}
	}

	if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
		const DSA_METHOD *meth = DSA_OpenSSL();

		memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
		if (cryptodev_asymfeat & CRF_DSA_SIGN)
			cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
		if (cryptodev_asymfeat & CRF_MOD_EXP) {
			cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
			cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
		}
		if (cryptodev_asymfeat & CRF_DSA_VERIFY)
			cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
	}

	if (ENGINE_set_DH(engine, &cryptodev_dh)){
		const DH_METHOD *dh_meth = DH_OpenSSL();

		cryptodev_dh.generate_key = dh_meth->generate_key;
		cryptodev_dh.compute_key = dh_meth->compute_key;
		cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
		if (cryptodev_asymfeat & CRF_MOD_EXP) {
			cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
			if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
				cryptodev_dh.compute_key =
				    cryptodev_dh_compute_key;
		}
	}

	ENGINE_add(engine);
	ENGINE_free(engine);
	ERR_clear_error();
}
コード例 #10
0
ファイル: cryptodev.c プロジェクト: jgimenez/libreswan
/*
 * Find out what we can support and use it.
 */
void load_cryptodev(void)
{
	struct session_op ses;
	int assisted = 0;
	u_int32_t feat;
	struct lswcrypto_meth old_meth = lswcrypto;

	if ((cryptodev_fd = get_dev_crypto()) == -1) {
		libreswan_log(
			"OCF assist for IKE disabled: is the cryptodev module loaded ?");
		return;
	}

	/* find out what asymmetric crypto algorithms we support */
	if (ioctl(cryptodev_fd, CIOCASYMFEAT, &feat) != -1) {
		if (feat & CRF_MOD_EXP) {
			/* Use modular exponentiation */
			lswcrypto.mod_exp = cryptodev_mod_exp;
			libreswan_log(
				"OCF assist for IKE for modular exponentiation enabled");
			assisted++;
		}
		if (feat & CRF_MOD_EXP_CRT) {
			lswcrypto.rsa_mod_exp_crt = cryptodev_rsa_mod_exp_crt;
			libreswan_log(
				"OCF assist for IKE for modular exponentiation (CRT) enabled");
			assisted++;
		}
	}

	/* test we can do AES */
	memset(&ses, 0, sizeof(ses));
	ses.key = (caddr_t)"12345678901234567890123456789012";
	ses.cipher = CRYPTO_AES_CBC;
	ses.keylen = 16;
	if (ioctl(cryptodev_fd, CIOCGSESSION, &ses) != -1 &&
	    ioctl(cryptodev_fd, CIOCFSESSION, &ses.ses) != -1) {
		libreswan_log("OCF assist for IKE for AES crypto enabled");
		lswcrypto.aes_set_key     = cryptodev_aes_set_key;
		lswcrypto.aes_cbc_encrypt = cryptodev_aes_cbc_encrypt;
		assisted++;
	}

	/* test we can do DES */
	memset(&ses, 0, sizeof(ses));
	ses.key = (caddr_t)"123456789012345678901234";
	ses.cipher = CRYPTO_DES_CBC;
	ses.keylen = 8;
	if (ioctl(cryptodev_fd, CIOCGSESSION, &ses) != -1 &&
	    ioctl(cryptodev_fd, CIOCFSESSION, &ses.ses) != -1) {
		libreswan_log("OCF assist for IKE for DES crypto enabled");
		lswcrypto.des_set_key      = cryptodev_des_set_key;
		lswcrypto.des_cbc_encrypt  = cryptodev_des_cbc_encrypt;
		lswcrypto.des_encrypt      = cryptodev_des_encrypt;
		lswcrypto.des_ncbc_encrypt = cryptodev_des_ncbc_encrypt;
		lswcrypto.des_ecb_encrypt  = cryptodev_des_ecb_encrypt;
		assisted++;
		/* test we can do 3DES */
		ses.cipher = CRYPTO_3DES_CBC;
		ses.keylen = 24;
		if (ioctl(cryptodev_fd, CIOCGSESSION, &ses) != -1 &&
		    ioctl(cryptodev_fd, CIOCFSESSION, &ses.ses) != -1) {
			libreswan_log(
				"OCF assist for IKE for 3DES crypto enabled");
			lswcrypto.des_ede3_cbc_encrypt =
				cryptodev_des_ede3_cbc_encrypt;
			//DAVIDM 3des setkey is technically needed if HW can only do DES
			assisted++;
		}
	}

	if (assisted == 0) {
		close(cryptodev_fd);
		cryptodev_fd = -1;
	} else if (!soft_meth_loaded) {
		soft_meth_loaded = 1;
		soft_meth = old_meth;
	}
}