/*
 * An OCF module for determining the cost of crypto versus the cost of
 * IPSec processing outside of OCF.  This modules gives us the effect of
 * zero cost encryption,  of course you will need to run it at both ends
 * since it does no crypto at all.
 *
 * Written by David McCullough <david_mccullough@mcafee.com>
 * Copyright (C) 2006-2010 David McCullough 
 *
 * LICENSE TERMS
 *
 * The free distribution and use of this software in both source and binary
 * form is allowed (with or without changes) provided that:
 *
 *   1. distributions of this source code include the above copyright
 *      notice, this list of conditions and the following disclaimer;
 *
 *   2. distributions in binary form include the above copyright
 *      notice, this list of conditions and the following disclaimer
 *      in the documentation and/or other associated materials;
 *
 *   3. the copyright holder's name is not used to endorse products
 *      built using this software without specific written permission.
 *
 * ALTERNATIVELY, provided that this notice is retained in full, this product
 * may be distributed under the terms of the GNU General Public License (GPL),
 * in which case the provisions of the GPL apply INSTEAD OF those given above.
 *
 * DISCLAIMER
 *
 * This software is provided 'as is' with no explicit or implied warranties
 * in respect of its properties, including, but not limited to, correctness
 * and/or fitness for purpose.
 */

#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/crypto.h>
#include <linux/interrupt.h>

#include <cryptodev.h>
#include <uio.h>

static int32_t			 null_id = -1;
static u_int32_t		 null_sesnum = 0;

static int null_process(device_t, struct cryptop *, int);
static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
static int null_freesession(device_t, u_int64_t);

#define debug ocfnull_debug
int ocfnull_debug = 0;
module_param(ocfnull_debug, int, 0644);
MODULE_PARM_DESC(ocfnull_debug, "Enable debug");

/*
 * dummy device structure
 */

static struct {
	softc_device_decl	sc_dev;
} nulldev;

static device_method_t null_methods = {
	/* crypto device methods */
	DEVMETHOD(cryptodev_newsession,	null_newsession),
	DEVMETHOD(cryptodev_freesession,null_freesession),
	DEVMETHOD(cryptodev_process,	null_process),
};

/*
 * Generate a new software session.
 */
static int
null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
{
	dprintk("%s()\n", __FUNCTION__);
	if (sid == NULL || cri == NULL) {
		dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
		return EINVAL;
	}

	if (null_sesnum == 0)
		null_sesnum++;
	*sid = null_sesnum++;
	return 0;
}


/*
 * Free a session.
 */
static int
null_freesession(device_t arg, u_int64_t tid)
{
	u_int32_t sid = CRYPTO_SESID2LID(tid);

	dprintk("%s()\n", __FUNCTION__);
	if (sid > null_sesnum) {
		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
		return EINVAL;
	}

	/* Silently accept and return */
	if (sid == 0)
		return 0;
	return 0;
}


/*
 * Process a request.
 */
static int
null_process(device_t arg, struct cryptop *crp, int hint)
{
	unsigned int lid;

	dprintk("%s()\n", __FUNCTION__);

	/* Sanity check */
	if (crp == NULL) {
		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
		return EINVAL;
	}

	crp->crp_etype = 0;

	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
		crp->crp_etype = EINVAL;
		goto done;
	}

	/*
	 * find the session we are using
	 */

	lid = crp->crp_sid & 0xffffffff;
	if (lid >= null_sesnum || lid == 0) {
		crp->crp_etype = ENOENT;
		dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
		goto done;
	}

done:
	crypto_done(crp);
	return 0;
}


/*
 * our driver startup and shutdown routines
 */

static int
null_init(void)
{
	dprintk("%s(%p)\n", __FUNCTION__, null_init);

	memset(&nulldev, 0, sizeof(nulldev));
	softc_device_init(&nulldev, "ocfnull", 0, null_methods);

	null_id = crypto_get_driverid(softc_get_device(&nulldev),
				CRYPTOCAP_F_HARDWARE);
	if (null_id < 0)
		panic("ocfnull: crypto device cannot initialize!");

#define	REGISTER(alg) \
	crypto_register(null_id,alg,0,0)
	REGISTER(CRYPTO_DES_CBC);
	REGISTER(CRYPTO_3DES_CBC);
	REGISTER(CRYPTO_RIJNDAEL128_CBC);
	REGISTER(CRYPTO_MD5);
	REGISTER(CRYPTO_SHA1);
	REGISTER(CRYPTO_MD5_HMAC);
	REGISTER(CRYPTO_SHA1_HMAC);
#undef REGISTER

	return 0;
}

static void
null_exit(void)
{
	dprintk("%s()\n", __FUNCTION__);
	crypto_unregister_all(null_id);
	null_id = -1;
}

module_init(null_init);
module_exit(null_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
