Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_security.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/14#define _RTW_SECURITY_C_1516#include <drv_types.h>1718static const char *_security_type_str[] = {19"N/A",20"WEP40",21"TKIP",22"TKIP_WM",23"AES",24"WEP104",25"SMS4",26"WEP_WPA",27"BIP",28};2930const char *security_type_str(u8 value)31{32#ifdef CONFIG_IEEE80211W33if (value <= _BIP_)34#else35if (value <= _WEP_WPA_MIXED_)36#endif37return _security_type_str[value];38return NULL;39}4041#ifdef DBG_SW_SEC_CNT42#define WEP_SW_ENC_CNT_INC(sec, ra) do {\43if (is_broadcast_mac_addr(ra)) \44sec->wep_sw_enc_cnt_bc++; \45else if (is_multicast_mac_addr(ra)) \46sec->wep_sw_enc_cnt_mc++; \47else \48sec->wep_sw_enc_cnt_uc++; \49} while (0)5051#define WEP_SW_DEC_CNT_INC(sec, ra) do {\52if (is_broadcast_mac_addr(ra)) \53sec->wep_sw_dec_cnt_bc++; \54else if (is_multicast_mac_addr(ra)) \55sec->wep_sw_dec_cnt_mc++; \56else \57sec->wep_sw_dec_cnt_uc++; \58} while (0)5960#define TKIP_SW_ENC_CNT_INC(sec, ra) do {\61if (is_broadcast_mac_addr(ra)) \62sec->tkip_sw_enc_cnt_bc++; \63else if (is_multicast_mac_addr(ra)) \64sec->tkip_sw_enc_cnt_mc++; \65else \66sec->tkip_sw_enc_cnt_uc++; \67} while (0)6869#define TKIP_SW_DEC_CNT_INC(sec, ra) do {\70if (is_broadcast_mac_addr(ra)) \71sec->tkip_sw_dec_cnt_bc++; \72else if (is_multicast_mac_addr(ra)) \73sec->tkip_sw_dec_cnt_mc++; \74else \75sec->tkip_sw_dec_cnt_uc++; \76} while (0)7778#define AES_SW_ENC_CNT_INC(sec, ra) do {\79if (is_broadcast_mac_addr(ra)) \80sec->aes_sw_enc_cnt_bc++; \81else if (is_multicast_mac_addr(ra)) \82sec->aes_sw_enc_cnt_mc++; \83else \84sec->aes_sw_enc_cnt_uc++; \85} while (0)8687#define AES_SW_DEC_CNT_INC(sec, ra) do {\88if (is_broadcast_mac_addr(ra)) \89sec->aes_sw_dec_cnt_bc++; \90else if (is_multicast_mac_addr(ra)) \91sec->aes_sw_dec_cnt_mc++; \92else \93sec->aes_sw_dec_cnt_uc++; \94} while (0)95#else96#define WEP_SW_ENC_CNT_INC(sec, ra)97#define WEP_SW_DEC_CNT_INC(sec, ra)98#define TKIP_SW_ENC_CNT_INC(sec, ra)99#define TKIP_SW_DEC_CNT_INC(sec, ra)100#define AES_SW_ENC_CNT_INC(sec, ra)101#define AES_SW_DEC_CNT_INC(sec, ra)102#endif /* DBG_SW_SEC_CNT */103104/* *****WEP related***** */105106#define CRC32_POLY 0x04c11db7107108struct arc4context {109u32 x;110u32 y;111u8 state[256];112};113114115static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len)116{117u32 t, u;118u32 keyindex;119u32 stateindex;120u8 *state;121u32 counter;122state = parc4ctx->state;123parc4ctx->x = 0;124parc4ctx->y = 0;125for (counter = 0; counter < 256; counter++)126state[counter] = (u8)counter;127keyindex = 0;128stateindex = 0;129for (counter = 0; counter < 256; counter++) {130t = state[counter];131stateindex = (stateindex + key[keyindex] + t) & 0xff;132u = state[stateindex];133state[stateindex] = (u8)t;134state[counter] = (u8)u;135if (++keyindex >= key_len)136keyindex = 0;137}138}139static u32 arcfour_byte(struct arc4context *parc4ctx)140{141u32 x;142u32 y;143u32 sx, sy;144u8 *state;145state = parc4ctx->state;146x = (parc4ctx->x + 1) & 0xff;147sx = state[x];148y = (sx + parc4ctx->y) & 0xff;149sy = state[y];150parc4ctx->x = x;151parc4ctx->y = y;152state[y] = (u8)sx;153state[x] = (u8)sy;154return state[(sx + sy) & 0xff];155}156157158static void arcfour_encrypt(struct arc4context *parc4ctx,159u8 *dest,160u8 *src,161u32 len)162{163u32 i;164for (i = 0; i < len; i++)165dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);166}167168static sint bcrc32initialized = 0;169static u32 crc32_table[256];170171172static u8 crc32_reverseBit(u8 data)173{174return (u8)((data << 7) & 0x80) | ((data << 5) & 0x40) | ((data << 3) & 0x20) | ((data << 1) & 0x10) | ((data >> 1) & 0x08) | ((data >> 3) & 0x04) | ((data >> 5) & 0x02) | ((175data >> 7) & 0x01) ;176}177178static void crc32_init(void)179{180if (bcrc32initialized == 1)181goto exit;182else {183sint i, j;184u32 c;185u8 *p = (u8 *)&c, *p1;186u8 k;187188c = 0x12340000;189190for (i = 0; i < 256; ++i) {191k = crc32_reverseBit((u8)i);192for (c = ((u32)k) << 24, j = 8; j > 0; --j)193c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);194p1 = (u8 *)&crc32_table[i];195196p1[0] = crc32_reverseBit(p[3]);197p1[1] = crc32_reverseBit(p[2]);198p1[2] = crc32_reverseBit(p[1]);199p1[3] = crc32_reverseBit(p[0]);200}201bcrc32initialized = 1;202}203exit:204return;205}206207static u32 getcrc32(u8 *buf, sint len)208{209u8 *p;210u32 crc;211if (bcrc32initialized == 0)212crc32_init();213214crc = 0xffffffff; /* preload shift register, per CRC-32 spec */215216for (p = buf; len > 0; ++p, --len)217crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);218return ~crc; /* transmit complement, per CRC-32 spec */219}220221222/*223Need to consider the fragment situation224*/225void rtw_wep_encrypt(_adapter *padapter, u8 *pxmitframe)226{227/* exclude ICV */228229unsigned char crc[4];230struct arc4context mycontext;231232sint curfragnum, length;233u32 keylength;234235u8 *pframe, *payload, *iv; /* ,*wepkey */236u8 wepkey[16];237u8 hw_hdr_offset = 0;238struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;239struct security_priv *psecuritypriv = &padapter->securitypriv;240struct xmit_priv *pxmitpriv = &padapter->xmitpriv;241242243244if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)245return;246247#ifdef CONFIG_USB_TX_AGGREGATION248hw_hdr_offset = TXDESC_SIZE +249(((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ);250#else251#ifdef CONFIG_TX_EARLY_MODE252hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;253#else254hw_hdr_offset = TXDESC_OFFSET;255#endif256#endif257258pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;259260/* start to encrypt each fragment */261if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {262keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex];263264for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {265iv = pframe + pattrib->hdrlen;266_rtw_memcpy(&wepkey[0], iv, 3);267_rtw_memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength);268payload = pframe + pattrib->iv_len + pattrib->hdrlen;269270if ((curfragnum + 1) == pattrib->nr_frags) {271/* the last fragment */272273length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;274275*((u32 *)crc) = cpu_to_le32(getcrc32(payload, length));276277arcfour_init(&mycontext, wepkey, 3 + keylength);278arcfour_encrypt(&mycontext, payload, payload, length);279arcfour_encrypt(&mycontext, payload + length, crc, 4);280281} else {282length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len ;283*((u32 *)crc) = cpu_to_le32(getcrc32(payload, length));284arcfour_init(&mycontext, wepkey, 3 + keylength);285arcfour_encrypt(&mycontext, payload, payload, length);286arcfour_encrypt(&mycontext, payload + length, crc, 4);287288pframe += pxmitpriv->frag_len;289pframe = (u8 *)RND4((SIZE_PTR)(pframe));290291}292293}294295WEP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);296}297298299}300301void rtw_wep_decrypt(_adapter *padapter, u8 *precvframe)302{303/* exclude ICV */304u8 crc[4];305struct arc4context mycontext;306sint length;307u32 keylength;308u8 *pframe, *payload, *iv, wepkey[16];309u8 keyindex;310struct rx_pkt_attrib *prxattrib = &(((union recv_frame *)precvframe)->u.hdr.attrib);311struct security_priv *psecuritypriv = &padapter->securitypriv;312313314pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;315316/* start to decrypt recvframe */317if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {318iv = pframe + prxattrib->hdrlen;319/* keyindex=(iv[3]&0x3); */320keyindex = prxattrib->key_index;321keylength = psecuritypriv->dot11DefKeylen[keyindex];322_rtw_memcpy(&wepkey[0], iv, 3);323/* _rtw_memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0],keylength); */324_rtw_memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);325length = ((union recv_frame *)precvframe)->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len;326327payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;328329/* decrypt payload include icv */330arcfour_init(&mycontext, wepkey, 3 + keylength);331arcfour_encrypt(&mycontext, payload, payload, length);332333/* calculate icv and compare the icv */334*((u32 *)crc) = le32_to_cpu(getcrc32(payload, length - 4));335336337WEP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);338}339340341return;342343}344345/* 3 =====TKIP related===== */346347static u32 secmicgetuint32(u8 *p)348/* Convert from Byte[] to Us4Byte32 in a portable way */349{350s32 i;351u32 res = 0;352for (i = 0; i < 4; i++)353res |= ((u32)(*p++)) << (8 * i);354return res;355}356357static void secmicputuint32(u8 *p, u32 val)358/* Convert from Us4Byte32 to Byte[] in a portable way */359{360long i;361for (i = 0; i < 4; i++) {362*p++ = (u8)(val & 0xff);363val >>= 8;364}365}366367static void secmicclear(struct mic_data *pmicdata)368{369/* Reset the state to the empty message. */370pmicdata->L = pmicdata->K0;371pmicdata->R = pmicdata->K1;372pmicdata->nBytesInM = 0;373pmicdata->M = 0;374}375376void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)377{378/* Set the key */379pmicdata->K0 = secmicgetuint32(key);380pmicdata->K1 = secmicgetuint32(key + 4);381/* and reset the message */382secmicclear(pmicdata);383}384385void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)386{387/* Append the byte to our word-sized buffer */388pmicdata->M |= ((unsigned long)b) << (8 * pmicdata->nBytesInM);389pmicdata->nBytesInM++;390/* Process the word if it is full. */391if (pmicdata->nBytesInM >= 4) {392pmicdata->L ^= pmicdata->M;393pmicdata->R ^= ROL32(pmicdata->L, 17);394pmicdata->L += pmicdata->R;395pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);396pmicdata->L += pmicdata->R;397pmicdata->R ^= ROL32(pmicdata->L, 3);398pmicdata->L += pmicdata->R;399pmicdata->R ^= ROR32(pmicdata->L, 2);400pmicdata->L += pmicdata->R;401/* Clear the buffer */402pmicdata->M = 0;403pmicdata->nBytesInM = 0;404}405}406407void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)408{409/* This is simple */410while (nbytes > 0) {411rtw_secmicappendbyte(pmicdata, *src++);412nbytes--;413}414}415416void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst)417{418/* Append the minimum padding */419rtw_secmicappendbyte(pmicdata, 0x5a);420rtw_secmicappendbyte(pmicdata, 0);421rtw_secmicappendbyte(pmicdata, 0);422rtw_secmicappendbyte(pmicdata, 0);423rtw_secmicappendbyte(pmicdata, 0);424/* and then zeroes until the length is a multiple of 4 */425while (pmicdata->nBytesInM != 0)426rtw_secmicappendbyte(pmicdata, 0);427/* The appendByte function has already computed the result. */428secmicputuint32(dst, pmicdata->L);429secmicputuint32(dst + 4, pmicdata->R);430/* Reset to the empty message. */431secmicclear(pmicdata);432}433434435void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri)436{437438struct mic_data micdata;439u8 priority[4] = {0x0, 0x0, 0x0, 0x0};440rtw_secmicsetkey(&micdata, key);441priority[0] = pri;442443/* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */444if (header[1] & 1) { /* ToDS==1 */445rtw_secmicappend(&micdata, &header[16], 6); /* DA */446if (header[1] & 2) /* From Ds==1 */447rtw_secmicappend(&micdata, &header[24], 6);448else449rtw_secmicappend(&micdata, &header[10], 6);450} else { /* ToDS==0 */451rtw_secmicappend(&micdata, &header[4], 6); /* DA */452if (header[1] & 2) /* From Ds==1 */453rtw_secmicappend(&micdata, &header[16], 6);454else455rtw_secmicappend(&micdata, &header[10], 6);456457}458rtw_secmicappend(&micdata, &priority[0], 4);459460461rtw_secmicappend(&micdata, data, data_len);462463rtw_secgetmic(&micdata, mic_code);464}465466467468469/* macros for extraction/creation of unsigned char/unsigned short values */470#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))471#define Lo8(v16) ((u8)((v16) & 0x00FF))472#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))473#define Lo16(v32) ((u16)((v32) & 0xFFFF))474#define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))475#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))476477/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */478#define TK16(N) Mk16(tk[2*(N)+1], tk[2*(N)])479480/* S-box lookup: 16 bits --> 16 bits */481#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])482483/* fixed algorithm "parameters" */484#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */485#define TA_SIZE 6 /* 48-bit transmitter address */486#define TK_SIZE 16 /* 128-bit temporal key */487#define P1K_SIZE 10 /* 80-bit Phase1 key */488#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */489490491/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */492static const unsigned short Sbox1[2][256] = /* Sbox for hash (can be in ROM) */493{ {4940xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,4950x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,4960x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,4970x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,4980x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,4990x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,5000x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,5010x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,5020x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,5030xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,5040xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,5050xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,5060xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,5070x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,5080xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,5090x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,5100x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,5110x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,5120xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,5130x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,5140xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,5150x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,5160xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,5170xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,5180x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,5190xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,5200xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,5210xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,5220xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,5230x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,5240x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,5250x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,526},527528529{ /* second half of table is unsigned char-reversed version of first! */5300xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,5310x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,5320x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,5330xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,5340xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,5350x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,5360x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,5370x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,5380x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,5390xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,5400xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,5410xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,5420x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,5430xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,5440xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,5450xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,5460x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,5470x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,5480xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,5490xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,5500x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,5510x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,5520x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,5530xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,5540xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,5550x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,5560x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,5570xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,5580x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,5590xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,5600x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,5610xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,562}563};564565/*566**********************************************************************567* Routine: Phase 1 -- generate P1K, given TA, TK, IV32568*569* Inputs:570* tk[] = temporal key [128 bits]571* ta[] = transmitter's MAC address [ 48 bits]572* iv32 = upper 32 bits of IV [ 32 bits]573* Output:574* p1k[] = Phase 1 key [ 80 bits]575*576* Note:577* This function only needs to be called every 2**16 packets,578* although in theory it could be called every packet.579*580**********************************************************************581*/582static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)583{584sint i;585/* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */586p1k[0] = Lo16(iv32);587p1k[1] = Hi16(iv32);588p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */589p1k[3] = Mk16(ta[3], ta[2]);590p1k[4] = Mk16(ta[5], ta[4]);591592/* Now compute an unbalanced Feistel cipher with 80-bit block */593/* size on the 80-bit block P1K[], using the 128-bit key TK[] */594for (i = 0; i < PHASE1_LOOP_CNT ; i++) {595/* Each add operation here is mod 2**16 */596p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0));597p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2));598p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4));599p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6));600p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0));601p1k[4] += (unsigned short)i; /* avoid "slide attacks" */602}603}604605606/*607**********************************************************************608* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16609*610* Inputs:611* tk[] = Temporal key [128 bits]612* p1k[] = Phase 1 output key [ 80 bits]613* iv16 = low 16 bits of IV counter [ 16 bits]614* Output:615* rc4key[] = the key used to encrypt the packet [128 bits]616*617* Note:618* The value {TA,IV32,IV16} for Phase1/Phase2 must be unique619* across all packets using the same key TK value. Then, for a620* given value of TK[], this TKIP48 construction guarantees that621* the final RC4KEY value is unique across all packets.622*623* Suggested implementation optimization: if PPK[] is "overlaid"624* appropriately on RC4KEY[], there is no need for the final625* for loop below that copies the PPK[] result into RC4KEY[].626*627**********************************************************************628*/629static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)630{631sint i;632u16 PPK[6]; /* temporary key for mixing */633/* Note: all adds in the PPK[] equations below are mod 2**16 */634for (i = 0; i < 5; i++)635PPK[i] = p1k[i]; /* first, copy P1K to PPK */636PPK[5] = p1k[4] + iv16; /* next, add in IV16 */637638/* Bijective non-linear mixing of the 96 bits of PPK[0..5] */639PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */640PPK[1] += _S_(PPK[0] ^ TK16(1));641PPK[2] += _S_(PPK[1] ^ TK16(2));642PPK[3] += _S_(PPK[2] ^ TK16(3));643PPK[4] += _S_(PPK[3] ^ TK16(4));644PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */645646/* Final sweep: bijective, "linear". Rotates kill LSB correlations */647PPK[0] += RotR1(PPK[5] ^ TK16(6));648PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */649PPK[2] += RotR1(PPK[1]);650PPK[3] += RotR1(PPK[2]);651PPK[4] += RotR1(PPK[3]);652PPK[5] += RotR1(PPK[4]);653/* Note: At this point, for a given key TK[0..15], the 96-bit output */654/* value PPK[0..5] is guaranteed to be unique, as a function */655/* of the 96-bit "input" value {TA,IV32,IV16}. That is, P1K */656/* is now a keyed permutation of {TA,IV32,IV16}. */657658/* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */659rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */660rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */661rc4key[2] = Lo8(iv16);662rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);663664665/* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */666for (i = 0; i < 6; i++) {667rc4key[4 + 2 * i] = Lo8(PPK[i]);668rc4key[5 + 2 * i] = Hi8(PPK[i]);669}670}671672673/* The hlen isn't include the IV */674u32 rtw_tkip_encrypt(_adapter *padapter, u8 *pxmitframe)675{676/* exclude ICV */677u16 pnl;678u32 pnh;679u8 rc4key[16];680u8 ttkey[16];681u8 crc[4];682u8 hw_hdr_offset = 0;683struct arc4context mycontext;684sint curfragnum, length;685u32 prwskeylen;686687u8 *pframe, *payload, *iv, *prwskey;688union pn48 dot11txpn;689/* struct sta_info *stainfo; */690struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;691struct security_priv *psecuritypriv = &padapter->securitypriv;692struct xmit_priv *pxmitpriv = &padapter->xmitpriv;693u32 res = _SUCCESS;694695if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)696return _FAIL;697698#ifdef CONFIG_USB_TX_AGGREGATION699hw_hdr_offset = TXDESC_SIZE +700(((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ);701#else702#ifdef CONFIG_TX_EARLY_MODE703hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;704#else705hw_hdr_offset = TXDESC_OFFSET;706#endif707#endif708709pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;710/* 4 start to encrypt each fragment */711if (pattrib->encrypt == _TKIP_) {712713/*714if(pattrib->psta)715{716stainfo = pattrib->psta;717}718else719{720RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);721stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] );722}723*/724/* if (stainfo!=NULL) */725{726/*727if(!(stainfo->state &_FW_LINKED))728{729RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);730return _FAIL;731}732*/733734if (IS_MCAST(pattrib->ra))735prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;736else {737/* prwskey=&stainfo->dot118021x_UncstKey.skey[0]; */738prwskey = pattrib->dot118021x_UncstKey.skey;739}740741prwskeylen = 16;742743for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {744iv = pframe + pattrib->hdrlen;745payload = pframe + pattrib->iv_len + pattrib->hdrlen;746747GET_TKIP_PN(iv, dot11txpn);748749pnl = (u16)(dot11txpn.val);750pnh = (u32)(dot11txpn.val >> 16);751752phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);753754phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);755756if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */757length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;758*((u32 *)crc) = cpu_to_le32(getcrc32(payload, length)); /* modified by Amy*/759760arcfour_init(&mycontext, rc4key, 16);761arcfour_encrypt(&mycontext, payload, payload, length);762arcfour_encrypt(&mycontext, payload + length, crc, 4);763764} else {765length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len ;766*((u32 *)crc) = cpu_to_le32(getcrc32(payload, length)); /* modified by Amy*/767arcfour_init(&mycontext, rc4key, 16);768arcfour_encrypt(&mycontext, payload, payload, length);769arcfour_encrypt(&mycontext, payload + length, crc, 4);770771pframe += pxmitpriv->frag_len;772pframe = (u8 *)RND4((SIZE_PTR)(pframe));773774}775}776777TKIP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);778}779/*780else{781RTW_INFO("%s, psta==NUL\n", __func__);782res=_FAIL;783}784*/785786}787return res;788789}790791792/* The hlen isn't include the IV */793u32 rtw_tkip_decrypt(_adapter *padapter, u8 *precvframe)794{795/* exclude ICV */796u16 pnl;797u32 pnh;798u8 rc4key[16];799u8 ttkey[16];800u8 crc[4];801struct arc4context mycontext;802sint length;803u32 prwskeylen;804805u8 *pframe, *payload, *iv, *prwskey;806union pn48 dot11txpn;807struct sta_info *stainfo;808struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;809struct security_priv *psecuritypriv = &padapter->securitypriv;810/* struct recv_priv *precvpriv=&padapter->recvpriv; */811u32 res = _SUCCESS;812813814pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;815816/* 4 start to decrypt recvframe */817if (prxattrib->encrypt == _TKIP_) {818819stainfo = rtw_get_stainfo(&padapter->stapriv , &prxattrib->ta[0]);820if (stainfo != NULL) {821822if (IS_MCAST(prxattrib->ra)) {823static systime start = 0;824static u32 no_gkey_bc_cnt = 0;825static u32 no_gkey_mc_cnt = 0;826827if (psecuritypriv->binstallGrpkey == _FALSE) {828res = _FAIL;829830if (start == 0)831start = rtw_get_current_time();832833if (is_broadcast_mac_addr(prxattrib->ra))834no_gkey_bc_cnt++;835else836no_gkey_mc_cnt++;837838if (rtw_get_passing_time_ms(start) > 1000) {839if (no_gkey_bc_cnt || no_gkey_mc_cnt) {840RTW_PRINT(FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",841FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);842}843start = rtw_get_current_time();844no_gkey_bc_cnt = 0;845no_gkey_mc_cnt = 0;846}847goto exit;848}849850if (no_gkey_bc_cnt || no_gkey_mc_cnt) {851RTW_PRINT(FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",852FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);853}854start = 0;855no_gkey_bc_cnt = 0;856no_gkey_mc_cnt = 0;857858/* RTW_INFO("rx bc/mc packets, to perform sw rtw_tkip_decrypt\n"); */859/* prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; */860prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;861prwskeylen = 16;862} else {863prwskey = &stainfo->dot118021x_UncstKey.skey[0];864prwskeylen = 16;865}866867iv = pframe + prxattrib->hdrlen;868payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;869length = ((union recv_frame *)precvframe)->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len;870871GET_TKIP_PN(iv, dot11txpn);872873pnl = (u16)(dot11txpn.val);874pnh = (u32)(dot11txpn.val >> 16);875876phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);877phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);878879/* 4 decrypt payload include icv */880881arcfour_init(&mycontext, rc4key, 16);882arcfour_encrypt(&mycontext, payload, payload, length);883884*((u32 *)crc) = le32_to_cpu(getcrc32(payload, length - 4));885886if (crc[3] != payload[length - 1] || crc[2] != payload[length - 2] || crc[1] != payload[length - 3] || crc[0] != payload[length - 4]) {887res = _FAIL;888}889890TKIP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);891} else {892res = _FAIL;893}894895}896exit:897return res;898899}900901902/* 3 =====AES related===== */903904905906#define MAX_MSG_SIZE 2048907/*****************************/908/******** SBOX Table *********/909/*****************************/910911static u8 sbox_table[256] = {9120x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,9130x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,9140xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,9150xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,9160xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,9170x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,9180x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,9190x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,9200x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,9210x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,9220x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,9230x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,9240xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,9250x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,9260x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,9270xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,9280xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,9290xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,9300x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,9310x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,9320xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,9330xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,9340xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,9350x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,9360xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,9370xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,9380x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,9390x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,9400xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,9410x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,9420x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,9430x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16944};945946/*****************************/947/**** Function Prototypes ****/948/*****************************/949950static void bitwise_xor(u8 *ina, u8 *inb, u8 *out);951static void construct_mic_iv(952u8 *mic_header1,953sint qc_exists,954sint a4_exists,955u8 *mpdu,956uint payload_length,957u8 *pn_vector,958uint frtype);/* add for CONFIG_IEEE80211W, none 11w also can use */959static void construct_mic_header1(960u8 *mic_header1,961sint header_length,962u8 *mpdu,963uint frtype);/* add for CONFIG_IEEE80211W, none 11w also can use */964static void construct_mic_header2(965u8 *mic_header2,966u8 *mpdu,967sint a4_exists,968sint qc_exists);969static void construct_ctr_preload(970u8 *ctr_preload,971sint a4_exists,972sint qc_exists,973u8 *mpdu,974u8 *pn_vector,975sint c,976uint frtype);/* add for CONFIG_IEEE80211W, none 11w also can use */977static void xor_128(u8 *a, u8 *b, u8 *out);978static void xor_32(u8 *a, u8 *b, u8 *out);979static u8 sbox(u8 a);980static void next_key(u8 *key, sint round);981static void byte_sub(u8 *in, u8 *out);982static void shift_row(u8 *in, u8 *out);983static void mix_column(u8 *in, u8 *out);984static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext);985986987/****************************************/988/* aes128k128d() */989/* Performs a 128 bit AES encrypt with */990/* 128 bit data. */991/****************************************/992static void xor_128(u8 *a, u8 *b, u8 *out)993{994sint i;995for (i = 0; i < 16; i++)996out[i] = a[i] ^ b[i];997}9989991000static void xor_32(u8 *a, u8 *b, u8 *out)1001{1002sint i;1003for (i = 0; i < 4; i++)1004out[i] = a[i] ^ b[i];1005}100610071008static u8 sbox(u8 a)1009{1010return sbox_table[(sint)a];1011}101210131014static void next_key(u8 *key, sint round)1015{1016u8 rcon;1017u8 sbox_key[4];1018u8 rcon_table[12] = {10190x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,10200x1b, 0x36, 0x36, 0x361021};1022sbox_key[0] = sbox(key[13]);1023sbox_key[1] = sbox(key[14]);1024sbox_key[2] = sbox(key[15]);1025sbox_key[3] = sbox(key[12]);10261027rcon = rcon_table[round];10281029xor_32(&key[0], sbox_key, &key[0]);1030key[0] = key[0] ^ rcon;10311032xor_32(&key[4], &key[0], &key[4]);1033xor_32(&key[8], &key[4], &key[8]);1034xor_32(&key[12], &key[8], &key[12]);1035}103610371038static void byte_sub(u8 *in, u8 *out)1039{1040sint i;1041for (i = 0; i < 16; i++)1042out[i] = sbox(in[i]);1043}104410451046static void shift_row(u8 *in, u8 *out)1047{1048out[0] = in[0];1049out[1] = in[5];1050out[2] = in[10];1051out[3] = in[15];1052out[4] = in[4];1053out[5] = in[9];1054out[6] = in[14];1055out[7] = in[3];1056out[8] = in[8];1057out[9] = in[13];1058out[10] = in[2];1059out[11] = in[7];1060out[12] = in[12];1061out[13] = in[1];1062out[14] = in[6];1063out[15] = in[11];1064}106510661067static void mix_column(u8 *in, u8 *out)1068{1069sint i;1070u8 add1b[4];1071u8 add1bf7[4];1072u8 rotl[4];1073u8 swap_halfs[4];1074u8 andf7[4];1075u8 rotr[4];1076u8 temp[4];1077u8 tempb[4];1078for (i = 0 ; i < 4; i++) {1079if ((in[i] & 0x80) == 0x80)1080add1b[i] = 0x1b;1081else1082add1b[i] = 0x00;1083}10841085swap_halfs[0] = in[2]; /* Swap halfs */1086swap_halfs[1] = in[3];1087swap_halfs[2] = in[0];1088swap_halfs[3] = in[1];10891090rotl[0] = in[3]; /* Rotate left 8 bits */1091rotl[1] = in[0];1092rotl[2] = in[1];1093rotl[3] = in[2];10941095andf7[0] = in[0] & 0x7f;1096andf7[1] = in[1] & 0x7f;1097andf7[2] = in[2] & 0x7f;1098andf7[3] = in[3] & 0x7f;10991100for (i = 3; i > 0; i--) { /* logical shift left 1 bit */1101andf7[i] = andf7[i] << 1;1102if ((andf7[i - 1] & 0x80) == 0x80)1103andf7[i] = (andf7[i] | 0x01);1104}1105andf7[0] = andf7[0] << 1;1106andf7[0] = andf7[0] & 0xfe;11071108xor_32(add1b, andf7, add1bf7);11091110xor_32(in, add1bf7, rotr);11111112temp[0] = rotr[0]; /* Rotate right 8 bits */1113rotr[0] = rotr[1];1114rotr[1] = rotr[2];1115rotr[2] = rotr[3];1116rotr[3] = temp[0];11171118xor_32(add1bf7, rotr, temp);1119xor_32(swap_halfs, rotl, tempb);1120xor_32(temp, tempb, out);1121}112211231124static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)1125{1126sint round;1127sint i;1128u8 intermediatea[16];1129u8 intermediateb[16];1130u8 round_key[16];1131for (i = 0; i < 16; i++)1132round_key[i] = key[i];11331134for (round = 0; round < 11; round++) {1135if (round == 0) {1136xor_128(round_key, data, ciphertext);1137next_key(round_key, round);1138} else if (round == 10) {1139byte_sub(ciphertext, intermediatea);1140shift_row(intermediatea, intermediateb);1141xor_128(intermediateb, round_key, ciphertext);1142} else { /* 1 - 9 */1143byte_sub(ciphertext, intermediatea);1144shift_row(intermediatea, intermediateb);1145mix_column(&intermediateb[0], &intermediatea[0]);1146mix_column(&intermediateb[4], &intermediatea[4]);1147mix_column(&intermediateb[8], &intermediatea[8]);1148mix_column(&intermediateb[12], &intermediatea[12]);1149xor_128(intermediatea, round_key, ciphertext);1150next_key(round_key, round);1151}1152}1153}115411551156/************************************************/1157/* construct_mic_iv() */1158/* Builds the MIC IV from header fields and PN */1159/* Baron think the function is construct CCM */1160/* nonce */1161/************************************************/1162static void construct_mic_iv(1163u8 *mic_iv,1164sint qc_exists,1165sint a4_exists,1166u8 *mpdu,1167uint payload_length,1168u8 *pn_vector,1169uint frtype/* add for CONFIG_IEEE80211W, none 11w also can use */1170)1171{1172sint i;1173mic_iv[0] = 0x59;1174if (qc_exists && a4_exists)1175mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */1176if (qc_exists && !a4_exists)1177mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */1178if (!qc_exists)1179mic_iv[1] = 0x00;1180#if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)1181/* 802.11w management frame should set management bit(4) */1182if (frtype == WIFI_MGT_TYPE)1183mic_iv[1] |= BIT(4);1184#endif1185for (i = 2; i < 8; i++)1186mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */1187#ifdef CONSISTENT_PN_ORDER1188for (i = 8; i < 14; i++)1189mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */1190#else1191for (i = 8; i < 14; i++)1192mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */1193#endif1194mic_iv[14] = (unsigned char)(payload_length / 256);1195mic_iv[15] = (unsigned char)(payload_length % 256);1196}119711981199/************************************************/1200/* construct_mic_header1() */1201/* Builds the first MIC header block from */1202/* header fields. */1203/* Build AAD SC,A1,A2 */1204/************************************************/1205static void construct_mic_header1(1206u8 *mic_header1,1207sint header_length,1208u8 *mpdu,1209uint frtype/* add for CONFIG_IEEE80211W, none 11w also can use */1210)1211{1212mic_header1[0] = (u8)((header_length - 2) / 256);1213mic_header1[1] = (u8)((header_length - 2) % 256);1214#if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)1215/* 802.11w management frame don't AND subtype bits 4,5,6 of frame control field */1216if (frtype == WIFI_MGT_TYPE)1217mic_header1[2] = mpdu[0];1218else1219#endif1220mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */12211222mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */1223mic_header1[4] = mpdu[4]; /* A1 */1224mic_header1[5] = mpdu[5];1225mic_header1[6] = mpdu[6];1226mic_header1[7] = mpdu[7];1227mic_header1[8] = mpdu[8];1228mic_header1[9] = mpdu[9];1229mic_header1[10] = mpdu[10]; /* A2 */1230mic_header1[11] = mpdu[11];1231mic_header1[12] = mpdu[12];1232mic_header1[13] = mpdu[13];1233mic_header1[14] = mpdu[14];1234mic_header1[15] = mpdu[15];1235}123612371238/************************************************/1239/* construct_mic_header2() */1240/* Builds the last MIC header block from */1241/* header fields. */1242/************************************************/1243static void construct_mic_header2(1244u8 *mic_header2,1245u8 *mpdu,1246sint a4_exists,1247sint qc_exists1248)1249{1250sint i;1251for (i = 0; i < 16; i++)1252mic_header2[i] = 0x00;12531254mic_header2[0] = mpdu[16]; /* A3 */1255mic_header2[1] = mpdu[17];1256mic_header2[2] = mpdu[18];1257mic_header2[3] = mpdu[19];1258mic_header2[4] = mpdu[20];1259mic_header2[5] = mpdu[21];12601261/* mic_header2[6] = mpdu[22] & 0xf0; SC */1262mic_header2[6] = 0x00;1263mic_header2[7] = 0x00; /* mpdu[23]; */126412651266if (!qc_exists && a4_exists) {1267for (i = 0; i < 6; i++)1268mic_header2[8 + i] = mpdu[24 + i]; /* A4 */12691270}12711272if (qc_exists && !a4_exists) {1273mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */1274mic_header2[9] = mpdu[25] & 0x00;1275}12761277if (qc_exists && a4_exists) {1278for (i = 0; i < 6; i++)1279mic_header2[8 + i] = mpdu[24 + i]; /* A4 */12801281mic_header2[14] = mpdu[30] & 0x0f;1282mic_header2[15] = mpdu[31] & 0x00;1283}12841285}128612871288/************************************************/1289/* construct_mic_header2() */1290/* Builds the last MIC header block from */1291/* header fields. */1292/* Baron think the function is construct CCM */1293/* nonce */1294/************************************************/1295static void construct_ctr_preload(1296u8 *ctr_preload,1297sint a4_exists,1298sint qc_exists,1299u8 *mpdu,1300u8 *pn_vector,1301sint c,1302uint frtype /* add for CONFIG_IEEE80211W, none 11w also can use */1303)1304{1305sint i = 0;1306for (i = 0; i < 16; i++)1307ctr_preload[i] = 0x00;1308i = 0;13091310ctr_preload[0] = 0x01; /* flag */1311if (qc_exists && a4_exists)1312ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */1313if (qc_exists && !a4_exists)1314ctr_preload[1] = mpdu[24] & 0x0f;1315#if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)1316/* 802.11w management frame should set management bit(4) */1317if (frtype == WIFI_MGT_TYPE)1318ctr_preload[1] |= BIT(4);1319#endif1320for (i = 2; i < 8; i++)1321ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */1322#ifdef CONSISTENT_PN_ORDER1323for (i = 8; i < 14; i++)1324ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */1325#else1326for (i = 8; i < 14; i++)1327ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */1328#endif1329ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */1330ctr_preload[15] = (unsigned char)(c % 256);1331}133213331334/************************************/1335/* bitwise_xor() */1336/* A 128 bit, bitwise exclusive or */1337/************************************/1338static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)1339{1340sint i;1341for (i = 0; i < 16; i++)1342out[i] = ina[i] ^ inb[i];1343}134413451346static sint aes_cipher(u8 *key, uint hdrlen,1347u8 *pframe, uint plen)1348{1349/* static unsigned char message[MAX_MSG_SIZE]; */1350uint qc_exists, a4_exists, i, j, payload_remainder,1351num_blocks, payload_index;13521353u8 pn_vector[6];1354u8 mic_iv[16];1355u8 mic_header1[16];1356u8 mic_header2[16];1357u8 ctr_preload[16];13581359/* Intermediate Buffers */1360u8 chain_buffer[16];1361u8 aes_out[16];1362u8 padded_buffer[16];1363u8 mic[8];1364/* uint offset = 0; */1365uint frtype = GetFrameType(pframe);1366uint frsubtype = get_frame_sub_type(pframe);13671368frsubtype = frsubtype >> 4;136913701371_rtw_memset((void *)mic_iv, 0, 16);1372_rtw_memset((void *)mic_header1, 0, 16);1373_rtw_memset((void *)mic_header2, 0, 16);1374_rtw_memset((void *)ctr_preload, 0, 16);1375_rtw_memset((void *)chain_buffer, 0, 16);1376_rtw_memset((void *)aes_out, 0, 16);1377_rtw_memset((void *)padded_buffer, 0, 16);13781379if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))1380a4_exists = 0;1381else1382a4_exists = 1;13831384if (1385((frtype | frsubtype) == WIFI_DATA_CFACK) ||1386((frtype | frsubtype) == WIFI_DATA_CFPOLL) ||1387((frtype | frsubtype) == WIFI_DATA_CFACKPOLL)) {1388qc_exists = 1;1389if (hdrlen != WLAN_HDR_A3_QOS_LEN && hdrlen != WLAN_HDR_A4_QOS_LEN)1390hdrlen += 2;1391}1392/* add for CONFIG_IEEE80211W, none 11w also can use */1393else if ((frtype == WIFI_DATA) &&1394((frsubtype == 0x08) ||1395(frsubtype == 0x09) ||1396(frsubtype == 0x0a) ||1397(frsubtype == 0x0b))) {1398if (hdrlen != WLAN_HDR_A3_QOS_LEN && hdrlen != WLAN_HDR_A4_QOS_LEN)1399hdrlen += 2;1400qc_exists = 1;1401} else1402qc_exists = 0;14031404pn_vector[0] = pframe[hdrlen];1405pn_vector[1] = pframe[hdrlen + 1];1406pn_vector[2] = pframe[hdrlen + 4];1407pn_vector[3] = pframe[hdrlen + 5];1408pn_vector[4] = pframe[hdrlen + 6];1409pn_vector[5] = pframe[hdrlen + 7];14101411construct_mic_iv(1412mic_iv,1413qc_exists,1414a4_exists,1415pframe, /* message, */1416plen,1417pn_vector,1418frtype /* add for CONFIG_IEEE80211W, none 11w also can use */1419);14201421construct_mic_header1(1422mic_header1,1423hdrlen,1424pframe, /* message */1425frtype /* add for CONFIG_IEEE80211W, none 11w also can use */1426);1427construct_mic_header2(1428mic_header2,1429pframe, /* message, */1430a4_exists,1431qc_exists1432);143314341435payload_remainder = plen % 16;1436num_blocks = plen / 16;14371438/* Find start of payload */1439payload_index = (hdrlen + 8);14401441/* Calculate MIC */1442aes128k128d(key, mic_iv, aes_out);1443bitwise_xor(aes_out, mic_header1, chain_buffer);1444aes128k128d(key, chain_buffer, aes_out);1445bitwise_xor(aes_out, mic_header2, chain_buffer);1446aes128k128d(key, chain_buffer, aes_out);14471448for (i = 0; i < num_blocks; i++) {1449bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */14501451payload_index += 16;1452aes128k128d(key, chain_buffer, aes_out);1453}14541455/* Add on the final payload block if it needs padding */1456if (payload_remainder > 0) {1457for (j = 0; j < 16; j++)1458padded_buffer[j] = 0x00;1459for (j = 0; j < payload_remainder; j++) {1460padded_buffer[j] = pframe[payload_index++];/* padded_buffer[j] = message[payload_index++]; */1461}1462bitwise_xor(aes_out, padded_buffer, chain_buffer);1463aes128k128d(key, chain_buffer, aes_out);14641465}14661467for (j = 0 ; j < 8; j++)1468mic[j] = aes_out[j];14691470/* Insert MIC into payload */1471for (j = 0; j < 8; j++)1472pframe[payload_index + j] = mic[j]; /* message[payload_index+j] = mic[j]; */14731474payload_index = hdrlen + 8;1475for (i = 0; i < num_blocks; i++) {1476construct_ctr_preload(1477ctr_preload,1478a4_exists,1479qc_exists,1480pframe, /* message, */1481pn_vector,1482i + 1,1483frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */1484aes128k128d(key, ctr_preload, aes_out);1485bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */1486for (j = 0; j < 16; j++)1487pframe[payload_index++] = chain_buffer[j];/* for (j=0; j<16;j++) message[payload_index++] = chain_buffer[j]; */1488}14891490if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/1491/* encrypt it and copy the unpadded part back */1492construct_ctr_preload(1493ctr_preload,1494a4_exists,1495qc_exists,1496pframe, /* message, */1497pn_vector,1498num_blocks + 1,1499frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */15001501for (j = 0; j < 16; j++)1502padded_buffer[j] = 0x00;1503for (j = 0; j < payload_remainder; j++) {1504padded_buffer[j] = pframe[payload_index + j]; /* padded_buffer[j] = message[payload_index+j]; */1505}1506aes128k128d(key, ctr_preload, aes_out);1507bitwise_xor(aes_out, padded_buffer, chain_buffer);1508for (j = 0; j < payload_remainder; j++)1509pframe[payload_index++] = chain_buffer[j];/* for (j=0; j<payload_remainder;j++) message[payload_index++] = chain_buffer[j]; */1510}15111512/* Encrypt the MIC */1513construct_ctr_preload(1514ctr_preload,1515a4_exists,1516qc_exists,1517pframe, /* message, */1518pn_vector,15190,1520frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */15211522for (j = 0; j < 16; j++)1523padded_buffer[j] = 0x00;1524for (j = 0; j < 8; j++) {1525padded_buffer[j] = pframe[j + hdrlen + 8 + plen]; /* padded_buffer[j] = message[j+hdrlen+8+plen]; */1526}15271528aes128k128d(key, ctr_preload, aes_out);1529bitwise_xor(aes_out, padded_buffer, chain_buffer);1530for (j = 0; j < 8; j++)1531pframe[payload_index++] = chain_buffer[j];/* for (j=0; j<8;j++) message[payload_index++] = chain_buffer[j]; */1532return _SUCCESS;1533}153415351536153715381539u32 rtw_aes_encrypt(_adapter *padapter, u8 *pxmitframe)1540{1541/* exclude ICV */154215431544/*static*/1545/* unsigned char message[MAX_MSG_SIZE]; */15461547/* Intermediate Buffers */1548sint curfragnum, length;1549u32 prwskeylen;1550u8 *pframe, *prwskey; /* , *payload,*iv */1551u8 hw_hdr_offset = 0;1552/* struct sta_info *stainfo=NULL; */1553struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;1554struct security_priv *psecuritypriv = &padapter->securitypriv;1555struct xmit_priv *pxmitpriv = &padapter->xmitpriv;15561557/* uint offset = 0; */1558u32 res = _SUCCESS;15591560if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)1561return _FAIL;15621563#ifdef CONFIG_USB_TX_AGGREGATION1564hw_hdr_offset = TXDESC_SIZE +1565(((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ);1566#else1567#ifdef CONFIG_TX_EARLY_MODE1568hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;1569#else1570hw_hdr_offset = TXDESC_OFFSET;1571#endif1572#endif15731574pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;15751576/* 4 start to encrypt each fragment */1577if ((pattrib->encrypt == _AES_)) {1578/*1579if(pattrib->psta)1580{1581stainfo = pattrib->psta;1582}1583else1584{1585RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);1586stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] );1587}1588*/1589/* if (stainfo!=NULL) */1590{1591/*1592if(!(stainfo->state &_FW_LINKED))1593{1594RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);1595return _FAIL;1596}1597*/15981599if (IS_MCAST(pattrib->ra))1600prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;1601else {1602/* prwskey=&stainfo->dot118021x_UncstKey.skey[0]; */1603prwskey = pattrib->dot118021x_UncstKey.skey;1604}16051606#ifdef CONFIG_TDLS1607{1608/* Swencryption */1609struct sta_info *ptdls_sta;1610ptdls_sta = rtw_get_stainfo(&padapter->stapriv , &pattrib->dst[0]);1611if ((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) {1612RTW_INFO("[%s] for tdls link\n", __FUNCTION__);1613prwskey = &ptdls_sta->tpk.tk[0];1614}1615}1616#endif /* CONFIG_TDLS */16171618prwskeylen = 16;16191620for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {16211622if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */1623length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;16241625aes_cipher(prwskey, pattrib->hdrlen, pframe, length);1626} else {1627length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len ;16281629aes_cipher(prwskey, pattrib->hdrlen, pframe, length);1630pframe += pxmitpriv->frag_len;1631pframe = (u8 *)RND4((SIZE_PTR)(pframe));16321633}1634}16351636AES_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);1637}1638/*1639else{1640RTW_INFO("%s, psta==NUL\n", __func__);1641res=_FAIL;1642}1643*/1644}1645164616471648return res;1649}16501651static sint aes_decipher(u8 *key, uint hdrlen,1652u8 *pframe, uint plen)1653{1654static u8 message[MAX_MSG_SIZE];1655uint qc_exists, a4_exists, i, j, payload_remainder,1656num_blocks, payload_index;1657sint res = _SUCCESS;1658u8 pn_vector[6];1659u8 mic_iv[16];1660u8 mic_header1[16];1661u8 mic_header2[16];1662u8 ctr_preload[16];16631664/* Intermediate Buffers */1665u8 chain_buffer[16];1666u8 aes_out[16];1667u8 padded_buffer[16];1668u8 mic[8];166916701671/* uint offset = 0; */1672uint frtype = GetFrameType(pframe);1673uint frsubtype = get_frame_sub_type(pframe);1674frsubtype = frsubtype >> 4;167516761677_rtw_memset((void *)mic_iv, 0, 16);1678_rtw_memset((void *)mic_header1, 0, 16);1679_rtw_memset((void *)mic_header2, 0, 16);1680_rtw_memset((void *)ctr_preload, 0, 16);1681_rtw_memset((void *)chain_buffer, 0, 16);1682_rtw_memset((void *)aes_out, 0, 16);1683_rtw_memset((void *)padded_buffer, 0, 16);16841685/* start to decrypt the payload */16861687num_blocks = (plen - 8) / 16; /* (plen including LLC, payload_length and mic ) */16881689payload_remainder = (plen - 8) % 16;16901691pn_vector[0] = pframe[hdrlen];1692pn_vector[1] = pframe[hdrlen + 1];1693pn_vector[2] = pframe[hdrlen + 4];1694pn_vector[3] = pframe[hdrlen + 5];1695pn_vector[4] = pframe[hdrlen + 6];1696pn_vector[5] = pframe[hdrlen + 7];16971698if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))1699a4_exists = 0;1700else1701a4_exists = 1;17021703if (1704((frtype | frsubtype) == WIFI_DATA_CFACK) ||1705((frtype | frsubtype) == WIFI_DATA_CFPOLL) ||1706((frtype | frsubtype) == WIFI_DATA_CFACKPOLL)) {1707qc_exists = 1;1708if (hdrlen != WLAN_HDR_A3_QOS_LEN && hdrlen != WLAN_HDR_A4_QOS_LEN)1709hdrlen += 2;1710} /* only for data packet . add for CONFIG_IEEE80211W, none 11w also can use */1711else if ((frtype == WIFI_DATA) &&1712((frsubtype == 0x08) ||1713(frsubtype == 0x09) ||1714(frsubtype == 0x0a) ||1715(frsubtype == 0x0b))) {1716if (hdrlen != WLAN_HDR_A3_QOS_LEN && hdrlen != WLAN_HDR_A4_QOS_LEN)1717hdrlen += 2;1718qc_exists = 1;1719} else1720qc_exists = 0;172117221723/* now, decrypt pframe with hdrlen offset and plen long */17241725payload_index = hdrlen + 8; /* 8 is for extiv */17261727for (i = 0; i < num_blocks; i++) {1728construct_ctr_preload(1729ctr_preload,1730a4_exists,1731qc_exists,1732pframe,1733pn_vector,1734i + 1,1735frtype /* add for CONFIG_IEEE80211W, none 11w also can use */1736);17371738aes128k128d(key, ctr_preload, aes_out);1739bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);17401741for (j = 0; j < 16; j++)1742pframe[payload_index++] = chain_buffer[j];1743}17441745if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/1746/* encrypt it and copy the unpadded part back */1747construct_ctr_preload(1748ctr_preload,1749a4_exists,1750qc_exists,1751pframe,1752pn_vector,1753num_blocks + 1,1754frtype /* add for CONFIG_IEEE80211W, none 11w also can use */1755);17561757for (j = 0; j < 16; j++)1758padded_buffer[j] = 0x00;1759for (j = 0; j < payload_remainder; j++)1760padded_buffer[j] = pframe[payload_index + j];1761aes128k128d(key, ctr_preload, aes_out);1762bitwise_xor(aes_out, padded_buffer, chain_buffer);1763for (j = 0; j < payload_remainder; j++)1764pframe[payload_index++] = chain_buffer[j];1765}17661767/* start to calculate the mic */1768if ((hdrlen + plen + 8) <= MAX_MSG_SIZE)1769_rtw_memcpy((void *)message, pframe, (hdrlen + plen + 8)); /* 8 is for ext iv len */177017711772pn_vector[0] = pframe[hdrlen];1773pn_vector[1] = pframe[hdrlen + 1];1774pn_vector[2] = pframe[hdrlen + 4];1775pn_vector[3] = pframe[hdrlen + 5];1776pn_vector[4] = pframe[hdrlen + 6];1777pn_vector[5] = pframe[hdrlen + 7];1778177917801781construct_mic_iv(1782mic_iv,1783qc_exists,1784a4_exists,1785message,1786plen - 8,1787pn_vector,1788frtype /* add for CONFIG_IEEE80211W, none 11w also can use */1789);17901791construct_mic_header1(1792mic_header1,1793hdrlen,1794message,1795frtype /* add for CONFIG_IEEE80211W, none 11w also can use */1796);1797construct_mic_header2(1798mic_header2,1799message,1800a4_exists,1801qc_exists1802);180318041805payload_remainder = (plen - 8) % 16;1806num_blocks = (plen - 8) / 16;18071808/* Find start of payload */1809payload_index = (hdrlen + 8);18101811/* Calculate MIC */1812aes128k128d(key, mic_iv, aes_out);1813bitwise_xor(aes_out, mic_header1, chain_buffer);1814aes128k128d(key, chain_buffer, aes_out);1815bitwise_xor(aes_out, mic_header2, chain_buffer);1816aes128k128d(key, chain_buffer, aes_out);18171818for (i = 0; i < num_blocks; i++) {1819bitwise_xor(aes_out, &message[payload_index], chain_buffer);18201821payload_index += 16;1822aes128k128d(key, chain_buffer, aes_out);1823}18241825/* Add on the final payload block if it needs padding */1826if (payload_remainder > 0) {1827for (j = 0; j < 16; j++)1828padded_buffer[j] = 0x00;1829for (j = 0; j < payload_remainder; j++)1830padded_buffer[j] = message[payload_index++];1831bitwise_xor(aes_out, padded_buffer, chain_buffer);1832aes128k128d(key, chain_buffer, aes_out);18331834}18351836for (j = 0 ; j < 8; j++)1837mic[j] = aes_out[j];18381839/* Insert MIC into payload */1840for (j = 0; j < 8; j++)1841message[payload_index + j] = mic[j];18421843payload_index = hdrlen + 8;1844for (i = 0; i < num_blocks; i++) {1845construct_ctr_preload(1846ctr_preload,1847a4_exists,1848qc_exists,1849message,1850pn_vector,1851i + 1,1852frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */1853aes128k128d(key, ctr_preload, aes_out);1854bitwise_xor(aes_out, &message[payload_index], chain_buffer);1855for (j = 0; j < 16; j++)1856message[payload_index++] = chain_buffer[j];1857}18581859if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/1860/* encrypt it and copy the unpadded part back */1861construct_ctr_preload(1862ctr_preload,1863a4_exists,1864qc_exists,1865message,1866pn_vector,1867num_blocks + 1,1868frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */18691870for (j = 0; j < 16; j++)1871padded_buffer[j] = 0x00;1872for (j = 0; j < payload_remainder; j++)1873padded_buffer[j] = message[payload_index + j];1874aes128k128d(key, ctr_preload, aes_out);1875bitwise_xor(aes_out, padded_buffer, chain_buffer);1876for (j = 0; j < payload_remainder; j++)1877message[payload_index++] = chain_buffer[j];1878}18791880/* Encrypt the MIC */1881construct_ctr_preload(1882ctr_preload,1883a4_exists,1884qc_exists,1885message,1886pn_vector,18870,1888frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */18891890for (j = 0; j < 16; j++)1891padded_buffer[j] = 0x00;1892for (j = 0; j < 8; j++)1893padded_buffer[j] = message[j + hdrlen + 8 + plen - 8];18941895aes128k128d(key, ctr_preload, aes_out);1896bitwise_xor(aes_out, padded_buffer, chain_buffer);1897for (j = 0; j < 8; j++)1898message[payload_index++] = chain_buffer[j];18991900/* compare the mic */1901for (i = 0; i < 8; i++) {1902if (pframe[hdrlen + 8 + plen - 8 + i] != message[hdrlen + 8 + plen - 8 + i]) {1903RTW_INFO("aes_decipher:mic check error mic[%d]: pframe(%x) != message(%x)\n",1904i, pframe[hdrlen + 8 + plen - 8 + i], message[hdrlen + 8 + plen - 8 + i]);1905res = _FAIL;1906}1907}1908return res;1909}19101911u32 rtw_aes_decrypt(_adapter *padapter, u8 *precvframe)1912{1913/* exclude ICV */191419151916/*static*/1917/* unsigned char message[MAX_MSG_SIZE]; */191819191920/* Intermediate Buffers */192119221923sint length;1924u8 *pframe, *prwskey; /* , *payload,*iv */1925struct sta_info *stainfo;1926struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;1927struct security_priv *psecuritypriv = &padapter->securitypriv;1928/* struct recv_priv *precvpriv=&padapter->recvpriv; */1929u32 res = _SUCCESS;1930pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;1931/* 4 start to encrypt each fragment */1932if ((prxattrib->encrypt == _AES_)) {19331934stainfo = rtw_get_stainfo(&padapter->stapriv , &prxattrib->ta[0]);1935if (stainfo != NULL) {19361937if (IS_MCAST(prxattrib->ra)) {1938static systime start = 0;1939static u32 no_gkey_bc_cnt = 0;1940static u32 no_gkey_mc_cnt = 0;19411942/* RTW_INFO("rx bc/mc packets, to perform sw rtw_aes_decrypt\n"); */1943/* prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; */1944if ((!MLME_IS_MESH(padapter) && psecuritypriv->binstallGrpkey == _FALSE)1945#ifdef CONFIG_RTW_MESH1946|| !(stainfo->gtk_bmp | BIT(prxattrib->key_index))1947#endif1948) {1949res = _FAIL;19501951if (start == 0)1952start = rtw_get_current_time();19531954if (is_broadcast_mac_addr(prxattrib->ra))1955no_gkey_bc_cnt++;1956else1957no_gkey_mc_cnt++;19581959if (rtw_get_passing_time_ms(start) > 1000) {1960if (no_gkey_bc_cnt || no_gkey_mc_cnt) {1961RTW_PRINT(FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",1962FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);1963}1964start = rtw_get_current_time();1965no_gkey_bc_cnt = 0;1966no_gkey_mc_cnt = 0;1967}19681969goto exit;1970}19711972if (no_gkey_bc_cnt || no_gkey_mc_cnt) {1973RTW_PRINT(FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",1974FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);1975}1976start = 0;1977no_gkey_bc_cnt = 0;1978no_gkey_mc_cnt = 0;19791980#ifdef CONFIG_RTW_MESH1981if (MLME_IS_MESH(padapter)) {1982/* TODO: multiple GK? */1983prwskey = &stainfo->gtk.skey[0];1984} else1985#endif1986{1987prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;1988if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {1989RTW_DBG("not match packet_index=%d, install_index=%d\n"1990, prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid);1991res = _FAIL;1992goto exit;1993}1994}1995} else1996prwskey = &stainfo->dot118021x_UncstKey.skey[0];19971998length = ((union recv_frame *)precvframe)->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len;1999#if 02000/* add for CONFIG_IEEE80211W, debug */2001if (0)2002printk("@@@@@@@@@@@@@@@@@@ length=%d, prxattrib->hdrlen=%d, prxattrib->pkt_len=%d\n"2003, length, prxattrib->hdrlen, prxattrib->pkt_len);2004if (0) {2005int no;2006/* test print PSK */2007printk("PSK key below:\n");2008for (no = 0; no < 16; no++)2009printk(" %02x ", prwskey[no]);2010printk("\n");2011}2012if (0) {2013int no;2014/* test print PSK */2015printk("frame:\n");2016for (no = 0; no < prxattrib->pkt_len; no++)2017printk(" %02x ", pframe[no]);2018printk("\n");2019}2020#endif20212022res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);20232024AES_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);2025} else {2026res = _FAIL;2027}20282029}2030exit:2031return res;2032}20332034#ifdef CONFIG_IEEE80211W2035u32 rtw_BIP_verify(_adapter *padapter, u8 *whdr_pos, sint flen2036, const u8 *key, u16 keyid, u64* ipn)2037{2038u8 *BIP_AAD, *mme;2039u32 res = _FAIL;2040uint len, ori_len;2041u16 pkt_keyid = 0;2042u64 pkt_ipn = 0;2043struct rtw_ieee80211_hdr *pwlanhdr;2044u8 mic[16];20452046mme = whdr_pos + flen - 18;2047if (*mme != _MME_IE_)2048return RTW_RX_HANDLED;20492050/* copy key index */2051_rtw_memcpy(&pkt_keyid, mme + 2, 2);2052pkt_keyid = le16_to_cpu(pkt_keyid);2053if (pkt_keyid != keyid) {2054RTW_INFO("BIP key index error!\n");2055return _FAIL;2056}20572058/* save packet number */2059_rtw_memcpy(&pkt_ipn, mme + 4, 6);2060pkt_ipn = le64_to_cpu(pkt_ipn);2061/* BIP packet number should bigger than previous BIP packet */2062if (pkt_ipn <= *ipn) { /* wrap around? */2063RTW_INFO("replay BIP packet\n");2064return _FAIL;2065}20662067ori_len = flen - WLAN_HDR_A3_LEN + BIP_AAD_SIZE;2068BIP_AAD = rtw_zmalloc(ori_len);2069if (BIP_AAD == NULL) {2070RTW_INFO("BIP AAD allocate fail\n");2071return _FAIL;2072}20732074/* mapping to wlan header */2075pwlanhdr = (struct rtw_ieee80211_hdr *)whdr_pos;20762077/* save the frame body + MME */2078_rtw_memcpy(BIP_AAD + BIP_AAD_SIZE, whdr_pos + WLAN_HDR_A3_LEN, flen - WLAN_HDR_A3_LEN);20792080/* point mme to the copy */2081mme = BIP_AAD + ori_len - 18;20822083/* clear the MIC field of MME to zero */2084_rtw_memset(mme + 10, 0, 8);20852086/* conscruct AAD, copy frame control field */2087_rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2);2088ClearRetry(BIP_AAD);2089ClearPwrMgt(BIP_AAD);2090ClearMData(BIP_AAD);2091/* conscruct AAD, copy address 1 to address 3 */2092_rtw_memcpy(BIP_AAD + 2, pwlanhdr->addr1, 18);20932094if (omac1_aes_128(key, BIP_AAD, ori_len, mic))2095goto BIP_exit;20962097#if 02098/* management packet content */2099{2100int pp;2101RTW_INFO("pkt: ");2102for (pp = 0; pp < flen; pp++)2103printk(" %02x ", whdr_pos[pp]);2104RTW_INFO("\n");2105/* BIP AAD + management frame body + MME(MIC is zero) */2106RTW_INFO("AAD+PKT: ");2107for (pp = 0; pp < ori_len; pp++)2108RTW_INFO(" %02x ", BIP_AAD[pp]);2109RTW_INFO("\n");2110/* show the MIC result */2111RTW_INFO("mic: ");2112for (pp = 0; pp < 16; pp++)2113RTW_INFO(" %02x ", mic[pp]);2114RTW_INFO("\n");2115}2116#endif21172118/* MIC field should be last 8 bytes of packet (packet without FCS) */2119if (_rtw_memcmp(mic, whdr_pos + flen - 8, 8)) {2120*ipn = pkt_ipn;2121res = _SUCCESS;2122} else2123RTW_INFO("BIP MIC error!\n");21242125BIP_exit:21262127rtw_mfree(BIP_AAD, ori_len);2128return res;2129}2130#endif /* CONFIG_IEEE80211W */21312132#ifndef PLATFORM_FREEBSD2133#if defined(CONFIG_TDLS)2134/* compress 512-bits */2135static int sha256_compress(struct _sha256_state *md, unsigned char *buf)2136{2137u32 S[8], W[64], t0, t1;2138u32 t;2139int i;21402141/* copy state into S */2142for (i = 0; i < 8; i++)2143S[i] = md->state[i];21442145/* copy the state into 512-bits into W[0..15] */2146for (i = 0; i < 16; i++)2147W[i] = WPA_GET_BE32(buf + (4 * i));21482149/* fill W[16..63] */2150for (i = 16; i < 64; i++) {2151W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +2152W[i - 16];2153}21542155/* Compress */2156#define RND(a, b, c, d, e, f, g, h, i) do {\2157t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \2158t1 = Sigma0(a) + Maj(a, b, c); \2159d += t0; \2160h = t0 + t1; \2161} while (0)21622163for (i = 0; i < 64; ++i) {2164RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);2165t = S[7];2166S[7] = S[6];2167S[6] = S[5];2168S[5] = S[4];2169S[4] = S[3];2170S[3] = S[2];2171S[2] = S[1];2172S[1] = S[0];2173S[0] = t;2174}21752176/* feedback */2177for (i = 0; i < 8; i++)2178md->state[i] = md->state[i] + S[i];2179return 0;2180}21812182/* Initialize the hash state */2183static void _sha256_init(struct _sha256_state *md)2184{2185md->curlen = 0;2186md->length = 0;2187md->state[0] = 0x6A09E667UL;2188md->state[1] = 0xBB67AE85UL;2189md->state[2] = 0x3C6EF372UL;2190md->state[3] = 0xA54FF53AUL;2191md->state[4] = 0x510E527FUL;2192md->state[5] = 0x9B05688CUL;2193md->state[6] = 0x1F83D9ABUL;2194md->state[7] = 0x5BE0CD19UL;2195}21962197/**2198Process a block of memory though the hash2199@param md The hash state2200@param in The data to hash2201@param inlen The length of the data (octets)2202@return CRYPT_OK if successful2203*/2204static int sha256_process(struct _sha256_state *md, unsigned char *in,2205unsigned long inlen)2206{2207unsigned long n;2208#define block_size 6422092210if (md->curlen >= sizeof(md->buf))2211return -1;22122213while (inlen > 0) {2214if (md->curlen == 0 && inlen >= block_size) {2215if (sha256_compress(md, (unsigned char *) in) < 0)2216return -1;2217md->length += block_size * 8;2218in += block_size;2219inlen -= block_size;2220} else {2221n = MIN(inlen, (block_size - md->curlen));2222_rtw_memcpy(md->buf + md->curlen, in, n);2223md->curlen += n;2224in += n;2225inlen -= n;2226if (md->curlen == block_size) {2227if (sha256_compress(md, md->buf) < 0)2228return -1;2229md->length += 8 * block_size;2230md->curlen = 0;2231}2232}2233}22342235return 0;2236}223722382239/**2240Terminate the hash to get the digest2241@param md The hash state2242@param out [out] The destination of the hash (32 bytes)2243@return CRYPT_OK if successful2244*/2245static int sha256_done(struct _sha256_state *md, unsigned char *out)2246{2247int i;22482249if (md->curlen >= sizeof(md->buf))2250return -1;22512252/* increase the length of the message */2253md->length += md->curlen * 8;22542255/* append the '1' bit */2256md->buf[md->curlen++] = (unsigned char) 0x80;22572258/* if the length is currently above 56 bytes we append zeros2259* then compress. Then we can fall back to padding zeros and length2260* encoding like normal.2261*/2262if (md->curlen > 56) {2263while (md->curlen < 64)2264md->buf[md->curlen++] = (unsigned char) 0;2265sha256_compress(md, md->buf);2266md->curlen = 0;2267}22682269/* pad upto 56 bytes of zeroes */2270while (md->curlen < 56)2271md->buf[md->curlen++] = (unsigned char) 0;22722273/* store length */2274WPA_PUT_BE64(md->buf + 56, md->length);2275sha256_compress(md, md->buf);22762277/* copy output */2278for (i = 0; i < 8; i++)2279WPA_PUT_BE32(out + (4 * i), md->state[i]);22802281return 0;2282}22832284/**2285* sha256_vector - SHA256 hash for data vector2286* @num_elem: Number of elements in the data vector2287* @addr: Pointers to the data areas2288* @len: Lengths of the data blocks2289* @mac: Buffer for the hash2290* Returns: 0 on success, -1 of failure2291*/2292static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len,2293u8 *mac)2294{2295struct _sha256_state ctx;2296size_t i;22972298_sha256_init(&ctx);2299for (i = 0; i < num_elem; i++)2300if (sha256_process(&ctx, addr[i], len[i]))2301return -1;2302if (sha256_done(&ctx, mac))2303return -1;2304return 0;2305}23062307static u8 os_strlen(const char *s)2308{2309const char *p = s;2310while (*p)2311p++;2312return p - s;2313}2314#endif23152316#if defined(CONFIG_TDLS) || defined(CONFIG_RTW_MESH_AEK)2317static int os_memcmp(const void *s1, const void *s2, u8 n)2318{2319const unsigned char *p1 = s1, *p2 = s2;23202321if (n == 0)2322return 0;23232324while (*p1 == *p2) {2325p1++;2326p2++;2327n--;2328if (n == 0)2329return 0;2330}23312332return *p1 - *p2;2333}2334#endif23352336/**2337* hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104)2338* @key: Key for HMAC operations2339* @key_len: Length of the key in bytes2340* @num_elem: Number of elements in the data vector2341* @addr: Pointers to the data areas2342* @len: Lengths of the data blocks2343* @mac: Buffer for the hash (32 bytes)2344*/2345#if defined(CONFIG_TDLS)2346static void hmac_sha256_vector(u8 *key, size_t key_len, size_t num_elem,2347u8 *addr[], size_t *len, u8 *mac)2348{2349unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */2350unsigned char tk[32];2351u8 *_addr[6];2352size_t _len[6], i;23532354if (num_elem > 5) {2355/*2356* Fixed limit on the number of fragments to avoid having to2357* allocate memory (which could fail).2358*/2359return;2360}23612362/* if key is longer than 64 bytes reset it to key = SHA256(key) */2363if (key_len > 64) {2364sha256_vector(1, &key, &key_len, tk);2365key = tk;2366key_len = 32;2367}23682369/* the HMAC_SHA256 transform looks like:2370*2371* SHA256(K XOR opad, SHA256(K XOR ipad, text))2372*2373* where K is an n byte key2374* ipad is the byte 0x36 repeated 64 times2375* opad is the byte 0x5c repeated 64 times2376* and text is the data being protected */23772378/* start out by storing key in ipad */2379_rtw_memset(k_pad, 0, sizeof(k_pad));2380_rtw_memcpy(k_pad, key, key_len);2381/* XOR key with ipad values */2382for (i = 0; i < 64; i++)2383k_pad[i] ^= 0x36;23842385/* perform inner SHA256 */2386_addr[0] = k_pad;2387_len[0] = 64;2388for (i = 0; i < num_elem; i++) {2389_addr[i + 1] = addr[i];2390_len[i + 1] = len[i];2391}2392sha256_vector(1 + num_elem, _addr, _len, mac);23932394_rtw_memset(k_pad, 0, sizeof(k_pad));2395_rtw_memcpy(k_pad, key, key_len);2396/* XOR key with opad values */2397for (i = 0; i < 64; i++)2398k_pad[i] ^= 0x5c;23992400/* perform outer SHA256 */2401_addr[0] = k_pad;2402_len[0] = 64;2403_addr[1] = mac;2404_len[1] = 32;2405sha256_vector(2, _addr, _len, mac);2406}2407#endif /* CONFIG_TDLS */2408#endif /* PLATFORM_FREEBSD */2409/**2410* sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)2411* @key: Key for PRF2412* @key_len: Length of the key in bytes2413* @label: A unique label for each purpose of the PRF2414* @data: Extra data to bind into the key2415* @data_len: Length of the data2416* @buf: Buffer for the generated pseudo-random key2417* @buf_len: Number of bytes of key to generate2418*2419* This function is used to derive new, cryptographically separate keys from a2420* given key.2421*/2422#ifndef PLATFORM_FREEBSD /* Baron */2423#if defined(CONFIG_TDLS)2424static void sha256_prf(u8 *key, size_t key_len, char *label,2425u8 *data, size_t data_len, u8 *buf, size_t buf_len)2426{2427u16 counter = 1;2428size_t pos, plen;2429u8 hash[SHA256_MAC_LEN];2430u8 *addr[4];2431size_t len[4];2432u8 counter_le[2], length_le[2];24332434addr[0] = counter_le;2435len[0] = 2;2436addr[1] = (u8 *) label;2437len[1] = os_strlen(label);2438addr[2] = data;2439len[2] = data_len;2440addr[3] = length_le;2441len[3] = sizeof(length_le);24422443WPA_PUT_LE16(length_le, buf_len * 8);2444pos = 0;2445while (pos < buf_len) {2446plen = buf_len - pos;2447WPA_PUT_LE16(counter_le, counter);2448if (plen >= SHA256_MAC_LEN) {2449hmac_sha256_vector(key, key_len, 4, addr, len,2450&buf[pos]);2451pos += SHA256_MAC_LEN;2452} else {2453hmac_sha256_vector(key, key_len, 4, addr, len, hash);2454_rtw_memcpy(&buf[pos], hash, plen);2455break;2456}2457counter++;2458}2459}2460#endif2461#endif /* PLATFORM_FREEBSD Baron */24622463/* AES tables*/2464const u32 Te0[256] = {24650xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,24660xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,24670x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,24680xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,24690x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,24700xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,24710x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,24720x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,24730x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,24740x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,24750x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,24760xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,24770x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,24780x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,24790x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,24800xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,24810x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,24820x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,24830xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,24840x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,24850xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,24860x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,24870xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,24880x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,24890xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,24900x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,24910x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,24920xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,24930xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,24940x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,24950x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,24960x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,24970x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,24980xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,24990x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,25000xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,25010xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,25020x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,25030x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,25040xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,25050xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,25060x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,25070x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,25080x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,25090xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,25100x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,25110xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,25120xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,25130x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,25140x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,25150xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,25160x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,25170xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,25180x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,25190xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,25200x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,25210xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,25220xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,25230x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,25240x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,25250x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,25260x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,25270x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,25280x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,2529};2530const u32 Td0[256] = {25310x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,25320x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,25330x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,25340x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,25350xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,25360xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,25370x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,25380xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,25390x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,25400xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,25410x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,25420xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,25430x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,25440xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,25450xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,25460x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,25470x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,25480x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,25490x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,25500x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,25510x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,25520x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,25530x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,25540xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,25550xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,25560x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,25570xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,25580x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,25590x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,25600x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,25610xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,25620x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,25630x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,25640xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,25650x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,25660xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,25670x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,25680x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,25690x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,25700xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,25710x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,25720xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,25730x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,25740xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,25750x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,25760xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,25770xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,25780xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,25790xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,25800x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,25810x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,25820xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,25830x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,25840x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,25850x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,25860xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,25870x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,25880xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,25890x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,25900x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,25910xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,25920x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,25930x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,25940x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,2595};2596const u8 Td4s[256] = {25970x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,25980xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,25990x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,26000x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,26010x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,26020xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,26030x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,26040x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,26050x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,26060xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,26070x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,26080x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,26090x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,26100xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,26110xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,26120xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,26130x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,26140x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,26150x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,26160xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,26170x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,26180x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,26190xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,26200x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,26210x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,26220xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,26230x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,26240x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,26250xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,26260xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,26270x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,26280xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,2629};2630const u8 rcons[] = {26310x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x362632/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */2633};26342635/**2636* Expand the cipher key into the encryption key schedule.2637*2638* @return the number of rounds for the given cipher key size.2639*/2640#ifndef PLATFORM_FREEBSD /* Baron */2641static void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])2642{2643int i;2644u32 temp;26452646rk[0] = GETU32(cipherKey);2647rk[1] = GETU32(cipherKey + 4);2648rk[2] = GETU32(cipherKey + 8);2649rk[3] = GETU32(cipherKey + 12);2650for (i = 0; i < 10; i++) {2651temp = rk[3];2652rk[4] = rk[0] ^2653TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^2654RCON(i);2655rk[5] = rk[1] ^ rk[4];2656rk[6] = rk[2] ^ rk[5];2657rk[7] = rk[3] ^ rk[6];2658rk += 4;2659}2660}26612662static void rijndaelEncrypt(u32 rk[/*44*/], u8 pt[16], u8 ct[16])2663{2664u32 s0, s1, s2, s3, t0, t1, t2, t3;2665int Nr = 10;2666#ifndef FULL_UNROLL2667int r;2668#endif /* ?FULL_UNROLL */26692670/*2671* map byte array block to cipher state2672* and add initial round key:2673*/2674s0 = GETU32(pt) ^ rk[0];2675s1 = GETU32(pt + 4) ^ rk[1];2676s2 = GETU32(pt + 8) ^ rk[2];2677s3 = GETU32(pt + 12) ^ rk[3];26782679#define ROUND(i, d, s) do {\2680d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \2681d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \2682d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \2683d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]; \2684} while (0)26852686#ifdef FULL_UNROLL26872688ROUND(1, t, s);2689ROUND(2, s, t);2690ROUND(3, t, s);2691ROUND(4, s, t);2692ROUND(5, t, s);2693ROUND(6, s, t);2694ROUND(7, t, s);2695ROUND(8, s, t);2696ROUND(9, t, s);26972698rk += Nr << 2;26992700#else /* !FULL_UNROLL */27012702/* Nr - 1 full rounds: */2703r = Nr >> 1;2704for (;;) {2705ROUND(1, t, s);2706rk += 8;2707if (--r == 0)2708break;2709ROUND(0, s, t);2710}27112712#endif /* ?FULL_UNROLL */27132714#undef ROUND27152716/*2717* apply last round and2718* map cipher state to byte array block:2719*/2720s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];2721PUTU32(ct , s0);2722s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];2723PUTU32(ct + 4, s1);2724s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];2725PUTU32(ct + 8, s2);2726s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];2727PUTU32(ct + 12, s3);2728}27292730static void *aes_encrypt_init(const u8 *key, size_t len)2731{2732u32 *rk;2733if (len != 16)2734return NULL;2735rk = (u32 *)rtw_malloc(AES_PRIV_SIZE);2736if (rk == NULL)2737return NULL;2738rijndaelKeySetupEnc(rk, key);2739return rk;2740}27412742static void aes_128_encrypt(void *ctx, u8 *plain, u8 *crypt)2743{2744rijndaelEncrypt(ctx, plain, crypt);2745}274627472748static void gf_mulx(u8 *pad)2749{2750int i, carry;27512752carry = pad[0] & 0x80;2753for (i = 0; i < AES_BLOCK_SIZE - 1; i++)2754pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);2755pad[AES_BLOCK_SIZE - 1] <<= 1;2756if (carry)2757pad[AES_BLOCK_SIZE - 1] ^= 0x87;2758}27592760static void aes_encrypt_deinit(void *ctx)2761{2762_rtw_memset(ctx, 0, AES_PRIV_SIZE);2763rtw_mfree(ctx, AES_PRIV_SIZE);2764}276527662767/**2768* omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-1282769* @key: 128-bit key for the hash operation2770* @num_elem: Number of elements in the data vector2771* @addr: Pointers to the data areas2772* @len: Lengths of the data blocks2773* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)2774* Returns: 0 on success, -1 on failure2775*2776* This is a mode for using block cipher (AES in this case) for authentication.2777* OMAC1 was standardized with the name CMAC by NIST in a Special Publication2778* (SP) 800-38B.2779*/2780static int omac1_aes_128_vector(const u8 *key, size_t num_elem,2781const u8 *addr[], const size_t *len, u8 *mac)2782{2783void *ctx;2784u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];2785const u8 *pos, *end;2786size_t i, e, left, total_len;27872788ctx = aes_encrypt_init(key, 16);2789if (ctx == NULL)2790return -1;2791_rtw_memset(cbc, 0, AES_BLOCK_SIZE);27922793total_len = 0;2794for (e = 0; e < num_elem; e++)2795total_len += len[e];2796left = total_len;27972798e = 0;2799pos = addr[0];2800end = pos + len[0];28012802while (left >= AES_BLOCK_SIZE) {2803for (i = 0; i < AES_BLOCK_SIZE; i++) {2804cbc[i] ^= *pos++;2805if (pos >= end) {2806e++;2807pos = addr[e];2808end = pos + len[e];2809}2810}2811if (left > AES_BLOCK_SIZE)2812aes_128_encrypt(ctx, cbc, cbc);2813left -= AES_BLOCK_SIZE;2814}28152816_rtw_memset(pad, 0, AES_BLOCK_SIZE);2817aes_128_encrypt(ctx, pad, pad);2818gf_mulx(pad);28192820if (left || total_len == 0) {2821for (i = 0; i < left; i++) {2822cbc[i] ^= *pos++;2823if (pos >= end) {2824e++;2825pos = addr[e];2826end = pos + len[e];2827}2828}2829cbc[left] ^= 0x80;2830gf_mulx(pad);2831}28322833for (i = 0; i < AES_BLOCK_SIZE; i++)2834pad[i] ^= cbc[i];2835aes_128_encrypt(ctx, pad, mac);2836aes_encrypt_deinit(ctx);2837return 0;2838}283928402841/**2842* omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)2843* @key: 128-bit key for the hash operation2844* @data: Data buffer for which a MAC is determined2845* @data_len: Length of data buffer in bytes2846* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)2847* Returns: 0 on success, -1 on failure2848*2849* This is a mode for using block cipher (AES in this case) for authentication.2850* OMAC1 was standardized with the name CMAC by NIST in a Special Publication2851* (SP) 800-38B.2852*/ /* modify for CONFIG_IEEE80211W */2853int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)2854{2855return omac1_aes_128_vector(key, 1, &data, &data_len, mac);2856}2857#endif /* PLATFORM_FREEBSD Baron */28582859#ifdef CONFIG_RTW_MESH_AEK2860/* for AES-SIV */2861#define os_memset _rtw_memset2862#define os_memcpy _rtw_memcpy2863#define os_malloc rtw_malloc2864#define bin_clear_free(bin, len) \2865do { \2866if (bin) { \2867os_memset(bin, 0, len); \2868rtw_mfree(bin, len); \2869} \2870} while (0)28712872static const u8 zero[AES_BLOCK_SIZE];28732874static void dbl(u8 *pad)2875{2876int i, carry;28772878carry = pad[0] & 0x80;2879for (i = 0; i < AES_BLOCK_SIZE - 1; i++)2880pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);2881pad[AES_BLOCK_SIZE - 1] <<= 1;2882if (carry)2883pad[AES_BLOCK_SIZE - 1] ^= 0x87;2884}28852886static void xor(u8 *a, const u8 *b)2887{2888int i;28892890for (i = 0; i < AES_BLOCK_SIZE; i++)2891*a++ ^= *b++;2892}28932894static void xorend(u8 *a, int alen, const u8 *b, int blen)2895{2896int i;28972898if (alen < blen)2899return;29002901for (i = 0; i < blen; i++)2902a[alen - blen + i] ^= b[i];2903}29042905static void pad_block(u8 *pad, const u8 *addr, size_t len)2906{2907os_memset(pad, 0, AES_BLOCK_SIZE);2908os_memcpy(pad, addr, len);29092910if (len < AES_BLOCK_SIZE)2911pad[len] = 0x80;2912}29132914static int aes_s2v(const u8 *key, size_t num_elem, const u8 *addr[],2915size_t *len, u8 *mac)2916{2917u8 tmp[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];2918u8 *buf = NULL;2919int ret;2920size_t i;29212922if (!num_elem) {2923os_memcpy(tmp, zero, sizeof(zero));2924tmp[AES_BLOCK_SIZE - 1] = 1;2925return omac1_aes_128(key, tmp, sizeof(tmp), mac);2926}29272928ret = omac1_aes_128(key, zero, sizeof(zero), tmp);2929if (ret)2930return ret;29312932for (i = 0; i < num_elem - 1; i++) {2933ret = omac1_aes_128(key, addr[i], len[i], tmp2);2934if (ret)2935return ret;29362937dbl(tmp);2938xor(tmp, tmp2);2939}2940if (len[i] >= AES_BLOCK_SIZE) {2941buf = os_malloc(len[i]);2942if (!buf)2943return -ENOMEM;29442945os_memcpy(buf, addr[i], len[i]);2946xorend(buf, len[i], tmp, AES_BLOCK_SIZE);2947ret = omac1_aes_128(key, buf, len[i], mac);2948bin_clear_free(buf, len[i]);2949return ret;2950}29512952dbl(tmp);2953pad_block(tmp2, addr[i], len[i]);2954xor(tmp, tmp2);29552956return omac1_aes_128(key, tmp, sizeof(tmp), mac);2957}29582959/**2960* aes_128_ctr_encrypt - AES-128 CTR mode encryption2961* @key: Key for encryption (16 bytes)2962* @nonce: Nonce for counter mode (16 bytes)2963* @data: Data to encrypt in-place2964* @data_len: Length of data in bytes2965* Returns: 0 on success, -1 on failure2966*/2967int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,2968u8 *data, size_t data_len)2969{2970void *ctx;2971size_t j, len, left = data_len;2972int i;2973u8 *pos = data;2974u8 counter[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE];29752976ctx = aes_encrypt_init(key, 16);2977if (ctx == NULL)2978return -1;2979os_memcpy(counter, nonce, AES_BLOCK_SIZE);29802981while (left > 0) {2982#if 02983aes_encrypt(ctx, counter, buf);2984#else2985aes_128_encrypt(ctx, counter, buf);2986#endif29872988len = (left < AES_BLOCK_SIZE) ? left : AES_BLOCK_SIZE;2989for (j = 0; j < len; j++)2990pos[j] ^= buf[j];2991pos += len;2992left -= len;29932994for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {2995counter[i]++;2996if (counter[i])2997break;2998}2999}3000aes_encrypt_deinit(ctx);3001return 0;3002}30033004int aes_siv_encrypt(const u8 *key, const u8 *pw,3005size_t pwlen, size_t num_elem,3006const u8 *addr[], const size_t *len, u8 *out)3007{3008const u8 *_addr[6];3009size_t _len[6];3010const u8 *k1 = key, *k2 = key + 16;3011u8 v[AES_BLOCK_SIZE];3012size_t i;3013u8 *iv, *crypt_pw;30143015if (num_elem > ARRAY_SIZE(_addr) - 1)3016return -1;30173018for (i = 0; i < num_elem; i++) {3019_addr[i] = addr[i];3020_len[i] = len[i];3021}3022_addr[num_elem] = pw;3023_len[num_elem] = pwlen;30243025if (aes_s2v(k1, num_elem + 1, _addr, _len, v))3026return -1;30273028iv = out;3029crypt_pw = out + AES_BLOCK_SIZE;30303031os_memcpy(iv, v, AES_BLOCK_SIZE);3032os_memcpy(crypt_pw, pw, pwlen);30333034/* zero out 63rd and 31st bits of ctr (from right) */3035v[8] &= 0x7f;3036v[12] &= 0x7f;3037return aes_128_ctr_encrypt(k2, v, crypt_pw, pwlen);3038}30393040int aes_siv_decrypt(const u8 *key, const u8 *iv_crypt, size_t iv_c_len,3041size_t num_elem, const u8 *addr[], const size_t *len,3042u8 *out)3043{3044const u8 *_addr[6];3045size_t _len[6];3046const u8 *k1 = key, *k2 = key + 16;3047size_t crypt_len;3048size_t i;3049int ret;3050u8 iv[AES_BLOCK_SIZE];3051u8 check[AES_BLOCK_SIZE];30523053if (iv_c_len < AES_BLOCK_SIZE || num_elem > ARRAY_SIZE(_addr) - 1)3054return -1;3055crypt_len = iv_c_len - AES_BLOCK_SIZE;30563057for (i = 0; i < num_elem; i++) {3058_addr[i] = addr[i];3059_len[i] = len[i];3060}3061_addr[num_elem] = out;3062_len[num_elem] = crypt_len;30633064os_memcpy(iv, iv_crypt, AES_BLOCK_SIZE);3065os_memcpy(out, iv_crypt + AES_BLOCK_SIZE, crypt_len);30663067iv[8] &= 0x7f;3068iv[12] &= 0x7f;30693070ret = aes_128_ctr_encrypt(k2, iv, out, crypt_len);3071if (ret)3072return ret;30733074ret = aes_s2v(k1, num_elem + 1, _addr, _len, check);3075if (ret)3076return ret;3077if (os_memcmp(check, iv_crypt, AES_BLOCK_SIZE) == 0)3078return 0;30793080return -1;3081}3082#endif /* CONFIG_RTW_MESH_AEK */30833084#ifdef CONFIG_TDLS3085void wpa_tdls_generate_tpk(_adapter *padapter, void *sta)3086{3087struct sta_info *psta = (struct sta_info *)sta;3088struct mlme_priv *pmlmepriv = &padapter->mlmepriv;3089u8 *SNonce = psta->SNonce;3090u8 *ANonce = psta->ANonce;30913092u8 key_input[SHA256_MAC_LEN];3093u8 *nonce[2];3094size_t len[2];3095u8 data[3 * ETH_ALEN];30963097/* IEEE Std 802.11z-2010 8.5.9.1:3098* TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce))3099*/3100len[0] = 32;3101len[1] = 32;3102if (os_memcmp(SNonce, ANonce, 32) < 0) {3103nonce[0] = SNonce;3104nonce[1] = ANonce;3105} else {3106nonce[0] = ANonce;3107nonce[1] = SNonce;3108}31093110sha256_vector(2, nonce, len, key_input);31113112/*3113* TPK-Key-Data = KDF-N_KEY(TPK-Key-Input, "TDLS PMK",3114* min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID || N_KEY)3115* TODO: is N_KEY really included in KDF Context and if so, in which3116* presentation format (little endian 16-bit?) is it used? It gets3117* added by the KDF anyway..3118*/31193120if (os_memcmp(adapter_mac_addr(padapter), psta->cmn.mac_addr, ETH_ALEN) < 0) {3121_rtw_memcpy(data, adapter_mac_addr(padapter), ETH_ALEN);3122_rtw_memcpy(data + ETH_ALEN, psta->cmn.mac_addr, ETH_ALEN);3123} else {3124_rtw_memcpy(data, psta->cmn.mac_addr, ETH_ALEN);3125_rtw_memcpy(data + ETH_ALEN, adapter_mac_addr(padapter), ETH_ALEN);3126}3127_rtw_memcpy(data + 2 * ETH_ALEN, get_bssid(pmlmepriv), ETH_ALEN);31283129sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data), (u8 *) &psta->tpk, sizeof(psta->tpk));313031313132}31333134/**3135* wpa_tdls_ftie_mic - Calculate TDLS FTIE MIC3136* @kck: TPK-KCK3137* @lnkid: Pointer to the beginning of Link Identifier IE3138* @rsnie: Pointer to the beginning of RSN IE used for handshake3139* @timeoutie: Pointer to the beginning of Timeout IE used for handshake3140* @ftie: Pointer to the beginning of FT IE3141* @mic: Pointer for writing MIC3142*3143* Calculate MIC for TDLS frame.3144*/3145int wpa_tdls_ftie_mic(u8 *kck, u8 trans_seq,3146u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie,3147u8 *mic)3148{3149u8 *buf, *pos;3150struct wpa_tdls_ftie *_ftie;3151struct wpa_tdls_lnkid *_lnkid;3152int ret;3153int len = 2 * ETH_ALEN + 1 + 2 + lnkid[1] + 2 + rsnie[1] +31542 + timeoutie[1] + 2 + ftie[1];3155buf = rtw_zmalloc(len);3156if (!buf) {3157RTW_INFO("TDLS: No memory for MIC calculation\n");3158return -1;3159}31603161pos = buf;3162_lnkid = (struct wpa_tdls_lnkid *) lnkid;3163/* 1) TDLS initiator STA MAC address */3164_rtw_memcpy(pos, _lnkid->init_sta, ETH_ALEN);3165pos += ETH_ALEN;3166/* 2) TDLS responder STA MAC address */3167_rtw_memcpy(pos, _lnkid->resp_sta, ETH_ALEN);3168pos += ETH_ALEN;3169/* 3) Transaction Sequence number */3170*pos++ = trans_seq;3171/* 4) Link Identifier IE */3172_rtw_memcpy(pos, lnkid, 2 + lnkid[1]);3173pos += 2 + lnkid[1];3174/* 5) RSN IE */3175_rtw_memcpy(pos, rsnie, 2 + rsnie[1]);3176pos += 2 + rsnie[1];3177/* 6) Timeout Interval IE */3178_rtw_memcpy(pos, timeoutie, 2 + timeoutie[1]);3179pos += 2 + timeoutie[1];3180/* 7) FTIE, with the MIC field of the FTIE set to 0 */3181_rtw_memcpy(pos, ftie, 2 + ftie[1]);3182_ftie = (struct wpa_tdls_ftie *) pos;3183_rtw_memset(_ftie->mic, 0, TDLS_MIC_LEN);3184pos += 2 + ftie[1];31853186ret = omac1_aes_128(kck, buf, pos - buf, mic);3187rtw_mfree(buf, len);3188return ret;31893190}31913192/**3193* wpa_tdls_teardown_ftie_mic - Calculate TDLS TEARDOWN FTIE MIC3194* @kck: TPK-KCK3195* @lnkid: Pointer to the beginning of Link Identifier IE3196* @reason: Reason code of TDLS Teardown3197* @dialog_token: Dialog token that was used in the MIC calculation for TPK Handshake Message 33198* @trans_seq: Transaction Sequence number (1 octet) which shall be set to the value 43199* @ftie: Pointer to the beginning of FT IE3200* @mic: Pointer for writing MIC3201*3202* Calculate MIC for TDLS TEARDOWN frame according to Section 10.22.5 in IEEE 802.11 - 2012.3203*/3204int wpa_tdls_teardown_ftie_mic(u8 *kck, u8 *lnkid, u16 reason,3205u8 dialog_token, u8 trans_seq, u8 *ftie, u8 *mic)3206{3207u8 *buf, *pos;3208struct wpa_tdls_ftie *_ftie;3209int ret;3210int len = 2 + lnkid[1] + 2 + 1 + 1 + 2 + ftie[1];32113212buf = rtw_zmalloc(len);3213if (!buf) {3214RTW_INFO("TDLS: No memory for MIC calculation\n");3215return -1;3216}32173218pos = buf;3219/* 1) Link Identifier IE */3220_rtw_memcpy(pos, lnkid, 2 + lnkid[1]);3221pos += 2 + lnkid[1];3222/* 2) Reason Code */3223_rtw_memcpy(pos, (u8 *)&reason, 2);3224pos += 2;3225/* 3) Dialog Token */3226*pos++ = dialog_token;3227/* 4) Transaction Sequence number */3228*pos++ = trans_seq;3229/* 5) FTIE, with the MIC field of the FTIE set to 0 */3230_rtw_memcpy(pos, ftie, 2 + ftie[1]);3231_ftie = (struct wpa_tdls_ftie *) pos;3232_rtw_memset(_ftie->mic, 0, TDLS_MIC_LEN);3233pos += 2 + ftie[1];32343235ret = omac1_aes_128(kck, buf, pos - buf, mic);3236rtw_mfree(buf, len);3237return ret;32383239}32403241int tdls_verify_mic(u8 *kck, u8 trans_seq,3242u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie)3243{3244u8 *buf, *pos;3245int len;3246u8 mic[16];3247int ret;3248u8 *rx_ftie, *tmp_ftie;32493250if (lnkid == NULL || rsnie == NULL ||3251timeoutie == NULL || ftie == NULL)3252return _FAIL;32533254len = 2 * ETH_ALEN + 1 + 2 + 18 + 2 + *(rsnie + 1) + 2 + *(timeoutie + 1) + 2 + *(ftie + 1);32553256buf = rtw_zmalloc(len);3257if (buf == NULL)3258return _FAIL;32593260pos = buf;3261/* 1) TDLS initiator STA MAC address */3262_rtw_memcpy(pos, lnkid + ETH_ALEN + 2, ETH_ALEN);3263pos += ETH_ALEN;3264/* 2) TDLS responder STA MAC address */3265_rtw_memcpy(pos, lnkid + 2 * ETH_ALEN + 2, ETH_ALEN);3266pos += ETH_ALEN;3267/* 3) Transaction Sequence number */3268*pos++ = trans_seq;3269/* 4) Link Identifier IE */3270_rtw_memcpy(pos, lnkid, 2 + 18);3271pos += 2 + 18;3272/* 5) RSN IE */3273_rtw_memcpy(pos, rsnie, 2 + *(rsnie + 1));3274pos += 2 + *(rsnie + 1);3275/* 6) Timeout Interval IE */3276_rtw_memcpy(pos, timeoutie, 2 + *(timeoutie + 1));3277pos += 2 + *(timeoutie + 1);3278/* 7) FTIE, with the MIC field of the FTIE set to 0 */3279_rtw_memcpy(pos, ftie, 2 + *(ftie + 1));3280pos += 2;3281tmp_ftie = (u8 *)(pos + 2);3282_rtw_memset(tmp_ftie, 0, 16);3283pos += *(ftie + 1);32843285ret = omac1_aes_128(kck, buf, pos - buf, mic);3286rtw_mfree(buf, len);3287if (ret)3288return _FAIL;3289rx_ftie = ftie + 4;32903291if (os_memcmp(mic, rx_ftie, 16) == 0) {3292/* Valid MIC */3293return _SUCCESS;3294}32953296/* Invalid MIC */3297RTW_INFO("[%s] Invalid MIC\n", __FUNCTION__);3298return _FAIL;32993300}3301#endif /* CONFIG_TDLS */33023303/* Restore HW wep key setting according to key_mask */3304void rtw_sec_restore_wep_key(_adapter *adapter)3305{3306struct security_priv *securitypriv = &(adapter->securitypriv);3307sint keyid;33083309if ((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) || (_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) {3310for (keyid = 0; keyid < 4; keyid++) {3311if (securitypriv->key_mask & BIT(keyid)) {3312if (keyid == securitypriv->dot11PrivacyKeyIndex)3313rtw_set_key(adapter, securitypriv, keyid, 1, _FALSE);3314else3315rtw_set_key(adapter, securitypriv, keyid, 0, _FALSE);3316}3317}3318}3319}33203321u8 rtw_handle_tkip_countermeasure(_adapter *adapter, const char *caller)3322{3323struct security_priv *securitypriv = &(adapter->securitypriv);3324u8 status = _SUCCESS;33253326if (securitypriv->btkip_countermeasure == _TRUE) {3327u32 passing_ms = rtw_get_passing_time_ms(securitypriv->btkip_countermeasure_time);3328if (passing_ms > 60 * 1000) {3329RTW_PRINT("%s("ADPT_FMT") countermeasure time:%ds > 60s\n",3330caller, ADPT_ARG(adapter), passing_ms / 1000);3331securitypriv->btkip_countermeasure = _FALSE;3332securitypriv->btkip_countermeasure_time = 0;3333} else {3334RTW_PRINT("%s("ADPT_FMT") countermeasure time:%ds < 60s\n",3335caller, ADPT_ARG(adapter), passing_ms / 1000);3336status = _FAIL;3337}3338}33393340return status;3341}33423343#ifdef CONFIG_WOWLAN3344u16 rtw_cal_crc16(u8 data, u16 crc)3345{3346u8 shift_in, data_bit;3347u8 crc_bit4, crc_bit11, crc_bit15;3348u16 crc_result;3349int index;33503351for (index = 0; index < 8; index++) {3352crc_bit15 = ((crc & BIT15) ? 1 : 0);3353data_bit = (data & (BIT0 << index) ? 1 : 0);3354shift_in = crc_bit15 ^ data_bit;3355/*printf("crc_bit15=%d, DataBit=%d, shift_in=%d\n",3356* crc_bit15, data_bit, shift_in);*/33573358crc_result = crc << 1;33593360if (shift_in == 0)3361crc_result &= (~BIT0);3362else3363crc_result |= BIT0;3364/*printf("CRC =%x\n",CRC_Result);*/33653366crc_bit11 = ((crc & BIT11) ? 1 : 0) ^ shift_in;33673368if (crc_bit11 == 0)3369crc_result &= (~BIT12);3370else3371crc_result |= BIT12;33723373/*printf("bit12 CRC =%x\n",CRC_Result);*/33743375crc_bit4 = ((crc & BIT4) ? 1 : 0) ^ shift_in;33763377if (crc_bit4 == 0)3378crc_result &= (~BIT5);3379else3380crc_result |= BIT5;33813382/* printf("bit5 CRC =%x\n",CRC_Result); */3383/* repeat using the last result*/3384crc = crc_result;3385}3386return crc;3387}33883389/*3390* function name :rtw_calc_crc3391*3392* input: char* pattern , pattern size3393*3394*/3395u16 rtw_calc_crc(u8 *pdata, int length)3396{3397u16 crc = 0xffff;3398int i;33993400for (i = 0; i < length; i++)3401crc = rtw_cal_crc16(pdata[i], crc);3402/* get 1' complement */3403crc = ~crc;34043405return crc;3406}3407#endif /*CONFIG_WOWLAN*/340834093410