rc4.c revision 116174
159108Sarchie/*
259108Sarchie * rc4.c
359108Sarchie *
459108Sarchie * Copyright (c) 1996-2000 Whistle Communications, Inc.
559108Sarchie * All rights reserved.
659108Sarchie *
759108Sarchie * Subject to the following obligations and disclaimer of warranty, use and
859108Sarchie * redistribution of this software, in source or object code forms, with or
959108Sarchie * without modifications are expressly permitted by Whistle Communications;
1059108Sarchie * provided, however, that:
1159108Sarchie * 1. Any and all reproductions of the source or object code must include the
1259108Sarchie *    copyright notice above and the following disclaimer of warranties; and
1359108Sarchie * 2. No rights are granted, in any manner or form, to use Whistle
1459108Sarchie *    Communications, Inc. trademarks, including the mark "WHISTLE
1559108Sarchie *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
1659108Sarchie *    such appears in the above copyright notice or in the software.
1759108Sarchie *
1859108Sarchie * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
1959108Sarchie * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
2059108Sarchie * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
2159108Sarchie * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
2259108Sarchie * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
2359108Sarchie * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
2459108Sarchie * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
2559108Sarchie * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
2659108Sarchie * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
2759108Sarchie * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
2859108Sarchie * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
2959108Sarchie * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
3059108Sarchie * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
3159108Sarchie * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3259108Sarchie * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3359108Sarchie * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
3459108Sarchie * OF SUCH DAMAGE.
3559108Sarchie */
3659108Sarchie
37116174Sobrien#include <sys/cdefs.h>
38116174Sobrien__FBSDID("$FreeBSD: head/sys/crypto/rc4/rc4.c 116174 2003-06-10 21:44:29Z obrien $");
39116174Sobrien
40109318Ssam#include <sys/param.h>
41109318Ssam#include <sys/kernel.h>
42109318Ssam#include <sys/module.h>
4359108Sarchie#include <sys/types.h>
4459108Sarchie#include <crypto/rc4/rc4.h>
4559108Sarchie
4659108Sarchiestatic __inline void
4759108Sarchieswap_bytes(u_char *a, u_char *b)
4859108Sarchie{
4959108Sarchie	u_char temp;
5059108Sarchie
5159108Sarchie	temp = *a;
5259108Sarchie	*a = *b;
5359108Sarchie	*b = temp;
5459108Sarchie}
5559108Sarchie
5659108Sarchie/*
5759108Sarchie * Initialize an RC4 state buffer using the supplied key,
5859108Sarchie * which can have arbitrary length.
5959108Sarchie */
6059108Sarchievoid
6159108Sarchierc4_init(struct rc4_state *const state, const u_char *key, int keylen)
6259108Sarchie{
6359108Sarchie	u_char j;
6459108Sarchie	int i;
6559108Sarchie
6659108Sarchie	/* Initialize state with identity permutation */
6759108Sarchie	for (i = 0; i < 256; i++)
6859108Sarchie		state->perm[i] = (u_char)i;
6959108Sarchie	state->index1 = 0;
7059108Sarchie	state->index2 = 0;
7159108Sarchie
7259108Sarchie	/* Randomize the permutation using key data */
7359108Sarchie	for (j = i = 0; i < 256; i++) {
7459108Sarchie		j += state->perm[i] + key[i % keylen];
7559108Sarchie		swap_bytes(&state->perm[i], &state->perm[j]);
7659108Sarchie	}
7759108Sarchie}
7859108Sarchie
7959108Sarchie/*
8059108Sarchie * Encrypt some data using the supplied RC4 state buffer.
8159108Sarchie * The input and output buffers may be the same buffer.
8259108Sarchie * Since RC4 is a stream cypher, this function is used
8359108Sarchie * for both encryption and decryption.
8459108Sarchie */
8559108Sarchievoid
8659108Sarchierc4_crypt(struct rc4_state *const state,
8759108Sarchie	const u_char *inbuf, u_char *outbuf, int buflen)
8859108Sarchie{
8959108Sarchie	int i;
9059108Sarchie	u_char j;
9159108Sarchie
9259108Sarchie	for (i = 0; i < buflen; i++) {
9359108Sarchie
9459108Sarchie		/* Update modification indicies */
9559108Sarchie		state->index1++;
9659108Sarchie		state->index2 += state->perm[state->index1];
9759108Sarchie
9859108Sarchie		/* Modify permutation */
9959108Sarchie		swap_bytes(&state->perm[state->index1],
10059108Sarchie		    &state->perm[state->index2]);
10159108Sarchie
10259108Sarchie		/* Encrypt/decrypt next byte */
10359108Sarchie		j = state->perm[state->index1] + state->perm[state->index2];
10459108Sarchie		outbuf[i] = inbuf[i] ^ state->perm[j];
10559108Sarchie	}
10659108Sarchie}
10759108Sarchie
108109318Ssamstatic int
109109318Ssamrc4_modevent(module_t mod, int type, void *unused)
110109318Ssam{
111109318Ssam	switch (type) {
112109318Ssam	case MOD_LOAD:
113109318Ssam		return 0;
114109318Ssam	case MOD_UNLOAD:
115109318Ssam		return 0;
116109318Ssam	}
117109318Ssam	return EINVAL;
118109318Ssam}
119109318Ssam
120109318Ssamstatic moduledata_t rc4_mod = {
121109318Ssam	"rc4",
122109318Ssam	rc4_modevent,
123109318Ssam	0
124109318Ssam};
125109318SsamDECLARE_MODULE(rc4, rc4_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
126109318SsamMODULE_VERSION(rc4, 1);
127