1189251Ssam/* 2189251Ssam * RC4 stream cipher 3189251Ssam * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi> 4189251Ssam * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7189251Ssam */ 8189251Ssam 9189251Ssam#include "includes.h" 10189251Ssam 11189251Ssam#include "common.h" 12214734Srpaulo#include "crypto.h" 13189251Ssam 14189251Ssam#define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0) 15189251Ssam 16214734Srpauloint rc4_skip(const u8 *key, size_t keylen, size_t skip, 17214734Srpaulo u8 *data, size_t data_len) 18189251Ssam{ 19189251Ssam u32 i, j, k; 20189251Ssam u8 S[256], *pos; 21189251Ssam size_t kpos; 22189251Ssam 23189251Ssam /* Setup RC4 state */ 24189251Ssam for (i = 0; i < 256; i++) 25189251Ssam S[i] = i; 26189251Ssam j = 0; 27189251Ssam kpos = 0; 28189251Ssam for (i = 0; i < 256; i++) { 29189251Ssam j = (j + S[i] + key[kpos]) & 0xff; 30189251Ssam kpos++; 31189251Ssam if (kpos >= keylen) 32189251Ssam kpos = 0; 33189251Ssam S_SWAP(i, j); 34189251Ssam } 35189251Ssam 36189251Ssam /* Skip the start of the stream */ 37189251Ssam i = j = 0; 38189251Ssam for (k = 0; k < skip; k++) { 39189251Ssam i = (i + 1) & 0xff; 40189251Ssam j = (j + S[i]) & 0xff; 41189251Ssam S_SWAP(i, j); 42189251Ssam } 43189251Ssam 44189251Ssam /* Apply RC4 to data */ 45189251Ssam pos = data; 46189251Ssam for (k = 0; k < data_len; k++) { 47189251Ssam i = (i + 1) & 0xff; 48189251Ssam j = (j + S[i]) & 0xff; 49189251Ssam S_SWAP(i, j); 50189251Ssam *pos++ ^= S[(S[i] + S[j]) & 0xff]; 51189251Ssam } 52214734Srpaulo 53214734Srpaulo return 0; 54189251Ssam} 55