1018204afSArchie Cobbs 2018204afSArchie Cobbs /* 3018204afSArchie Cobbs * rc4.c 4018204afSArchie Cobbs * 5018204afSArchie Cobbs * Copyright (c) 1996-2000 Whistle Communications, Inc. 6018204afSArchie Cobbs * All rights reserved. 7018204afSArchie Cobbs * 8018204afSArchie Cobbs * Subject to the following obligations and disclaimer of warranty, use and 9018204afSArchie Cobbs * redistribution of this software, in source or object code forms, with or 10018204afSArchie Cobbs * without modifications are expressly permitted by Whistle Communications; 11018204afSArchie Cobbs * provided, however, that: 12018204afSArchie Cobbs * 1. Any and all reproductions of the source or object code must include the 13018204afSArchie Cobbs * copyright notice above and the following disclaimer of warranties; and 14018204afSArchie Cobbs * 2. No rights are granted, in any manner or form, to use Whistle 15018204afSArchie Cobbs * Communications, Inc. trademarks, including the mark "WHISTLE 16018204afSArchie Cobbs * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 17018204afSArchie Cobbs * such appears in the above copyright notice or in the software. 18018204afSArchie Cobbs * 19018204afSArchie Cobbs * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 20018204afSArchie Cobbs * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 21018204afSArchie Cobbs * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 22018204afSArchie Cobbs * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 23018204afSArchie Cobbs * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 24018204afSArchie Cobbs * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 25018204afSArchie Cobbs * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 26018204afSArchie Cobbs * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 27018204afSArchie Cobbs * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 28018204afSArchie Cobbs * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 29018204afSArchie Cobbs * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 30018204afSArchie Cobbs * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 31018204afSArchie Cobbs * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 32018204afSArchie Cobbs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33018204afSArchie Cobbs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34018204afSArchie Cobbs * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 35018204afSArchie Cobbs * OF SUCH DAMAGE. 36018204afSArchie Cobbs * 37018204afSArchie Cobbs * $FreeBSD$ 38018204afSArchie Cobbs */ 39018204afSArchie Cobbs 40018204afSArchie Cobbs #include <sys/types.h> 41018204afSArchie Cobbs #include <crypto/rc4/rc4.h> 42018204afSArchie Cobbs 43018204afSArchie Cobbs static __inline void 44018204afSArchie Cobbs swap_bytes(u_char *a, u_char *b) 45018204afSArchie Cobbs { 46018204afSArchie Cobbs u_char temp; 47018204afSArchie Cobbs 48018204afSArchie Cobbs temp = *a; 49018204afSArchie Cobbs *a = *b; 50018204afSArchie Cobbs *b = temp; 51018204afSArchie Cobbs } 52018204afSArchie Cobbs 53018204afSArchie Cobbs /* 54018204afSArchie Cobbs * Initialize an RC4 state buffer using the supplied key, 55018204afSArchie Cobbs * which can have arbitrary length. 56018204afSArchie Cobbs */ 57018204afSArchie Cobbs void 58018204afSArchie Cobbs rc4_init(struct rc4_state *const state, const u_char *key, int keylen) 59018204afSArchie Cobbs { 60018204afSArchie Cobbs u_char j; 61018204afSArchie Cobbs int i; 62018204afSArchie Cobbs 63018204afSArchie Cobbs /* Initialize state with identity permutation */ 64018204afSArchie Cobbs for (i = 0; i < 256; i++) 65018204afSArchie Cobbs state->perm[i] = (u_char)i; 66018204afSArchie Cobbs state->index1 = 0; 67018204afSArchie Cobbs state->index2 = 0; 68018204afSArchie Cobbs 69018204afSArchie Cobbs /* Randomize the permutation using key data */ 70018204afSArchie Cobbs for (j = i = 0; i < 256; i++) { 71018204afSArchie Cobbs j += state->perm[i] + key[i % keylen]; 72018204afSArchie Cobbs swap_bytes(&state->perm[i], &state->perm[j]); 73018204afSArchie Cobbs } 74018204afSArchie Cobbs } 75018204afSArchie Cobbs 76018204afSArchie Cobbs /* 77018204afSArchie Cobbs * Encrypt some data using the supplied RC4 state buffer. 78018204afSArchie Cobbs * The input and output buffers may be the same buffer. 79018204afSArchie Cobbs * Since RC4 is a stream cypher, this function is used 80018204afSArchie Cobbs * for both encryption and decryption. 81018204afSArchie Cobbs */ 82018204afSArchie Cobbs void 83018204afSArchie Cobbs rc4_crypt(struct rc4_state *const state, 84018204afSArchie Cobbs const u_char *inbuf, u_char *outbuf, int buflen) 85018204afSArchie Cobbs { 86018204afSArchie Cobbs int i; 87018204afSArchie Cobbs u_char j; 88018204afSArchie Cobbs 89018204afSArchie Cobbs for (i = 0; i < buflen; i++) { 90018204afSArchie Cobbs 91018204afSArchie Cobbs /* Update modification indicies */ 92018204afSArchie Cobbs state->index1++; 93018204afSArchie Cobbs state->index2 += state->perm[state->index1]; 94018204afSArchie Cobbs 95018204afSArchie Cobbs /* Modify permutation */ 96018204afSArchie Cobbs swap_bytes(&state->perm[state->index1], 97018204afSArchie Cobbs &state->perm[state->index2]); 98018204afSArchie Cobbs 99018204afSArchie Cobbs /* Encrypt/decrypt next byte */ 100018204afSArchie Cobbs j = state->perm[state->index1] + state->perm[state->index2]; 101018204afSArchie Cobbs outbuf[i] = inbuf[i] ^ state->perm[j]; 102018204afSArchie Cobbs } 103018204afSArchie Cobbs } 104018204afSArchie Cobbs 105