/* * Routine: Phase 1 -- generate P1K, given TA, TK, IV32 * * Inputs: * TK[] = temporal key [128 bits] * TA[] = transmitter's MAC address [ 48 bits] * IV32 = upper 32 bits of IV [ 32 bits] * Output: * P1K[] = Phase 1 key [ 80 bits] * * Note: * This function only needs to be called every 2**16 packets, * although in theory it could be called every packet. * */ void BCMROMFN(tkhash_phase1)(uint16 *P1K, const uint8 *TK, const uint8 *TA, uint32 IV32) { uint16 i; /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */ P1K[0] = Lo16(IV32); P1K[1] = Hi16(IV32); P1K[2] = Mk16(TA[1], TA[0]); /* use TA[] as little-endian */ P1K[3] = Mk16(TA[3], TA[2]); P1K[4] = Mk16(TA[5], TA[4]); /* Now compute an unbalanced Feistel cipher with 80-bit block */ /* size on the 80-bit block P1K[], using the 128-bit key TK[] */ for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* Each add operation here is mod 2**16 */ P1K[0] += _S_(P1K[4] ^ TK16((i & 1) + 0)); P1K[1] += _S_(P1K[0] ^ TK16((i & 1) + 2)); P1K[2] += _S_(P1K[1] ^ TK16((i & 1) + 4)); P1K[3] += _S_(P1K[2] ^ TK16((i & 1) + 6)); P1K[4] += _S_(P1K[3] ^ TK16((i & 1) + 0)); P1K[4] += i; /* avoid "slide attacks" */ } }
void AirPDcapTkipMixingPhase1( UINT16 *TTAK, const UINT8 *TK, const UINT8 *TA, UINT32 TSC) { UINT16 i, j; /* Initialize the 80-bit TTAK from TSC (TSC) and TA[0..5] */ TTAK[0] = Lo16(TSC); TTAK[1] = Hi16(TSC); TTAK[2] = Mk16(TA[1], TA[0]); TTAK[3] = Mk16(TA[3], TA[2]); TTAK[4] = Mk16(TA[5], TA[4]); for (i = 0; i < PHASE1_LOOP_COUNT; i++) { j = (UINT16)(2 * (i & 1)); TTAK[0] = (UINT16)(TTAK[0] + _S_((UINT16)(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])))); TTAK[1] = (UINT16)(TTAK[1] + _S_((UINT16)(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])))); TTAK[2] = (UINT16)(TTAK[2] + _S_((UINT16)(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])))); TTAK[3] = (UINT16)(TTAK[3] + _S_((UINT16)(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])))); TTAK[4] = (UINT16)(TTAK[4] + _S_((UINT16)(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j]))) + i); } }