1/*
2 * An OCF module for determining the cost of crypto versus the cost of
3 * IPSec processing outside of OCF.  This modules gives us the effect of
4 * zero cost encryption,  of course you will need to run it at both ends
5 * since it does no crypto at all.
6 *
7 * Written by David McCullough <david_mccullough@mcafee.com>
8 * Copyright (C) 2006-2010 David McCullough
9 *
10 * LICENSE TERMS
11 *
12 * The free distribution and use of this software in both source and binary
13 * form is allowed (with or without changes) provided that:
14 *
15 *   1. distributions of this source code include the above copyright
16 *      notice, this list of conditions and the following disclaimer;
17 *
18 *   2. distributions in binary form include the above copyright
19 *      notice, this list of conditions and the following disclaimer
20 *      in the documentation and/or other associated materials;
21 *
22 *   3. the copyright holder's name is not used to endorse products
23 *      built using this software without specific written permission.
24 *
25 * ALTERNATIVELY, provided that this notice is retained in full, this product
26 * may be distributed under the terms of the GNU General Public License (GPL),
27 * in which case the provisions of the GPL apply INSTEAD OF those given above.
28 *
29 * DISCLAIMER
30 *
31 * This software is provided 'as is' with no explicit or implied warranties
32 * in respect of its properties, including, but not limited to, correctness
33 * and/or fitness for purpose.
34 */
35
36#include <linux/version.h>
37#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
38#include <linux/config.h>
39#endif
40#include <linux/module.h>
41#include <linux/init.h>
42#include <linux/list.h>
43#include <linux/slab.h>
44#include <linux/sched.h>
45#include <linux/wait.h>
46#include <linux/crypto.h>
47#include <linux/interrupt.h>
48
49#include <cryptodev.h>
50#include <uio.h>
51
52static int32_t			 null_id = -1;
53static u_int32_t		 null_sesnum = 0;
54
55static int null_process(device_t, struct cryptop *, int);
56static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
57static int null_freesession(device_t, u_int64_t);
58
59#define debug ocfnull_debug
60int ocfnull_debug = 0;
61module_param(ocfnull_debug, int, 0644);
62MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
63
64/*
65 * dummy device structure
66 */
67
68static struct {
69	softc_device_decl	sc_dev;
70} nulldev;
71
72static device_method_t null_methods = {
73	/* crypto device methods */
74	DEVMETHOD(cryptodev_newsession,	null_newsession),
75	DEVMETHOD(cryptodev_freesession,null_freesession),
76	DEVMETHOD(cryptodev_process,	null_process),
77};
78
79/*
80 * Generate a new software session.
81 */
82static int
83null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
84{
85	dprintk("%s()\n", __FUNCTION__);
86	if (sid == NULL || cri == NULL) {
87		dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
88		return EINVAL;
89	}
90
91	if (null_sesnum == 0)
92		null_sesnum++;
93	*sid = null_sesnum++;
94	return 0;
95}
96
97
98/*
99 * Free a session.
100 */
101static int
102null_freesession(device_t arg, u_int64_t tid)
103{
104	u_int32_t sid = CRYPTO_SESID2LID(tid);
105
106	dprintk("%s()\n", __FUNCTION__);
107	if (sid > null_sesnum) {
108		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
109		return EINVAL;
110	}
111
112	/* Silently accept and return */
113	if (sid == 0)
114		return 0;
115	return 0;
116}
117
118
119/*
120 * Process a request.
121 */
122static int
123null_process(device_t arg, struct cryptop *crp, int hint)
124{
125	unsigned int lid;
126
127	dprintk("%s()\n", __FUNCTION__);
128
129	/* Sanity check */
130	if (crp == NULL) {
131		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
132		return EINVAL;
133	}
134
135	crp->crp_etype = 0;
136
137	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
138		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
139		crp->crp_etype = EINVAL;
140		goto done;
141	}
142
143	/*
144	 * find the session we are using
145	 */
146
147	lid = crp->crp_sid & 0xffffffff;
148	if (lid >= null_sesnum || lid == 0) {
149		crp->crp_etype = ENOENT;
150		dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
151		goto done;
152	}
153
154done:
155	crypto_done(crp);
156	return 0;
157}
158
159
160/*
161 * our driver startup and shutdown routines
162 */
163
164static int
165null_init(void)
166{
167	dprintk("%s(%p)\n", __FUNCTION__, null_init);
168
169	memset(&nulldev, 0, sizeof(nulldev));
170	softc_device_init(&nulldev, "ocfnull", 0, null_methods);
171
172	null_id = crypto_get_driverid(softc_get_device(&nulldev),
173				CRYPTOCAP_F_HARDWARE);
174	if (null_id < 0)
175		panic("ocfnull: crypto device cannot initialize!");
176
177#define	REGISTER(alg) \
178	crypto_register(null_id,alg,0,0)
179	REGISTER(CRYPTO_DES_CBC);
180	REGISTER(CRYPTO_3DES_CBC);
181	REGISTER(CRYPTO_RIJNDAEL128_CBC);
182	REGISTER(CRYPTO_MD5);
183	REGISTER(CRYPTO_SHA1);
184	REGISTER(CRYPTO_MD5_HMAC);
185	REGISTER(CRYPTO_SHA1_HMAC);
186#undef REGISTER
187
188	return 0;
189}
190
191static void
192null_exit(void)
193{
194	dprintk("%s()\n", __FUNCTION__);
195	crypto_unregister_all(null_id);
196	null_id = -1;
197}
198
199module_init(null_init);
200module_exit(null_exit);
201
202MODULE_LICENSE("Dual BSD/GPL");
203MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
204MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
205