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);
    }
}
Example #2
0
/*
 * 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" */
	}
}