1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * RC4 stream cipher 3e5b75505Sopenharmony_ci * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi> 4e5b75505Sopenharmony_ci * 5e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 6e5b75505Sopenharmony_ci * See README for more details. 7e5b75505Sopenharmony_ci */ 8e5b75505Sopenharmony_ci 9e5b75505Sopenharmony_ci#include "includes.h" 10e5b75505Sopenharmony_ci 11e5b75505Sopenharmony_ci#include "common.h" 12e5b75505Sopenharmony_ci#include "crypto.h" 13e5b75505Sopenharmony_ci 14e5b75505Sopenharmony_ci#define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0) 15e5b75505Sopenharmony_ci 16e5b75505Sopenharmony_ciint rc4_skip(const u8 *key, size_t keylen, size_t skip, 17e5b75505Sopenharmony_ci u8 *data, size_t data_len) 18e5b75505Sopenharmony_ci{ 19e5b75505Sopenharmony_ci u32 i, j, k; 20e5b75505Sopenharmony_ci u8 S[256], *pos; 21e5b75505Sopenharmony_ci size_t kpos; 22e5b75505Sopenharmony_ci 23e5b75505Sopenharmony_ci /* Setup RC4 state */ 24e5b75505Sopenharmony_ci for (i = 0; i < 256; i++) 25e5b75505Sopenharmony_ci S[i] = i; 26e5b75505Sopenharmony_ci j = 0; 27e5b75505Sopenharmony_ci kpos = 0; 28e5b75505Sopenharmony_ci for (i = 0; i < 256; i++) { 29e5b75505Sopenharmony_ci j = (j + S[i] + key[kpos]) & 0xff; 30e5b75505Sopenharmony_ci kpos++; 31e5b75505Sopenharmony_ci if (kpos >= keylen) 32e5b75505Sopenharmony_ci kpos = 0; 33e5b75505Sopenharmony_ci S_SWAP(i, j); 34e5b75505Sopenharmony_ci } 35e5b75505Sopenharmony_ci 36e5b75505Sopenharmony_ci /* Skip the start of the stream */ 37e5b75505Sopenharmony_ci i = j = 0; 38e5b75505Sopenharmony_ci for (k = 0; k < skip; k++) { 39e5b75505Sopenharmony_ci i = (i + 1) & 0xff; 40e5b75505Sopenharmony_ci j = (j + S[i]) & 0xff; 41e5b75505Sopenharmony_ci S_SWAP(i, j); 42e5b75505Sopenharmony_ci } 43e5b75505Sopenharmony_ci 44e5b75505Sopenharmony_ci /* Apply RC4 to data */ 45e5b75505Sopenharmony_ci pos = data; 46e5b75505Sopenharmony_ci for (k = 0; k < data_len; k++) { 47e5b75505Sopenharmony_ci i = (i + 1) & 0xff; 48e5b75505Sopenharmony_ci j = (j + S[i]) & 0xff; 49e5b75505Sopenharmony_ci S_SWAP(i, j); 50e5b75505Sopenharmony_ci *pos++ ^= S[(S[i] + S[j]) & 0xff]; 51e5b75505Sopenharmony_ci } 52e5b75505Sopenharmony_ci 53e5b75505Sopenharmony_ci return 0; 54e5b75505Sopenharmony_ci} 55