xref: /netbsd-src/external/bsd/wpa/dist/src/crypto/rc4.c (revision e604d8611dacba7ab12396e19398c8a39b20a815)
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