/*
 * 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 <crypto/dh/dh.h>
#include <crypto/dsa/dsa.h>
#include <crypto/err/err.h>
#include <crypto/rsa/rsa.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;
#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);
#ifdef USE_CRYPTODEV_DIGESTS
static int get_cryptodev_digests(const int **cnids);
#endif
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, },
};

#ifdef USE_CRYPTODEV_DIGESTS
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

/*
 * 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);
#ifndef CRIOGET_NOT_NEEDED
	if (ioctl(fd, CRIOGET, &retfd) == -1)
		return (-1);

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

static void put_dev_crypto(int fd)
{
#ifndef CRIOGET_NOT_NEEDED
	close(fd);
#endif
}

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

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

#ifdef USE_CRYPTODEV_DIGESTS
/*
 * 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
 */
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;
	}
	put_dev_crypto(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) {
		put_dev_crypto(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;
	}
	put_dev_crypto(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) {
		put_dev_crypto(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 == NULL)
	  return 0;

	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 (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
		printf("cryptodev_digest_cleanup: failed to close session\n");
		ret = 0;
	} else {
		ret = 1;
	}
	put_dev_crypto(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;
	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_init: Open session failed\n");
		return (0);
	}

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

	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)) {
		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
		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_SSLeay();
		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);
}

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)) {
		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
		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_SSLeay();
		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 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) {
/*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 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) {
		put_dev_crypto(fd);
		ENGINE_free(engine);
		return;
	}
	put_dev_crypto(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 */
