linux/drivers/staging/rtl8712/rtl871x_security.c
<<
>>
Prefs
   1/******************************************************************************
   2 * rtl871x_security.c
   3 *
   4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
   5 * Linux device driver for RTL8192SU
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of version 2 of the GNU General Public License as
   9 * published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program; if not, write to the Free Software Foundation, Inc.,
  18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  19 *
  20 * Modifications for inclusion into the Linux staging tree are
  21 * Copyright(c) 2010 Larry Finger. All rights reserved.
  22 *
  23 * Contact information:
  24 * WLAN FAE <wlanfae@realtek.com>
  25 * Larry Finger <Larry.Finger@lwfinger.net>
  26 *
  27 ******************************************************************************/
  28
  29#define  _RTL871X_SECURITY_C_
  30
  31#include "osdep_service.h"
  32#include "drv_types.h"
  33#include "wifi.h"
  34#include "osdep_intf.h"
  35
  36/* =====WEP related===== */
  37
  38#define CRC32_POLY 0x04c11db7
  39
  40struct arc4context {
  41        u32 x;
  42        u32 y;
  43        u8 state[256];
  44};
  45
  46static void arcfour_init(struct arc4context *parc4ctx, u8 * key, u32 key_len)
  47{
  48        u32     t, u;
  49        u32     keyindex;
  50        u32     stateindex;
  51        u8 *state;
  52        u32     counter;
  53
  54        state = parc4ctx->state;
  55        parc4ctx->x = 0;
  56        parc4ctx->y = 0;
  57        for (counter = 0; counter < 256; counter++)
  58                state[counter] = (u8)counter;
  59        keyindex = 0;
  60        stateindex = 0;
  61        for (counter = 0; counter < 256; counter++) {
  62                t = state[counter];
  63                stateindex = (stateindex + key[keyindex] + t) & 0xff;
  64                u = state[stateindex];
  65                state[stateindex] = (u8)t;
  66                state[counter] = (u8)u;
  67                if (++keyindex >= key_len)
  68                        keyindex = 0;
  69        }
  70}
  71
  72static u32 arcfour_byte(struct arc4context *parc4ctx)
  73{
  74        u32 x;
  75        u32 y;
  76        u32 sx, sy;
  77        u8 *state;
  78
  79        state = parc4ctx->state;
  80        x = (parc4ctx->x + 1) & 0xff;
  81        sx = state[x];
  82        y = (sx + parc4ctx->y) & 0xff;
  83        sy = state[y];
  84        parc4ctx->x = x;
  85        parc4ctx->y = y;
  86        state[y] = (u8)sx;
  87        state[x] = (u8)sy;
  88        return state[(sx + sy) & 0xff];
  89}
  90
  91static void arcfour_encrypt(struct arc4context  *parc4ctx,
  92                     u8 *dest, u8 *src, u32 len)
  93{
  94        u32 i;
  95
  96        for (i = 0; i < len; i++)
  97                dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
  98}
  99
 100static sint bcrc32initialized;
 101static u32 crc32_table[256];
 102
 103static u8 crc32_reverseBit(u8 data)
 104{
 105        return ((u8)(data << 7) & 0x80) | ((data << 5) & 0x40) | ((data << 3)
 106                 & 0x20) | ((data << 1) & 0x10) | ((data >> 1) & 0x08) |
 107                 ((data >> 3) & 0x04) | ((data >> 5) & 0x02) | ((data >> 7) &
 108                 0x01);
 109}
 110
 111static void crc32_init(void)
 112{
 113        if (bcrc32initialized == 1)
 114                return;
 115        else {
 116                sint i, j;
 117                u32 c;
 118                u8 *p = (u8 *)&c, *p1;
 119                u8 k;
 120
 121                c = 0x12340000;
 122                for (i = 0; i < 256; ++i) {
 123                        k = crc32_reverseBit((u8)i);
 124                        for (c = ((u32)k) << 24, j = 8; j > 0; --j)
 125                                c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY :
 126                                    (c << 1);
 127                        p1 = (u8 *)&crc32_table[i];
 128                        p1[0] = crc32_reverseBit(p[3]);
 129                        p1[1] = crc32_reverseBit(p[2]);
 130                        p1[2] = crc32_reverseBit(p[1]);
 131                        p1[3] = crc32_reverseBit(p[0]);
 132                }
 133                bcrc32initialized = 1;
 134        }
 135}
 136
 137static u32 getcrc32(u8 *buf, u32 len)
 138{
 139        u8 *p;
 140        u32  crc;
 141
 142        if (bcrc32initialized == 0)
 143                crc32_init();
 144        crc = 0xffffffff; /* preload shift register, per CRC-32 spec */
 145        for (p = buf; len > 0; ++p, --len)
 146                crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
 147        return ~crc;    /* transmit complement, per CRC-32 spec */
 148}
 149
 150/*
 151        Need to consider the fragment  situation
 152*/
 153void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe)
 154{       /* exclude ICV */
 155        unsigned char   crc[4];
 156        struct arc4context  mycontext;
 157        u32 curfragnum, length, keylength;
 158        u8 *pframe, *payload, *iv;    /*,*wepkey*/
 159        u8 wepkey[16];
 160        struct  pkt_attrib  *pattrib = &((struct xmit_frame *)
 161                                       pxmitframe)->attrib;
 162        struct  security_priv *psecuritypriv = &padapter->securitypriv;
 163        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
 164
 165        if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
 166                return;
 167        pframe = ((struct xmit_frame *)pxmitframe)->buf_addr+TXDESC_OFFSET;
 168        /*start to encrypt each fragment*/
 169        if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
 170                keylength = psecuritypriv->DefKeylen[psecuritypriv->
 171                            PrivacyKeyIndex];
 172                for (curfragnum = 0; curfragnum < pattrib->nr_frags;
 173                     curfragnum++) {
 174                        iv = pframe+pattrib->hdrlen;
 175                        memcpy(&wepkey[0], iv, 3);
 176                        memcpy(&wepkey[3], &psecuritypriv->DefKey[
 177                                psecuritypriv->PrivacyKeyIndex].skey[0],
 178                                keylength);
 179                        payload = pframe+pattrib->iv_len+pattrib->hdrlen;
 180                        if ((curfragnum + 1) == pattrib->nr_frags) {
 181                                length = pattrib->last_txcmdsz-pattrib->
 182                                         hdrlen-pattrib->iv_len -
 183                                         pattrib->icv_len;
 184                                *((u32 *)crc) = cpu_to_le32(getcrc32(
 185                                                payload, length));
 186                                arcfour_init(&mycontext, wepkey, 3 + keylength);
 187                                arcfour_encrypt(&mycontext, payload, payload,
 188                                                length);
 189                                arcfour_encrypt(&mycontext, payload + length,
 190                                                crc, 4);
 191                        } else {
 192                                length = pxmitpriv->frag_len-pattrib->hdrlen -
 193                                         pattrib->iv_len-pattrib->icv_len;
 194                                *((u32 *)crc) = cpu_to_le32(getcrc32(
 195                                                payload, length));
 196                                arcfour_init(&mycontext, wepkey, 3 + keylength);
 197                                arcfour_encrypt(&mycontext, payload, payload,
 198                                                length);
 199                                arcfour_encrypt(&mycontext, payload+length,
 200                                                crc, 4);
 201                                pframe += pxmitpriv->frag_len;
 202                                pframe = (u8 *)RND4((addr_t)(pframe));
 203                        }
 204                }
 205        }
 206}
 207
 208void r8712_wep_decrypt(struct _adapter  *padapter, u8 *precvframe)
 209{
 210        /* exclude ICV */
 211        u8 crc[4];
 212        struct arc4context  mycontext;
 213        u32 length, keylength;
 214        u8 *pframe, *payload, *iv, wepkey[16];
 215        u8  keyindex;
 216        struct rx_pkt_attrib  *prxattrib = &(((union recv_frame *)
 217                                          precvframe)->u.hdr.attrib);
 218        struct security_priv *psecuritypriv = &padapter->securitypriv;
 219
 220        pframe = (unsigned char *)((union recv_frame *)precvframe)->
 221                  u.hdr.rx_data;
 222        /* start to decrypt recvframe */
 223        if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt ==
 224             _WEP104_)) {
 225                iv = pframe + prxattrib->hdrlen;
 226                keyindex = (iv[3] & 0x3);
 227                keylength = psecuritypriv->DefKeylen[keyindex];
 228                memcpy(&wepkey[0], iv, 3);
 229                memcpy(&wepkey[3], &psecuritypriv->DefKey[
 230                        psecuritypriv->PrivacyKeyIndex].skey[0],
 231                        keylength);
 232                length = ((union recv_frame *)precvframe)->
 233                           u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
 234                payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
 235                /* decrypt payload include icv */
 236                arcfour_init(&mycontext, wepkey, 3 + keylength);
 237                arcfour_encrypt(&mycontext, payload, payload,  length);
 238                /* calculate icv and compare the icv */
 239                *((u32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4));
 240        }
 241        return;
 242}
 243
 244/* 3 =====TKIP related===== */
 245
 246static u32 secmicgetuint32(u8 *p)
 247/* Convert from Byte[] to Us4Byte32 in a portable way */
 248{
 249        s32 i;
 250        u32 res = 0;
 251
 252        for (i = 0; i < 4; i++)
 253                res |= ((u32)(*p++)) << (8 * i);
 254        return res;
 255}
 256
 257static void secmicputuint32(u8 *p, u32 val)
 258/* Convert from Us4Byte32 to Byte[] in a portable way */
 259{
 260        long i;
 261        for (i = 0; i < 4; i++) {
 262                *p++ = (u8) (val & 0xff);
 263                val >>= 8;
 264        }
 265}
 266
 267static void secmicclear(struct mic_data *pmicdata)
 268{
 269/* Reset the state to the empty message. */
 270        pmicdata->L = pmicdata->K0;
 271        pmicdata->R = pmicdata->K1;
 272        pmicdata->nBytesInM = 0;
 273        pmicdata->M = 0;
 274}
 275
 276void r8712_secmicsetkey(struct mic_data *pmicdata, u8 * key)
 277{
 278        /* Set the key */
 279        pmicdata->K0 = secmicgetuint32(key);
 280        pmicdata->K1 = secmicgetuint32(key + 4);
 281        /* and reset the message */
 282        secmicclear(pmicdata);
 283}
 284
 285static void secmicappendbyte(struct mic_data *pmicdata, u8 b)
 286{
 287        /* Append the byte to our word-sized buffer */
 288        pmicdata->M |= ((u32)b) << (8 * pmicdata->nBytesInM);
 289        pmicdata->nBytesInM++;
 290        /* Process the word if it is full. */
 291        if (pmicdata->nBytesInM >= 4) {
 292                pmicdata->L ^= pmicdata->M;
 293                pmicdata->R ^= ROL32(pmicdata->L, 17);
 294                pmicdata->L += pmicdata->R;
 295                pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) |
 296                               ((pmicdata->L & 0x00ff00ff) << 8);
 297                pmicdata->L += pmicdata->R;
 298                pmicdata->R ^= ROL32(pmicdata->L, 3);
 299                pmicdata->L += pmicdata->R;
 300                pmicdata->R ^= ROR32(pmicdata->L, 2);
 301                pmicdata->L += pmicdata->R;
 302                /* Clear the buffer */
 303                pmicdata->M = 0;
 304                pmicdata->nBytesInM = 0;
 305        }
 306}
 307
 308void r8712_secmicappend(struct mic_data *pmicdata, u8 * src, u32 nbytes)
 309{
 310        /* This is simple */
 311        while (nbytes > 0) {
 312                secmicappendbyte(pmicdata, *src++);
 313                nbytes--;
 314        }
 315}
 316
 317void r8712_secgetmic(struct mic_data *pmicdata, u8 *dst)
 318{
 319        /* Append the minimum padding */
 320        secmicappendbyte(pmicdata, 0x5a);
 321        secmicappendbyte(pmicdata, 0);
 322        secmicappendbyte(pmicdata, 0);
 323        secmicappendbyte(pmicdata, 0);
 324        secmicappendbyte(pmicdata, 0);
 325        /* and then zeroes until the length is a multiple of 4 */
 326        while (pmicdata->nBytesInM != 0)
 327                secmicappendbyte(pmicdata, 0);
 328        /* The appendByte function has already computed the result. */
 329        secmicputuint32(dst, pmicdata->L);
 330        secmicputuint32(dst + 4, pmicdata->R);
 331        /* Reset to the empty message. */
 332        secmicclear(pmicdata);
 333}
 334
 335void seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code,
 336                    u8 pri)
 337{
 338
 339        struct mic_data micdata;
 340        u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
 341
 342        r8712_secmicsetkey(&micdata, key);
 343        priority[0] = pri;
 344        /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
 345        if (header[1] & 1) {   /* ToDS==1 */
 346                r8712_secmicappend(&micdata, &header[16], 6);  /* DA */
 347                if (header[1] & 2)  /* From Ds==1 */
 348                        r8712_secmicappend(&micdata, &header[24], 6);
 349                else
 350                        r8712_secmicappend(&micdata, &header[10], 6);
 351        } else {        /* ToDS==0 */
 352                r8712_secmicappend(&micdata, &header[4], 6);   /* DA */
 353                if (header[1] & 2)  /* From Ds==1 */
 354                        r8712_secmicappend(&micdata, &header[16], 6);
 355                else
 356                        r8712_secmicappend(&micdata, &header[10], 6);
 357        }
 358        r8712_secmicappend(&micdata, &priority[0], 4);
 359        r8712_secmicappend(&micdata, data, data_len);
 360        r8712_secgetmic(&micdata, mic_code);
 361}
 362
 363/* macros for extraction/creation of unsigned char/unsigned short values  */
 364#define RotR1(v16)   ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
 365#define   Lo8(v16)   ((u8)((v16) & 0x00FF))
 366#define   Hi8(v16)   ((u8)(((v16) >> 8) & 0x00FF))
 367#define  Lo16(v32)   ((u16)((v32) & 0xFFFF))
 368#define  Hi16(v32)   ((u16)(((v32) >> 16) & 0xFFFF))
 369#define  Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
 370
 371/* select the Nth 16-bit word of the temporal key unsigned char array TK[]   */
 372#define  TK16(N)  Mk16(tk[2 * (N) + 1], tk[2 * (N)])
 373
 374/* S-box lookup: 16 bits --> 16 bits */
 375#define _S_(v16)  (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
 376
 377/* fixed algorithm "parameters" */
 378#define PHASE1_LOOP_CNT   8    /* this needs to be "big enough"     */
 379#define TA_SIZE           6    /*  48-bit transmitter address       */
 380#define TK_SIZE          16    /* 128-bit temporal key              */
 381#define P1K_SIZE         10    /*  80-bit Phase1 key                */
 382#define RC4_KEY_SIZE     16    /* 128-bit RC4KEY (104 bits unknown) */
 383
 384
 385/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
 386static const unsigned short Sbox1[2][256] = {/* Sbox for hash (can be in ROM) */
 387        {
 388        0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
 389        0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
 390        0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
 391        0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
 392        0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
 393        0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
 394        0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
 395        0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
 396        0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
 397        0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
 398        0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
 399        0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
 400        0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
 401        0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
 402        0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
 403        0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
 404        0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
 405        0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
 406        0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
 407        0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
 408        0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
 409        0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
 410        0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
 411        0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
 412        0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
 413        0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
 414        0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
 415        0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
 416        0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
 417        0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
 418        0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
 419        0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
 420        },
 421        {  /* second half is unsigned char-reversed version of first! */
 422        0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
 423        0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
 424        0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
 425        0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
 426        0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
 427        0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
 428        0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
 429        0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
 430        0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
 431        0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
 432        0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
 433        0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
 434        0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
 435        0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
 436        0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
 437        0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
 438        0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
 439        0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
 440        0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
 441        0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
 442        0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
 443        0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
 444        0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
 445        0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
 446        0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
 447        0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
 448        0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
 449        0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
 450        0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
 451        0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
 452        0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
 453        0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
 454        }
 455};
 456
 457/*
 458**********************************************************************
 459* Routine: Phase 1 -- generate P1K, given TA, TK, IV32
 460*
 461* Inputs:
 462*     tk[]      = temporal key                         [128 bits]
 463*     ta[]      = transmitter's MAC address            [ 48 bits]
 464*     iv32      = upper 32 bits of IV                  [ 32 bits]
 465* Output:
 466*     p1k[]     = Phase 1 key                          [ 80 bits]
 467*
 468* Note:
 469*     This function only needs to be called every 2**16 packets,
 470*     although in theory it could be called every packet.
 471*
 472**********************************************************************
 473*/
 474static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
 475{
 476        sint  i;
 477
 478        /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5]     */
 479        p1k[0] = Lo16(iv32);
 480        p1k[1] = Hi16(iv32);
 481        p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
 482        p1k[3] = Mk16(ta[3], ta[2]);
 483        p1k[4] = Mk16(ta[5], ta[4]);
 484        /* Now compute an unbalanced Feistel cipher with 80-bit block */
 485        /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
 486        for (i = 0; i < PHASE1_LOOP_CNT; i++) {  /* Each add is mod 2**16 */
 487                p1k[0] += _S_(p1k[4] ^ TK16((i&1) + 0));
 488                p1k[1] += _S_(p1k[0] ^ TK16((i&1) + 2));
 489                p1k[2] += _S_(p1k[1] ^ TK16((i&1) + 4));
 490                p1k[3] += _S_(p1k[2] ^ TK16((i&1) + 6));
 491                p1k[4] += _S_(p1k[3] ^ TK16((i&1) + 0));
 492                p1k[4] +=  (unsigned short)i;   /* avoid "slide attacks" */
 493        }
 494}
 495
 496/*
 497**********************************************************************
 498* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
 499*
 500* Inputs:
 501*     tk[]      = Temporal key                         [128 bits]
 502*     p1k[]     = Phase 1 output key                   [ 80 bits]
 503*     iv16      = low 16 bits of IV counter            [ 16 bits]
 504* Output:
 505*     rc4key[]  = the key used to encrypt the packet   [128 bits]
 506*
 507* Note:
 508*     The value {TA,IV32,IV16} for Phase1/Phase2 must be unique
 509*     across all packets using the same key TK value. Then, for a
 510*     given value of TK[], this TKIP48 construction guarantees that
 511*     the final RC4KEY value is unique across all packets.
 512*
 513* Suggested implementation optimization: if PPK[] is "overlaid"
 514*     appropriately on RC4KEY[], there is no need for the final
 515*     for loop below that copies the PPK[] result into RC4KEY[].
 516*
 517**********************************************************************
 518*/
 519static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
 520{
 521        sint  i;
 522        u16 PPK[6];                     /* temporary key for mixing    */
 523
 524        /* Note: all adds in the PPK[] equations below are mod 2**16 */
 525        for (i = 0; i < 5; i++)
 526                PPK[i] = p1k[i]; /* first, copy P1K to PPK */
 527        PPK[5]  =  p1k[4] + iv16; /* next,  add in IV16 */
 528        /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
 529        PPK[0] += _S_(PPK[5] ^ TK16(0));   /* Mix key in each "round" */
 530        PPK[1] += _S_(PPK[0] ^ TK16(1));
 531        PPK[2] += _S_(PPK[1] ^ TK16(2));
 532        PPK[3] += _S_(PPK[2] ^ TK16(3));
 533        PPK[4] += _S_(PPK[3] ^ TK16(4));
 534        PPK[5] += _S_(PPK[4] ^ TK16(5));   /* Total # S-box lookups == 6  */
 535        /* Final sweep: bijective, "linear". Rotates kill LSB correlations   */
 536        PPK[0] +=  RotR1(PPK[5] ^ TK16(6));
 537        PPK[1] +=  RotR1(PPK[0] ^ TK16(7));   /* Use all of TK[] in Phase2   */
 538        PPK[2] +=  RotR1(PPK[1]);
 539        PPK[3] +=  RotR1(PPK[2]);
 540        PPK[4] +=  RotR1(PPK[3]);
 541        PPK[5] +=  RotR1(PPK[4]);
 542        /* Note: At this point, for a given key TK[0..15], the 96-bit output */
 543        /* value PPK[0..5] is guaranteed to be unique, as a function   */
 544        /* of the 96-bit "input" value   {TA,IV32,IV16}. That is, P1K  */
 545        /* is now a keyed permutation of {TA,IV32,IV16}. */
 546        /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key   */
 547        rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV  */
 548        rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys  */
 549        rc4key[2] = Lo8(iv16);
 550        rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
 551        /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15]  (little-endian) */
 552        for (i = 0; i < 6; i++) {
 553                rc4key[4 + 2 * i] = Lo8(PPK[i]);
 554                rc4key[5 + 2 * i] = Hi8(PPK[i]);
 555        }
 556}
 557
 558/*The hlen isn't include the IV*/
 559u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe)
 560{       /*  exclude ICV */
 561        u16 pnl;
 562        u32 pnh;
 563        u8 rc4key[16];
 564        u8 ttkey[16];
 565        u8 crc[4];
 566        struct arc4context mycontext;
 567        u32 curfragnum, length, prwskeylen;
 568
 569        u8 *pframe, *payload, *iv, *prwskey;
 570        union pn48 txpn;
 571        struct sta_info *stainfo;
 572        struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
 573        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 574        u32 res = _SUCCESS;
 575
 576        if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
 577                return _FAIL;
 578
 579        pframe = ((struct xmit_frame *)pxmitframe)->buf_addr+TXDESC_OFFSET;
 580        /* 4 start to encrypt each fragment */
 581        if (pattrib->encrypt == _TKIP_) {
 582                if (pattrib->psta)
 583                        stainfo = pattrib->psta;
 584                else
 585                        stainfo = r8712_get_stainfo(&padapter->stapriv,
 586                                  &pattrib->ra[0]);
 587                if (stainfo != NULL) {
 588                        prwskey = &stainfo->x_UncstKey.skey[0];
 589                        prwskeylen = 16;
 590                        for (curfragnum = 0; curfragnum < pattrib->nr_frags;
 591                             curfragnum++) {
 592                                iv = pframe + pattrib->hdrlen;
 593                                payload = pframe+pattrib->iv_len +
 594                                          pattrib->hdrlen;
 595                                GET_TKIP_PN(iv, txpn);
 596                                pnl = (u16)(txpn.val);
 597                                pnh = (u32)(txpn.val >> 16);
 598                                phase1((u16 *)&ttkey[0], prwskey, &pattrib->
 599                                       ta[0], pnh);
 600                                phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0],
 601                                       pnl);
 602                                if ((curfragnum + 1) == pattrib->nr_frags) {
 603                                        /* 4 the last fragment */
 604                                        length = pattrib->last_txcmdsz -
 605                                             pattrib->hdrlen-pattrib->iv_len -
 606                                             pattrib->icv_len;
 607                                        *((u32 *)crc) = cpu_to_le32(
 608                                                getcrc32(payload, length));
 609                                        arcfour_init(&mycontext, rc4key, 16);
 610                                        arcfour_encrypt(&mycontext, payload,
 611                                                        payload, length);
 612                                        arcfour_encrypt(&mycontext, payload +
 613                                                        length, crc, 4);
 614                                } else {
 615                                        length = pxmitpriv->frag_len-pattrib->
 616                                                 hdrlen-pattrib->
 617                                                 iv_len-pattrib->icv_len;
 618                                        *((u32 *)crc) = cpu_to_le32(getcrc32(
 619                                                        payload, length));
 620                                        arcfour_init(&mycontext, rc4key, 16);
 621                                        arcfour_encrypt(&mycontext, payload,
 622                                                         payload, length);
 623                                        arcfour_encrypt(&mycontext,
 624                                                        payload+length, crc, 4);
 625                                        pframe += pxmitpriv->frag_len;
 626                                        pframe = (u8 *)RND4((addr_t)(pframe));
 627                                }
 628                        }
 629                } else
 630                        res = _FAIL;
 631        }
 632        return res;
 633}
 634
 635/* The hlen doesn't include the IV */
 636u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe)
 637{       /* exclude ICV */
 638        u16 pnl;
 639        u32 pnh;
 640        u8 rc4key[16];
 641        u8 ttkey[16];
 642        u8 crc[4];
 643        struct arc4context mycontext;
 644        u32 length, prwskeylen;
 645        u8 *pframe, *payload, *iv, *prwskey, idx = 0;
 646        union pn48 txpn;
 647        struct  sta_info *stainfo;
 648        struct  rx_pkt_attrib *prxattrib = &((union recv_frame *)
 649                                           precvframe)->u.hdr.attrib;
 650        struct  security_priv   *psecuritypriv = &padapter->securitypriv;
 651
 652        pframe = (unsigned char *)((union recv_frame *)
 653                                   precvframe)->u.hdr.rx_data;
 654        /* 4 start to decrypt recvframe */
 655        if (prxattrib->encrypt == _TKIP_) {
 656                stainfo = r8712_get_stainfo(&padapter->stapriv,
 657                                            &prxattrib->ta[0]);
 658                if (stainfo != NULL) {
 659                        iv = pframe+prxattrib->hdrlen;
 660                        payload = pframe+prxattrib->iv_len + prxattrib->hdrlen;
 661                        length = ((union recv_frame *)precvframe)->
 662                                 u.hdr.len - prxattrib->hdrlen -
 663                                 prxattrib->iv_len;
 664                        if (IS_MCAST(prxattrib->ra)) {
 665                                idx = iv[3];
 666                                prwskey = &psecuritypriv->XGrpKey[
 667                                         ((idx >> 6) & 0x3) - 1].skey[0];
 668                                if (psecuritypriv->binstallGrpkey == false)
 669                                        return _FAIL;
 670                        } else
 671                                prwskey = &stainfo->x_UncstKey.skey[0];
 672                        prwskeylen = 16;
 673                        GET_TKIP_PN(iv, txpn);
 674                        pnl = (u16)(txpn.val);
 675                        pnh = (u32)(txpn.val >> 16);
 676                        phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0],
 677                                pnh);
 678                        phase2(&rc4key[0], prwskey, (unsigned short *)
 679                               &ttkey[0], pnl);
 680                        /* 4 decrypt payload include icv */
 681                        arcfour_init(&mycontext, rc4key, 16);
 682                        arcfour_encrypt(&mycontext, payload, payload, length);
 683                        *((u32 *)crc) = cpu_to_le32(getcrc32(payload,
 684                                        length - 4));
 685                        if (crc[3] != payload[length - 1] ||
 686                            crc[2] != payload[length - 2] ||
 687                            crc[1] != payload[length - 3] ||
 688                            crc[0] != payload[length - 4])
 689                                return _FAIL;
 690                } else
 691                        return _FAIL;
 692        }
 693        return _SUCCESS;
 694}
 695
 696/* 3 =====AES related===== */
 697
 698#define MAX_MSG_SIZE    2048
 699/*****************************/
 700/******** SBOX Table *********/
 701/*****************************/
 702
 703static const u8 sbox_table[256] = {
 704        0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
 705        0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
 706        0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
 707        0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
 708        0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
 709        0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
 710        0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
 711        0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
 712        0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
 713        0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
 714        0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
 715        0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
 716        0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
 717        0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
 718        0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
 719        0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
 720        0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
 721        0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
 722        0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
 723        0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
 724        0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
 725        0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
 726        0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
 727        0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
 728        0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
 729        0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
 730        0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
 731        0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
 732        0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
 733        0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
 734        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
 735        0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
 736};
 737
 738/****************************************/
 739/* aes128k128d()                        */
 740/* Performs a 128 bit AES encrypt with  */
 741/* 128 bit data.                        */
 742/****************************************/
 743static void xor_128(u8 *a, u8 *b, u8 *out)
 744{
 745        sint i;
 746
 747        for (i = 0; i < 16; i++)
 748                out[i] = a[i] ^ b[i];
 749}
 750
 751static void xor_32(u8 *a, u8 *b, u8 *out)
 752{
 753        sint i;
 754        for (i = 0; i < 4; i++)
 755                out[i] = a[i] ^ b[i];
 756}
 757
 758static u8 sbox(u8 a)
 759{
 760        return sbox_table[(sint)a];
 761}
 762
 763static void next_key(u8 *key, sint round)
 764{
 765        u8 rcon;
 766        u8 sbox_key[4];
 767        u8 rcon_table[12] = {
 768                0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
 769                0x1b, 0x36, 0x36, 0x36
 770        };
 771
 772        sbox_key[0] = sbox(key[13]);
 773        sbox_key[1] = sbox(key[14]);
 774        sbox_key[2] = sbox(key[15]);
 775        sbox_key[3] = sbox(key[12]);
 776        rcon = rcon_table[round];
 777        xor_32(&key[0], sbox_key, &key[0]);
 778        key[0] = key[0] ^ rcon;
 779        xor_32(&key[4], &key[0], &key[4]);
 780        xor_32(&key[8], &key[4], &key[8]);
 781        xor_32(&key[12], &key[8], &key[12]);
 782}
 783
 784static void byte_sub(u8 *in, u8 *out)
 785{
 786        sint i;
 787        for (i = 0; i < 16; i++)
 788                out[i] = sbox(in[i]);
 789}
 790
 791static void shift_row(u8 *in, u8 *out)
 792{
 793        out[0] =  in[0];
 794        out[1] =  in[5];
 795        out[2] =  in[10];
 796        out[3] =  in[15];
 797        out[4] =  in[4];
 798        out[5] =  in[9];
 799        out[6] =  in[14];
 800        out[7] =  in[3];
 801        out[8] =  in[8];
 802        out[9] =  in[13];
 803        out[10] = in[2];
 804        out[11] = in[7];
 805        out[12] = in[12];
 806        out[13] = in[1];
 807        out[14] = in[6];
 808        out[15] = in[11];
 809}
 810
 811static void mix_column(u8 *in, u8 *out)
 812{
 813        sint i;
 814        u8 add1b[4];
 815        u8 add1bf7[4];
 816        u8 rotl[4];
 817        u8 swap_halfs[4];
 818        u8 andf7[4];
 819        u8 rotr[4];
 820        u8 temp[4];
 821        u8 tempb[4];
 822
 823        for (i = 0 ; i < 4; i++) {
 824                if ((in[i] & 0x80) == 0x80)
 825                        add1b[i] = 0x1b;
 826                else
 827                        add1b[i] = 0x00;
 828        }
 829        swap_halfs[0] = in[2];    /* Swap halves */
 830        swap_halfs[1] = in[3];
 831        swap_halfs[2] = in[0];
 832        swap_halfs[3] = in[1];
 833        rotl[0] = in[3];        /* Rotate left 8 bits */
 834        rotl[1] = in[0];
 835        rotl[2] = in[1];
 836        rotl[3] = in[2];
 837        andf7[0] = in[0] & 0x7f;
 838        andf7[1] = in[1] & 0x7f;
 839        andf7[2] = in[2] & 0x7f;
 840        andf7[3] = in[3] & 0x7f;
 841        for (i = 3; i > 0; i--) {   /* logical shift left 1 bit */
 842                andf7[i] = andf7[i] << 1;
 843                if ((andf7[i-1] & 0x80) == 0x80)
 844                        andf7[i] = (andf7[i] | 0x01);
 845        }
 846        andf7[0] = andf7[0] << 1;
 847        andf7[0] = andf7[0] & 0xfe;
 848        xor_32(add1b, andf7, add1bf7);
 849        xor_32(in, add1bf7, rotr);
 850        temp[0] = rotr[0];         /* Rotate right 8 bits */
 851        rotr[0] = rotr[1];
 852        rotr[1] = rotr[2];
 853        rotr[2] = rotr[3];
 854        rotr[3] = temp[0];
 855        xor_32(add1bf7, rotr, temp);
 856        xor_32(swap_halfs, rotl, tempb);
 857        xor_32(temp, tempb, out);
 858}
 859
 860static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
 861{
 862        sint round;
 863        sint i;
 864        u8 intermediatea[16];
 865        u8 intermediateb[16];
 866        u8 round_key[16];
 867
 868        for (i = 0; i < 16; i++)
 869                round_key[i] = key[i];
 870        for (round = 0; round < 11; round++) {
 871                if (round == 0) {
 872                        xor_128(round_key, data, ciphertext);
 873                        next_key(round_key, round);
 874                } else if (round == 10) {
 875                        byte_sub(ciphertext, intermediatea);
 876                        shift_row(intermediatea, intermediateb);
 877                        xor_128(intermediateb, round_key, ciphertext);
 878                } else {   /* 1 - 9 */
 879                        byte_sub(ciphertext, intermediatea);
 880                        shift_row(intermediatea, intermediateb);
 881                        mix_column(&intermediateb[0], &intermediatea[0]);
 882                        mix_column(&intermediateb[4], &intermediatea[4]);
 883                        mix_column(&intermediateb[8], &intermediatea[8]);
 884                        mix_column(&intermediateb[12], &intermediatea[12]);
 885                        xor_128(intermediatea, round_key, ciphertext);
 886                        next_key(round_key, round);
 887                }
 888        }
 889}
 890
 891/************************************************/
 892/* construct_mic_iv()                           */
 893/* Builds the MIC IV from header fields and PN  */
 894/************************************************/
 895static void construct_mic_iv(u8 *mic_iv, sint qc_exists, sint a4_exists,
 896                             u8 *mpdu, uint payload_length, u8 *pn_vector)
 897{
 898        sint i;
 899
 900        mic_iv[0] = 0x59;
 901        if (qc_exists && a4_exists)
 902                mic_iv[1] = mpdu[30] & 0x0f;    /* QoS_TC           */
 903        if (qc_exists && !a4_exists)
 904                mic_iv[1] = mpdu[24] & 0x0f;   /* mute bits 7-4    */
 905        if (!qc_exists)
 906                mic_iv[1] = 0x00;
 907        for (i = 2; i < 8; i++)
 908                mic_iv[i] = mpdu[i + 8];
 909        for (i = 8; i < 14; i++)
 910                mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
 911        mic_iv[14] = (unsigned char) (payload_length / 256);
 912        mic_iv[15] = (unsigned char) (payload_length % 256);
 913}
 914
 915/************************************************/
 916/* construct_mic_header1()                      */
 917/* Builds the first MIC header block from       */
 918/* header fields.                               */
 919/************************************************/
 920static void construct_mic_header1(u8 *mic_header1, sint header_length, u8 *mpdu)
 921{
 922        mic_header1[0] = (u8)((header_length - 2) / 256);
 923        mic_header1[1] = (u8)((header_length - 2) % 256);
 924        mic_header1[2] = mpdu[0] & 0xcf;    /* Mute CF poll & CF ack bits */
 925        /* Mute retry, more data and pwr mgt bits */
 926        mic_header1[3] = mpdu[1] & 0xc7;
 927        mic_header1[4] = mpdu[4];       /* A1 */
 928        mic_header1[5] = mpdu[5];
 929        mic_header1[6] = mpdu[6];
 930        mic_header1[7] = mpdu[7];
 931        mic_header1[8] = mpdu[8];
 932        mic_header1[9] = mpdu[9];
 933        mic_header1[10] = mpdu[10];     /* A2 */
 934        mic_header1[11] = mpdu[11];
 935        mic_header1[12] = mpdu[12];
 936        mic_header1[13] = mpdu[13];
 937        mic_header1[14] = mpdu[14];
 938        mic_header1[15] = mpdu[15];
 939}
 940
 941/************************************************/
 942/* construct_mic_header2()                      */
 943/* Builds the last MIC header block from        */
 944/* header fields.                               */
 945/************************************************/
 946static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, sint a4_exists,
 947                           sint qc_exists)
 948{
 949        sint i;
 950
 951        for (i = 0; i < 16; i++)
 952                mic_header2[i] = 0x00;
 953        mic_header2[0] = mpdu[16];    /* A3 */
 954        mic_header2[1] = mpdu[17];
 955        mic_header2[2] = mpdu[18];
 956        mic_header2[3] = mpdu[19];
 957        mic_header2[4] = mpdu[20];
 958        mic_header2[5] = mpdu[21];
 959        mic_header2[6] = 0x00;
 960        mic_header2[7] = 0x00; /* mpdu[23]; */
 961        if (!qc_exists && a4_exists)
 962                for (i = 0; i < 6; i++)
 963                        mic_header2[8 + i] = mpdu[24 + i];   /* A4 */
 964        if (qc_exists && !a4_exists) {
 965                mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
 966                mic_header2[9] = mpdu[25] & 0x00;
 967        }
 968        if (qc_exists && a4_exists) {
 969                for (i = 0; i < 6; i++)
 970                        mic_header2[8 + i] = mpdu[24 + i];   /* A4 */
 971                mic_header2[14] = mpdu[30] & 0x0f;
 972                mic_header2[15] = mpdu[31] & 0x00;
 973        }
 974}
 975
 976/************************************************/
 977/* construct_mic_header2()                      */
 978/* Builds the last MIC header block from        */
 979/* header fields.                               */
 980/************************************************/
 981static void construct_ctr_preload(u8 *ctr_preload, sint a4_exists, sint qc_exists,
 982                           u8 *mpdu, u8 *pn_vector, sint c)
 983{
 984        sint i;
 985
 986        for (i = 0; i < 16; i++)
 987                ctr_preload[i] = 0x00;
 988        i = 0;
 989        ctr_preload[0] = 0x01;    /* flag */
 990        if (qc_exists && a4_exists)
 991                ctr_preload[1] = mpdu[30] & 0x0f;
 992        if (qc_exists && !a4_exists)
 993                ctr_preload[1] = mpdu[24] & 0x0f;
 994        for (i = 2; i < 8; i++)
 995                ctr_preload[i] = mpdu[i + 8];
 996        for (i = 8; i < 14; i++)
 997                ctr_preload[i] = pn_vector[13 - i];
 998        ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */
 999        ctr_preload[15] = (unsigned char) (c % 256);
1000}
1001
1002/************************************/
1003/* bitwise_xor()                    */
1004/* A 128 bit, bitwise exclusive or  */
1005/************************************/
1006static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
1007{
1008        sint i;
1009
1010        for (i = 0; i < 16; i++)
1011                out[i] = ina[i] ^ inb[i];
1012}
1013
1014static sint aes_cipher(u8 *key, uint    hdrlen,
1015                        u8 *pframe, uint plen)
1016{
1017        uint qc_exists, a4_exists, i, j, payload_remainder;
1018        uint num_blocks, payload_index;
1019
1020        u8 pn_vector[6];
1021        u8 mic_iv[16];
1022        u8 mic_header1[16];
1023        u8 mic_header2[16];
1024        u8 ctr_preload[16];
1025
1026        /* Intermediate Buffers */
1027        u8 chain_buffer[16];
1028        u8 aes_out[16];
1029        u8 padded_buffer[16];
1030        u8 mic[8];
1031        uint    frtype  = GetFrameType(pframe);
1032        uint    frsubtype  = GetFrameSubType(pframe);
1033
1034        frsubtype = frsubtype >> 4;
1035        memset((void *)mic_iv, 0, 16);
1036        memset((void *)mic_header1, 0, 16);
1037        memset((void *)mic_header2, 0, 16);
1038        memset((void *)ctr_preload, 0, 16);
1039        memset((void *)chain_buffer, 0, 16);
1040        memset((void *)aes_out, 0, 16);
1041        memset((void *)padded_buffer, 0, 16);
1042
1043        if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen ==  WLAN_HDR_A3_QOS_LEN))
1044                a4_exists = 0;
1045        else
1046                a4_exists = 1;
1047
1048        if ((frtype == WIFI_DATA_CFACK) ||
1049             (frtype == WIFI_DATA_CFPOLL) ||
1050             (frtype == WIFI_DATA_CFACKPOLL)) {
1051                        qc_exists = 1;
1052                        if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
1053                                hdrlen += 2;
1054        } else if ((frsubtype == 0x08) ||
1055                   (frsubtype == 0x09) ||
1056                   (frsubtype == 0x0a) ||
1057                   (frsubtype == 0x0b)) {
1058                        if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
1059                                hdrlen += 2;
1060                        qc_exists = 1;
1061        } else
1062                qc_exists = 0;
1063        pn_vector[0] = pframe[hdrlen];
1064        pn_vector[1] = pframe[hdrlen+1];
1065        pn_vector[2] = pframe[hdrlen+4];
1066        pn_vector[3] = pframe[hdrlen+5];
1067        pn_vector[4] = pframe[hdrlen+6];
1068        pn_vector[5] = pframe[hdrlen+7];
1069        construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector);
1070        construct_mic_header1(mic_header1, hdrlen, pframe);
1071        construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists);
1072        payload_remainder = plen % 16;
1073        num_blocks = plen / 16;
1074        /* Find start of payload */
1075        payload_index = (hdrlen + 8);
1076        /* Calculate MIC */
1077        aes128k128d(key, mic_iv, aes_out);
1078        bitwise_xor(aes_out, mic_header1, chain_buffer);
1079        aes128k128d(key, chain_buffer, aes_out);
1080        bitwise_xor(aes_out, mic_header2, chain_buffer);
1081        aes128k128d(key, chain_buffer, aes_out);
1082        for (i = 0; i < num_blocks; i++) {
1083                bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1084                payload_index += 16;
1085                aes128k128d(key, chain_buffer, aes_out);
1086        }
1087        /* Add on the final payload block if it needs padding */
1088        if (payload_remainder > 0) {
1089                for (j = 0; j < 16; j++)
1090                        padded_buffer[j] = 0x00;
1091                for (j = 0; j < payload_remainder; j++)
1092                        padded_buffer[j] = pframe[payload_index++];
1093                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1094                aes128k128d(key, chain_buffer, aes_out);
1095        }
1096        for (j = 0; j < 8; j++)
1097                mic[j] = aes_out[j];
1098        /* Insert MIC into payload */
1099        for (j = 0; j < 8; j++)
1100                pframe[payload_index+j] = mic[j];
1101        payload_index = hdrlen + 8;
1102        for (i = 0; i < num_blocks; i++) {
1103                construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1104                                      pframe, pn_vector, i + 1);
1105                aes128k128d(key, ctr_preload, aes_out);
1106                bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1107                for (j = 0; j < 16; j++)
1108                        pframe[payload_index++] = chain_buffer[j];
1109        }
1110        if (payload_remainder > 0) {  /* If short final block, then pad it,*/
1111                                      /* encrypt and copy unpadded part back */
1112                construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1113                                      pframe, pn_vector, num_blocks+1);
1114                for (j = 0; j < 16; j++)
1115                        padded_buffer[j] = 0x00;
1116                for (j = 0; j < payload_remainder; j++)
1117                        padded_buffer[j] = pframe[payload_index+j];
1118                aes128k128d(key, ctr_preload, aes_out);
1119                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1120                for (j = 0; j < payload_remainder; j++)
1121                        pframe[payload_index++] = chain_buffer[j];
1122        }
1123        /* Encrypt the MIC */
1124        construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1125                              pframe, pn_vector, 0);
1126        for (j = 0; j < 16; j++)
1127                padded_buffer[j] = 0x00;
1128        for (j = 0; j < 8; j++)
1129                padded_buffer[j] = pframe[j+hdrlen+8+plen];
1130        aes128k128d(key, ctr_preload, aes_out);
1131        bitwise_xor(aes_out, padded_buffer, chain_buffer);
1132        for (j = 0; j < 8; j++)
1133                pframe[payload_index++] = chain_buffer[j];
1134        return _SUCCESS;
1135}
1136
1137u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe)
1138{       /* exclude ICV */
1139        /* Intermediate Buffers */
1140        sint    curfragnum, length;
1141        u32     prwskeylen;
1142        u8      *pframe, *prwskey;
1143        struct  sta_info *stainfo;
1144        struct  pkt_attrib  *pattrib = &((struct xmit_frame *)
1145                                       pxmitframe)->attrib;
1146        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
1147        u32 res = _SUCCESS;
1148
1149        if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
1150                return _FAIL;
1151        pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
1152        /* 4 start to encrypt each fragment */
1153        if ((pattrib->encrypt == _AES_)) {
1154                if (pattrib->psta)
1155                        stainfo = pattrib->psta;
1156                else
1157                        stainfo = r8712_get_stainfo(&padapter->stapriv,
1158                                  &pattrib->ra[0]);
1159                if (stainfo != NULL) {
1160                        prwskey = &stainfo->x_UncstKey.skey[0];
1161                        prwskeylen = 16;
1162                        for (curfragnum = 0; curfragnum < pattrib->nr_frags;
1163                             curfragnum++) {
1164                                if ((curfragnum + 1) == pattrib->nr_frags) {\
1165                                        length = pattrib->last_txcmdsz -
1166                                                 pattrib->hdrlen -
1167                                                 pattrib->iv_len -
1168                                                 pattrib->icv_len;
1169                                        aes_cipher(prwskey, pattrib->
1170                                                  hdrlen, pframe, length);
1171                                } else {
1172                                        length = pxmitpriv->frag_len -
1173                                                 pattrib->hdrlen -
1174                                                 pattrib->iv_len -
1175                                                 pattrib->icv_len ;
1176                                        aes_cipher(prwskey, pattrib->
1177                                                   hdrlen, pframe, length);
1178                                        pframe += pxmitpriv->frag_len;
1179                                        pframe = (u8 *)RND4((addr_t)(pframe));
1180                                }
1181                        }
1182                } else
1183                        res = _FAIL;
1184        }
1185        return res;
1186}
1187
1188static sint aes_decipher(u8 *key, uint  hdrlen,
1189                        u8 *pframe, uint plen)
1190{
1191        static u8 message[MAX_MSG_SIZE];
1192        uint qc_exists, a4_exists, i, j, payload_remainder;
1193        uint num_blocks, payload_index;
1194        u8 pn_vector[6];
1195        u8 mic_iv[16];
1196        u8 mic_header1[16];
1197        u8 mic_header2[16];
1198        u8 ctr_preload[16];
1199        /* Intermediate Buffers */
1200        u8 chain_buffer[16];
1201        u8 aes_out[16];
1202        u8 padded_buffer[16];
1203        u8 mic[8];
1204        uint frtype  = GetFrameType(pframe);
1205        uint frsubtype  = GetFrameSubType(pframe);
1206
1207        frsubtype = frsubtype >> 4;
1208        memset((void *)mic_iv, 0, 16);
1209        memset((void *)mic_header1, 0, 16);
1210        memset((void *)mic_header2, 0, 16);
1211        memset((void *)ctr_preload, 0, 16);
1212        memset((void *)chain_buffer, 0, 16);
1213        memset((void *)aes_out, 0, 16);
1214        memset((void *)padded_buffer, 0, 16);
1215        /* start to decrypt the payload */
1216        /*(plen including llc, payload and mic) */
1217        num_blocks = (plen - 8) / 16;
1218        payload_remainder = (plen-8) % 16;
1219        pn_vector[0] = pframe[hdrlen];
1220        pn_vector[1] = pframe[hdrlen+1];
1221        pn_vector[2] = pframe[hdrlen+4];
1222        pn_vector[3] = pframe[hdrlen+5];
1223        pn_vector[4] = pframe[hdrlen+6];
1224        pn_vector[5] = pframe[hdrlen+7];
1225        if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen ==  WLAN_HDR_A3_QOS_LEN))
1226                a4_exists = 0;
1227        else
1228                a4_exists = 1;
1229        if ((frtype == WIFI_DATA_CFACK) ||
1230            (frtype == WIFI_DATA_CFPOLL) ||
1231            (frtype == WIFI_DATA_CFACKPOLL)) {
1232                qc_exists = 1;
1233                if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
1234                        hdrlen += 2;
1235                }  else if ((frsubtype == 0x08) ||
1236                   (frsubtype == 0x09) ||
1237                   (frsubtype == 0x0a) ||
1238                   (frsubtype == 0x0b)) {
1239                        if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
1240                                hdrlen += 2;
1241                        qc_exists = 1;
1242        } else
1243                qc_exists = 0;
1244        /* now, decrypt pframe with hdrlen offset and plen long */
1245        payload_index = hdrlen + 8; /* 8 is for extiv */
1246        for (i = 0; i < num_blocks; i++) {
1247                construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1248                                      pframe, pn_vector, i + 1);
1249                aes128k128d(key, ctr_preload, aes_out);
1250                bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1251                for (j = 0; j < 16; j++)
1252                        pframe[payload_index++] = chain_buffer[j];
1253        }
1254        if (payload_remainder > 0) {  /* If short final block, pad it,*/
1255                /* encrypt it and copy the unpadded part back   */
1256                construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1257                                      pframe, pn_vector, num_blocks+1);
1258                for (j = 0; j < 16; j++)
1259                        padded_buffer[j] = 0x00;
1260                for (j = 0; j < payload_remainder; j++)
1261                        padded_buffer[j] = pframe[payload_index + j];
1262                aes128k128d(key, ctr_preload, aes_out);
1263                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1264                for (j = 0; j < payload_remainder; j++)
1265                        pframe[payload_index++] = chain_buffer[j];
1266        }
1267        /* start to calculate the mic */
1268        memcpy((void *)message, pframe, (hdrlen + plen + 8));
1269        pn_vector[0] = pframe[hdrlen];
1270        pn_vector[1] = pframe[hdrlen+1];
1271        pn_vector[2] = pframe[hdrlen+4];
1272        pn_vector[3] = pframe[hdrlen+5];
1273        pn_vector[4] = pframe[hdrlen+6];
1274        pn_vector[5] = pframe[hdrlen+7];
1275        construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen-8,
1276                         pn_vector);
1277        construct_mic_header1(mic_header1, hdrlen, message);
1278        construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
1279        payload_remainder = (plen - 8) % 16;
1280        num_blocks = (plen - 8) / 16;
1281        /* Find start of payload */
1282        payload_index = (hdrlen + 8);
1283        /* Calculate MIC */
1284        aes128k128d(key, mic_iv, aes_out);
1285        bitwise_xor(aes_out, mic_header1, chain_buffer);
1286        aes128k128d(key, chain_buffer, aes_out);
1287        bitwise_xor(aes_out, mic_header2, chain_buffer);
1288        aes128k128d(key, chain_buffer, aes_out);
1289        for (i = 0; i < num_blocks; i++) {
1290                bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1291                payload_index += 16;
1292                aes128k128d(key, chain_buffer, aes_out);
1293        }
1294        /* Add on the final payload block if it needs padding */
1295        if (payload_remainder > 0) {
1296                for (j = 0; j < 16; j++)
1297                        padded_buffer[j] = 0x00;
1298                for (j = 0; j < payload_remainder; j++)
1299                        padded_buffer[j] = message[payload_index++];
1300                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1301                aes128k128d(key, chain_buffer, aes_out);
1302        }
1303        for (j = 0 ; j < 8; j++)
1304                mic[j] = aes_out[j];
1305        /* Insert MIC into payload */
1306        for (j = 0; j < 8; j++)
1307                message[payload_index+j] = mic[j];
1308        payload_index = hdrlen + 8;
1309        for (i = 0; i < num_blocks; i++) {
1310                construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1311                                      message, pn_vector, i + 1);
1312                aes128k128d(key, ctr_preload, aes_out);
1313                bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1314                for (j = 0; j < 16; j++)
1315                        message[payload_index++] = chain_buffer[j];
1316        }
1317        if (payload_remainder > 0) { /* If short final block, pad it,*/
1318                                     /* encrypt and copy unpadded part back */
1319                construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1320                                      message, pn_vector, num_blocks+1);
1321                for (j = 0; j < 16; j++)
1322                        padded_buffer[j] = 0x00;
1323                for (j = 0; j < payload_remainder; j++)
1324                        padded_buffer[j] = message[payload_index + j];
1325                aes128k128d(key, ctr_preload, aes_out);
1326                bitwise_xor(aes_out, padded_buffer, chain_buffer);
1327                for (j = 0; j < payload_remainder; j++)
1328                        message[payload_index++] = chain_buffer[j];
1329        }
1330        /* Encrypt the MIC */
1331        construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message,
1332                              pn_vector, 0);
1333        for (j = 0; j < 16; j++)
1334                padded_buffer[j] = 0x00;
1335        for (j = 0; j < 8; j++)
1336                padded_buffer[j] = message[j + hdrlen + plen];
1337        aes128k128d(key, ctr_preload, aes_out);
1338        bitwise_xor(aes_out, padded_buffer, chain_buffer);
1339        for (j = 0; j < 8; j++)
1340                message[payload_index++] = chain_buffer[j];
1341        /* compare the mic */
1342        return _SUCCESS;
1343}
1344
1345u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe)
1346{       /* exclude ICV */
1347        /* Intermediate Buffers */
1348        sint            length;
1349        u32     prwskeylen;
1350        u8      *pframe, *prwskey, *iv, idx;
1351        struct  sta_info *stainfo;
1352        struct  rx_pkt_attrib *prxattrib = &((union recv_frame *)
1353                                           precvframe)->u.hdr.attrib;
1354        struct  security_priv *psecuritypriv = &padapter->securitypriv;
1355
1356        pframe = (unsigned char *)((union recv_frame*)precvframe)->
1357                 u.hdr.rx_data;
1358        /* 4 start to encrypt each fragment */
1359        if ((prxattrib->encrypt == _AES_)) {
1360                stainfo = r8712_get_stainfo(&padapter->stapriv,
1361                                            &prxattrib->ta[0]);
1362                if (stainfo != NULL) {
1363                        if (IS_MCAST(prxattrib->ra)) {
1364                                iv = pframe+prxattrib->hdrlen;
1365                                idx = iv[3];
1366                                prwskey = &psecuritypriv->XGrpKey[
1367                                          ((idx >> 6) & 0x3) - 1].skey[0];
1368                                if (psecuritypriv->binstallGrpkey == false)
1369                                        return _FAIL;
1370
1371                        } else
1372                                prwskey = &stainfo->x_UncstKey.skey[0];
1373                        prwskeylen = 16;
1374                        length = ((union recv_frame *)precvframe)->
1375                                 u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
1376                        aes_decipher(prwskey, prxattrib->hdrlen, pframe,
1377                                     length);
1378                } else
1379                        return _FAIL;
1380        }
1381        return _SUCCESS;
1382}
1383
1384void r8712_use_tkipkey_handler(void *FunctionContext)
1385{
1386        struct _adapter *padapter = (struct _adapter *)FunctionContext;
1387
1388        padapter->securitypriv.busetkipkey = true;
1389}
1390