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$"); 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; 64186179Smav int i, k; 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 */ 73186179Smav for (j = i = k = 0; i < 256; i++) { 74186179Smav j += state->perm[i] + key[k]; 7559108Sarchie swap_bytes(&state->perm[i], &state->perm[j]); 76186179Smav if (++k >= keylen) 77186179Smav k = 0; 7859108Sarchie } 7959108Sarchie} 8059108Sarchie 8159108Sarchie/* 8259108Sarchie * Encrypt some data using the supplied RC4 state buffer. 8359108Sarchie * The input and output buffers may be the same buffer. 8459108Sarchie * Since RC4 is a stream cypher, this function is used 8559108Sarchie * for both encryption and decryption. 8659108Sarchie */ 8759108Sarchievoid 8859108Sarchierc4_crypt(struct rc4_state *const state, 8959108Sarchie const u_char *inbuf, u_char *outbuf, int buflen) 9059108Sarchie{ 9159108Sarchie int i; 9259108Sarchie u_char j; 9359108Sarchie 9459108Sarchie for (i = 0; i < buflen; i++) { 9559108Sarchie 9659108Sarchie /* Update modification indicies */ 9759108Sarchie state->index1++; 9859108Sarchie state->index2 += state->perm[state->index1]; 9959108Sarchie 10059108Sarchie /* Modify permutation */ 10159108Sarchie swap_bytes(&state->perm[state->index1], 10259108Sarchie &state->perm[state->index2]); 10359108Sarchie 10459108Sarchie /* Encrypt/decrypt next byte */ 10559108Sarchie j = state->perm[state->index1] + state->perm[state->index2]; 10659108Sarchie outbuf[i] = inbuf[i] ^ state->perm[j]; 10759108Sarchie } 10859108Sarchie} 10959108Sarchie 110109318Ssamstatic int 111109318Ssamrc4_modevent(module_t mod, int type, void *unused) 112109318Ssam{ 113109318Ssam switch (type) { 114109318Ssam case MOD_LOAD: 115109318Ssam return 0; 116109318Ssam case MOD_UNLOAD: 117109318Ssam return 0; 118109318Ssam } 119109318Ssam return EINVAL; 120109318Ssam} 121109318Ssam 122109318Ssamstatic moduledata_t rc4_mod = { 123109318Ssam "rc4", 124109318Ssam rc4_modevent, 125241394Skevlo 0 126109318Ssam}; 127109318SsamDECLARE_MODULE(rc4, rc4_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 128109318SsamMODULE_VERSION(rc4, 1); 129