예제 #1
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] );
    }
}