Page 2 of 2
/**********************************************************************
* teste un vecteur d'initialisation : *
* - "o_rc4" est le premier octet généré par RC4 avec "IV" *
* - "n" est l'octet de la clé que l'on recherche *
* - "cle" contient les morceaux de la clé que l'on a déjà calculée *
* *
* La fonction renvoie 1 si la clé était faible, et dans ce cas, *
* la prédiction correspondante se trouve dans le dernier paramètre *
* "prediction". *
* Si la clé n'était pas faible, cette fonction renvoie 1 et le *
* paramètre n'est pas modifié. *
**********************************************************************/
int predit_octet_simple(octet o_rc4, int n, octet *cle, octet *prediction)
{
unsigned char P[256];
unsigned char s_1;
unsigned char tmp_key[8];
int i, j;
memcpy(tmp_key, cle, 8);
j = s_1 = 0;
for(i=0; i<256; i++)
P[i] = i;
for(i=0; i<n+3; i++)
{
j = (unsigned char)(j+P[i]+tmp_key[i%8]);
echange(&P[i], &P[j]);
}
for (i=0; i<256; i++)
{
if(P[i] == *prediction)
s_1 = i;
}
if(P[0] != n+3 || P[1] != 0)
return -1;
*prediction = (s_1-j-P[n+3]);
return 1;
}
/**********************************************************************
* devine le "n"-ième octet de la clé (en supposant qu'on connaît les *
* n-1 octets précédents) en essayant tous les vecteurs *
* d'initialisations faibles. *
* L'argument "cle_WEP_partielle" contient le début de la clé (octets *
* 0 à "n"-1, non compris). *
* La fonction ne modifie pas les "n"-1 premières valeurs de *
* "cle_WEP_partielle". *
* *
* L'argument "nb_IV_faibles" est le nombre de vecteurs faibles à *
* considérer. *
* L'argument "nb_IV_total" est le nombre total de vecteurs à tester. *
* *
* La fonction s'arrête quand l'une des deux bornes est atteinte. *
* *
* Si les 2 bornes sont nulles, on utilise alors uniquement la *
* famille de vecteurs (n+3, 255, ...). ATTENTION, ça n'est possible *
* que si "taille_IV = 3". *
* *
* La fonction positionne le n-ème octet de "cle_WEP_partielle" en *
* utilisant la prédiction faite. *
**********************************************************************/
void predit_octet_multiple(int n, octet *cle_WEP_partielle, int nb_IV_faibles_total, int nb_IV_total)
{
int i;
int faible;
/* la prédiction finale */
octet prediction = 0;
int resultat = -1;
/* le vecteur d'initialisation courant */
octet IV[taille_IV];
/* la clé RC4 que l'on essaie de compléter :
* les premiers octets sont variables et contiennent le vecteur
* d'initialisation,
* les derniers octets contiennent le morceau de la clé WEP que l'on a déjà
* craquée*/
octet cle_partielle[taille_cle_RC4];
for (i = 0; i < taille_cle_RC4 - taille_IV; i++)
cle_partielle[i + taille_IV] = cle_WEP_partielle[i]; /* cette partie de la clé est constante : c'est le morceau de la clé WEP déjà craqué */
if (verbose > 2)
printf("Pour l'octet n=%d : ", n); fflush(NULL);
/* nb de vecteurs et de vecteurs faibles rencontrés */
int nb_IV = 0;
int nb_IV_faibles = 0;
while (1) { // on boucle jusqu'à avoir tester suffisamment de vecteurs d'initialisation
/* si nb_IV_total et nb_IV_faibles_total sont négatifs, on choisit un
* nouveau vecteur d'initialisation dans la famille (n+3, 255, ...) */
if (nb_IV_total < 1 && nb_IV_faibles_total < 1) {
if (nb_IV > 255) break; //on a testé tous les vecteurs de la forme (n+3, 255, ...)
IV[0] = n + taille_IV;
IV[1] = 255;
IV[2] = nb_IV;
} else {
/* sinon, on tire un vecteur d'initialisation aléatoirement */
if ((nb_IV_total > 0) && (nb_IV > nb_IV_total)) break; // on a testé suffisamment de vecteurs
if ((nb_IV_faibles_total > 0) && (nb_IV_faibles > nb_IV_faibles_total)) break; // idem
for (i=0; i < taille_IV; i++) IV[i] = rand() % 256;
}
nb_IV++;
/* on initialise RC4 avec le vecteur d'initialisation courant,
* puis on demande le premier octet */
init_WEP_RC4(IV);
octet o_rc4 = RC4_PRGA();
/* On initialize la clé partielle */
/* on recopie le vecteur d'initialisation dans la clé (le reste de la clé
* est constant : c'est ce qu'on cherche) */
for (int k = 0; k < taille_IV; k++)
cle_partielle[k] = IV[k];
/***
* on appelle la fonction "predit_octet_simple" pour vérifier si "IV" est
* un vecteur d'initialisation faible (et calculer la prédiction)
***/
faible = predit_octet_simple(o_rc4, n, cle_partielle, &prediction);
/* si le vecteur IV était faible, on prend en compte la prediction */
if (1 == faible) {
nb_IV_faibles++;
resultat = prediction;
}
}
cle_WEP_partielle[n] = resultat;
}