/* This file is part of AirSnort. AirSnort is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. AirSnort is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with AirSnort; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "RC4.h" #define NORM(x) ((x) & (N-1)) #define SWAP(i,j) do {int t = this->S[i]; this->S[i] = this->S[j]; this->S[j] = t;} while(0) unsigned char Identity[N]; void RC4init(RC4 *this) { memcpy(this->S, Identity, sizeof(unsigned char) * N); this->i = this->j = 0; } void keyStep(RC4 *this, unsigned char *K,int l) { this->j += (this->S)[this->i] + K[this->i % l]; SWAP(this->i, this->j); (this->i)++; } void keyWith(RC4 *this, unsigned char *K, int l) { int a; for (a = 0; a < N; a++) keyStep(this, K, l); this->i = this->j = 0; } int step(RC4 *this) { (this->i)++; this->j += this->S[this->i]; SWAP(this->i, this->j); return (this->S[NORM(this->S[this->i] + this->S[this->j])]); } int SInverse(RC4 *this, int x) { int a; for(a = 0; a < N; a++) { if (this->S[a] == x) return(a); } printf("Reality Error #1"); exit(1); } /* Returns the key guess, the assumptions are as follows: 1. The IV is assumed to be IV_SIZE bytes, B is which byte of the key we seek 3. The system is in a 'resolved state' and is at time IV_SIZE+B of keying 4. out is the first output byte of the cypher */ int keyGuess(RC4 *this, int B,int out) { return(NORM(SInverse(this, out) - this->j - this->S[IV_SIZE+B])); } /* Checks if the system is in a state where we can use keyGuess. Assumptions: 1. The IV is IV_SIZE bytes 2. B is byte of the key we seek 3. In key setup as of time IV+B */ int isOk(RC4 *this, int B) { return(this->S[1] < IV_SIZE && NORM(this->S[1] + this->S[this->S[1]]) == IV_SIZE + B); } /* Trys to guess key at location B, Assumptions: IV_SIZE is the size of the initialization vector. key is the Initialization Vector+Key key[x] where x= 5%, so just get a bunch of guesses and look for the answer that shows up the most */ int tryIV(RC4 *this, unsigned char *key, int B, int out) { int a; for(a = 0; a < IV_SIZE; a++) { keyStep(this, key, 16); } if (!isOk(this, B)) return(-1); for(a = IV_SIZE; a < IV_SIZE+B; a++) { keyStep(this, key, 16); } return keyGuess(this, B, out); } void setupIdentity() { int a; for(a = 0; a < N; a++) { Identity[a] = a; } }