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);
    }
}
Exemplo n.º 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" */
	}
}
Exemplo n.º 3
0
VOID CKIP_key_permute
    (
     OUT UCHAR  *PK,           /* output permuted key */
     IN UCHAR *CK,           /* input CKIP key */
     IN UCHAR  toDsFromDs,    /* input toDs/FromDs bits */
     IN UCHAR *piv           /* input pointer to IV */
     )
{
    int i;
    USHORT H[2], tmp;          /* H=32-bits of per-packet hash value */
    USHORT L[8], R[8];         /* L=u16 array of CK, R=u16 array of PK */

    /* build L from input key */
    memset(L, 0, sizeof(L));
    for (i=0; i<16; i++) {
        L[i>>1] |= ( ((USHORT)(CK[i])) << ( i & 1 ? 8 : 0) );
    }

    H[0] = (((USHORT)piv[0]) << 8) + piv[1];
    H[1] = ( ((USHORT)toDsFromDs) << 8) | piv[2];

    for (i=0; i<8; i++) {
        H[0] ^= L[i];           /* 16-bits of key material */
        tmp   = _S_(H[0]);      /* 16x16 permutation */
        H[0]  = tmp ^ H[1];     /* set up for next round */
        H[1]  = tmp;
        R[i]  = H[0];           /* store into key array  */
    }
    
    /* sweep in the other direction */
    tmp=L[0];
    for (i=7; i>0; i--) {
        R[i] = tmp = rotLeft_1(tmp) + R[i];
    }
    
    /* IV of the permuted key is unchanged */
    PK[0] = piv[0];
    PK[1] = piv[1];
    PK[2] = piv[2];

    /* key portion of the permuted key is changed */
    for (i=3; i<16; i++) {
        PK[i] = (UCHAR) (R[i>>1] >> (i & 1 ? 8 : 0));
    }
}    
Exemplo n.º 4
0
/*
 *
 * 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] );
    }
}