linux/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
<<
>>
Prefs
   1/*
   2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
   3 *
   4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation. See README and COPYING for
   9 * more details.
  10 */
  11
  12//#include <linux/config.h>
  13#include <linux/version.h>
  14#include <linux/module.h>
  15#include <linux/init.h>
  16#include <linux/slab.h>
  17#include <linux/random.h>
  18#include <linux/skbuff.h>
  19#include <linux/netdevice.h>
  20#include <linux/if_ether.h>
  21#include <linux/if_arp.h>
  22#include <asm/string.h>
  23
  24#include "ieee80211.h"
  25
  26
  27#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  28#include "rtl_crypto.h"
  29#else
  30#include <linux/crypto.h>
  31#endif
  32//#include <asm/scatterlist.h>
  33#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  34    #include <asm/scatterlist.h>
  35#else
  36        #include <linux/scatterlist.h>
  37#endif
  38
  39#include <linux/crc32.h>
  40
  41MODULE_AUTHOR("Jouni Malinen");
  42MODULE_DESCRIPTION("Host AP crypt: TKIP");
  43MODULE_LICENSE("GPL");
  44
  45#ifndef OPENSUSE_SLED
  46#define OPENSUSE_SLED 0
  47#endif
  48
  49struct ieee80211_tkip_data {
  50#define TKIP_KEY_LEN 32
  51        u8 key[TKIP_KEY_LEN];
  52        int key_set;
  53
  54        u32 tx_iv32;
  55        u16 tx_iv16;
  56        u16 tx_ttak[5];
  57        int tx_phase1_done;
  58
  59        u32 rx_iv32;
  60        u16 rx_iv16;
  61        u16 rx_ttak[5];
  62        int rx_phase1_done;
  63        u32 rx_iv32_new;
  64        u16 rx_iv16_new;
  65
  66        u32 dot11RSNAStatsTKIPReplays;
  67        u32 dot11RSNAStatsTKIPICVErrors;
  68        u32 dot11RSNAStatsTKIPLocalMICFailures;
  69
  70        int key_idx;
  71#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
  72        struct crypto_blkcipher *rx_tfm_arc4;
  73        struct crypto_hash *rx_tfm_michael;
  74        struct crypto_blkcipher *tx_tfm_arc4;
  75        struct crypto_hash *tx_tfm_michael;
  76#else
  77        struct crypto_tfm *tx_tfm_arc4;
  78        struct crypto_tfm *tx_tfm_michael;
  79        struct crypto_tfm *rx_tfm_arc4;
  80        struct crypto_tfm *rx_tfm_michael;
  81#endif
  82        /* scratch buffers for virt_to_page() (crypto API) */
  83        u8 rx_hdr[16], tx_hdr[16];
  84};
  85
  86static void * ieee80211_tkip_init(int key_idx)
  87{
  88        struct ieee80211_tkip_data *priv;
  89
  90        priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
  91        if (priv == NULL)
  92                goto fail;
  93        memset(priv, 0, sizeof(*priv));
  94        priv->key_idx = key_idx;
  95#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
  96        priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
  97        if (priv->tx_tfm_arc4 == NULL) {
  98                printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  99                                "crypto API arc4\n");
 100                goto fail;
 101        }
 102
 103        priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
 104        if (priv->tx_tfm_michael == NULL) {
 105                printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
 106                                "crypto API michael_mic\n");
 107                goto fail;
 108        }
 109
 110        priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
 111        if (priv->rx_tfm_arc4 == NULL) {
 112                printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
 113                                "crypto API arc4\n");
 114                goto fail;
 115        }
 116
 117        priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
 118        if (priv->rx_tfm_michael == NULL) {
 119                printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
 120                                "crypto API michael_mic\n");
 121                goto fail;
 122        }
 123#else
 124        priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
 125                        CRYPTO_ALG_ASYNC);
 126        if (IS_ERR(priv->tx_tfm_arc4)) {
 127                printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
 128                                "crypto API arc4\n");
 129                priv->tx_tfm_arc4 = NULL;
 130                goto fail;
 131        }
 132
 133        priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
 134                        CRYPTO_ALG_ASYNC);
 135        if (IS_ERR(priv->tx_tfm_michael)) {
 136                printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
 137                                "crypto API michael_mic\n");
 138                priv->tx_tfm_michael = NULL;
 139                goto fail;
 140        }
 141
 142        priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
 143                        CRYPTO_ALG_ASYNC);
 144        if (IS_ERR(priv->rx_tfm_arc4)) {
 145                printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
 146                                "crypto API arc4\n");
 147                priv->rx_tfm_arc4 = NULL;
 148                goto fail;
 149        }
 150
 151        priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
 152                        CRYPTO_ALG_ASYNC);
 153        if (IS_ERR(priv->rx_tfm_michael)) {
 154                printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
 155                                "crypto API michael_mic\n");
 156                priv->rx_tfm_michael = NULL;
 157                goto fail;
 158        }
 159#endif
 160        return priv;
 161
 162fail:
 163        if (priv) {
 164#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 165                if (priv->tx_tfm_michael)
 166                        crypto_free_tfm(priv->tx_tfm_michael);
 167                if (priv->tx_tfm_arc4)
 168                        crypto_free_tfm(priv->tx_tfm_arc4);
 169                if (priv->rx_tfm_michael)
 170                        crypto_free_tfm(priv->rx_tfm_michael);
 171                if (priv->rx_tfm_arc4)
 172                        crypto_free_tfm(priv->rx_tfm_arc4);
 173
 174#else
 175                if (priv->tx_tfm_michael)
 176                        crypto_free_hash(priv->tx_tfm_michael);
 177                if (priv->tx_tfm_arc4)
 178                        crypto_free_blkcipher(priv->tx_tfm_arc4);
 179                if (priv->rx_tfm_michael)
 180                        crypto_free_hash(priv->rx_tfm_michael);
 181                if (priv->rx_tfm_arc4)
 182                        crypto_free_blkcipher(priv->rx_tfm_arc4);
 183#endif
 184                kfree(priv);
 185        }
 186
 187        return NULL;
 188}
 189
 190
 191static void ieee80211_tkip_deinit(void *priv)
 192{
 193        struct ieee80211_tkip_data *_priv = priv;
 194#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 195        if (_priv->tx_tfm_michael)
 196                crypto_free_tfm(_priv->tx_tfm_michael);
 197        if (_priv->tx_tfm_arc4)
 198                crypto_free_tfm(_priv->tx_tfm_arc4);
 199        if (_priv->rx_tfm_michael)
 200                crypto_free_tfm(_priv->rx_tfm_michael);
 201        if (_priv->rx_tfm_arc4)
 202                crypto_free_tfm(_priv->rx_tfm_arc4);
 203#else
 204        if (_priv) {
 205                if (_priv->tx_tfm_michael)
 206                        crypto_free_hash(_priv->tx_tfm_michael);
 207                if (_priv->tx_tfm_arc4)
 208                        crypto_free_blkcipher(_priv->tx_tfm_arc4);
 209                if (_priv->rx_tfm_michael)
 210                        crypto_free_hash(_priv->rx_tfm_michael);
 211                if (_priv->rx_tfm_arc4)
 212                        crypto_free_blkcipher(_priv->rx_tfm_arc4);
 213        }
 214#endif
 215        kfree(priv);
 216}
 217
 218
 219static inline u16 RotR1(u16 val)
 220{
 221        return (val >> 1) | (val << 15);
 222}
 223
 224
 225static inline u8 Lo8(u16 val)
 226{
 227        return val & 0xff;
 228}
 229
 230
 231static inline u8 Hi8(u16 val)
 232{
 233        return val >> 8;
 234}
 235
 236
 237static inline u16 Lo16(u32 val)
 238{
 239        return val & 0xffff;
 240}
 241
 242
 243static inline u16 Hi16(u32 val)
 244{
 245        return val >> 16;
 246}
 247
 248
 249static inline u16 Mk16(u8 hi, u8 lo)
 250{
 251        return lo | (((u16) hi) << 8);
 252}
 253
 254
 255static inline u16 Mk16_le(u16 *v)
 256{
 257        return le16_to_cpu(*v);
 258}
 259
 260
 261static const u16 Sbox[256] =
 262{
 263        0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
 264        0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
 265        0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
 266        0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
 267        0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
 268        0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
 269        0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
 270        0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
 271        0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
 272        0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
 273        0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
 274        0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
 275        0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
 276        0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
 277        0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
 278        0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
 279        0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
 280        0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
 281        0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
 282        0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
 283        0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
 284        0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
 285        0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
 286        0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
 287        0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
 288        0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
 289        0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
 290        0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
 291        0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
 292        0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
 293        0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
 294        0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
 295};
 296
 297
 298static inline u16 _S_(u16 v)
 299{
 300        u16 t = Sbox[Hi8(v)];
 301        return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
 302}
 303
 304
 305#define PHASE1_LOOP_COUNT 8
 306
 307
 308static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
 309{
 310        int i, j;
 311
 312        /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
 313        TTAK[0] = Lo16(IV32);
 314        TTAK[1] = Hi16(IV32);
 315        TTAK[2] = Mk16(TA[1], TA[0]);
 316        TTAK[3] = Mk16(TA[3], TA[2]);
 317        TTAK[4] = Mk16(TA[5], TA[4]);
 318
 319        for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
 320                j = 2 * (i & 1);
 321                TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
 322                TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
 323                TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
 324                TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
 325                TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
 326        }
 327}
 328
 329
 330static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
 331                               u16 IV16)
 332{
 333        /* Make temporary area overlap WEP seed so that the final copy can be
 334         * avoided on little endian hosts. */
 335        u16 *PPK = (u16 *) &WEPSeed[4];
 336
 337        /* Step 1 - make copy of TTAK and bring in TSC */
 338        PPK[0] = TTAK[0];
 339        PPK[1] = TTAK[1];
 340        PPK[2] = TTAK[2];
 341        PPK[3] = TTAK[3];
 342        PPK[4] = TTAK[4];
 343        PPK[5] = TTAK[4] + IV16;
 344
 345        /* Step 2 - 96-bit bijective mixing using S-box */
 346        PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
 347        PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
 348        PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
 349        PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
 350        PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
 351        PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
 352
 353        PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
 354        PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
 355        PPK[2] += RotR1(PPK[1]);
 356        PPK[3] += RotR1(PPK[2]);
 357        PPK[4] += RotR1(PPK[3]);
 358        PPK[5] += RotR1(PPK[4]);
 359
 360        /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
 361         * WEPSeed[0..2] is transmitted as WEP IV */
 362        WEPSeed[0] = Hi8(IV16);
 363        WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
 364        WEPSeed[2] = Lo8(IV16);
 365        WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
 366
 367#ifdef __BIG_ENDIAN
 368        {
 369                int i;
 370                for (i = 0; i < 6; i++)
 371                        PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
 372        }
 373#endif
 374}
 375
 376
 377static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 378{
 379        struct ieee80211_tkip_data *tkey = priv;
 380                int len;
 381        u8 *pos;
 382        struct ieee80211_hdr_4addr *hdr;
 383        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
 384
 385        #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
 386        struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
 387        int ret = 0;
 388        #endif
 389        u8 rc4key[16],  *icv;
 390        u32 crc;
 391        struct scatterlist sg;
 392
 393        if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
 394            skb->len < hdr_len)
 395                return -1;
 396
 397        hdr = (struct ieee80211_hdr_4addr *) skb->data;
 398
 399#if 0
 400printk("@@ tkey\n");
 401printk("%x|", ((u32*)tkey->key)[0]);
 402printk("%x|", ((u32*)tkey->key)[1]);
 403printk("%x|", ((u32*)tkey->key)[2]);
 404printk("%x|", ((u32*)tkey->key)[3]);
 405printk("%x|", ((u32*)tkey->key)[4]);
 406printk("%x|", ((u32*)tkey->key)[5]);
 407printk("%x|", ((u32*)tkey->key)[6]);
 408printk("%x\n", ((u32*)tkey->key)[7]);
 409#endif
 410
 411        if (!tcb_desc->bHwSec)
 412        {
 413                if (!tkey->tx_phase1_done) {
 414                        tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
 415                                        tkey->tx_iv32);
 416                        tkey->tx_phase1_done = 1;
 417                }
 418                tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
 419        }
 420        else
 421        tkey->tx_phase1_done = 1;
 422
 423
 424        len = skb->len - hdr_len;
 425        pos = skb_push(skb, 8);
 426        memmove(pos, pos + 8, hdr_len);
 427        pos += hdr_len;
 428
 429        if (tcb_desc->bHwSec)
 430        {
 431                *pos++ = Hi8(tkey->tx_iv16);
 432                *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
 433                *pos++ = Lo8(tkey->tx_iv16);
 434        }
 435        else
 436        {
 437                *pos++ = rc4key[0];
 438                *pos++ = rc4key[1];
 439                *pos++ = rc4key[2];
 440        }
 441
 442        *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
 443        *pos++ = tkey->tx_iv32 & 0xff;
 444        *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
 445        *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
 446        *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
 447
 448        if (!tcb_desc->bHwSec)
 449        {
 450                icv = skb_put(skb, 4);
 451#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 452                crc = ~crc32_le(~0, pos, len);
 453#else
 454                crc = ~ether_crc_le(len, pos);
 455#endif
 456                icv[0] = crc;
 457                icv[1] = crc >> 8;
 458                icv[2] = crc >> 16;
 459                icv[3] = crc >> 24;
 460#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 461                crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
 462                sg.page = virt_to_page(pos);
 463                sg.offset = offset_in_page(pos);
 464                sg.length = len + 4;
 465                crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4);
 466#else
 467                crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
 468#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
 469                sg.page = virt_to_page(pos);
 470                sg.offset = offset_in_page(pos);
 471                sg.length = len + 4;
 472#else
 473                sg_init_one(&sg, pos, len+4);
 474#endif
 475                ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 476#endif
 477
 478        }
 479
 480        tkey->tx_iv16++;
 481        if (tkey->tx_iv16 == 0) {
 482                tkey->tx_phase1_done = 0;
 483                tkey->tx_iv32++;
 484        }
 485
 486        if (!tcb_desc->bHwSec)
 487#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 488                return 0;
 489        #else
 490                return ret;
 491        #endif
 492        else
 493                return 0;
 494
 495
 496}
 497
 498static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 499{
 500        struct ieee80211_tkip_data *tkey = priv;
 501        u8 keyidx, *pos;
 502        u32 iv32;
 503        u16 iv16;
 504        struct ieee80211_hdr_4addr *hdr;
 505        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
 506        #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
 507        struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
 508        #endif
 509        u8 rc4key[16];
 510        u8 icv[4];
 511        u32 crc;
 512        struct scatterlist sg;
 513        int plen;
 514        if (skb->len < hdr_len + 8 + 4)
 515                return -1;
 516
 517        hdr = (struct ieee80211_hdr_4addr *) skb->data;
 518        pos = skb->data + hdr_len;
 519        keyidx = pos[3];
 520        if (!(keyidx & (1 << 5))) {
 521                if (net_ratelimit()) {
 522                        printk(KERN_DEBUG "TKIP: received packet without ExtIV"
 523                               " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
 524                }
 525                return -2;
 526        }
 527        keyidx >>= 6;
 528        if (tkey->key_idx != keyidx) {
 529                printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
 530                       "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
 531                return -6;
 532        }
 533        if (!tkey->key_set) {
 534                if (net_ratelimit()) {
 535                        printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
 536                               " with keyid=%d that does not have a configured"
 537                               " key\n", MAC_ARG(hdr->addr2), keyidx);
 538                }
 539                return -3;
 540        }
 541        iv16 = (pos[0] << 8) | pos[2];
 542        iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
 543        pos += 8;
 544
 545        if (!tcb_desc->bHwSec)
 546        {
 547                if (iv32 < tkey->rx_iv32 ||
 548                (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
 549                        if (net_ratelimit()) {
 550                                printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
 551                                " previous TSC %08x%04x received TSC "
 552                                "%08x%04x\n", MAC_ARG(hdr->addr2),
 553                                tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
 554                        }
 555                        tkey->dot11RSNAStatsTKIPReplays++;
 556                        return -4;
 557                }
 558
 559                if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
 560                        tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
 561                        tkey->rx_phase1_done = 1;
 562                }
 563                tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
 564
 565                plen = skb->len - hdr_len - 12;
 566
 567#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 568                crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
 569                sg.page = virt_to_page(pos);
 570                sg.offset = offset_in_page(pos);
 571                sg.length = plen + 4;
 572                crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4);
 573#else
 574                crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
 575#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
 576                sg.page = virt_to_page(pos);
 577                sg.offset = offset_in_page(pos);
 578                sg.length = plen + 4;
 579#else
 580                sg_init_one(&sg, pos, plen+4);
 581#endif
 582                if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 583                        if (net_ratelimit()) {
 584                                printk(KERN_DEBUG ": TKIP: failed to decrypt "
 585                                                "received packet from " MAC_FMT "\n",
 586                                                MAC_ARG(hdr->addr2));
 587                        }
 588                        return -7;
 589                }
 590#endif
 591
 592        #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 593                crc = ~crc32_le(~0, pos, plen);
 594        #else
 595                crc = ~ether_crc_le(plen, pos);
 596        #endif
 597                icv[0] = crc;
 598                icv[1] = crc >> 8;
 599                icv[2] = crc >> 16;
 600                icv[3] = crc >> 24;
 601
 602                if (memcmp(icv, pos + plen, 4) != 0) {
 603                        if (iv32 != tkey->rx_iv32) {
 604                                /* Previously cached Phase1 result was already lost, so
 605                                * it needs to be recalculated for the next packet. */
 606                                tkey->rx_phase1_done = 0;
 607                        }
 608                        if (net_ratelimit()) {
 609                                printk(KERN_DEBUG "TKIP: ICV error detected: STA="
 610                                MAC_FMT "\n", MAC_ARG(hdr->addr2));
 611                        }
 612                        tkey->dot11RSNAStatsTKIPICVErrors++;
 613                        return -5;
 614                }
 615
 616        }
 617
 618        /* Update real counters only after Michael MIC verification has
 619         * completed */
 620        tkey->rx_iv32_new = iv32;
 621        tkey->rx_iv16_new = iv16;
 622
 623        /* Remove IV and ICV */
 624        memmove(skb->data + 8, skb->data, hdr_len);
 625        skb_pull(skb, 8);
 626        skb_trim(skb, skb->len - 4);
 627
 628//john's test
 629#ifdef JOHN_DUMP
 630if( ((u16*)skb->data)[0] & 0x4000){
 631        printk("@@ rx decrypted skb->data");
 632        int i;
 633        for(i=0;i<skb->len;i++){
 634                if( (i%24)==0 ) printk("\n");
 635                printk("%2x ", ((u8*)skb->data)[i]);
 636        }
 637        printk("\n");
 638}
 639#endif /*JOHN_DUMP*/
 640        return keyidx;
 641}
 642
 643
 644#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 645static int michael_mic(struct crypto_tfm * tfm_michael, u8 *key, u8 *hdr,
 646                       u8 *data, size_t data_len, u8 *mic)
 647{
 648        struct scatterlist sg[2];
 649#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 650        struct hash_desc desc;
 651        int ret = 0;
 652#endif
 653
 654        if (tfm_michael == NULL){
 655                printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
 656                return -1;
 657        }
 658        sg[0].page = virt_to_page(hdr);
 659        sg[0].offset = offset_in_page(hdr);
 660        sg[0].length = 16;
 661
 662        sg[1].page = virt_to_page(data);
 663        sg[1].offset = offset_in_page(data);
 664        sg[1].length = data_len;
 665
 666
 667#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
 668        crypto_digest_init(tfm_michael);
 669        crypto_digest_setkey(tfm_michael, key, 8);
 670        crypto_digest_update(tfm_michael, sg, 2);
 671        crypto_digest_final(tfm_michael, mic);
 672        return 0;
 673#else
 674if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
 675                return -1;
 676
 677//      return 0;
 678              desc.tfm = tkey->tfm_michael;
 679              desc.flags = 0;
 680              ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
 681              return ret;
 682#endif
 683}
 684#else
 685static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
 686                       u8 * data, size_t data_len, u8 * mic)
 687{
 688        struct hash_desc desc;
 689        struct scatterlist sg[2];
 690
 691        if (tfm_michael == NULL) {
 692                printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
 693                return -1;
 694        }
 695#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
 696        sg[0].page = virt_to_page(hdr);
 697        sg[0].offset = offset_in_page(hdr);
 698        sg[0].length = 16;
 699
 700        sg[1].page = virt_to_page(data);
 701        sg[1].offset = offset_in_page(data);
 702        sg[1].length = data_len;
 703#else
 704        sg_init_table(sg, 2);
 705        sg_set_buf(&sg[0], hdr, 16);
 706        sg_set_buf(&sg[1], data, data_len);
 707#endif
 708
 709        if (crypto_hash_setkey(tfm_michael, key, 8))
 710                return -1;
 711
 712        desc.tfm = tfm_michael;
 713        desc.flags = 0;
 714        return crypto_hash_digest(&desc, sg, data_len + 16, mic);
 715}
 716#endif
 717
 718
 719
 720static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
 721{
 722        struct ieee80211_hdr_4addr *hdr11;
 723
 724        hdr11 = (struct ieee80211_hdr_4addr *) skb->data;
 725        switch (le16_to_cpu(hdr11->frame_ctl) &
 726                (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
 727        case IEEE80211_FCTL_TODS:
 728                memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
 729                memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
 730                break;
 731        case IEEE80211_FCTL_FROMDS:
 732                memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
 733                memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
 734                break;
 735        case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
 736                memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
 737                memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
 738                break;
 739        case 0:
 740                memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
 741                memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
 742                break;
 743        }
 744
 745        hdr[12] = 0; /* priority */
 746
 747        hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
 748}
 749
 750
 751static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
 752{
 753        struct ieee80211_tkip_data *tkey = priv;
 754        u8 *pos;
 755        struct ieee80211_hdr_4addr *hdr;
 756
 757        hdr = (struct ieee80211_hdr_4addr *) skb->data;
 758
 759        if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
 760                printk(KERN_DEBUG "Invalid packet for Michael MIC add "
 761                       "(tailroom=%d hdr_len=%d skb->len=%d)\n",
 762                       skb_tailroom(skb), hdr_len, skb->len);
 763                return -1;
 764        }
 765
 766        michael_mic_hdr(skb, tkey->tx_hdr);
 767
 768        // { david, 2006.9.1
 769        // fix the wpa process with wmm enabled.
 770        if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
 771                tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
 772        }
 773        // }
 774        pos = skb_put(skb, 8);
 775#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 776        if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
 777                                skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
 778#else
 779        if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
 780                                skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
 781#endif
 782                return -1;
 783
 784        return 0;
 785}
 786
 787
 788#if WIRELESS_EXT >= 18
 789static void ieee80211_michael_mic_failure(struct net_device *dev,
 790                                       struct ieee80211_hdr_4addr *hdr,
 791                                       int keyidx)
 792{
 793        union iwreq_data wrqu;
 794        struct iw_michaelmicfailure ev;
 795
 796        /* TODO: needed parameters: count, keyid, key type, TSC */
 797        memset(&ev, 0, sizeof(ev));
 798        ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
 799        if (hdr->addr1[0] & 0x01)
 800                ev.flags |= IW_MICFAILURE_GROUP;
 801        else
 802                ev.flags |= IW_MICFAILURE_PAIRWISE;
 803        ev.src_addr.sa_family = ARPHRD_ETHER;
 804        memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
 805        memset(&wrqu, 0, sizeof(wrqu));
 806        wrqu.data.length = sizeof(ev);
 807        wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
 808}
 809#elif WIRELESS_EXT >= 15
 810static void ieee80211_michael_mic_failure(struct net_device *dev,
 811                                       struct ieee80211_hdr_4addr *hdr,
 812                                       int keyidx)
 813{
 814        union iwreq_data wrqu;
 815        char buf[128];
 816
 817        /* TODO: needed parameters: count, keyid, key type, TSC */
 818        sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
 819                MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
 820                MAC_ARG(hdr->addr2));
 821        memset(&wrqu, 0, sizeof(wrqu));
 822        wrqu.data.length = strlen(buf);
 823        wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
 824}
 825#else /* WIRELESS_EXT >= 15 */
 826static inline void ieee80211_michael_mic_failure(struct net_device *dev,
 827                                              struct ieee80211_hdr_4addr *hdr,
 828                                              int keyidx)
 829{
 830}
 831#endif /* WIRELESS_EXT >= 15 */
 832
 833static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
 834                                     int hdr_len, void *priv)
 835{
 836        struct ieee80211_tkip_data *tkey = priv;
 837        u8 mic[8];
 838        struct ieee80211_hdr_4addr *hdr;
 839
 840        hdr = (struct ieee80211_hdr_4addr *) skb->data;
 841
 842        if (!tkey->key_set)
 843                return -1;
 844
 845        michael_mic_hdr(skb, tkey->rx_hdr);
 846        // { david, 2006.9.1
 847        // fix the wpa process with wmm enabled.
 848        if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
 849                tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
 850        }
 851        // }
 852
 853#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 854        if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
 855                                skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
 856#else
 857        if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
 858                                skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
 859#endif
 860                return -1;
 861        if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
 862                struct ieee80211_hdr_4addr *hdr;
 863                hdr = (struct ieee80211_hdr_4addr *) skb->data;
 864                printk(KERN_DEBUG "%s: Michael MIC verification failed for "
 865                       "MSDU from " MAC_FMT " keyidx=%d\n",
 866                       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
 867                       keyidx);
 868                if (skb->dev)
 869                        ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
 870                tkey->dot11RSNAStatsTKIPLocalMICFailures++;
 871                return -1;
 872        }
 873
 874        /* Update TSC counters for RX now that the packet verification has
 875         * completed. */
 876        tkey->rx_iv32 = tkey->rx_iv32_new;
 877        tkey->rx_iv16 = tkey->rx_iv16_new;
 878
 879        skb_trim(skb, skb->len - 8);
 880
 881        return 0;
 882}
 883
 884
 885static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
 886{
 887        struct ieee80211_tkip_data *tkey = priv;
 888        int keyidx;
 889#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 890        struct crypto_tfm *tfm = tkey->tx_tfm_michael;
 891        struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4;
 892        struct crypto_tfm *tfm3 = tkey->rx_tfm_michael;
 893        struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4;
 894#else
 895        struct crypto_hash *tfm = tkey->tx_tfm_michael;
 896        struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
 897        struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
 898        struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
 899#endif
 900
 901        keyidx = tkey->key_idx;
 902        memset(tkey, 0, sizeof(*tkey));
 903        tkey->key_idx = keyidx;
 904#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
 905        tkey->tx_tfm_michael = tfm;
 906        tkey->tx_tfm_arc4 = tfm2;
 907        tkey->rx_tfm_michael = tfm3;
 908        tkey->rx_tfm_arc4 = tfm4;
 909#else
 910        tkey->tx_tfm_michael = tfm;
 911        tkey->tx_tfm_arc4 = tfm2;
 912        tkey->rx_tfm_michael = tfm3;
 913        tkey->rx_tfm_arc4 = tfm4;
 914#endif
 915
 916        if (len == TKIP_KEY_LEN) {
 917                memcpy(tkey->key, key, TKIP_KEY_LEN);
 918                tkey->key_set = 1;
 919                tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
 920                if (seq) {
 921                        tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
 922                                (seq[3] << 8) | seq[2];
 923                        tkey->rx_iv16 = (seq[1] << 8) | seq[0];
 924                }
 925        } else if (len == 0)
 926                tkey->key_set = 0;
 927        else
 928                return -1;
 929
 930        return 0;
 931}
 932
 933
 934static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
 935{
 936        struct ieee80211_tkip_data *tkey = priv;
 937
 938        if (len < TKIP_KEY_LEN)
 939                return -1;
 940
 941        if (!tkey->key_set)
 942                return 0;
 943        memcpy(key, tkey->key, TKIP_KEY_LEN);
 944
 945        if (seq) {
 946                /* Return the sequence number of the last transmitted frame. */
 947                u16 iv16 = tkey->tx_iv16;
 948                u32 iv32 = tkey->tx_iv32;
 949                if (iv16 == 0)
 950                        iv32--;
 951                iv16--;
 952                seq[0] = tkey->tx_iv16;
 953                seq[1] = tkey->tx_iv16 >> 8;
 954                seq[2] = tkey->tx_iv32;
 955                seq[3] = tkey->tx_iv32 >> 8;
 956                seq[4] = tkey->tx_iv32 >> 16;
 957                seq[5] = tkey->tx_iv32 >> 24;
 958        }
 959
 960        return TKIP_KEY_LEN;
 961}
 962
 963
 964static char * ieee80211_tkip_print_stats(char *p, void *priv)
 965{
 966        struct ieee80211_tkip_data *tkip = priv;
 967        p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
 968                     "tx_pn=%02x%02x%02x%02x%02x%02x "
 969                     "rx_pn=%02x%02x%02x%02x%02x%02x "
 970                     "replays=%d icv_errors=%d local_mic_failures=%d\n",
 971                     tkip->key_idx, tkip->key_set,
 972                     (tkip->tx_iv32 >> 24) & 0xff,
 973                     (tkip->tx_iv32 >> 16) & 0xff,
 974                     (tkip->tx_iv32 >> 8) & 0xff,
 975                     tkip->tx_iv32 & 0xff,
 976                     (tkip->tx_iv16 >> 8) & 0xff,
 977                     tkip->tx_iv16 & 0xff,
 978                     (tkip->rx_iv32 >> 24) & 0xff,
 979                     (tkip->rx_iv32 >> 16) & 0xff,
 980                     (tkip->rx_iv32 >> 8) & 0xff,
 981                     tkip->rx_iv32 & 0xff,
 982                     (tkip->rx_iv16 >> 8) & 0xff,
 983                     tkip->rx_iv16 & 0xff,
 984                     tkip->dot11RSNAStatsTKIPReplays,
 985                     tkip->dot11RSNAStatsTKIPICVErrors,
 986                     tkip->dot11RSNAStatsTKIPLocalMICFailures);
 987        return p;
 988}
 989
 990
 991static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
 992        .name                   = "TKIP",
 993        .init                   = ieee80211_tkip_init,
 994        .deinit                 = ieee80211_tkip_deinit,
 995        .encrypt_mpdu           = ieee80211_tkip_encrypt,
 996        .decrypt_mpdu           = ieee80211_tkip_decrypt,
 997        .encrypt_msdu           = ieee80211_michael_mic_add,
 998        .decrypt_msdu           = ieee80211_michael_mic_verify,
 999        .set_key                = ieee80211_tkip_set_key,
1000        .get_key                = ieee80211_tkip_get_key,
1001        .print_stats            = ieee80211_tkip_print_stats,
1002        .extra_prefix_len       = 4 + 4, /* IV + ExtIV */
1003        .extra_postfix_len      = 8 + 4, /* MIC + ICV */
1004        .owner                  = THIS_MODULE,
1005};
1006
1007
1008int __init ieee80211_crypto_tkip_init(void)
1009{
1010        return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
1011}
1012
1013
1014void __exit ieee80211_crypto_tkip_exit(void)
1015{
1016        ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
1017}
1018
1019void ieee80211_tkip_null(void)
1020{
1021//    printk("============>%s()\n", __FUNCTION__);
1022        return;
1023}
1024#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1025//EXPORT_SYMBOL(ieee80211_tkip_null);
1026#else
1027EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
1028#endif
1029
1030//module_init(ieee80211_crypto_tkip_init);
1031//module_exit(ieee80211_crypto_tkip_exit);
1032