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