linux/drivers/staging/rtl8723bs/core/rtw_security.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   5 *
   6 ******************************************************************************/
   7#define  _RTW_SECURITY_C_
   8
   9#include <linux/crc32poly.h>
  10#include <drv_types.h>
  11#include <rtw_debug.h>
  12
  13static const char *_security_type_str[] = {
  14        "N/A",
  15        "WEP40",
  16        "TKIP",
  17        "TKIP_WM",
  18        "AES",
  19        "WEP104",
  20        "SMS4",
  21        "WEP_WPA",
  22        "BIP",
  23};
  24
  25const char *security_type_str(u8 value)
  26{
  27        if (value <= _BIP_)
  28                return _security_type_str[value];
  29        return NULL;
  30}
  31
  32#ifdef DBG_SW_SEC_CNT
  33#define WEP_SW_ENC_CNT_INC(sec, ra) \
  34        if (is_broadcast_mac_addr(ra)) \
  35                sec->wep_sw_enc_cnt_bc++; \
  36        else if (is_multicast_mac_addr(ra)) \
  37                sec->wep_sw_enc_cnt_mc++; \
  38        else \
  39                sec->wep_sw_enc_cnt_uc++;
  40
  41#define WEP_SW_DEC_CNT_INC(sec, ra) \
  42        if (is_broadcast_mac_addr(ra)) \
  43                sec->wep_sw_dec_cnt_bc++; \
  44        else if (is_multicast_mac_addr(ra)) \
  45                sec->wep_sw_dec_cnt_mc++; \
  46        else \
  47                sec->wep_sw_dec_cnt_uc++;
  48
  49#define TKIP_SW_ENC_CNT_INC(sec, ra) \
  50        if (is_broadcast_mac_addr(ra)) \
  51                sec->tkip_sw_enc_cnt_bc++; \
  52        else if (is_multicast_mac_addr(ra)) \
  53                sec->tkip_sw_enc_cnt_mc++; \
  54        else \
  55                sec->tkip_sw_enc_cnt_uc++;
  56
  57#define TKIP_SW_DEC_CNT_INC(sec, ra) \
  58        if (is_broadcast_mac_addr(ra)) \
  59                sec->tkip_sw_dec_cnt_bc++; \
  60        else if (is_multicast_mac_addr(ra)) \
  61                sec->tkip_sw_dec_cnt_mc++; \
  62        else \
  63                sec->tkip_sw_dec_cnt_uc++;
  64
  65#define AES_SW_ENC_CNT_INC(sec, ra) \
  66        if (is_broadcast_mac_addr(ra)) \
  67                sec->aes_sw_enc_cnt_bc++; \
  68        else if (is_multicast_mac_addr(ra)) \
  69                sec->aes_sw_enc_cnt_mc++; \
  70        else \
  71                sec->aes_sw_enc_cnt_uc++;
  72
  73#define AES_SW_DEC_CNT_INC(sec, ra) \
  74        if (is_broadcast_mac_addr(ra)) \
  75                sec->aes_sw_dec_cnt_bc++; \
  76        else if (is_multicast_mac_addr(ra)) \
  77                sec->aes_sw_dec_cnt_mc++; \
  78        else \
  79                sec->aes_sw_dec_cnt_uc++;
  80#else
  81#define WEP_SW_ENC_CNT_INC(sec, ra)
  82#define WEP_SW_DEC_CNT_INC(sec, ra)
  83#define TKIP_SW_ENC_CNT_INC(sec, ra)
  84#define TKIP_SW_DEC_CNT_INC(sec, ra)
  85#define AES_SW_ENC_CNT_INC(sec, ra)
  86#define AES_SW_DEC_CNT_INC(sec, ra)
  87#endif /* DBG_SW_SEC_CNT */
  88
  89/* WEP related ===== */
  90
  91struct arc4context {
  92        u32 x;
  93        u32 y;
  94        u8 state[256];
  95};
  96
  97
  98static void arcfour_init(struct arc4context     *parc4ctx, u8 *key, u32 key_len)
  99{
 100        u32 t, u;
 101        u32 keyindex;
 102        u32 stateindex;
 103        u8 *state;
 104        u32 counter;
 105
 106        state = parc4ctx->state;
 107        parc4ctx->x = 0;
 108        parc4ctx->y = 0;
 109        for (counter = 0; counter < 256; counter++)
 110                state[counter] = (u8)counter;
 111        keyindex = 0;
 112        stateindex = 0;
 113        for (counter = 0; counter < 256; counter++) {
 114                t = state[counter];
 115                stateindex = (stateindex + key[keyindex] + t) & 0xff;
 116                u = state[stateindex];
 117                state[stateindex] = (u8)t;
 118                state[counter] = (u8)u;
 119                if (++keyindex >= key_len)
 120                        keyindex = 0;
 121        }
 122}
 123
 124static u32 arcfour_byte(struct arc4context      *parc4ctx)
 125{
 126        u32 x;
 127        u32 y;
 128        u32 sx, sy;
 129        u8 *state;
 130
 131        state = parc4ctx->state;
 132        x = (parc4ctx->x + 1) & 0xff;
 133        sx = state[x];
 134        y = (sx + parc4ctx->y) & 0xff;
 135        sy = state[y];
 136        parc4ctx->x = x;
 137        parc4ctx->y = y;
 138        state[y] = (u8)sx;
 139        state[x] = (u8)sy;
 140        return state[(sx + sy) & 0xff];
 141}
 142
 143static void arcfour_encrypt(
 144        struct arc4context *parc4ctx,
 145        u8 *dest,
 146        u8 *src,
 147        u32 len
 148)
 149{
 150        u32 i;
 151
 152        for (i = 0; i < len; i++)
 153                dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
 154}
 155
 156static sint bcrc32initialized;
 157static u32 crc32_table[256];
 158
 159
 160static u8 crc32_reverseBit(u8 data)
 161{
 162        return((u8)((data<<7)&0x80) | ((data<<5)&0x40) | ((data<<3)&0x20) | ((data<<1)&0x10) | ((data>>1)&0x08) | ((data>>3)&0x04) | ((data>>5)&0x02) | ((data>>7)&0x01));
 163}
 164
 165static void crc32_init(void)
 166{
 167        if (bcrc32initialized == 1)
 168                return;
 169        else {
 170                sint i, j;
 171                u32 c;
 172                u8 *p = (u8 *)&c, *p1;
 173                u8 k;
 174
 175                c = 0x12340000;
 176
 177                for (i = 0; i < 256; ++i) {
 178                        k = crc32_reverseBit((u8)i);
 179                        for (c = ((u32)k) << 24, j = 8; j > 0; --j) {
 180                                c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY_BE : (c << 1);
 181                        }
 182                        p1 = (u8 *)&crc32_table[i];
 183
 184                        p1[0] = crc32_reverseBit(p[3]);
 185                        p1[1] = crc32_reverseBit(p[2]);
 186                        p1[2] = crc32_reverseBit(p[1]);
 187                        p1[3] = crc32_reverseBit(p[0]);
 188                }
 189                bcrc32initialized = 1;
 190        }
 191}
 192
 193static __le32 getcrc32(u8 *buf, sint len)
 194{
 195        u8 *p;
 196        u32  crc;
 197
 198        if (bcrc32initialized == 0)
 199                crc32_init();
 200
 201        crc = 0xffffffff;       /* preload shift register, per CRC-32 spec */
 202
 203        for (p = buf; len > 0; ++p, --len) {
 204                crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
 205        }
 206        return cpu_to_le32(~crc);    /* transmit complement, per CRC-32 spec */
 207}
 208
 209
 210/*
 211        Need to consider the fragment  situation
 212*/
 213void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
 214{                                                                                                                                       /*  exclude ICV */
 215
 216        unsigned char crc[4];
 217        struct arc4context       mycontext;
 218
 219        sint    curfragnum, length;
 220        u32 keylength;
 221
 222        u8 *pframe, *payload, *iv;    /* wepkey */
 223        u8 wepkey[16];
 224        u8   hw_hdr_offset = 0;
 225        struct  pkt_attrib       *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
 226        struct  security_priv *psecuritypriv = &padapter->securitypriv;
 227        struct  xmit_priv       *pxmitpriv = &padapter->xmitpriv;
 228
 229        if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
 230                return;
 231
 232        hw_hdr_offset = TXDESC_OFFSET;
 233        pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
 234
 235        /* start to encrypt each fragment */
 236        if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
 237                keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex];
 238
 239                for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
 240                        iv = pframe+pattrib->hdrlen;
 241                        memcpy(&wepkey[0], iv, 3);
 242                        memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength);
 243                        payload = pframe+pattrib->iv_len+pattrib->hdrlen;
 244
 245                        if ((curfragnum+1) == pattrib->nr_frags) {      /* the last fragment */
 246
 247                                length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
 248
 249                                *((__le32 *)crc) = getcrc32(payload, length);
 250
 251                                arcfour_init(&mycontext, wepkey, 3+keylength);
 252                                arcfour_encrypt(&mycontext, payload, payload, length);
 253                                arcfour_encrypt(&mycontext, payload+length, crc, 4);
 254
 255                        } else {
 256                                length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
 257                                *((__le32 *)crc) = getcrc32(payload, length);
 258                                arcfour_init(&mycontext, wepkey, 3+keylength);
 259                                arcfour_encrypt(&mycontext, payload, payload, length);
 260                                arcfour_encrypt(&mycontext, payload+length, crc, 4);
 261
 262                                pframe += pxmitpriv->frag_len;
 263                                pframe = (u8 *)RND4((SIZE_PTR)(pframe));
 264                        }
 265                }
 266
 267                WEP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);
 268        }
 269}
 270
 271void rtw_wep_decrypt(struct adapter  *padapter, u8 *precvframe)
 272{
 273        /*  exclude ICV */
 274        u8 crc[4];
 275        struct arc4context       mycontext;
 276        sint    length;
 277        u32 keylength;
 278        u8 *pframe, *payload, *iv, wepkey[16];
 279        u8  keyindex;
 280        struct  rx_pkt_attrib    *prxattrib = &(((union recv_frame *)precvframe)->u.hdr.attrib);
 281        struct  security_priv *psecuritypriv = &padapter->securitypriv;
 282
 283        pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
 284
 285        /* start to decrypt recvframe */
 286        if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
 287                iv = pframe+prxattrib->hdrlen;
 288                /* keyindex =(iv[3]&0x3); */
 289                keyindex = prxattrib->key_index;
 290                keylength = psecuritypriv->dot11DefKeylen[keyindex];
 291                memcpy(&wepkey[0], iv, 3);
 292                /* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
 293                memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
 294                length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
 295
 296                payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
 297
 298                /* decrypt payload include icv */
 299                arcfour_init(&mycontext, wepkey, 3+keylength);
 300                arcfour_encrypt(&mycontext, payload, payload,  length);
 301
 302                /* calculate icv and compare the icv */
 303                *((u32 *)crc) = le32_to_cpu(getcrc32(payload, length-4));
 304
 305                if (crc[3] != payload[length-1] || crc[2] != payload[length-2] || crc[1] != payload[length-3] || crc[0] != payload[length-4]) {
 306                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_wep_decrypt:icv error crc[3](%x)!=payload[length-1](%x) || crc[2](%x)!=payload[length-2](%x) || crc[1](%x)!=payload[length-3](%x) || crc[0](%x)!=payload[length-4](%x)\n",
 307                                                crc[3], payload[length-1], crc[2], payload[length-2], crc[1], payload[length-3], crc[0], payload[length-4]));
 308                }
 309
 310                WEP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);
 311        }
 312        return;
 313}
 314
 315/* 3            =====TKIP related ===== */
 316
 317static u32 secmicgetuint32(u8 *p)
 318/*  Convert from Byte[] to Us3232 in a portable way */
 319{
 320        s32 i;
 321        u32 res = 0;
 322
 323        for (i = 0; i < 4; i++) {
 324                res |= ((u32)(*p++)) << (8*i);
 325        }
 326
 327        return res;
 328}
 329
 330static void secmicputuint32(u8 *p, u32 val)
 331/*  Convert from Us3232 to Byte[] in a portable way */
 332{
 333        long i;
 334
 335        for (i = 0; i < 4; i++) {
 336                *p++ = (u8) (val & 0xff);
 337                val >>= 8;
 338        }
 339}
 340
 341static void secmicclear(struct mic_data *pmicdata)
 342{
 343/*  Reset the state to the empty message. */
 344        pmicdata->L = pmicdata->K0;
 345        pmicdata->R = pmicdata->K1;
 346        pmicdata->nBytesInM = 0;
 347        pmicdata->M = 0;
 348}
 349
 350void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
 351{
 352        /*  Set the key */
 353        pmicdata->K0 = secmicgetuint32(key);
 354        pmicdata->K1 = secmicgetuint32(key + 4);
 355        /*  and reset the message */
 356        secmicclear(pmicdata);
 357}
 358
 359void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
 360{
 361        /*  Append the byte to our word-sized buffer */
 362        pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM);
 363        pmicdata->nBytesInM++;
 364        /*  Process the word if it is full. */
 365        if (pmicdata->nBytesInM >= 4) {
 366                pmicdata->L ^= pmicdata->M;
 367                pmicdata->R ^= ROL32(pmicdata->L, 17);
 368                pmicdata->L += pmicdata->R;
 369                pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
 370                pmicdata->L += pmicdata->R;
 371                pmicdata->R ^= ROL32(pmicdata->L, 3);
 372                pmicdata->L += pmicdata->R;
 373                pmicdata->R ^= ROR32(pmicdata->L, 2);
 374                pmicdata->L += pmicdata->R;
 375                /*  Clear the buffer */
 376                pmicdata->M = 0;
 377                pmicdata->nBytesInM = 0;
 378        }
 379}
 380
 381void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)
 382{
 383        /*  This is simple */
 384        while (nbytes > 0) {
 385                rtw_secmicappendbyte(pmicdata, *src++);
 386                nbytes--;
 387        }
 388}
 389
 390void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst)
 391{
 392        /*  Append the minimum padding */
 393        rtw_secmicappendbyte(pmicdata, 0x5a);
 394        rtw_secmicappendbyte(pmicdata, 0);
 395        rtw_secmicappendbyte(pmicdata, 0);
 396        rtw_secmicappendbyte(pmicdata, 0);
 397        rtw_secmicappendbyte(pmicdata, 0);
 398        /*  and then zeroes until the length is a multiple of 4 */
 399        while (pmicdata->nBytesInM != 0) {
 400                rtw_secmicappendbyte(pmicdata, 0);
 401        }
 402        /*  The appendByte function has already computed the result. */
 403        secmicputuint32(dst, pmicdata->L);
 404        secmicputuint32(dst+4, pmicdata->R);
 405        /*  Reset to the empty message. */
 406        secmicclear(pmicdata);
 407}
 408
 409
 410void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri)
 411{
 412
 413        struct mic_data micdata;
 414        u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
 415
 416        rtw_secmicsetkey(&micdata, key);
 417        priority[0] = pri;
 418
 419        /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
 420        if (header[1]&1) {   /* ToDS == 1 */
 421                rtw_secmicappend(&micdata, &header[16], 6);  /* DA */
 422                if (header[1]&2)  /* From Ds == 1 */
 423                        rtw_secmicappend(&micdata, &header[24], 6);
 424                else
 425                        rtw_secmicappend(&micdata, &header[10], 6);
 426        } else {        /* ToDS == 0 */
 427                rtw_secmicappend(&micdata, &header[4], 6);   /* DA */
 428                if (header[1]&2)  /* From Ds == 1 */
 429                        rtw_secmicappend(&micdata, &header[16], 6);
 430                else
 431                        rtw_secmicappend(&micdata, &header[10], 6);
 432
 433        }
 434        rtw_secmicappend(&micdata, &priority[0], 4);
 435
 436
 437        rtw_secmicappend(&micdata, data, data_len);
 438
 439        rtw_secgetmic(&micdata, mic_code);
 440}
 441
 442/* macros for extraction/creation of unsigned char/unsigned short values  */
 443#define RotR1(v16)   ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
 444#define   Lo8(v16)   ((u8)((v16)       & 0x00FF))
 445#define   Hi8(v16)   ((u8)(((v16) >> 8) & 0x00FF))
 446#define  Lo16(v32)   ((u16)((v32)       & 0xFFFF))
 447#define  Hi16(v32)   ((u16)(((v32) >> 16) & 0xFFFF))
 448#define  Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
 449
 450/* select the Nth 16-bit word of the temporal key unsigned char array TK[]   */
 451#define  TK16(N)     Mk16(tk[2*(N)+1], tk[2*(N)])
 452
 453/* S-box lookup: 16 bits --> 16 bits */
 454#define _S_(v16)     (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
 455
 456/* fixed algorithm "parameters" */
 457#define PHASE1_LOOP_CNT   8    /* this needs to be "big enough"     */
 458#define TA_SIZE           6    /*  48-bit transmitter address       */
 459#define TK_SIZE          16    /* 128-bit temporal key              */
 460#define P1K_SIZE         10    /*  80-bit Phase1 key                */
 461#define RC4_KEY_SIZE     16    /* 128-bit RC4KEY (104 bits unknown) */
 462
 463
 464/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
 465static const unsigned short Sbox1[2][256] = {      /* Sbox for hash (can be in ROM)     */
 466{
 467         0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
 468         0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
 469         0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
 470         0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
 471         0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
 472         0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
 473         0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
 474         0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
 475         0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
 476         0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
 477         0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
 478         0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
 479         0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
 480         0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
 481         0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
 482         0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
 483         0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
 484         0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
 485         0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
 486         0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
 487         0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
 488         0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
 489         0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
 490         0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
 491         0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
 492         0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
 493         0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
 494         0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
 495         0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
 496         0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
 497         0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
 498         0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
 499        },
 500
 501
 502        {  /* second half of table is unsigned char-reversed version of first! */
 503         0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
 504         0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
 505         0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
 506         0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
 507         0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
 508         0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
 509         0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
 510         0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
 511         0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
 512         0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
 513         0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
 514         0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
 515         0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
 516         0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
 517         0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
 518         0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
 519         0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
 520         0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
 521         0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
 522         0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
 523         0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
 524         0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
 525         0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
 526         0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
 527         0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
 528         0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
 529         0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
 530         0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
 531         0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
 532         0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
 533         0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
 534         0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
 535        }
 536};
 537
 538 /*
 539**********************************************************************
 540* Routine: Phase 1 -- generate P1K, given TA, TK, IV32
 541*
 542* Inputs:
 543*     tk[]      = temporal key                         [128 bits]
 544*     ta[]      = transmitter's MAC address            [ 48 bits]
 545*     iv32      = upper 32 bits of IV                  [ 32 bits]
 546* Output:
 547*     p1k[]     = Phase 1 key                          [ 80 bits]
 548*
 549* Note:
 550*     This function only needs to be called every 2**16 packets,
 551*     although in theory it could be called every packet.
 552*
 553**********************************************************************
 554*/
 555static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
 556{
 557        sint  i;
 558
 559        /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5]     */
 560        p1k[0]      = Lo16(iv32);
 561        p1k[1]      = Hi16(iv32);
 562        p1k[2]      = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
 563        p1k[3]      = Mk16(ta[3], ta[2]);
 564        p1k[4]      = Mk16(ta[5], ta[4]);
 565
 566        /* Now compute an unbalanced Feistel cipher with 80-bit block */
 567        /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
 568        for (i = 0; i < PHASE1_LOOP_CNT; i++) {
 569                /* Each add operation here is mod 2**16 */
 570                p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0));
 571                p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2));
 572                p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4));
 573                p1k[3] += _S_(p1k[2] ^ TK16((i&1)+6));
 574                p1k[4] += _S_(p1k[3] ^ TK16((i&1)+0));
 575                p1k[4] +=  (unsigned short)i;          /* avoid "slide attacks" */
 576        }
 577}
 578
 579
 580/*
 581**********************************************************************
 582* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
 583*
 584* Inputs:
 585*     tk[]      = Temporal key                         [128 bits]
 586*     p1k[]     = Phase 1 output key                   [ 80 bits]
 587*     iv16      = low 16 bits of IV counter            [ 16 bits]
 588* Output:
 589*     rc4key[]  = the key used to encrypt the packet   [128 bits]
 590*
 591* Note:
 592*     The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
 593*     across all packets using the same key TK value. Then, for a
 594*     given value of TK[], this TKIP48 construction guarantees that
 595*     the final RC4KEY value is unique across all packets.
 596*
 597* Suggested implementation optimization: if PPK[] is "overlaid"
 598*     appropriately on RC4KEY[], there is no need for the final
 599*     for loop below that copies the PPK[] result into RC4KEY[].
 600*
 601**********************************************************************
 602*/
 603static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
 604{
 605        sint  i;
 606        u16 PPK[6];                          /* temporary key for mixing    */
 607
 608        /* Note: all adds in the PPK[] equations below are mod 2**16         */
 609        for (i = 0; i < 5; i++)
 610                PPK[i] = p1k[i];      /* first, copy P1K to PPK      */
 611
 612        PPK[5]  =  p1k[4]+iv16;             /* next,  add in IV16          */
 613
 614        /* Bijective non-linear mixing of the 96 bits of PPK[0..5]           */
 615        PPK[0] +=    _S_(PPK[5] ^ TK16(0));   /* Mix key in each "round"     */
 616        PPK[1] +=    _S_(PPK[0] ^ TK16(1));
 617        PPK[2] +=    _S_(PPK[1] ^ TK16(2));
 618        PPK[3] +=    _S_(PPK[2] ^ TK16(3));
 619        PPK[4] +=    _S_(PPK[3] ^ TK16(4));
 620        PPK[5] +=    _S_(PPK[4] ^ TK16(5));   /* Total # S-box lookups == 6  */
 621
 622        /* Final sweep: bijective, "linear". Rotates kill LSB correlations   */
 623        PPK[0] +=  RotR1(PPK[5] ^ TK16(6));
 624        PPK[1] +=  RotR1(PPK[0] ^ TK16(7));   /* Use all of TK[] in Phase2   */
 625        PPK[2] +=  RotR1(PPK[1]);
 626        PPK[3] +=  RotR1(PPK[2]);
 627        PPK[4] +=  RotR1(PPK[3]);
 628        PPK[5] +=  RotR1(PPK[4]);
 629        /* Note: At this point, for a given key TK[0..15], the 96-bit output */
 630        /*       value PPK[0..5] is guaranteed to be unique, as a function   */
 631        /*       of the 96-bit "input" value   {TA, IV32, IV16}. That is, P1K  */
 632        /*       is now a keyed permutation of {TA, IV32, IV16}.               */
 633
 634        /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key   */
 635        rc4key[0] = Hi8(iv16);                /* RC4KEY[0..2] is the WEP IV  */
 636        rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys  */
 637        rc4key[2] = Lo8(iv16);
 638        rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
 639
 640
 641        /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15]  (little-endian)       */
 642        for (i = 0; i < 6; i++) {
 643                rc4key[4+2*i] = Lo8(PPK[i]);
 644                rc4key[5+2*i] = Hi8(PPK[i]);
 645        }
 646}
 647
 648
 649/* The hlen isn't include the IV */
 650u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
 651{                                                                                                                                       /*  exclude ICV */
 652        u16 pnl;
 653        u32 pnh;
 654        u8 rc4key[16];
 655        u8   ttkey[16];
 656        u8 crc[4];
 657        u8   hw_hdr_offset = 0;
 658        struct arc4context mycontext;
 659        sint                    curfragnum, length;
 660        u32 prwskeylen;
 661
 662        u8 *pframe, *payload, *iv, *prwskey;
 663        union pn48 dot11txpn;
 664        /* struct       sta_info        *stainfo; */
 665        struct  pkt_attrib       *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
 666        struct  security_priv *psecuritypriv = &padapter->securitypriv;
 667        struct  xmit_priv       *pxmitpriv = &padapter->xmitpriv;
 668        u32 res = _SUCCESS;
 669
 670        if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
 671                return _FAIL;
 672
 673        hw_hdr_offset = TXDESC_OFFSET;
 674        pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
 675
 676        /* 4 start to encrypt each fragment */
 677        if (pattrib->encrypt == _TKIP_) {
 678
 679/*
 680                if (pattrib->psta)
 681                {
 682                        stainfo = pattrib->psta;
 683                }
 684                else
 685                {
 686                        DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
 687                        stainfo =rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
 688                }
 689*/
 690                /* if (stainfo!= NULL) */
 691                {
 692/*
 693                        if (!(stainfo->state &_FW_LINKED))
 694                        {
 695                                DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);
 696                                return _FAIL;
 697                        }
 698*/
 699                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_encrypt: stainfo!= NULL!!!\n"));
 700
 701                        if (IS_MCAST(pattrib->ra))
 702                                prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
 703                        else
 704                                /* prwskey =&stainfo->dot118021x_UncstKey.skey[0]; */
 705                                prwskey = pattrib->dot118021x_UncstKey.skey;
 706
 707                        prwskeylen = 16;
 708
 709                        for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
 710                                iv = pframe+pattrib->hdrlen;
 711                                payload = pframe+pattrib->iv_len+pattrib->hdrlen;
 712
 713                                GET_TKIP_PN(iv, dot11txpn);
 714
 715                                pnl = (u16)(dot11txpn.val);
 716                                pnh = (u32)(dot11txpn.val>>16);
 717
 718                                phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
 719
 720                                phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
 721
 722                                if ((curfragnum+1) == pattrib->nr_frags) {      /* 4 the last fragment */
 723                                        length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
 724                                        RT_TRACE(_module_rtl871x_security_c_, _drv_info_, ("pattrib->iv_len =%x, pattrib->icv_len =%x\n", pattrib->iv_len, pattrib->icv_len));
 725                                        *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
 726
 727                                        arcfour_init(&mycontext, rc4key, 16);
 728                                        arcfour_encrypt(&mycontext, payload, payload, length);
 729                                        arcfour_encrypt(&mycontext, payload+length, crc, 4);
 730
 731                                } else {
 732                                        length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
 733                                        *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
 734                                        arcfour_init(&mycontext, rc4key, 16);
 735                                        arcfour_encrypt(&mycontext, payload, payload, length);
 736                                        arcfour_encrypt(&mycontext, payload+length, crc, 4);
 737
 738                                        pframe += pxmitpriv->frag_len;
 739                                        pframe = (u8 *)RND4((SIZE_PTR)(pframe));
 740                                }
 741                        }
 742
 743                        TKIP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);
 744                }
 745/*
 746                else {
 747                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_encrypt: stainfo == NULL!!!\n"));
 748                        DBG_871X("%s, psta ==NUL\n", __func__);
 749                        res = _FAIL;
 750                }
 751*/
 752
 753        }
 754        return res;
 755}
 756
 757
 758/* The hlen isn't include the IV */
 759u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)
 760{                                                                                                                                       /*  exclude ICV */
 761        u16 pnl;
 762        u32 pnh;
 763        u8   rc4key[16];
 764        u8   ttkey[16];
 765        u8 crc[4];
 766        struct arc4context mycontext;
 767        sint                    length;
 768        u32 prwskeylen;
 769
 770        u8 *pframe, *payload, *iv, *prwskey;
 771        union pn48 dot11txpn;
 772        struct  sta_info        *stainfo;
 773        struct  rx_pkt_attrib    *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
 774        struct  security_priv *psecuritypriv = &padapter->securitypriv;
 775/*      struct  recv_priv       *precvpriv =&padapter->recvpriv; */
 776        u32     res = _SUCCESS;
 777
 778        pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
 779
 780        /* 4 start to decrypt recvframe */
 781        if (prxattrib->encrypt == _TKIP_) {
 782                stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
 783                if (stainfo != NULL) {
 784                        if (IS_MCAST(prxattrib->ra)) {
 785                                static unsigned long start;
 786                                static u32 no_gkey_bc_cnt;
 787                                static u32 no_gkey_mc_cnt;
 788
 789                                if (psecuritypriv->binstallGrpkey == false) {
 790                                        res = _FAIL;
 791
 792                                        if (start == 0)
 793                                                start = jiffies;
 794
 795                                        if (is_broadcast_mac_addr(prxattrib->ra))
 796                                                no_gkey_bc_cnt++;
 797                                        else
 798                                                no_gkey_mc_cnt++;
 799
 800                                        if (jiffies_to_msecs(jiffies - start) > 1000) {
 801                                                if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
 802                                                        DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
 803                                                                FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
 804                                                }
 805                                                start = jiffies;
 806                                                no_gkey_bc_cnt = 0;
 807                                                no_gkey_mc_cnt = 0;
 808                                        }
 809                                        goto exit;
 810                                }
 811
 812                                if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
 813                                        DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
 814                                                FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
 815                                }
 816                                start = 0;
 817                                no_gkey_bc_cnt = 0;
 818                                no_gkey_mc_cnt = 0;
 819
 820                                /* DBG_871X("rx bc/mc packets, to perform sw rtw_tkip_decrypt\n"); */
 821                                /* prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; */
 822                                prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
 823                                prwskeylen = 16;
 824                        } else {
 825                                prwskey = &stainfo->dot118021x_UncstKey.skey[0];
 826                                prwskeylen = 16;
 827                        }
 828
 829                        iv = pframe+prxattrib->hdrlen;
 830                        payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
 831                        length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
 832
 833                        GET_TKIP_PN(iv, dot11txpn);
 834
 835                        pnl = (u16)(dot11txpn.val);
 836                        pnh = (u32)(dot11txpn.val>>16);
 837
 838                        phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
 839                        phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
 840
 841                        /* 4 decrypt payload include icv */
 842
 843                        arcfour_init(&mycontext, rc4key, 16);
 844                        arcfour_encrypt(&mycontext, payload, payload, length);
 845
 846                        *((u32 *)crc) = le32_to_cpu(getcrc32(payload, length-4));
 847
 848                        if (crc[3] != payload[length-1] || crc[2] != payload[length-2] || crc[1] != payload[length-3] || crc[0] != payload[length-4]) {
 849                                RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
 850                                         ("rtw_wep_decrypt:icv error crc[3](%x)!=payload[length-1](%x) || crc[2](%x)!=payload[length-2](%x) || crc[1](%x)!=payload[length-3](%x) || crc[0](%x)!=payload[length-4](%x)\n",
 851                                         crc[3], payload[length-1], crc[2], payload[length-2], crc[1], payload[length-3], crc[0], payload[length-4]));
 852                                res = _FAIL;
 853                        }
 854
 855                        TKIP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);
 856                } else {
 857                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_decrypt: stainfo == NULL!!!\n"));
 858                        res = _FAIL;
 859                }
 860
 861        }
 862exit:
 863        return res;
 864
 865}
 866
 867
 868/* 3                    =====AES related ===== */
 869
 870
 871
 872#define MAX_MSG_SIZE    2048
 873/*****************************/
 874/******** SBOX Table *********/
 875/*****************************/
 876
 877        static  u8 sbox_table[256] = {
 878                        0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
 879                        0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
 880                        0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
 881                        0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
 882                        0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
 883                        0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
 884                        0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
 885                        0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
 886                        0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
 887                        0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
 888                        0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
 889                        0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
 890                        0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
 891                        0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
 892                        0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
 893                        0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
 894                        0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
 895                        0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
 896                        0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
 897                        0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
 898                        0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
 899                        0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
 900                        0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
 901                        0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
 902                        0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
 903                        0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
 904                        0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
 905                        0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
 906                        0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
 907                        0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
 908                        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
 909                        0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
 910                };
 911
 912/*****************************/
 913/**** Function Prototypes ****/
 914/*****************************/
 915
 916static void bitwise_xor(u8 *ina, u8 *inb, u8 *out);
 917static void construct_mic_iv(
 918        u8 *mic_header1,
 919        sint qc_exists,
 920        sint a4_exists,
 921        u8 *mpdu,
 922        uint payload_length,
 923        u8 *pn_vector,
 924        uint frtype
 925);/*  add for CONFIG_IEEE80211W, none 11w also can use */
 926static void construct_mic_header1(
 927        u8 *mic_header1,
 928        sint header_length,
 929        u8 *mpdu,
 930        uint frtype
 931);/*  add for CONFIG_IEEE80211W, none 11w also can use */
 932static void construct_mic_header2(
 933        u8 *mic_header2,
 934        u8 *mpdu,
 935        sint a4_exists,
 936        sint qc_exists
 937);
 938static void construct_ctr_preload(
 939        u8 *ctr_preload,
 940        sint a4_exists,
 941        sint qc_exists,
 942        u8 *mpdu,
 943        u8 *pn_vector,
 944        sint c,
 945        uint frtype
 946);/*  add for CONFIG_IEEE80211W, none 11w also can use */
 947static void xor_128(u8 *a, u8 *b, u8 *out);
 948static void xor_32(u8 *a, u8 *b, u8 *out);
 949static u8 sbox(u8 a);
 950static void next_key(u8 *key, sint round);
 951static void byte_sub(u8 *in, u8 *out);
 952static void shift_row(u8 *in, u8 *out);
 953static void mix_column(u8 *in, u8 *out);
 954static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext);
 955
 956
 957/****************************************/
 958/* aes128k128d()                        */
 959/* Performs a 128 bit AES encrypt with  */
 960/* 128 bit data.                        */
 961/****************************************/
 962static void xor_128(u8 *a, u8 *b, u8 *out)
 963{
 964                sint i;
 965
 966                for (i = 0; i < 16; i++) {
 967                        out[i] = a[i] ^ b[i];
 968                }
 969}
 970
 971
 972static void xor_32(u8 *a, u8 *b, u8 *out)
 973{
 974                sint i;
 975
 976                for (i = 0; i < 4; i++) {
 977                        out[i] = a[i] ^ b[i];
 978                }
 979}
 980
 981
 982static u8 sbox(u8 a)
 983{
 984                return sbox_table[(sint)a];
 985}
 986
 987
 988static void next_key(u8 *key, sint round)
 989{
 990                u8 rcon;
 991                u8 sbox_key[4];
 992                u8 rcon_table[12] = {
 993                        0x01, 0x02, 0x04, 0x08,
 994                        0x10, 0x20, 0x40, 0x80,
 995                        0x1b, 0x36, 0x36, 0x36
 996                };
 997                sbox_key[0] = sbox(key[13]);
 998                sbox_key[1] = sbox(key[14]);
 999                sbox_key[2] = sbox(key[15]);
1000                sbox_key[3] = sbox(key[12]);
1001
1002                rcon = rcon_table[round];
1003
1004                xor_32(&key[0], sbox_key, &key[0]);
1005                key[0] = key[0] ^ rcon;
1006
1007                xor_32(&key[4], &key[0], &key[4]);
1008                xor_32(&key[8], &key[4], &key[8]);
1009                xor_32(&key[12], &key[8], &key[12]);
1010}
1011
1012
1013static void byte_sub(u8 *in, u8 *out)
1014{
1015                sint i;
1016
1017                for (i = 0; i < 16; i++) {
1018                        out[i] = sbox(in[i]);
1019                }
1020}
1021
1022
1023static void shift_row(u8 *in, u8 *out)
1024{
1025                out[0] =  in[0];
1026                out[1] =  in[5];
1027                out[2] =  in[10];
1028                out[3] =  in[15];
1029                out[4] =  in[4];
1030                out[5] =  in[9];
1031                out[6] =  in[14];
1032                out[7] =  in[3];
1033                out[8] =  in[8];
1034                out[9] =  in[13];
1035                out[10] = in[2];
1036                out[11] = in[7];
1037                out[12] = in[12];
1038                out[13] = in[1];
1039                out[14] = in[6];
1040                out[15] = in[11];
1041}
1042
1043
1044static void mix_column(u8 *in, u8 *out)
1045{
1046                sint i;
1047                u8 add1b[4];
1048                u8 add1bf7[4];
1049                u8 rotl[4];
1050                u8 swap_halfs[4];
1051                u8 andf7[4];
1052                u8 rotr[4];
1053                u8 temp[4];
1054                u8 tempb[4];
1055
1056                for (i = 0; i < 4; i++) {
1057                        if ((in[i] & 0x80) == 0x80)
1058                                add1b[i] = 0x1b;
1059                        else
1060                                add1b[i] = 0x00;
1061                }
1062
1063                swap_halfs[0] = in[2];    /* Swap halfs */
1064                swap_halfs[1] = in[3];
1065                swap_halfs[2] = in[0];
1066                swap_halfs[3] = in[1];
1067
1068                rotl[0] = in[3];        /* Rotate left 8 bits */
1069                rotl[1] = in[0];
1070                rotl[2] = in[1];
1071                rotl[3] = in[2];
1072
1073                andf7[0] = in[0] & 0x7f;
1074                andf7[1] = in[1] & 0x7f;
1075                andf7[2] = in[2] & 0x7f;
1076                andf7[3] = in[3] & 0x7f;
1077
1078                for (i = 3; i > 0; i--) {  /* logical shift left 1 bit */
1079                        andf7[i] = andf7[i] << 1;
1080                        if ((andf7[i-1] & 0x80) == 0x80)
1081                                andf7[i] = (andf7[i] | 0x01);
1082                }
1083                andf7[0] = andf7[0] << 1;
1084                andf7[0] = andf7[0] & 0xfe;
1085
1086                xor_32(add1b, andf7, add1bf7);
1087
1088                xor_32(in, add1bf7, rotr);
1089
1090                temp[0] = rotr[0];         /* Rotate right 8 bits */
1091                rotr[0] = rotr[1];
1092                rotr[1] = rotr[2];
1093                rotr[2] = rotr[3];
1094                rotr[3] = temp[0];
1095
1096                xor_32(add1bf7, rotr, temp);
1097                xor_32(swap_halfs, rotl, tempb);
1098                xor_32(temp, tempb, out);
1099}
1100
1101static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
1102{
1103                sint round;
1104                sint i;
1105                u8 intermediatea[16];
1106                u8 intermediateb[16];
1107                u8 round_key[16];
1108
1109                for (i = 0; i < 16; i++)
1110                        round_key[i] = key[i];
1111
1112                for (round = 0; round < 11; round++) {
1113                        if (round == 0) {
1114                                xor_128(round_key, data, ciphertext);
1115                                next_key(round_key, round);
1116                        } else if (round == 10) {
1117                                byte_sub(ciphertext, intermediatea);
1118                                shift_row(intermediatea, intermediateb);
1119                                xor_128(intermediateb, round_key, ciphertext);
1120                        } else {   /* 1 - 9 */
1121                                byte_sub(ciphertext, intermediatea);
1122                                shift_row(intermediatea, intermediateb);
1123                                mix_column(&intermediateb[0], &intermediatea[0]);
1124                                mix_column(&intermediateb[4], &intermediatea[4]);
1125                                mix_column(&intermediateb[8], &intermediatea[8]);
1126                                mix_column(&intermediateb[12], &intermediatea[12]);
1127                                xor_128(intermediatea, round_key, ciphertext);
1128                                next_key(round_key, round);
1129                        }
1130                }
1131}
1132
1133
1134/************************************************/
1135/* construct_mic_iv()                           */
1136/* Builds the MIC IV from header fields and PN  */
1137/* Baron think the function is construct CCM    */
1138/* nonce                                        */
1139/************************************************/
1140static void construct_mic_iv(
1141        u8 *mic_iv,
1142        sint qc_exists,
1143        sint a4_exists,
1144        u8 *mpdu,
1145        uint payload_length,
1146        u8 *pn_vector,
1147        uint frtype/*  add for CONFIG_IEEE80211W, none 11w also can use */
1148)
1149{
1150                sint i;
1151
1152                mic_iv[0] = 0x59;
1153
1154                if (qc_exists && a4_exists)
1155                        mic_iv[1] = mpdu[30] & 0x0f;    /* QoS_TC           */
1156
1157                if (qc_exists && !a4_exists)
1158                        mic_iv[1] = mpdu[24] & 0x0f;   /* mute bits 7-4    */
1159
1160                if (!qc_exists)
1161                        mic_iv[1] = 0x00;
1162
1163                /* 802.11w management frame should set management bit(4) */
1164                if (frtype == WIFI_MGT_TYPE)
1165                        mic_iv[1] |= BIT(4);
1166
1167                for (i = 2; i < 8; i++)
1168                        mic_iv[i] = mpdu[i + 8];   /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
1169                #ifdef CONSISTENT_PN_ORDER
1170                for (i = 8; i < 14; i++)
1171                        mic_iv[i] = pn_vector[i - 8];           /* mic_iv[8:13] = PN[0:5] */
1172                #else
1173                for (i = 8; i < 14; i++)
1174                        mic_iv[i] = pn_vector[13 - i];          /* mic_iv[8:13] = PN[5:0] */
1175                #endif
1176                mic_iv[14] = (unsigned char) (payload_length / 256);
1177                mic_iv[15] = (unsigned char) (payload_length % 256);
1178}
1179
1180
1181/************************************************/
1182/* construct_mic_header1()                      */
1183/* Builds the first MIC header block from       */
1184/* header fields.                               */
1185/* Build AAD SC, A1, A2                           */
1186/************************************************/
1187static void construct_mic_header1(
1188        u8 *mic_header1,
1189        sint header_length,
1190        u8 *mpdu,
1191        uint frtype/*  add for CONFIG_IEEE80211W, none 11w also can use */
1192)
1193{
1194                mic_header1[0] = (u8)((header_length - 2) / 256);
1195                mic_header1[1] = (u8)((header_length - 2) % 256);
1196
1197                /* 802.11w management frame don't AND subtype bits 4, 5, 6 of frame control field */
1198                if (frtype == WIFI_MGT_TYPE)
1199                        mic_header1[2] = mpdu[0];
1200                else
1201                        mic_header1[2] = mpdu[0] & 0xcf;    /* Mute CF poll & CF ack bits */
1202
1203                mic_header1[3] = mpdu[1] & 0xc7;    /* Mute retry, more data and pwr mgt bits */
1204                mic_header1[4] = mpdu[4];       /* A1 */
1205                mic_header1[5] = mpdu[5];
1206                mic_header1[6] = mpdu[6];
1207                mic_header1[7] = mpdu[7];
1208                mic_header1[8] = mpdu[8];
1209                mic_header1[9] = mpdu[9];
1210                mic_header1[10] = mpdu[10];     /* A2 */
1211                mic_header1[11] = mpdu[11];
1212                mic_header1[12] = mpdu[12];
1213                mic_header1[13] = mpdu[13];
1214                mic_header1[14] = mpdu[14];
1215                mic_header1[15] = mpdu[15];
1216}
1217
1218
1219/************************************************/
1220/* construct_mic_header2()                      */
1221/* Builds the last MIC header block from        */
1222/* header fields.                               */
1223/************************************************/
1224static void construct_mic_header2(
1225        u8 *mic_header2,
1226        u8 *mpdu,
1227        sint a4_exists,
1228        sint qc_exists
1229)
1230{
1231                sint i;
1232
1233                for (i = 0; i < 16; i++)
1234                        mic_header2[i] = 0x00;
1235
1236                mic_header2[0] = mpdu[16];    /* A3 */
1237                mic_header2[1] = mpdu[17];
1238                mic_header2[2] = mpdu[18];
1239                mic_header2[3] = mpdu[19];
1240                mic_header2[4] = mpdu[20];
1241                mic_header2[5] = mpdu[21];
1242
1243                mic_header2[6] = 0x00;
1244                mic_header2[7] = 0x00; /* mpdu[23]; */
1245
1246
1247                if (!qc_exists && a4_exists) {
1248                        for (i = 0; i < 6; i++)
1249                                mic_header2[8+i] = mpdu[24+i];   /* A4 */
1250
1251                }
1252
1253                if (qc_exists && !a4_exists) {
1254                        mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
1255                        mic_header2[9] = mpdu[25] & 0x00;
1256                }
1257
1258                if (qc_exists && a4_exists) {
1259                        for (i = 0; i < 6; i++)
1260                                mic_header2[8+i] = mpdu[24+i];   /* A4 */
1261
1262                        mic_header2[14] = mpdu[30] & 0x0f;
1263                        mic_header2[15] = mpdu[31] & 0x00;
1264                }
1265
1266}
1267
1268/************************************************/
1269/* construct_mic_header2()                      */
1270/* Builds the last MIC header block from        */
1271/* header fields.                               */
1272/* Baron think the function is construct CCM    */
1273/* nonce                                        */
1274/************************************************/
1275static void construct_ctr_preload(
1276        u8 *ctr_preload,
1277        sint a4_exists,
1278        sint qc_exists,
1279        u8 *mpdu,
1280        u8 *pn_vector,
1281        sint c,
1282        uint frtype /*  add for CONFIG_IEEE80211W, none 11w also can use */
1283)
1284{
1285        sint i = 0;
1286
1287        for (i = 0; i < 16; i++)
1288                ctr_preload[i] = 0x00;
1289        i = 0;
1290
1291        ctr_preload[0] = 0x01;                                  /* flag */
1292        if (qc_exists && a4_exists)
1293                ctr_preload[1] = mpdu[30] & 0x0f;   /* QoC_Control */
1294        if (qc_exists && !a4_exists)
1295                ctr_preload[1] = mpdu[24] & 0x0f;
1296
1297        /* 802.11w management frame should set management bit(4) */
1298        if (frtype == WIFI_MGT_TYPE)
1299                ctr_preload[1] |= BIT(4);
1300
1301        for (i = 2; i < 8; i++)
1302                ctr_preload[i] = mpdu[i + 8];                       /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1303#ifdef CONSISTENT_PN_ORDER
1304        for (i = 8; i < 14; i++)
1305                ctr_preload[i] =    pn_vector[i - 8];           /* ctr_preload[8:13] = PN[0:5] */
1306#else
1307        for (i = 8; i < 14; i++)
1308                ctr_preload[i] =    pn_vector[13 - i];          /* ctr_preload[8:13] = PN[5:0] */
1309#endif
1310        ctr_preload[14] =  (unsigned char) (c / 256); /* Ctr */
1311        ctr_preload[15] =  (unsigned char) (c % 256);
1312}
1313
1314
1315/************************************/
1316/* bitwise_xor()                    */
1317/* A 128 bit, bitwise exclusive or  */
1318/************************************/
1319static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
1320{
1321                sint i;
1322
1323                for (i = 0; i < 16; i++) {
1324                        out[i] = ina[i] ^ inb[i];
1325                }
1326}
1327
1328
1329static sint aes_cipher(u8 *key, uint    hdrlen,
1330                        u8 *pframe, uint plen)
1331{
1332        uint    qc_exists, a4_exists, i, j, payload_remainder,
1333                num_blocks, payload_index;
1334
1335        u8 pn_vector[6];
1336        u8 mic_iv[16];
1337        u8 mic_header1[16];
1338        u8 mic_header2[16];
1339        u8 ctr_preload[16];
1340
1341        /* Intermediate Buffers */
1342        u8 chain_buffer[16];
1343        u8 aes_out[16];
1344        u8 padded_buffer[16];
1345        u8 mic[8];
1346        uint    frtype  = GetFrameType(pframe);
1347        uint    frsubtype  = GetFrameSubType(pframe);
1348
1349        frsubtype = frsubtype>>4;
1350
1351
1352        memset((void *)mic_iv, 0, 16);
1353        memset((void *)mic_header1, 0, 16);
1354        memset((void *)mic_header2, 0, 16);
1355        memset((void *)ctr_preload, 0, 16);
1356        memset((void *)chain_buffer, 0, 16);
1357        memset((void *)aes_out, 0, 16);
1358        memset((void *)padded_buffer, 0, 16);
1359
1360        if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen ==  WLAN_HDR_A3_QOS_LEN))
1361                a4_exists = 0;
1362        else
1363                a4_exists = 1;
1364
1365        if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
1366            ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
1367            ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
1368                qc_exists = 1;
1369                if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
1370                        hdrlen += 2;
1371
1372        } else if ((frtype == WIFI_DATA) && /*  add for CONFIG_IEEE80211W, none 11w also can use */
1373                   ((frsubtype == 0x08) ||
1374                   (frsubtype == 0x09) ||
1375                   (frsubtype == 0x0a) ||
1376                   (frsubtype == 0x0b))) {
1377                if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
1378                        hdrlen += 2;
1379
1380                qc_exists = 1;
1381        } else
1382                qc_exists = 0;
1383
1384        pn_vector[0] = pframe[hdrlen];
1385        pn_vector[1] = pframe[hdrlen+1];
1386        pn_vector[2] = pframe[hdrlen+4];
1387        pn_vector[3] = pframe[hdrlen+5];
1388        pn_vector[4] = pframe[hdrlen+6];
1389        pn_vector[5] = pframe[hdrlen+7];
1390
1391        construct_mic_iv(
1392                        mic_iv,
1393                        qc_exists,
1394                        a4_exists,
1395                        pframe,  /* message, */
1396                        plen,
1397                        pn_vector,
1398                        frtype /*  add for CONFIG_IEEE80211W, none 11w also can use */
1399        );
1400
1401        construct_mic_header1(
1402                mic_header1,
1403                hdrlen,
1404                pframe, /* message */
1405                frtype /*  add for CONFIG_IEEE80211W, none 11w also can use */
1406        );
1407        construct_mic_header2(
1408                mic_header2,
1409                pframe, /* message, */
1410                a4_exists,
1411                qc_exists
1412        );
1413
1414
1415        payload_remainder = plen % 16;
1416        num_blocks = plen / 16;
1417
1418        /* Find start of payload */
1419        payload_index = (hdrlen + 8);
1420
1421        /* Calculate MIC */
1422        aes128k128d(key, mic_iv, aes_out);
1423        bitwise_xor(aes_out, mic_header1, chain_buffer);
1424        aes128k128d(key, chain_buffer, aes_out);
1425        bitwise_xor(aes_out, mic_header2, chain_buffer);
1426        aes128k128d(key, chain_buffer, aes_out);
1427
1428        for (i = 0; i < num_blocks; i++) {
1429                bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */
1430
1431                payload_index += 16;
1432                aes128k128d(key, chain_buffer, aes_out);
1433        }
1434
1435        /* Add on the final payload block if it needs padding */
1436        if (payload_remainder > 0) {
1437                for (j = 0; j < 16; j++)
1438                        padded_buffer[j] = 0x00;
1439                for (j = 0; j < payload_remainder; j++) {
1440                        padded_buffer[j] = pframe[payload_index++];/* padded_buffer[j] = message[payload_index++]; */
1441                }
1442                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1443                aes128k128d(key, chain_buffer, aes_out);
1444
1445        }
1446
1447        for (j = 0 ; j < 8; j++)
1448                mic[j] = aes_out[j];
1449
1450        /* Insert MIC into payload */
1451        for (j = 0; j < 8; j++)
1452                pframe[payload_index+j] = mic[j];       /* message[payload_index+j] = mic[j]; */
1453
1454        payload_index = hdrlen + 8;
1455        for (i = 0; i < num_blocks; i++) {
1456                construct_ctr_preload(
1457                        ctr_preload,
1458                        a4_exists,
1459                        qc_exists,
1460                        pframe, /* message, */
1461                        pn_vector,
1462                        i+1,
1463                        frtype
1464                ); /*  add for CONFIG_IEEE80211W, none 11w also can use */
1465                aes128k128d(key, ctr_preload, aes_out);
1466                bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */
1467                for (j = 0; j < 16; j++)
1468                        pframe[payload_index++] = chain_buffer[j];/* for (j = 0; j<16;j++) message[payload_index++] = chain_buffer[j]; */
1469        }
1470
1471        if (payload_remainder > 0) {
1472                /* If there is a short final block, then pad it,*/
1473                /* encrypt it and copy the unpadded part back   */
1474                construct_ctr_preload(
1475                        ctr_preload,
1476                        a4_exists,
1477                        qc_exists,
1478                        pframe, /* message, */
1479                        pn_vector,
1480                        num_blocks+1,
1481                        frtype
1482                ); /*  add for CONFIG_IEEE80211W, none 11w also can use */
1483
1484                for (j = 0; j < 16; j++)
1485                        padded_buffer[j] = 0x00;
1486                for (j = 0; j < payload_remainder; j++)
1487                        padded_buffer[j] = pframe[payload_index+j];/* padded_buffer[j] = message[payload_index+j]; */
1488
1489                aes128k128d(key, ctr_preload, aes_out);
1490                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1491                for (j = 0; j < payload_remainder; j++)
1492                        pframe[payload_index++] = chain_buffer[j];/* for (j = 0; j<payload_remainder;j++) message[payload_index++] = chain_buffer[j]; */
1493        }
1494
1495        /* Encrypt the MIC */
1496        construct_ctr_preload(
1497                ctr_preload,
1498                a4_exists,
1499                qc_exists,
1500                pframe, /* message, */
1501                pn_vector,
1502                0,
1503                frtype
1504        ); /*  add for CONFIG_IEEE80211W, none 11w also can use */
1505
1506        for (j = 0; j < 16; j++)
1507                padded_buffer[j] = 0x00;
1508        for (j = 0; j < 8; j++)
1509                padded_buffer[j] = pframe[j+hdrlen+8+plen];/* padded_buffer[j] = message[j+hdrlen+8+plen]; */
1510
1511        aes128k128d(key, ctr_preload, aes_out);
1512        bitwise_xor(aes_out, padded_buffer, chain_buffer);
1513        for (j = 0; j < 8; j++)
1514                 pframe[payload_index++] = chain_buffer[j];/* for (j = 0; j<8;j++) message[payload_index++] = chain_buffer[j]; */
1515
1516        return _SUCCESS;
1517}
1518
1519u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
1520{       /*  exclude ICV */
1521
1522
1523        /*static*/
1524/*      unsigned char message[MAX_MSG_SIZE]; */
1525
1526        /* Intermediate Buffers */
1527        sint    curfragnum, length;
1528        u32 prwskeylen;
1529        u8 *pframe, *prwskey;   /*  *payload,*iv */
1530        u8   hw_hdr_offset = 0;
1531        /* struct       sta_info        *stainfo = NULL; */
1532        struct  pkt_attrib       *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
1533        struct  security_priv *psecuritypriv = &padapter->securitypriv;
1534        struct  xmit_priv       *pxmitpriv = &padapter->xmitpriv;
1535
1536/*      uint    offset = 0; */
1537        u32 res = _SUCCESS;
1538
1539        if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
1540                return _FAIL;
1541
1542        hw_hdr_offset = TXDESC_OFFSET;
1543        pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
1544
1545        /* 4 start to encrypt each fragment */
1546        if (pattrib->encrypt == _AES_) {
1547                RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo!= NULL!!!\n"));
1548
1549                if (IS_MCAST(pattrib->ra))
1550                        prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
1551                else
1552                        /* prwskey =&stainfo->dot118021x_UncstKey.skey[0]; */
1553                        prwskey = pattrib->dot118021x_UncstKey.skey;
1554
1555                prwskeylen = 16;
1556
1557                for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1558                        if ((curfragnum+1) == pattrib->nr_frags) {      /* 4 the last fragment */
1559                                length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1560
1561                                aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1562                        } else {
1563                                length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1564
1565                                aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1566                                pframe += pxmitpriv->frag_len;
1567                                pframe = (u8 *)RND4((SIZE_PTR)(pframe));
1568                        }
1569                }
1570
1571                AES_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);
1572        }
1573        return res;
1574}
1575
1576static sint aes_decipher(u8 *key, uint  hdrlen,
1577                        u8 *pframe, uint plen)
1578{
1579        static u8 message[MAX_MSG_SIZE];
1580        uint    qc_exists, a4_exists, i, j, payload_remainder,
1581                        num_blocks, payload_index;
1582        sint res = _SUCCESS;
1583        u8 pn_vector[6];
1584        u8 mic_iv[16];
1585        u8 mic_header1[16];
1586        u8 mic_header2[16];
1587        u8 ctr_preload[16];
1588
1589                /* Intermediate Buffers */
1590        u8 chain_buffer[16];
1591        u8 aes_out[16];
1592        u8 padded_buffer[16];
1593        u8 mic[8];
1594
1595
1596/*      uint    offset = 0; */
1597        uint    frtype  = GetFrameType(pframe);
1598        uint    frsubtype  = GetFrameSubType(pframe);
1599
1600        frsubtype = frsubtype>>4;
1601
1602
1603        memset((void *)mic_iv, 0, 16);
1604        memset((void *)mic_header1, 0, 16);
1605        memset((void *)mic_header2, 0, 16);
1606        memset((void *)ctr_preload, 0, 16);
1607        memset((void *)chain_buffer, 0, 16);
1608        memset((void *)aes_out, 0, 16);
1609        memset((void *)padded_buffer, 0, 16);
1610
1611        /* start to decrypt the payload */
1612
1613        num_blocks = (plen-8) / 16; /* plen including LLC, payload_length and mic) */
1614
1615        payload_remainder = (plen-8) % 16;
1616
1617        pn_vector[0]  = pframe[hdrlen];
1618        pn_vector[1]  = pframe[hdrlen+1];
1619        pn_vector[2]  = pframe[hdrlen+4];
1620        pn_vector[3]  = pframe[hdrlen+5];
1621        pn_vector[4]  = pframe[hdrlen+6];
1622        pn_vector[5]  = pframe[hdrlen+7];
1623
1624        if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen ==  WLAN_HDR_A3_QOS_LEN))
1625                a4_exists = 0;
1626        else
1627                a4_exists = 1;
1628
1629        if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
1630            ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
1631            ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
1632                qc_exists = 1;
1633                if (hdrlen !=  WLAN_HDR_A3_QOS_LEN) {
1634                        hdrlen += 2;
1635                }
1636        } else if ((frtype == WIFI_DATA) && /* only for data packet . add for CONFIG_IEEE80211W, none 11w also can use */
1637                   ((frsubtype == 0x08) ||
1638                   (frsubtype == 0x09) ||
1639                   (frsubtype == 0x0a) ||
1640                   (frsubtype == 0x0b))) {
1641                if (hdrlen !=  WLAN_HDR_A3_QOS_LEN) {
1642                        hdrlen += 2;
1643                }
1644                qc_exists = 1;
1645        } else
1646                qc_exists = 0;
1647
1648
1649        /*  now, decrypt pframe with hdrlen offset and plen long */
1650
1651        payload_index = hdrlen + 8; /*  8 is for extiv */
1652
1653        for (i = 0; i < num_blocks; i++) {
1654                        construct_ctr_preload(
1655                                ctr_preload,
1656                                a4_exists,
1657                                qc_exists,
1658                                pframe,
1659                                pn_vector,
1660                                i+1,
1661                                frtype /*  add for CONFIG_IEEE80211W, none 11w also can use */
1662                        );
1663
1664                        aes128k128d(key, ctr_preload, aes_out);
1665                        bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1666
1667                        for (j = 0; j < 16; j++)
1668                                pframe[payload_index++] = chain_buffer[j];
1669                }
1670
1671        if (payload_remainder > 0) {
1672                /* If there is a short final block, then pad it,*/
1673                /* encrypt it and copy the unpadded part back   */
1674                construct_ctr_preload(
1675                        ctr_preload,
1676                        a4_exists,
1677                        qc_exists,
1678                        pframe,
1679                        pn_vector,
1680                        num_blocks+1,
1681                        frtype /*  add for CONFIG_IEEE80211W, none 11w also can use */
1682                );
1683
1684                for (j = 0; j < 16; j++)
1685                        padded_buffer[j] = 0x00;
1686                for (j = 0; j < payload_remainder; j++) {
1687                        padded_buffer[j] = pframe[payload_index+j];
1688                }
1689                aes128k128d(key, ctr_preload, aes_out);
1690                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1691                for (j = 0; j < payload_remainder; j++)
1692                        pframe[payload_index++] = chain_buffer[j];
1693        }
1694
1695        /* start to calculate the mic */
1696        if ((hdrlen + plen+8) <= MAX_MSG_SIZE)
1697                memcpy((void *)message, pframe, (hdrlen + plen+8)); /* 8 is for ext iv len */
1698
1699
1700        pn_vector[0] = pframe[hdrlen];
1701        pn_vector[1] = pframe[hdrlen+1];
1702        pn_vector[2] = pframe[hdrlen+4];
1703        pn_vector[3] = pframe[hdrlen+5];
1704        pn_vector[4] = pframe[hdrlen+6];
1705        pn_vector[5] = pframe[hdrlen+7];
1706
1707
1708
1709        construct_mic_iv(
1710                mic_iv,
1711                qc_exists,
1712                a4_exists,
1713                message,
1714                plen-8,
1715                pn_vector,
1716                frtype /*  add for CONFIG_IEEE80211W, none 11w also can use */
1717        );
1718
1719        construct_mic_header1(
1720                mic_header1,
1721                hdrlen,
1722                message,
1723                frtype /*  add for CONFIG_IEEE80211W, none 11w also can use */
1724        );
1725        construct_mic_header2(
1726                mic_header2,
1727                message,
1728                a4_exists,
1729                qc_exists
1730        );
1731
1732
1733        payload_remainder = (plen-8) % 16;
1734        num_blocks = (plen-8) / 16;
1735
1736        /* Find start of payload */
1737        payload_index = (hdrlen + 8);
1738
1739        /* Calculate MIC */
1740        aes128k128d(key, mic_iv, aes_out);
1741        bitwise_xor(aes_out, mic_header1, chain_buffer);
1742        aes128k128d(key, chain_buffer, aes_out);
1743        bitwise_xor(aes_out, mic_header2, chain_buffer);
1744        aes128k128d(key, chain_buffer, aes_out);
1745
1746        for (i = 0; i < num_blocks; i++) {
1747                bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1748
1749                payload_index += 16;
1750                aes128k128d(key, chain_buffer, aes_out);
1751        }
1752
1753        /* Add on the final payload block if it needs padding */
1754        if (payload_remainder > 0) {
1755                for (j = 0; j < 16; j++)
1756                        padded_buffer[j] = 0x00;
1757                for (j = 0; j < payload_remainder; j++) {
1758                        padded_buffer[j] = message[payload_index++];
1759                }
1760                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1761                aes128k128d(key, chain_buffer, aes_out);
1762
1763        }
1764
1765        for (j = 0; j < 8; j++)
1766                mic[j] = aes_out[j];
1767
1768        /* Insert MIC into payload */
1769        for (j = 0; j < 8; j++)
1770                message[payload_index+j] = mic[j];
1771
1772        payload_index = hdrlen + 8;
1773        for (i = 0; i < num_blocks; i++) {
1774                construct_ctr_preload(
1775                        ctr_preload,
1776                        a4_exists,
1777                        qc_exists,
1778                        message,
1779                        pn_vector,
1780                        i+1,
1781                        frtype
1782                ); /*  add for CONFIG_IEEE80211W, none 11w also can use */
1783                aes128k128d(key, ctr_preload, aes_out);
1784                bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1785                for (j = 0; j < 16; j++)
1786                        message[payload_index++] = chain_buffer[j];
1787        }
1788
1789        if (payload_remainder > 0) {
1790                /* If there is a short final block, then pad it,*/
1791                /* encrypt it and copy the unpadded part back   */
1792                construct_ctr_preload(
1793                        ctr_preload,
1794                        a4_exists,
1795                        qc_exists,
1796                        message,
1797                        pn_vector,
1798                        num_blocks+1,
1799                        frtype
1800                ); /*  add for CONFIG_IEEE80211W, none 11w also can use */
1801
1802                for (j = 0; j < 16; j++)
1803                        padded_buffer[j] = 0x00;
1804                for (j = 0; j < payload_remainder; j++) {
1805                        padded_buffer[j] = message[payload_index+j];
1806                }
1807                aes128k128d(key, ctr_preload, aes_out);
1808                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1809                for (j = 0; j < payload_remainder; j++)
1810                        message[payload_index++] = chain_buffer[j];
1811        }
1812
1813        /* Encrypt the MIC */
1814        construct_ctr_preload(
1815                ctr_preload,
1816                a4_exists,
1817                qc_exists,
1818                message,
1819                pn_vector,
1820                0,
1821                frtype
1822        ); /*  add for CONFIG_IEEE80211W, none 11w also can use */
1823
1824        for (j = 0; j < 16; j++)
1825                padded_buffer[j] = 0x00;
1826        for (j = 0; j < 8; j++) {
1827                padded_buffer[j] = message[j+hdrlen+8+plen-8];
1828        }
1829
1830        aes128k128d(key, ctr_preload, aes_out);
1831        bitwise_xor(aes_out, padded_buffer, chain_buffer);
1832        for (j = 0; j < 8; j++)
1833                message[payload_index++] = chain_buffer[j];
1834
1835        /* compare the mic */
1836        for (i = 0; i < 8; i++) {
1837                if (pframe[hdrlen+8+plen-8+i] != message[hdrlen+8+plen-8+i]) {
1838                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("aes_decipher:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1839                                        i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]));
1840                        DBG_871X("aes_decipher:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1841                                        i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]);
1842                        res = _FAIL;
1843                }
1844        }
1845        return res;
1846}
1847
1848u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
1849{       /*  exclude ICV */
1850
1851
1852        /*static*/
1853/*      unsigned char message[MAX_MSG_SIZE]; */
1854
1855
1856        /* Intermediate Buffers */
1857
1858
1859        sint            length;
1860        u8 *pframe, *prwskey;   /*  *payload,*iv */
1861        struct  sta_info        *stainfo;
1862        struct  rx_pkt_attrib    *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
1863        struct  security_priv *psecuritypriv = &padapter->securitypriv;
1864/*      struct  recv_priv       *precvpriv =&padapter->recvpriv; */
1865        u32 res = _SUCCESS;
1866
1867        pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
1868        /* 4 start to encrypt each fragment */
1869        if (prxattrib->encrypt == _AES_) {
1870                stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
1871                if (stainfo != NULL) {
1872                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo!= NULL!!!\n"));
1873
1874                        if (IS_MCAST(prxattrib->ra)) {
1875                                static unsigned long start;
1876                                static u32 no_gkey_bc_cnt;
1877                                static u32 no_gkey_mc_cnt;
1878
1879                                /* DBG_871X("rx bc/mc packets, to perform sw rtw_aes_decrypt\n"); */
1880                                /* prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; */
1881                                if (psecuritypriv->binstallGrpkey == false) {
1882                                        res = _FAIL;
1883
1884                                        if (start == 0)
1885                                                start = jiffies;
1886
1887                                        if (is_broadcast_mac_addr(prxattrib->ra))
1888                                                no_gkey_bc_cnt++;
1889                                        else
1890                                                no_gkey_mc_cnt++;
1891
1892                                        if (jiffies_to_msecs(jiffies - start) > 1000) {
1893                                                if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
1894                                                        DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
1895                                                                FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
1896                                                }
1897                                                start = jiffies;
1898                                                no_gkey_bc_cnt = 0;
1899                                                no_gkey_mc_cnt = 0;
1900                                        }
1901
1902                                        goto exit;
1903                                }
1904
1905                                if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
1906                                        DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
1907                                                FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
1908                                }
1909                                start = 0;
1910                                no_gkey_bc_cnt = 0;
1911                                no_gkey_mc_cnt = 0;
1912
1913                                prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
1914                                if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
1915                                        DBG_871X("not match packet_index =%d, install_index =%d\n"
1916                                        , prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid);
1917                                        res = _FAIL;
1918                                        goto exit;
1919                                }
1920                        } else
1921                                prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1922
1923
1924                        length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
1925
1926                        res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
1927
1928                        AES_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);
1929                } else {
1930                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo == NULL!!!\n"));
1931                        res = _FAIL;
1932                }
1933        }
1934exit:
1935        return res;
1936}
1937
1938u32 rtw_BIP_verify(struct adapter *padapter, u8 *precvframe)
1939{
1940        struct rx_pkt_attrib *pattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
1941        u8 *pframe;
1942        u8 *BIP_AAD, *p;
1943        u32 res = _FAIL;
1944        uint len, ori_len;
1945        struct ieee80211_hdr *pwlanhdr;
1946        u8 mic[16];
1947        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1948        __le16 le_tmp;
1949        __le64 le_tmp64;
1950
1951        ori_len = pattrib->pkt_len-WLAN_HDR_A3_LEN+BIP_AAD_SIZE;
1952        BIP_AAD = rtw_zmalloc(ori_len);
1953
1954        if (BIP_AAD == NULL) {
1955                DBG_871X("BIP AAD allocate fail\n");
1956                return _FAIL;
1957        }
1958        /* PKT start */
1959        pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
1960        /* mapping to wlan header */
1961        pwlanhdr = (struct ieee80211_hdr *)pframe;
1962        /* save the frame body + MME */
1963        memcpy(BIP_AAD+BIP_AAD_SIZE, pframe+WLAN_HDR_A3_LEN, pattrib->pkt_len-WLAN_HDR_A3_LEN);
1964        /* find MME IE pointer */
1965        p = rtw_get_ie(BIP_AAD+BIP_AAD_SIZE, _MME_IE_, &len, pattrib->pkt_len-WLAN_HDR_A3_LEN);
1966        /* Baron */
1967        if (p) {
1968                u16 keyid = 0;
1969                u64 temp_ipn = 0;
1970                /* save packet number */
1971                memcpy(&le_tmp64, p+4, 6);
1972                temp_ipn = le64_to_cpu(le_tmp64);
1973                /* BIP packet number should bigger than previous BIP packet */
1974                if (temp_ipn <= pmlmeext->mgnt_80211w_IPN_rx) {
1975                        DBG_871X("replay BIP packet\n");
1976                        goto BIP_exit;
1977                }
1978                /* copy key index */
1979                memcpy(&le_tmp, p+2, 2);
1980                keyid = le16_to_cpu(le_tmp);
1981                if (keyid != padapter->securitypriv.dot11wBIPKeyid) {
1982                        DBG_871X("BIP key index error!\n");
1983                        goto BIP_exit;
1984                }
1985                /* clear the MIC field of MME to zero */
1986                memset(p+2+len-8, 0, 8);
1987
1988                /* conscruct AAD, copy frame control field */
1989                memcpy(BIP_AAD, &pwlanhdr->frame_control, 2);
1990                ClearRetry(BIP_AAD);
1991                ClearPwrMgt(BIP_AAD);
1992                ClearMData(BIP_AAD);
1993                /* conscruct AAD, copy address 1 to address 3 */
1994                memcpy(BIP_AAD+2, pwlanhdr->addr1, 18);
1995
1996                if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
1997                        , BIP_AAD, ori_len, mic))
1998                        goto BIP_exit;
1999
2000                /* MIC field should be last 8 bytes of packet (packet without FCS) */
2001                if (!memcmp(mic, pframe+pattrib->pkt_len-8, 8)) {
2002                        pmlmeext->mgnt_80211w_IPN_rx = temp_ipn;
2003                        res = _SUCCESS;
2004                } else
2005                        DBG_871X("BIP MIC error!\n");
2006
2007        } else
2008                res = RTW_RX_HANDLED;
2009BIP_exit:
2010
2011        kfree(BIP_AAD);
2012        return res;
2013}
2014
2015/* AES tables*/
2016const u32 Te0[256] = {
2017        0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
2018        0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
2019        0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
2020        0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
2021        0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
2022        0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
2023        0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
2024        0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
2025        0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
2026        0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
2027        0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
2028        0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
2029        0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
2030        0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
2031        0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
2032        0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
2033        0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
2034        0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
2035        0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
2036        0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
2037        0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
2038        0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
2039        0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
2040        0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
2041        0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
2042        0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
2043        0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
2044        0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
2045        0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
2046        0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
2047        0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
2048        0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
2049        0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
2050        0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
2051        0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
2052        0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
2053        0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
2054        0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
2055        0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
2056        0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
2057        0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
2058        0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
2059        0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
2060        0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
2061        0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
2062        0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
2063        0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
2064        0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
2065        0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
2066        0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
2067        0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
2068        0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
2069        0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
2070        0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
2071        0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
2072        0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
2073        0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
2074        0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
2075        0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
2076        0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
2077        0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
2078        0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
2079        0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
2080        0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
2081};
2082const u32 Td0[256] = {
2083        0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
2084        0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
2085        0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
2086        0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
2087        0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
2088        0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
2089        0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
2090        0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
2091        0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
2092        0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
2093        0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
2094        0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
2095        0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
2096        0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
2097        0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
2098        0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
2099        0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
2100        0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
2101        0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
2102        0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
2103        0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
2104        0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
2105        0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
2106        0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
2107        0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
2108        0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
2109        0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
2110        0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
2111        0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
2112        0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
2113        0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
2114        0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
2115        0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
2116        0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
2117        0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
2118        0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
2119        0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
2120        0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
2121        0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
2122        0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
2123        0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
2124        0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
2125        0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
2126        0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
2127        0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
2128        0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
2129        0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
2130        0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
2131        0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
2132        0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
2133        0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
2134        0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
2135        0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
2136        0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
2137        0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
2138        0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
2139        0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
2140        0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
2141        0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
2142        0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
2143        0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
2144        0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
2145        0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
2146        0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
2147};
2148const u8 Td4s[256] = {
2149        0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
2150        0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
2151        0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
2152        0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
2153        0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
2154        0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
2155        0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
2156        0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
2157        0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
2158        0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
2159        0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
2160        0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
2161        0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
2162        0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
2163        0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
2164        0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
2165        0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
2166        0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
2167        0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
2168        0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
2169        0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
2170        0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
2171        0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
2172        0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
2173        0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
2174        0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
2175        0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
2176        0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
2177        0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
2178        0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
2179        0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
2180        0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
2181};
2182const u8 rcons[] = {
2183        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
2184        /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
2185};
2186
2187/**
2188 * Expand the cipher key into the encryption key schedule.
2189 *
2190 * @return      the number of rounds for the given cipher key size.
2191 */
2192static void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])
2193{
2194        int i;
2195        u32 temp;
2196
2197        rk[0] = GETU32(cipherKey);
2198        rk[1] = GETU32(cipherKey +  4);
2199        rk[2] = GETU32(cipherKey +  8);
2200        rk[3] = GETU32(cipherKey + 12);
2201        for (i = 0; i < 10; i++) {
2202                temp  = rk[3];
2203                rk[4] = rk[0] ^
2204                        TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^
2205                        RCON(i);
2206                rk[5] = rk[1] ^ rk[4];
2207                rk[6] = rk[2] ^ rk[5];
2208                rk[7] = rk[3] ^ rk[6];
2209                rk += 4;
2210        }
2211}
2212
2213static void rijndaelEncrypt(u32 rk[/*44*/], u8 pt[16], u8 ct[16])
2214{
2215        u32 s0, s1, s2, s3, t0, t1, t2, t3;
2216        int Nr = 10;
2217        int r;
2218
2219        /*
2220         * map byte array block to cipher state
2221         * and add initial round key:
2222         */
2223        s0 = GETU32(pt) ^ rk[0];
2224        s1 = GETU32(pt +  4) ^ rk[1];
2225        s2 = GETU32(pt +  8) ^ rk[2];
2226        s3 = GETU32(pt + 12) ^ rk[3];
2227
2228#define ROUND(i, d, s) \
2229d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
2230d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
2231d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
2232d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
2233
2234        /* Nr - 1 full rounds: */
2235        r = Nr >> 1;
2236        for (;;) {
2237                ROUND(1, t, s);
2238                rk += 8;
2239                if (--r == 0)
2240                        break;
2241                ROUND(0, s, t);
2242        }
2243
2244#undef ROUND
2245
2246        /*
2247         * apply last round and
2248         * map cipher state to byte array block:
2249         */
2250        s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];
2251        PUTU32(ct, s0);
2252        s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];
2253        PUTU32(ct +  4, s1);
2254        s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];
2255        PUTU32(ct +  8, s2);
2256        s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
2257        PUTU32(ct + 12, s3);
2258}
2259
2260static void *aes_encrypt_init(u8 *key, size_t len)
2261{
2262        u32 *rk;
2263        if (len != 16)
2264                return NULL;
2265        rk = rtw_malloc(AES_PRIV_SIZE);
2266        if (rk == NULL)
2267                return NULL;
2268        rijndaelKeySetupEnc(rk, key);
2269        return rk;
2270}
2271
2272static void aes_128_encrypt(void *ctx, u8 *plain, u8 *crypt)
2273{
2274        rijndaelEncrypt(ctx, plain, crypt);
2275}
2276
2277
2278static void gf_mulx(u8 *pad)
2279{
2280        int i, carry;
2281
2282        carry = pad[0] & 0x80;
2283        for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
2284                pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
2285
2286        pad[AES_BLOCK_SIZE - 1] <<= 1;
2287        if (carry)
2288                pad[AES_BLOCK_SIZE - 1] ^= 0x87;
2289}
2290
2291static void aes_encrypt_deinit(void *ctx)
2292{
2293        memset(ctx, 0, AES_PRIV_SIZE);
2294        kfree(ctx);
2295}
2296
2297
2298/**
2299 * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
2300 * @key: 128-bit key for the hash operation
2301 * @num_elem: Number of elements in the data vector
2302 * @addr: Pointers to the data areas
2303 * @len: Lengths of the data blocks
2304 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
2305 * Returns: 0 on success, -1 on failure
2306 *
2307 * This is a mode for using block cipher (AES in this case) for authentication.
2308 * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
2309 * (SP) 800-38B.
2310 */
2311static int omac1_aes_128_vector(u8 *key, size_t num_elem,
2312                                                         u8 *addr[], size_t *len, u8 *mac)
2313{
2314        void *ctx;
2315        u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
2316        u8 *pos, *end;
2317        size_t i, e, left, total_len;
2318
2319        ctx = aes_encrypt_init(key, 16);
2320        if (ctx == NULL)
2321                return -1;
2322        memset(cbc, 0, AES_BLOCK_SIZE);
2323
2324        total_len = 0;
2325        for (e = 0; e < num_elem; e++)
2326                total_len += len[e];
2327        left = total_len;
2328
2329        e = 0;
2330        pos = addr[0];
2331        end = pos + len[0];
2332
2333        while (left >= AES_BLOCK_SIZE) {
2334                for (i = 0; i < AES_BLOCK_SIZE; i++) {
2335                        cbc[i] ^= *pos++;
2336                        if (pos >= end) {
2337                                e++;
2338                                pos = addr[e];
2339                                end = pos + len[e];
2340                        }
2341                }
2342                if (left > AES_BLOCK_SIZE)
2343                        aes_128_encrypt(ctx, cbc, cbc);
2344                left -= AES_BLOCK_SIZE;
2345        }
2346
2347        memset(pad, 0, AES_BLOCK_SIZE);
2348        aes_128_encrypt(ctx, pad, pad);
2349        gf_mulx(pad);
2350
2351        if (left || total_len == 0) {
2352                for (i = 0; i < left; i++) {
2353                        cbc[i] ^= *pos++;
2354                        if (pos >= end) {
2355                                e++;
2356                                pos = addr[e];
2357                                end = pos + len[e];
2358                        }
2359                }
2360                cbc[left] ^= 0x80;
2361                gf_mulx(pad);
2362        }
2363
2364        for (i = 0; i < AES_BLOCK_SIZE; i++)
2365                pad[i] ^= cbc[i];
2366        aes_128_encrypt(ctx, pad, mac);
2367        aes_encrypt_deinit(ctx);
2368        return 0;
2369}
2370
2371
2372/**
2373 * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
2374 * @key: 128-bit key for the hash operation
2375 * @data: Data buffer for which a MAC is determined
2376 * @data_len: Length of data buffer in bytes
2377 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
2378 * Returns: 0 on success, -1 on failure
2379 *
2380 * This is a mode for using block cipher (AES in this case) for authentication.
2381 * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
2382 * (SP) 800-38B.
2383 * modify for CONFIG_IEEE80211W */
2384int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac)
2385{
2386        return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
2387}
2388
2389/* Restore HW wep key setting according to key_mask */
2390void rtw_sec_restore_wep_key(struct adapter *adapter)
2391{
2392        struct security_priv *securitypriv = &(adapter->securitypriv);
2393        sint keyid;
2394
2395        if ((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) || (_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) {
2396                for (keyid = 0; keyid < 4; keyid++) {
2397                        if (securitypriv->key_mask & BIT(keyid)) {
2398                                if (keyid == securitypriv->dot11PrivacyKeyIndex)
2399                                        rtw_set_key(adapter, securitypriv, keyid, 1, false);
2400                                else
2401                                        rtw_set_key(adapter, securitypriv, keyid, 0, false);
2402                        }
2403                }
2404        }
2405}
2406
2407u8 rtw_handle_tkip_countermeasure(struct adapter *adapter, const char *caller)
2408{
2409        struct security_priv *securitypriv = &(adapter->securitypriv);
2410        u8 status = _SUCCESS;
2411
2412        if (securitypriv->btkip_countermeasure == true) {
2413                unsigned long passing_ms = jiffies_to_msecs(jiffies - securitypriv->btkip_countermeasure_time);
2414                if (passing_ms > 60*1000) {
2415                        DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%lus > 60s\n",
2416                                caller, ADPT_ARG(adapter), passing_ms/1000);
2417                        securitypriv->btkip_countermeasure = false;
2418                        securitypriv->btkip_countermeasure_time = 0;
2419                } else {
2420                        DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%lus < 60s\n",
2421                                caller, ADPT_ARG(adapter), passing_ms/1000);
2422                        status = _FAIL;
2423                }
2424        }
2425
2426        return status;
2427}
2428