1189251Ssam/* 2189251Ssam * RC4 stream cipher 3189251Ssam * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi> 4189251Ssam * 5189251Ssam * This program is free software; you can redistribute it and/or modify 6189251Ssam * it under the terms of the GNU General Public License version 2 as 7189251Ssam * published by the Free Software Foundation. 8189251Ssam * 9189251Ssam * Alternatively, this software may be distributed under the terms of BSD 10189251Ssam * license. 11189251Ssam * 12189251Ssam * See README and COPYING for more details. 13189251Ssam */ 14189251Ssam 15189251Ssam#include "includes.h" 16189251Ssam 17189251Ssam#include "common.h" 18214734Srpaulo#include "crypto.h" 19189251Ssam 20189251Ssam#define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0) 21189251Ssam 22214734Srpauloint rc4_skip(const u8 *key, size_t keylen, size_t skip, 23214734Srpaulo u8 *data, size_t data_len) 24189251Ssam{ 25189251Ssam u32 i, j, k; 26189251Ssam u8 S[256], *pos; 27189251Ssam size_t kpos; 28189251Ssam 29189251Ssam /* Setup RC4 state */ 30189251Ssam for (i = 0; i < 256; i++) 31189251Ssam S[i] = i; 32189251Ssam j = 0; 33189251Ssam kpos = 0; 34189251Ssam for (i = 0; i < 256; i++) { 35189251Ssam j = (j + S[i] + key[kpos]) & 0xff; 36189251Ssam kpos++; 37189251Ssam if (kpos >= keylen) 38189251Ssam kpos = 0; 39189251Ssam S_SWAP(i, j); 40189251Ssam } 41189251Ssam 42189251Ssam /* Skip the start of the stream */ 43189251Ssam i = j = 0; 44189251Ssam for (k = 0; k < skip; k++) { 45189251Ssam i = (i + 1) & 0xff; 46189251Ssam j = (j + S[i]) & 0xff; 47189251Ssam S_SWAP(i, j); 48189251Ssam } 49189251Ssam 50189251Ssam /* Apply RC4 to data */ 51189251Ssam pos = data; 52189251Ssam for (k = 0; k < data_len; k++) { 53189251Ssam i = (i + 1) & 0xff; 54189251Ssam j = (j + S[i]) & 0xff; 55189251Ssam S_SWAP(i, j); 56189251Ssam *pos++ ^= S[(S[i] + S[j]) & 0xff]; 57189251Ssam } 58214734Srpaulo 59214734Srpaulo return 0; 60189251Ssam} 61