1 /* 2 * RC4 stream cipher 3 * Copyright (c) 2002-2005, Jouni Malinen <j (at) w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #include "common.h" 18 #include "rc4.h" 19 20 #define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0) 21 22 /** 23 * rc4 - XOR RC4 stream to given data with skip-stream-start 24 * @key: RC4 key 25 * @keylen: RC4 key length 26 * @skip: number of bytes to skip from the beginning of the RC4 stream 27 * @data: data to be XOR'ed with RC4 stream 28 * @data_len: buf length 29 * 30 * Generate RC4 pseudo random stream for the given key, skip beginning of the 31 * stream, and XOR the end result with the data buffer to perform RC4 32 * encryption/decryption. 33 */ 34 void rc4_skip(const u8 *key, size_t keylen, size_t skip, 35 u8 *data, size_t data_len) 36 { 37 u32 i, j, k; 38 u8 S[256], *pos; 39 size_t kpos; 40 41 /* Setup RC4 state */ 42 for (i = 0; i < 256; i++) 43 S[i] = i; 44 j = 0; 45 kpos = 0; 46 for (i = 0; i < 256; i++) { 47 j = (j + S[i] + key[kpos]) & 0xff; 48 kpos++; 49 if (kpos >= keylen) 50 kpos = 0; 51 S_SWAP(i, j); 52 } 53 54 /* Skip the start of the stream */ 55 i = j = 0; 56 for (k = 0; k < skip; k++) { 57 i = (i + 1) & 0xff; 58 j = (j + S[i]) & 0xff; 59 S_SWAP(i, j); 60 } 61 62 /* Apply RC4 to data */ 63 pos = data; 64 for (k = 0; k < data_len; k++) { 65 i = (i + 1) & 0xff; 66 j = (j + S[i]) & 0xff; 67 S_SWAP(i, j); 68 *pos++ ^= S[(S[i] + S[j]) & 0xff]; 69 } 70 } 71 72 73 /** 74 * rc4 - XOR RC4 stream to given data 75 * @buf: data to be XOR'ed with RC4 stream 76 * @len: buf length 77 * @key: RC4 key 78 * @key_len: RC4 key length 79 * 80 * Generate RC4 pseudo random stream for the given key and XOR this with the 81 * data buffer to perform RC4 encryption/decryption. 82 */ 83 void rc4(u8 *buf, size_t len, const u8 *key, size_t key_len) 84 { 85 rc4_skip(key, key_len, 0, buf, len); 86 } 87