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