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