18dbcf02cSchristos /*
28dbcf02cSchristos * RC4 stream cipher
38dbcf02cSchristos * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
48dbcf02cSchristos *
5*e604d861Schristos * This software may be distributed under the terms of the BSD license.
6*e604d861Schristos * See README for more details.
78dbcf02cSchristos */
88dbcf02cSchristos
98dbcf02cSchristos #include "includes.h"
108dbcf02cSchristos
118dbcf02cSchristos #include "common.h"
128dbcf02cSchristos #include "crypto.h"
138dbcf02cSchristos
148dbcf02cSchristos #define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
158dbcf02cSchristos
rc4_skip(const u8 * key,size_t keylen,size_t skip,u8 * data,size_t data_len)168dbcf02cSchristos int rc4_skip(const u8 *key, size_t keylen, size_t skip,
178dbcf02cSchristos u8 *data, size_t data_len)
188dbcf02cSchristos {
198dbcf02cSchristos u32 i, j, k;
208dbcf02cSchristos u8 S[256], *pos;
218dbcf02cSchristos size_t kpos;
228dbcf02cSchristos
238dbcf02cSchristos /* Setup RC4 state */
248dbcf02cSchristos for (i = 0; i < 256; i++)
258dbcf02cSchristos S[i] = i;
268dbcf02cSchristos j = 0;
278dbcf02cSchristos kpos = 0;
288dbcf02cSchristos for (i = 0; i < 256; i++) {
298dbcf02cSchristos j = (j + S[i] + key[kpos]) & 0xff;
308dbcf02cSchristos kpos++;
318dbcf02cSchristos if (kpos >= keylen)
328dbcf02cSchristos kpos = 0;
338dbcf02cSchristos S_SWAP(i, j);
348dbcf02cSchristos }
358dbcf02cSchristos
368dbcf02cSchristos /* Skip the start of the stream */
378dbcf02cSchristos i = j = 0;
388dbcf02cSchristos for (k = 0; k < skip; k++) {
398dbcf02cSchristos i = (i + 1) & 0xff;
408dbcf02cSchristos j = (j + S[i]) & 0xff;
418dbcf02cSchristos S_SWAP(i, j);
428dbcf02cSchristos }
438dbcf02cSchristos
448dbcf02cSchristos /* Apply RC4 to data */
458dbcf02cSchristos pos = data;
468dbcf02cSchristos for (k = 0; k < data_len; k++) {
478dbcf02cSchristos i = (i + 1) & 0xff;
488dbcf02cSchristos j = (j + S[i]) & 0xff;
498dbcf02cSchristos S_SWAP(i, j);
508dbcf02cSchristos *pos++ ^= S[(S[i] + S[j]) & 0xff];
518dbcf02cSchristos }
528dbcf02cSchristos
538dbcf02cSchristos return 0;
548dbcf02cSchristos }
55