here is code i wrote to simulate how WEP crypto work, and how it's key is generated. wrote simple crib drag function to decrypt messages with same key used for encryption. WPA also uses RC4, but improved the way keys are generated, so crib dragging is no longer possible since same key wont be generated in as few packets.
Code:
#include <stdio.h>
#include <random>
void ksa(unsigned char state[], unsigned char key[], unsigned int len)
{
int i, j = 0, k;
for (i = 0; i <= 255; ++i)
{
state[i] = i;
}
for (i = 0; i <= 255; ++i)
{
j = (j + state[i] + key[i & (len - 1)]) & 255;
k = state[i];
state[i] = state[j];
state[j] = k;
}
}
void prga(unsigned char state[], unsigned char stream[], unsigned int len)
{
int i, j = 0, k = 0, l;
for (i = 0; i < len; ++i)
{
j = (j + 1) & 255;
k = (k + state[j]) & 255;
l = state[j];
state[j] = state[k];
state[k] = l;
stream[i] = state[(state[j] + state[k]) & 255];
}
}
void _xor(unsigned char data1[], unsigned char data2[], unsigned int len)
{
for (int i = 0; i < len; i++)
{
data1[i] ^= data2[i];
}
}
void crib_drag(unsigned char data[], unsigned char crib[], unsigned int data_len, unsigned int crib_len)
{
int i, j;
unsigned char *temp = new unsigned char[crib_len];
for (i = 0; i <= data_len - crib_len; i++)
{
for (j = 0; j < crib_len; j++)
{
temp[j] = crib[j];
}
for (j = 0; j < crib_len; j++)
{
temp[j] ^= data[j + i];
printf("%02X ", temp[j]);
}
printf("\n");
}
delete[] temp;
}
int main()
{
unsigned char state[256];
unsigned char data[] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };
unsigned char *stream = new unsigned char[sizeof(data) / sizeof(data[0])];
unsigned int iv;
unsigned long long key;
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<float> dist(0.0, 16777215.0);
iv = dist(mt);
key = 10000000000;
printf("iv + key: %d + %llu", iv, key);
unsigned char seed[] =
{
(unsigned char)(iv >> 0), (unsigned char)(iv >> 8), (unsigned char)(iv >> 16),
(unsigned char)(key >> 0), (unsigned char)(key >> 8), (unsigned char)(key >> 16), (unsigned char)(key >> 24), (unsigned char)(key >> 32)
};
ksa(state, seed, sizeof(seed) / sizeof(seed[0]));
prga(state, stream, sizeof(data) / sizeof(data[0]));
_xor(data, stream, sizeof(data) / sizeof(data[0]));
printf("\nencoded data: ");
for (int i = 0; i < sizeof(data) / sizeof(data[0]); i++)
{
printf("%02X ", data[i]);
}
ksa(state, seed, sizeof(seed) / sizeof(seed[0]));
prga(state, stream, sizeof(data) / sizeof(data[0]));
_xor(data, stream, sizeof(data) / sizeof(data[0]));
printf("\ndecoded data: ");
for (int i = 0; i < sizeof(data) / sizeof(data[0]); i++)
{
printf("%02X ", data[i]);
}
delete[] stream;
getchar();
}