/*
 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
 * Copyright (c) 2002 Theo de Raadt
 * Copyright (c) 2002 Markus Friedl
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <openssl/objects.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/bn.h>

#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
	(defined(OpenBSD) || defined(__FreeBSD__))
#include <sys/param.h>
# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
#  define HAVE_CRYPTODEV
# endif
# if (OpenBSD >= 200110)
#  define HAVE_SYSLOG_R
# endif
#endif

#ifndef HAVE_CRYPTODEV

void
ENGINE_load_cryptodev(void)
{
	/* This is a NOP on platforms without /dev/crypto */
	return;
}

#else 
 
#include <sys/types.h>
#include <crypto/cryptodev.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
#include <syslog.h>
#include <errno.h>
#include <string.h>

struct dev_crypto_state {
	struct session_op d_sess;
	int d_fd;

#ifdef USE_CRYPTODEV_DIGESTS
	char dummy_mac_key[HASH_MAX_LEN];

	unsigned char digest_res[HASH_MAX_LEN];
	char *mac_data;
	int mac_len;

	int copy;
#endif
};

static u_int32_t cryptodev_asymfeat = 0;

static int get_asym_dev_crypto(void);
static int open_dev_crypto(void);
static int get_dev_crypto(void);
static int get_cryptodev_ciphers(const int **cnids);
/*static int get_cryptodev_digests(const int **cnids);*/
static int cryptodev_usable_ciphers(const int **nids);
static int cryptodev_usable_digests(const int **nids);
static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
    const unsigned char *in, size_t inl);
static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
    const unsigned char *iv, int enc);
static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
    const int **nids, int nid);
static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
    const int **nids, int nid);
static int bn2crparam(const BIGNUM *a, struct crparam *crp);
static int crparam2bn(struct crparam *crp, BIGNUM *a);
static void zapparams(struct crypt_kop *kop);
static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
    int slen, BIGNUM *s);

static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
    RSA *rsa, BN_CTX *ctx);
static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
    BN_CTX *ctx, BN_MONT_CTX *mont);
static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
    int dlen, DSA *dsa);
static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
    DSA_SIG *sig, DSA *dsa);
static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
    BN_MONT_CTX *m_ctx);
static int cryptodev_dh_compute_key(unsigned char *key,
    const BIGNUM *pub_key, DH *dh);
static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
    void (*f)(void));
void ENGINE_load_cryptodev(void);

static const ENGINE_CMD_DEFN cryptodev_defns[] = {
	{ 0, NULL, NULL, 0 }
};

static struct {
	int	id;
	int	nid;
	int	ivmax;
	int	keylen;
} ciphers[] = {
	{ CRYPTO_ARC4,			NID_rc4,		0,	16, },
	{ CRYPTO_DES_CBC,		NID_des_cbc,		8,	 8, },
	{ CRYPTO_3DES_CBC,		NID_des_ede3_cbc,	8,	24, },
	{ CRYPTO_AES_CBC,		NID_aes_128_cbc,	16,	16, },
	{ CRYPTO_AES_CBC,		NID_aes_192_cbc,	16,	24, },
	{ CRYPTO_AES_CBC,		NID_aes_256_cbc,	16,	32, },
	{ CRYPTO_BLF_CBC,		NID_bf_cbc,		8,	16, },
	{ CRYPTO_CAST_CBC,		NID_cast5_cbc,		8,	16, },
	{ CRYPTO_SKIPJACK_CBC,		NID_undef,		0,	 0, },
	{ 0,				NID_undef,		0,	 0, },
};

#if 0  /* not (yet?) used */
static struct {
	int	id;
	int	nid;
	int 	keylen;
} digests[] = {
	{ CRYPTO_MD5_HMAC,		NID_hmacWithMD5,	16},
	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	20},
	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		16/*?*/},
	{ CRYPTO_MD5_KPDK,		NID_undef,		0},
	{ CRYPTO_SHA1_KPDK,		NID_undef,		0},
	{ CRYPTO_MD5,			NID_md5,		16},
	{ CRYPTO_SHA1,			NID_sha1,		20},
	{ 0,				NID_undef,		0},
};
#endif  /* 0 */

/*
 * Return a fd if /dev/crypto seems usable, 0 otherwise.
 */
static int
open_dev_crypto(void)
{
	static int fd = -1;

	if (fd == -1) {
		if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
			return (-1);
		/* close on exec */
		if (fcntl(fd, F_SETFD, 1) == -1) {
			close(fd);
			fd = -1;
			return (-1);
		}
	}
	return (fd);
}

static int
get_dev_crypto(void)
{
	int fd, retfd;

	if ((fd = open_dev_crypto()) == -1)
		return (-1);
	if (ioctl(fd, CRIOGET, &retfd) == -1)
		return (-1);

	/* close on exec */
	if (fcntl(retfd, F_SETFD, 1) == -1) {
		close(retfd);
		return (-1);
	}
	return (retfd);
}

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

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

	if (count > 0)
		*cnids = nids;
	else
		*cnids = NULL;
	return (count);
}

/*
 * 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  /* not (yet?) used */
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));
	sess.mackey = (caddr_t)"123456789abcdefghijklmno";
	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
		if (digests[i].nid == NID_undef)
			continue;
		sess.mac = digests[i].id;
		sess.mackeylen = digests[i].keylen;
		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);
}
#endif  /* 0 */

/*
 * Find the useable ciphers|digests from dev/crypto - this is the first
 * thing called by the engine init crud which determines what it
 * can use for ciphers from this engine. We want to return
 * only what we can do, anythine else is handled by software.
 *
 * If we can't initialize the device to do anything useful for
 * any reason, we want to return a NULL array, and 0 length,
 * which forces everything to be done is software. By putting
 * the initalization of the device in here, we ensure we can
 * use this engine as the default, and if for whatever reason
 * /dev/crypto won't do what we want it will just be done in
 * software
 *
 * This can (should) be greatly expanded to perhaps take into
 * account speed of the device, and what we want to do.
 * (although the disabling of particular alg's could be controlled
 * by the device driver with sysctl's.) - this is where we
 * want most of the decisions made about what we actually want
 * to use from /dev/crypto.
 */
static int
cryptodev_usable_ciphers(const int **nids)
{
	return (get_cryptodev_ciphers(nids));
}

static int
cryptodev_usable_digests(const int **nids)
{
#ifdef USE_CRYPTODEV_DIGESTS
	return (get_cryptodev_digests(nids));
#else
	/*
	 * XXXX just disable all digests for now, because it sucks.
	 * we need a better way to decide this - i.e. I may not
	 * want digests on slow cards like hifn on fast machines,
	 * but might want them on slow or loaded machines, etc.
	 * will also want them when using crypto cards that don't
	 * suck moose gonads - would be nice to be able to decide something
	 * as reasonable default without having hackery that's card dependent.
	 * of course, the default should probably be just do everything,
	 * with perhaps a sysctl to turn algoritms off (or have them off
	 * by default) on cards that generally suck like the hifn.
	 */
	*nids = NULL;
	return (0);
#endif
}

static int
cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
    const unsigned char *in, size_t inl)
{
	struct crypt_op cryp;
	struct dev_crypto_state *state = ctx->cipher_data;
	struct session_op *sess = &state->d_sess;
	const void *iiv;
	unsigned char save_iv[EVP_MAX_IV_LENGTH];

	if (state->d_fd < 0)
		return (0);
	if (!inl)
		return (1);
	if ((inl % ctx->cipher->block_size) != 0)
		return (0);

	memset(&cryp, 0, sizeof(cryp));

	cryp.ses = sess->ses;
	cryp.flags = 0;
	cryp.len = inl;
	cryp.src = (caddr_t) in;
	cryp.dst = (caddr_t) out;
	cryp.mac = 0;

	cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;

	if (ctx->cipher->iv_len) {
		cryp.iv = (caddr_t) ctx->iv;
		if (!ctx->encrypt) {
			iiv = in + inl - ctx->cipher->iv_len;
			memcpy(save_iv, iiv, ctx->cipher->iv_len);
		}
	} else
		cryp.iv = NULL;

	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
		/* XXX need better errror handling
		 * this can fail for a number of different reasons.
		 */
		return (0);
	}

	if (ctx->cipher->iv_len) {
		if (ctx->encrypt)
			iiv = out + inl - ctx->cipher->iv_len;
		else
			iiv = save_iv;
		memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
	}
	return (1);
}

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(struct session_op));

	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) {
		close(state->d_fd);
		state->d_fd = -1;
		return (0);
	}
	return (1);
}

/*
 * free anything we allocated earlier when initting a
 * session, and close the session.
 */
static int
cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
{
	int ret = 0;
	struct dev_crypto_state *state = ctx->cipher_data;
	struct session_op *sess = &state->d_sess;

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

	/* XXX if this ioctl fails, someting's wrong. the invoker
	 * may have called us with a bogus ctx, or we could
	 * have a device that for whatever reason just doesn't
	 * want to play ball - it's not clear what's right
	 * here - should this be an error? should it just
	 * increase a counter, hmm. For right now, we return
	 * 0 - I don't believe that to be "right". we could
	 * call the gorpy openssl lib error handlers that
	 * print messages to users of the library. hmm..
	 */

	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
		ret = 0;
	} else {
		ret = 1;
	}
	close(state->d_fd);
	state->d_fd = -1;

	return (ret);
}

/*
 * libcrypto EVP stuff - this is how we get wired to EVP so the engine
 * gets called when libcrypto requests a cipher NID.
 */

/* RC4 */
const EVP_CIPHER cryptodev_rc4 = {
	NID_rc4,
	1, 16, 0,
	EVP_CIPH_VARIABLE_LENGTH,
	cryptodev_init_key,
	cryptodev_cipher,
	cryptodev_cleanup,
	sizeof(struct dev_crypto_state),
	NULL,
	NULL,
	NULL
};

/* DES CBC EVP */
const EVP_CIPHER cryptodev_des_cbc = {
	NID_des_cbc,
	8, 8, 8,
	EVP_CIPH_CBC_MODE,
	cryptodev_init_key,
	cryptodev_cipher,
	cryptodev_cleanup,
	sizeof(struct dev_crypto_state),
	EVP_CIPHER_set_asn1_iv,
	EVP_CIPHER_get_asn1_iv,
	NULL
};

/* 3DES CBC EVP */
const EVP_CIPHER cryptodev_3des_cbc = {
	NID_des_ede3_cbc,
	8, 24, 8,
	EVP_CIPH_CBC_MODE,
	cryptodev_init_key,
	cryptodev_cipher,
	cryptodev_cleanup,
	sizeof(struct dev_crypto_state),
	EVP_CIPHER_set_asn1_iv,
	EVP_CIPHER_get_asn1_iv,
	NULL
};

const EVP_CIPHER cryptodev_bf_cbc = {
	NID_bf_cbc,
	8, 16, 8,
	EVP_CIPH_CBC_MODE,
	cryptodev_init_key,
	cryptodev_cipher,
	cryptodev_cleanup,
	sizeof(struct dev_crypto_state),
	EVP_CIPHER_set_asn1_iv,
	EVP_CIPHER_get_asn1_iv,
	NULL
};

const EVP_CIPHER cryptodev_cast_cbc = {
	NID_cast5_cbc,
	8, 16, 8,
	EVP_CIPH_CBC_MODE,
	cryptodev_init_key,
	cryptodev_cipher,
	cryptodev_cleanup,
	sizeof(struct dev_crypto_state),
	EVP_CIPHER_set_asn1_iv,
	EVP_CIPHER_get_asn1_iv,
	NULL
};

const EVP_CIPHER cryptodev_aes_cbc = {
	NID_aes_128_cbc,
	16, 16, 16,
	EVP_CIPH_CBC_MODE,
	cryptodev_init_key,
	cryptodev_cipher,
	cryptodev_cleanup,
	sizeof(struct dev_crypto_state),
	EVP_CIPHER_set_asn1_iv,
	EVP_CIPHER_get_asn1_iv,
	NULL
};

const EVP_CIPHER cryptodev_aes_192_cbc = {
	NID_aes_192_cbc,
	16, 24, 16,
	EVP_CIPH_CBC_MODE,
	cryptodev_init_key,
	cryptodev_cipher,
	cryptodev_cleanup,
	sizeof(struct dev_crypto_state),
	EVP_CIPHER_set_asn1_iv,
	EVP_CIPHER_get_asn1_iv,
	NULL
};

const EVP_CIPHER cryptodev_aes_256_cbc = {
	NID_aes_256_cbc,
	16, 32, 16,
	EVP_CIPH_CBC_MODE,
	cryptodev_init_key,
	cryptodev_cipher,
	cryptodev_cleanup,
	sizeof(struct dev_crypto_state),
	EVP_CIPHER_set_asn1_iv,
	EVP_CIPHER_get_asn1_iv,
	NULL
};

/*
 * Registered by the ENGINE when used to find out how to deal with
 * a particular NID in the ENGINE. this says what we'll do at the
 * top level - note, that list is restricted by what we answer with
 */
static int
cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
    const int **nids, int nid)
{
	if (!cipher)
		return (cryptodev_usable_ciphers(nids));

	switch (nid) {
	case NID_rc4:
		*cipher = &cryptodev_rc4;
		break;
	case NID_des_ede3_cbc:
		*cipher = &cryptodev_3des_cbc;
		break;
	case NID_des_cbc:
		*cipher = &cryptodev_des_cbc;
		break;
	case NID_bf_cbc:
		*cipher = &cryptodev_bf_cbc;
		break;
	case NID_cast5_cbc:
		*cipher = &cryptodev_cast_cbc;
		break;
	case NID_aes_128_cbc:
		*cipher = &cryptodev_aes_cbc;
		break;
	case NID_aes_192_cbc:
		*cipher = &cryptodev_aes_192_cbc;
		break;
	case NID_aes_256_cbc:
		*cipher = &cryptodev_aes_256_cbc;
		break;
	default:
		*cipher = NULL;
		break;
	}
	return (*cipher != NULL);
}


#ifdef USE_CRYPTODEV_DIGESTS

/* convert digest type to cryptodev */
static int
digest_nid_to_cryptodev(int nid)
{
	int i;

	for (i = 0; digests[i].id; i++)
		if (digests[i].nid == nid)
			return (digests[i].id);
	return (0);
}


static int
digest_key_length(int nid)
{
	int i;

	for (i = 0; digests[i].id; i++)
		if (digests[i].nid == nid)
			return digests[i].keylen;
	return (0);
}


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(struct dev_crypto_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) {
		close(state->d_fd);
		state->d_fd = -1;
		printf("cryptodev_digest_init: Open session failed\n");
		return (0);
	}

	return (1);
}

static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
		size_t count)
{
	struct crypt_op cryp;
	struct dev_crypto_state *state = ctx->md_data;
	struct session_op *sess = &state->d_sess;

	if (!data || state->d_fd < 0) {
		printf("cryptodev_digest_update: illegal inputs \n");
		return (0);
	}

	if (!count) {
		return (0);
	}

	if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
		/* if application doesn't support one buffer */
		state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);

		if (!state->mac_data) {
			printf("cryptodev_digest_update: realloc failed\n");
			return (0);
		}

		memcpy(state->mac_data + state->mac_len, data, count);
   		state->mac_len += count;
	
		return (1);
	}

	memset(&cryp, 0, sizeof(cryp));

	cryp.ses = sess->ses;
	cryp.flags = 0;
	cryp.len = count;
	cryp.src = (caddr_t) data;
	cryp.dst = NULL;
	cryp.mac = (caddr_t) state->digest_res;
	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
		printf("cryptodev_digest_update: digest failed\n");
		return (0);
	}
	return (1);
}


static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
{
	struct crypt_op cryp;
	struct dev_crypto_state *state = ctx->md_data;
	struct session_op *sess = &state->d_sess;

	int ret = 1;

	if (!md || state->d_fd < 0) {
		printf("cryptodev_digest_final: illegal input\n");
		return(0);
	}

	if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
		/* if application doesn't support one buffer */
		memset(&cryp, 0, sizeof(cryp));

		cryp.ses = sess->ses;
		cryp.flags = 0;
		cryp.len = state->mac_len;
		cryp.src = state->mac_data;
		cryp.dst = NULL;
		cryp.mac = (caddr_t)md;

		if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
			printf("cryptodev_digest_final: digest failed\n");
			return (0);
		}

		return 1;
	}

	memcpy(md, state->digest_res, ctx->digest->md_size);

	return (ret);
}


static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
{
	int ret = 1;
	struct dev_crypto_state *state = ctx->md_data;
	struct session_op *sess = &state->d_sess;

	if (state->d_fd < 0) {
		printf("cryptodev_digest_cleanup: illegal input\n");
		return (0);
	}

	if (state->mac_data) {
		OPENSSL_free(state->mac_data);
		state->mac_data = NULL;
		state->mac_len = 0;
	}

	if (state->copy)
		return 1;

	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
		printf("cryptodev_digest_cleanup: failed to close session\n");
		ret = 0;
	} else {
		ret = 1;
	}
	close(state->d_fd);	
	state->d_fd = -1;

	return (ret);
}

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;

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

	if (fstate->mac_len != 0) {
		dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
		memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
	}

	dstate->copy = 1;

	return 1;
}


const EVP_MD cryptodev_sha1 = {
	NID_sha1,
	NID_undef, 
	SHA_DIGEST_LENGTH, 
	EVP_MD_FLAG_ONESHOT,
	cryptodev_digest_init,
	cryptodev_digest_update,
	cryptodev_digest_final,
	cryptodev_digest_copy,
	cryptodev_digest_cleanup,
	EVP_PKEY_NULL_method,
	SHA_CBLOCK,
	sizeof(struct dev_crypto_state),
};

const EVP_MD cryptodev_md5 = {
	NID_md5,
	NID_undef, 
	16 /* MD5_DIGEST_LENGTH */, 
	EVP_MD_FLAG_ONESHOT,
	cryptodev_digest_init,
	cryptodev_digest_update,
	cryptodev_digest_final,
	cryptodev_digest_copy,
	cryptodev_digest_cleanup,
	EVP_PKEY_NULL_method,
	64 /* MD5_CBLOCK */,
	sizeof(struct dev_crypto_state),
};

#endif /* USE_CRYPTODEV_DIGESTS */


static int
cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
    const int **nids, int nid)
{
	if (!digest)
		return (cryptodev_usable_digests(nids));

	switch (nid) {
#ifdef USE_CRYPTODEV_DIGESTS
	case NID_md5:
		*digest = &cryptodev_md5; 
		break;
	case NID_sha1:
		*digest = &cryptodev_sha1;
 		break;
	default:
#endif /* USE_CRYPTODEV_DIGESTS */
		*digest = NULL;
		break;
	}
	return (*digest != NULL);
}

/*
 * Convert a BIGNUM to the representation that /dev/crypto needs.
 * Upon completion of use, the caller is responsible for freeing
 * crp->crp_p.
 */
static int
bn2crparam(const BIGNUM *a, struct crparam *crp)
{
	int i, j, k;
	ssize_t bytes, bits;
	u_char *b;

	crp->crp_p = NULL;
	crp->crp_nbits = 0;

	bits = BN_num_bits(a);
	bytes = (bits + 7) / 8;

	b = malloc(bytes);
	if (b == NULL)
		return (1);
	memset(b, 0, bytes);

	crp->crp_p = (caddr_t) b;
	crp->crp_nbits = bits;

	for (i = 0, j = 0; i < a->top; i++) {
		for (k = 0; k < BN_BITS2 / 8; k++) {
			if ((j + k) >= bytes)
				return (0);
			b[j + k] = a->d[i] >> (k * 8);
		}
		j += BN_BITS2 / 8;
	}
	return (0);
}

/* Convert a /dev/crypto parameter to a BIGNUM */
static int
crparam2bn(struct crparam *crp, BIGNUM *a)
{
	u_int8_t *pd;
	int i, bytes;

	bytes = (crp->crp_nbits + 7) / 8;

	if (bytes == 0)
		return (-1);

	if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
		return (-1);

	for (i = 0; i < bytes; i++)
		pd[i] = crp->crp_p[bytes - i - 1];

	BN_bin2bn(pd, bytes, a);
	free(pd);

	return (0);
}

static void
zapparams(struct crypt_kop *kop)
{
	int i;

	for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
		if (kop->crk_param[i].crp_p)
			free(kop->crk_param[i].crp_p);
		kop->crk_param[i].crp_p = NULL;
		kop->crk_param[i].crp_nbits = 0;
	}
}

static int
cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
{
	int fd, ret = -1;

	if ((fd = get_asym_dev_crypto()) < 0)
		return (ret);

	if (r) {
		kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
		kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
		kop->crk_oparams++;
	}
	if (s) {
		kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
		kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
		kop->crk_oparams++;
	}

	if (ioctl(fd, CIOCKEY, kop) == 0) {
		if (r)
			crparam2bn(&kop->crk_param[kop->crk_iparams], r);
		if (s)
			crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
		ret = 0;
	}

	return (ret);
}

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 int
cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
{
	int r;
	ctx = BN_CTX_new();
	r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
	BN_CTX_free(ctx);
	return (r);
}

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

static RSA_METHOD cryptodev_rsa = {
	"cryptodev RSA method",
	NULL,				/* rsa_pub_enc */
	NULL,				/* rsa_pub_dec */
	NULL,				/* rsa_priv_enc */
	NULL,				/* rsa_priv_dec */
	NULL,
	NULL,
	NULL,				/* init */
	NULL,				/* finish */
	0,				/* flags */
	NULL,				/* app_data */
	NULL,				/* rsa_sign */
	NULL				/* rsa_verify */
};

static int
cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
{
	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
}

static int
cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
    BN_CTX *ctx, BN_MONT_CTX *mont)
{
	BIGNUM t2;
	int ret = 0;

	BN_init(&t2);

	/* v = ( g^u1 * y^u2 mod p ) mod q */
	/* let t1 = g ^ u1 mod p */
	ret = 0;

	if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
		goto err;

	/* let t2 = y ^ u2 mod p */
	if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
		goto err;
	/* let u1 = t1 * t2 mod p */
	if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
		goto err;

	BN_copy(t1,u1);

	ret = 1;
err:
	BN_free(&t2);
	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();
		dsaret->r = r;
		dsaret->s = s;
	} else {
		const DSA_METHOD *meth = DSA_OpenSSL();
		BN_free(r);
		BN_free(s);
		dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
	}
err:
	kop.crk_param[0].crp_p = NULL;
	zapparams(&kop);
	return (dsaret);
}

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) {
		dsaret = kop.crk_status;
	} 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 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 */
};

static int
cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
    BN_MONT_CTX *m_ctx)
{
	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
}

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 = (caddr_t) 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);
}

static DH_METHOD cryptodev_dh = {
	"cryptodev DH method",
	NULL,				/* cryptodev_dh_generate_key */
	NULL,
	NULL,
	NULL,
	NULL,
	0,	/* flags */
	NULL	/* app_data */
};

/*
 * ctrl right now is just a wrapper that doesn't do much
 * but I expect we'll want some options soon.
 */
static int
cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
{
#ifdef HAVE_SYSLOG_R
	struct syslog_data sd = SYSLOG_DATA_INIT;
#endif

	switch (cmd) {
	default:
#ifdef HAVE_SYSLOG_R
		syslog_r(LOG_ERR, &sd,
		    "cryptodev_ctrl: unknown command %d", cmd);
#else
		syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
#endif
		break;
	}
	return (1);
}

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();
}

#endif /* HAVE_CRYPTODEV */
