wpa.c

来自「台湾RALink公司的 rt2570无线 802.11g 网卡的 驱动的源代码 」· C语言 代码 · 共 1,350 行 · 第 1/4 页

C
1,350
字号
		pDest +=  8;
		Len += 8;
		RTMPSetICV(pAdapter, pDest);
		Len += 12;
			
		MiniportMMRequest(pAdapter, OutBuffer, Len);
        
    }
    else if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)
    {
#if 0
        INT     i;
        PUCHAR  pTmp;

        i = 0;
        pTmp = (PUCHAR) &Iv16;
        *pTmp       = pWpaKey->TxTsc[0];
        *(pTmp + 1) = pWpaKey->TxTsc[1];
        *(pTmp + 2) = 0;
        *(pTmp + 3) = 0x20;
            
        Iv32 = *(PULONG)(&pWpaKey->TxTsc[2]);
            
        // Increase TxTsc value for next transmission
        while (++pWpaKey->TxTsc[i] == 0x0)
        {
            i++;
            if (i == 6)
                break;
        }
            
        // Copy IV
        NdisMoveMemory(&pTxD->Iv, &Iv16, 4);
            
        // Copy EIV
        NdisMoveMemory(&pTxD->Eiv, &Iv32, 4);
            
        // Set IV offset
        pTxD->IvOffset = LENGTH_802_11;

        // Copy TKey
        //red,NdisMoveMemory(pTxD->Key, pWpaKey->Key, 16);

        // Set Cipher suite
        //red,CipherAlg = CIPHER_AES;

	//red
	pTempDest += LENGTH_802_11;
	NdisMoveMemory(pTempDest, &Iv16, 4);
	pTempDest += 4;
	NdisMoveMemory(pTempDest, &Iv32, 4);
	pTempDest += 4;
            
        // IV + EIV + HW MIC
        //red,Asic's suggestionLen += 16;
        PLCPLength = Len + 12;//12 is MIC + crc32
#endif
    }               
                
}

/*
    ========================================================================
    
    Routine Description:
        SHA1 function 

    Arguments:
        
    Return Value:

    Note:
        
    ========================================================================
*/
VOID    HMAC_SHA1(
    IN  UCHAR   *text,
    IN  UINT    text_len,
    IN  UCHAR   *key,
    IN  UINT    key_len,
    IN  UCHAR   *digest)
{
    SHA_CTX context;
    UCHAR   k_ipad[65]; /* inner padding - key XORd with ipad   */
    UCHAR   k_opad[65]; /* outer padding - key XORd with opad   */
    INT     i;

    // if key is longer than 64 bytes reset it to key=SHA1(key) 
    if (key_len > 64) 
    {
        SHA_CTX      tctx;
        SHAInit(&tctx);
        SHAUpdate(&tctx, key, key_len);
        SHAFinal(&tctx, key);
        key_len = 20;
    }
    NdisZeroMemory(k_ipad, sizeof(k_ipad));
    NdisZeroMemory(k_opad, sizeof(k_opad));
    NdisMoveMemory(k_ipad, key, key_len);
    NdisMoveMemory(k_opad, key, key_len);

    // XOR key with ipad and opad values  
    for (i = 0; i < 64; i++) 
    {   
        k_ipad[i] ^= 0x36;
        k_opad[i] ^= 0x5c;
    }

    // perform inner SHA1 
    SHAInit(&context);                      /* init context for 1st pass */
    SHAUpdate(&context, k_ipad, 64);        /*  start with inner pad */
    SHAUpdate(&context, text, text_len);    /*  then text of datagram */
    SHAFinal(&context, digest);             /* finish up 1st pass */

    //perform outer SHA1  
    SHAInit(&context);                  /* init context for 2nd pass */
    SHAUpdate(&context, k_opad, 64);    /*  start with outer pad */
    SHAUpdate(&context, digest, 20);    /*  then results of 1st hash */
    SHAFinal(&context, digest);         /* finish up 2nd pass */
}

/*
    ========================================================================
    
    Routine Description:
        PRF function 

    Arguments:
        
    Return Value:

    Note:
        802.1i  Annex F.9
        
    ========================================================================
*/
VOID    PRF(
    IN  UCHAR   *key,
    IN  INT     key_len,
    IN  UCHAR   *prefix,
    IN  INT     prefix_len,
    IN  UCHAR   *data,
    IN  INT     data_len,
    OUT UCHAR   *output,
    IN  INT     len)
{
    INT     i;
    UCHAR   input[1024];
    INT     currentindex = 0;
    INT     total_len;
    
    NdisMoveMemory(input, prefix, prefix_len);
    input[prefix_len] = 0;
    NdisMoveMemory(&input[prefix_len + 1], data, data_len);
    total_len = prefix_len + 1 + data_len;
    input[total_len] = 0;
    total_len++;
    for (i = 0; i < (len + 19) / 20; i++)
    {
        HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
        currentindex += 20;
        input[total_len - 1]++;
    }   
}

/*
    ========================================================================
    
    Routine Description:
        Count TPTK from PMK

    Arguments:
        
    Return Value:
        Output      Store the TPTK

    Note:
        
    ========================================================================
*/
VOID WpaCountPTK(
    IN  UCHAR   *PMK,
    IN  UCHAR   *ANonce,
    IN  UCHAR   *AA,
    IN  UCHAR   *SNonce,
    IN  UCHAR   *SA,
    OUT UCHAR   *output,
    IN  UINT    len)
{   
    UCHAR   concatenation[76];
    UINT    CurrPos = 0;
    UCHAR   temp[32];
    UCHAR   Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ', 
                        'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};

    NdisZeroMemory(temp, sizeof(temp));

    // Get smaller address
    if (RTMPCompareMemory(SA, AA, 6) == 1)
        NdisMoveMemory(concatenation, AA, 6);
    else
        NdisMoveMemory(concatenation, SA, 6);       
    CurrPos += 6;

    // Get larger address
    if (RTMPCompareMemory(SA, AA, 6) == 1)
        NdisMoveMemory(&concatenation[CurrPos], SA, 6);
    else
        NdisMoveMemory(&concatenation[CurrPos], AA, 6);     
    CurrPos += 6;

    // Get smaller address
    if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) 
        NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
    else        
        NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
    CurrPos += 32;

    // Get larger address
    if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) 
        NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
    else        
        NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
    CurrPos += 32;
        
    PRF(PMK, LEN_MASTER_KEY, Prefix,  22, concatenation, 76 , output, len);
}

/*
    ========================================================================
    
    Routine Description:
        Misc function to Generate random number

    Arguments:
        
    Return Value:

    Note:
        802.1i  Annex F.9
        
    ========================================================================
*/
VOID    GenRandom(
    IN  PRT2570ADAPTER   pAd, 
    OUT UCHAR           *random)
{   
    INT     i, curr ;
    UCHAR   local[80], KeyCounter[32];
    UCHAR   result[80];
     ULONG   CurrentTime;
    UCHAR   prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};

    NdisZeroMemory(result, 80);
    NdisZeroMemory(local, 80);
    NdisZeroMemory(KeyCounter, 32);
    NdisMoveMemory(local, pAd->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
    
    for (i = 0; i < 32; i++)
    {       
        curr =  ETH_LENGTH_OF_ADDRESS;
        CurrentTime = jiffies;
        NdisMoveMemory(local,  pAd->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
        curr += ETH_LENGTH_OF_ADDRESS;
        NdisMoveMemory(&local[curr],  &CurrentTime, sizeof(CurrentTime));
        curr += sizeof(CurrentTime);
        NdisMoveMemory(&local[curr],  result, 32);
        curr += 32;
        NdisMoveMemory(&local[curr],  &i,  2);      
        curr += 2;
        PRF(KeyCounter, 32, prefix,12, local,   curr, result, 32); 
    }
    NdisMoveMemory(random, result,  32);    
}

/*
    ========================================================================
    
    Routine Description:
        Misc function to decrypt AES body
    
    Arguments:
            
    Return Value:
    
    Note:
        This function references to RFC 3394 for aes key unwrap algorithm.
            
    ========================================================================
*/
VOID    AES_GTK_KEY_UNWRAP( 
    IN  UCHAR   *key,
    OUT UCHAR   *plaintext,
    IN  UCHAR   *ciphertext)
{
    UCHAR       A[8],   BIN[16], BOUT[16];
    UCHAR       R1[8],R2[8];
    UCHAR       xor;
    INT         num_blocks = 2;
    INT         j;
    aes_context aesctx;
    
    // Initialize
    // A = C[0]
    NdisMoveMemory(A, ciphertext, 8);
    // R1 = C1
    NdisMoveMemory(R1, &ciphertext[8], 8);
    // R2 = C2
    NdisMoveMemory(R2, &ciphertext[16], 8);

    aes_set_key(&aesctx, key, 128);
    
    for (j = 5; j >= 0; j--)
    {
        xor = num_blocks * j + 2;
        NdisMoveMemory(BIN, A, 8);
        BIN[7] = A[7] ^ xor;
        NdisMoveMemory(&BIN[8], R2, 8);
        aes_decrypt(&aesctx, BIN, BOUT);
        NdisMoveMemory(A, &BOUT[0], 8);
        NdisMoveMemory(R2, &BOUT[8], 8);
        
        xor = num_blocks * j + 1;
        NdisMoveMemory(BIN, A, 8);
        BIN[7] = A[7] ^ xor;
        NdisMoveMemory(&BIN[8], R1, 8);
        aes_decrypt(&aesctx, BIN, BOUT);
        NdisMoveMemory(A, &BOUT[0], 8);
        NdisMoveMemory(R1, &BOUT[8], 8);
    }

    // OUTPUT
    NdisMoveMemory(&plaintext[0], R1, 8);
    NdisMoveMemory(&plaintext[8], R2, 8);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?