/* * * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16 * * Inputs: * TK[] = Temporal key [128 bits] * P1K[] = Phase 1 output key [ 80 bits] * IV16 = low 16 bits of IV counter [ 16 bits] * Output: * RC4KEY[] = the key used to encrypt the packet [128 bits] * * Note: * The value {TA,IV32,IV16} for Phase1/Phase2 must be unique * across all packets using the same key TK value. Then, for a * given value of TK[], this TKIP48 construction guarantees that * the final RC4KEY value is unique across all packets. * * Suggested implementation optimization: if PPK[] is "overlaid" * appropriately on RC4KEY[], there is no need for the final * for loop below that copies the PPK[] result into RC4KEY[]. * */ void BCMROMFN(tkhash_phase2)(uint8 *RC4KEY, const uint8 *TK, const uint16 *P1K, uint16 IV16) { uint16 i; uint16 PPK[6]; /* temporary key for mixing */ /* Note: all adds in the PPK[] equations below are mod 2**16 */ for (i = 0; i < 5; i++) PPK[i]=P1K[i]; /* first, copy P1K to PPK */ PPK[5] = P1K[4] + IV16; /* next, add in IV16 */ /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */ PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */ PPK[1] += _S_(PPK[0] ^ TK16(1)); PPK[2] += _S_(PPK[1] ^ TK16(2)); PPK[3] += _S_(PPK[2] ^ TK16(3)); PPK[4] += _S_(PPK[3] ^ TK16(4)); PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */ /* Final sweep: bijective, "linear". Rotates kill LSB correlations */ PPK[0] += RotR1(PPK[5] ^ TK16(6)); PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */ PPK[2] += RotR1(PPK[1]); PPK[3] += RotR1(PPK[2]); PPK[4] += RotR1(PPK[3]); PPK[5] += RotR1(PPK[4]); /* Note: At this point, for a given key TK[0..15], the 96-bit output */ /* value PPK[0..5] is guaranteed to be unique, as a function */ /* of the 96-bit "input" value {TA,IV32,IV16}. That is, P1K */ /* is now a keyed permutation of {TA,IV32,IV16}. */ /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */ RC4KEY[0] = Hi8(IV16); /* RC4KEY[0..2] is the WEP IV */ RC4KEY[1] =(Hi8(IV16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */ RC4KEY[2] = Lo8(IV16); RC4KEY[3] = Lo8((PPK[5] ^ TK16(0)) >> 1); /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */ for (i = 0; i < 6; i++) { RC4KEY[4 + 2 * i] = Lo8(PPK[i]); RC4KEY[5 + 2 * i] = Hi8(PPK[i]); } }
static void AirPDcapTkipMixingPhase2( UINT8 *wep_seed, const UINT8 *TK, UINT16 *TTAK, UINT16 TSC16) { INT i; TTAK[5] = (UINT16)(TTAK[4] + TSC16); /* Step 2 - 96-bit bijective mixing using S-box */ TTAK[0] = (UINT16)(TTAK[0] + _S_((UINT16)(TTAK[5] ^ Mk16_le(&TK[0])))); TTAK[1] = (UINT16)(TTAK[1] + _S_((UINT16)(TTAK[0] ^ Mk16_le(&TK[2])))); TTAK[2] = (UINT16)(TTAK[2] + _S_((UINT16)(TTAK[1] ^ Mk16_le(&TK[4])))); TTAK[3] = (UINT16)(TTAK[3] + _S_((UINT16)(TTAK[2] ^ Mk16_le(&TK[6])))); TTAK[4] = (UINT16)(TTAK[4] + _S_((UINT16)(TTAK[3] ^ Mk16_le(&TK[8])))); TTAK[5] = (UINT16)(TTAK[5] + _S_((UINT16)(TTAK[4] ^ Mk16_le(&TK[10])))); TTAK[0] = (UINT16)(TTAK[0] + RotR1((UINT16)(TTAK[5] ^ Mk16_le(&TK[12])))); TTAK[1] = (UINT16)(TTAK[1] + RotR1((UINT16)(TTAK[0] ^ Mk16_le(&TK[14])))); TTAK[2] = (UINT16)(TTAK[2] + RotR1(TTAK[1])); TTAK[3] = (UINT16)(TTAK[3] + RotR1(TTAK[2])); TTAK[4] = (UINT16)(TTAK[4] + RotR1(TTAK[3])); TTAK[5] = (UINT16)(TTAK[5] + RotR1(TTAK[4])); /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value * wep_seed[0..2] is transmitted as WEP IV */ wep_seed[0] = Hi8(TSC16); wep_seed[1] = (UINT8)((Hi8(TSC16) | 0x20) & 0x7F); wep_seed[2] = Lo8(TSC16); wep_seed[3] = Lo8((UINT16)((TTAK[5] ^ Mk16_le(&TK[0])) >> 1)); for (i = 0; i < 6; i++) { wep_seed[4 + ( 2 * i)] = Lo8( TTAK[i] ); wep_seed[5 + ( 2 * i)] = Hi8( TTAK[i] ); } }