Annotation of qemu/roms/ipxe/src/net/80211/wpa_tkip.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2009 Joshua Oreman <[email protected]>.
        !             3:  *
        !             4:  * This program is free software; you can redistribute it and/or
        !             5:  * modify it under the terms of the GNU General Public License as
        !             6:  * published by the Free Software Foundation; either version 2 of the
        !             7:  * License, or any later version.
        !             8:  *
        !             9:  * This program is distributed in the hope that it will be useful, but
        !            10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            12:  * General Public License for more details.
        !            13:  *
        !            14:  * You should have received a copy of the GNU General Public License
        !            15:  * along with this program; if not, write to the Free Software
        !            16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            17:  */
        !            18: 
        !            19: FILE_LICENCE ( GPL2_OR_LATER );
        !            20: 
        !            21: #include <ipxe/net80211.h>
        !            22: #include <ipxe/crypto.h>
        !            23: #include <ipxe/hmac.h>
        !            24: #include <ipxe/sha1.h>
        !            25: #include <ipxe/md5.h>
        !            26: #include <ipxe/crc32.h>
        !            27: #include <ipxe/arc4.h>
        !            28: #include <ipxe/wpa.h>
        !            29: #include <byteswap.h>
        !            30: #include <errno.h>
        !            31: 
        !            32: /** @file
        !            33:  *
        !            34:  * Backend for WPA using the TKIP encryption standard.
        !            35:  */
        !            36: 
        !            37: /** Context for one direction of TKIP, either encryption or decryption */
        !            38: struct tkip_dir_ctx
        !            39: {
        !            40:        /** High 32 bits of last sequence counter value used */
        !            41:        u32 tsc_hi;
        !            42: 
        !            43:        /** Low 32 bits of last sequence counter value used */
        !            44:        u16 tsc_lo;
        !            45: 
        !            46:        /** MAC address used to derive TTAK */
        !            47:        u8 mac[ETH_ALEN];
        !            48: 
        !            49:        /** If TRUE, TTAK is valid */
        !            50:        u16 ttak_ok;
        !            51: 
        !            52:        /** TKIP-mixed transmit address and key, depends on tsc_hi and MAC */
        !            53:        u16 ttak[5];
        !            54: };
        !            55: 
        !            56: /** Context for TKIP encryption and decryption */
        !            57: struct tkip_ctx
        !            58: {
        !            59:        /** Temporal key to use */
        !            60:        struct tkip_tk tk;
        !            61: 
        !            62:        /** State for encryption */
        !            63:        struct tkip_dir_ctx enc;
        !            64: 
        !            65:        /** State for decryption */
        !            66:        struct tkip_dir_ctx dec;
        !            67: };
        !            68: 
        !            69: /** Header structure at the beginning of TKIP frame data */
        !            70: struct tkip_head
        !            71: {
        !            72:        u8 tsc1;                /**< High byte of low 16 bits of TSC */
        !            73:        u8 seed1;               /**< Second byte of WEP seed */
        !            74:        u8 tsc0;                /**< Low byte of TSC */
        !            75:        u8 kid;                 /**< Key ID and ExtIV byte */
        !            76:        u32 tsc_hi;             /**< High 32 bits of TSC, as an ExtIV */
        !            77: } __attribute__ (( packed ));
        !            78: 
        !            79: 
        !            80: /** TKIP header overhead (IV + KID + ExtIV) */
        !            81: #define TKIP_HEAD_LEN  8
        !            82: 
        !            83: /** TKIP trailer overhead (MIC + ICV) [assumes unfragmented] */
        !            84: #define TKIP_FOOT_LEN  12
        !            85: 
        !            86: /** TKIP MIC length */
        !            87: #define TKIP_MIC_LEN   8
        !            88: 
        !            89: /** TKIP ICV length */
        !            90: #define TKIP_ICV_LEN   4
        !            91: 
        !            92: 
        !            93: /** TKIP S-box */
        !            94: static const u16 Sbox[256] = {
        !            95:        0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
        !            96:        0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
        !            97:        0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
        !            98:        0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
        !            99:        0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
        !           100:        0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
        !           101:        0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
        !           102:        0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
        !           103:        0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
        !           104:        0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
        !           105:        0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
        !           106:        0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
        !           107:        0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
        !           108:        0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
        !           109:        0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
        !           110:        0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
        !           111:        0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
        !           112:        0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
        !           113:        0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
        !           114:        0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
        !           115:        0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
        !           116:        0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
        !           117:        0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
        !           118:        0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
        !           119:        0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
        !           120:        0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
        !           121:        0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
        !           122:        0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
        !           123:        0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
        !           124:        0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
        !           125:        0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
        !           126:        0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
        !           127: };
        !           128: 
        !           129: /**
        !           130:  * Perform S-box mapping on a 16-bit value
        !           131:  *
        !           132:  * @v v                Value to perform S-box mapping on
        !           133:  * @ret Sv     S-box mapped value
        !           134:  */
        !           135: static inline u16 S ( u16 v )
        !           136: {
        !           137:        return Sbox[v & 0xFF] ^ swap16 ( Sbox[v >> 8] );
        !           138: }
        !           139: 
        !           140: /**
        !           141:  * Rotate 16-bit value right
        !           142:  *
        !           143:  * @v v                Value to rotate
        !           144:  * @v bits     Number of bits to rotate by
        !           145:  * @ret rotv   Rotated value
        !           146:  */
        !           147: static inline u16 ror16 ( u16 v, int bits )
        !           148: {
        !           149:        return ( v >> bits ) | ( v << ( 16 - bits ) );
        !           150: }
        !           151: 
        !           152: /**
        !           153:  * Rotate 32-bit value right
        !           154:  *
        !           155:  * @v v                Value to rotate
        !           156:  * @v bits     Number of bits to rotate by
        !           157:  * @ret rotv   Rotated value
        !           158:  */
        !           159: static inline u32 ror32 ( u32 v, int bits )
        !           160: {
        !           161:        return ( v >> bits ) | ( v << ( 32 - bits ) );
        !           162: }
        !           163: 
        !           164: /**
        !           165:  * Rotate 32-bit value left
        !           166:  *
        !           167:  * @v v                Value to rotate
        !           168:  * @v bits     Number of bits to rotate by
        !           169:  * @ret rotv   Rotated value
        !           170:  */
        !           171: static inline u32 rol32 ( u32 v, int bits )
        !           172: {
        !           173:        return ( v << bits ) | ( v >> ( 32 - bits ) );
        !           174: }
        !           175: 
        !           176: 
        !           177: /**
        !           178:  * Initialise TKIP state and install key
        !           179:  *
        !           180:  * @v crypto   TKIP cryptosystem structure
        !           181:  * @v key      Pointer to tkip_tk to install
        !           182:  * @v keylen   Length of key (32 bytes)
        !           183:  * @v rsc      Initial receive sequence counter
        !           184:  */
        !           185: static int tkip_init ( struct net80211_crypto *crypto, const void *key,
        !           186:                       int keylen, const void *rsc )
        !           187: {
        !           188:        struct tkip_ctx *ctx = crypto->priv;
        !           189:        const u8 *rscb = rsc;
        !           190: 
        !           191:        if ( keylen != sizeof ( ctx->tk ) )
        !           192:                return -EINVAL;
        !           193: 
        !           194:        if ( rscb ) {
        !           195:                ctx->dec.tsc_lo =   ( rscb[1] <<  8 ) |   rscb[0];
        !           196:                ctx->dec.tsc_hi = ( ( rscb[5] << 24 ) | ( rscb[4] << 16 ) |
        !           197:                                    ( rscb[3] <<  8 ) |   rscb[2] );
        !           198:        }
        !           199: 
        !           200:        memcpy ( &ctx->tk, key, sizeof ( ctx->tk ) );
        !           201: 
        !           202:        return 0;
        !           203: }
        !           204: 
        !           205: /**
        !           206:  * Perform TKIP key mixing, phase 1
        !           207:  *
        !           208:  * @v dctx     TKIP directional context
        !           209:  * @v tk       TKIP temporal key
        !           210:  * @v mac      MAC address of transmitter
        !           211:  *
        !           212:  * This recomputes the TTAK in @a dctx if necessary, and sets
        !           213:  * @c dctx->ttak_ok.
        !           214:  */
        !           215: static void tkip_mix_1 ( struct tkip_dir_ctx *dctx, struct tkip_tk *tk, u8 *mac )
        !           216: {
        !           217:        int i, j;
        !           218: 
        !           219:        if ( dctx->ttak_ok && ! memcmp ( mac, dctx->mac, ETH_ALEN ) )
        !           220:                return;
        !           221: 
        !           222:        memcpy ( dctx->mac, mac, ETH_ALEN );
        !           223: 
        !           224:        dctx->ttak[0] = dctx->tsc_hi & 0xFFFF;
        !           225:        dctx->ttak[1] = dctx->tsc_hi >> 16;
        !           226:        dctx->ttak[2] = ( mac[1] << 8 ) | mac[0];
        !           227:        dctx->ttak[3] = ( mac[3] << 8 ) | mac[2];
        !           228:        dctx->ttak[4] = ( mac[5] << 8 ) | mac[4];
        !           229: 
        !           230:        for ( i = 0; i < 8; i++ ) {
        !           231:                j = 2 * ( i & 1 );
        !           232: 
        !           233:                dctx->ttak[0] += S ( dctx->ttak[4] ^ ( ( tk->key[1 + j] << 8 ) |
        !           234:                                                         tk->key[0 + j] ) );
        !           235:                dctx->ttak[1] += S ( dctx->ttak[0] ^ ( ( tk->key[5 + j] << 8 ) |
        !           236:                                                         tk->key[4 + j] ) );
        !           237:                dctx->ttak[2] += S ( dctx->ttak[1] ^ ( ( tk->key[9 + j] << 8 ) |
        !           238:                                                         tk->key[8 + j] ) );
        !           239:                dctx->ttak[3] += S ( dctx->ttak[2] ^ ( ( tk->key[13+ j] << 8 ) |
        !           240:                                                         tk->key[12+ j] ) );
        !           241:                dctx->ttak[4] += S ( dctx->ttak[3] ^ ( ( tk->key[1 + j] << 8 ) |
        !           242:                                                         tk->key[0 + j] ) ) + i;
        !           243:        }
        !           244: 
        !           245:        dctx->ttak_ok = 1;
        !           246: }
        !           247: 
        !           248: /**
        !           249:  * Perform TKIP key mixing, phase 2
        !           250:  *
        !           251:  * @v dctx     TKIP directional context
        !           252:  * @v tk       TKIP temporal key
        !           253:  * @ret key    ARC4 key, 16 bytes long
        !           254:  */
        !           255: static void tkip_mix_2 ( struct tkip_dir_ctx *dctx, struct tkip_tk *tk,
        !           256:                         void *key )
        !           257: {
        !           258:        u8 *kb = key;
        !           259:        u16 ppk[6];
        !           260:        int i;
        !           261: 
        !           262:        memcpy ( ppk, dctx->ttak, sizeof ( dctx->ttak ) );
        !           263:        ppk[5] = dctx->ttak[4] + dctx->tsc_lo;
        !           264: 
        !           265:        ppk[0] += S ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) );
        !           266:        ppk[1] += S ( ppk[0] ^ ( ( tk->key[3] << 8 ) | tk->key[2] ) );
        !           267:        ppk[2] += S ( ppk[1] ^ ( ( tk->key[5] << 8 ) | tk->key[4] ) );
        !           268:        ppk[3] += S ( ppk[2] ^ ( ( tk->key[7] << 8 ) | tk->key[6] ) );
        !           269:        ppk[4] += S ( ppk[3] ^ ( ( tk->key[9] << 8 ) | tk->key[8] ) );
        !           270:        ppk[5] += S ( ppk[4] ^ ( ( tk->key[11] << 8 ) | tk->key[10] ) );
        !           271: 
        !           272:        ppk[0] += ror16 ( ppk[5] ^ ( ( tk->key[13] << 8 ) | tk->key[12] ), 1 );
        !           273:        ppk[1] += ror16 ( ppk[0] ^ ( ( tk->key[15] << 8 ) | tk->key[14] ), 1 );
        !           274:        ppk[2] += ror16 ( ppk[1], 1 );
        !           275:        ppk[3] += ror16 ( ppk[2], 1 );
        !           276:        ppk[4] += ror16 ( ppk[3], 1 );
        !           277:        ppk[5] += ror16 ( ppk[4], 1 );
        !           278: 
        !           279:        kb[0] = dctx->tsc_lo >> 8;
        !           280:        kb[1] = ( ( dctx->tsc_lo >> 8 ) | 0x20 ) & 0x7F;
        !           281:        kb[2] = dctx->tsc_lo & 0xFF;
        !           282:        kb[3] = ( ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) ) >> 1 )
        !           283:                & 0xFF;
        !           284: 
        !           285:        for ( i = 0; i < 6; i++ ) {
        !           286:                kb[4 + 2*i] = ppk[i] & 0xFF;
        !           287:                kb[5 + 2*i] = ppk[i] >> 8;
        !           288:        }
        !           289: }
        !           290: 
        !           291: /**
        !           292:  * Update Michael message integrity code based on next 32-bit word of data
        !           293:  *
        !           294:  * @v V                Michael code state (two 32-bit words)
        !           295:  * @v word     Next 32-bit word of data
        !           296:  */
        !           297: static void tkip_feed_michael ( u32 *V, u32 word )
        !           298: {
        !           299:        V[0] ^= word;
        !           300:        V[1] ^= rol32 ( V[0], 17 );
        !           301:        V[0] += V[1];
        !           302:        V[1] ^= ( ( V[0] & 0xFF00FF00 ) >> 8 ) | ( ( V[0] & 0x00FF00FF ) << 8 );
        !           303:        V[0] += V[1];
        !           304:        V[1] ^= rol32 ( V[0], 3 );
        !           305:        V[0] += V[1];
        !           306:        V[1] ^= ror32 ( V[0], 2 );
        !           307:        V[0] += V[1];
        !           308: }
        !           309: 
        !           310: /**
        !           311:  * Calculate Michael message integrity code
        !           312:  *
        !           313:  * @v key      MIC key to use (8 bytes)
        !           314:  * @v da       Destination link-layer address
        !           315:  * @v sa       Source link-layer address
        !           316:  * @v data     Start of data to calculate over
        !           317:  * @v len      Length of header + data
        !           318:  * @ret mic    Calculated Michael MIC (8 bytes)
        !           319:  */
        !           320: static void tkip_michael ( const void *key, const void *da, const void *sa,
        !           321:                           const void *data, size_t len, void *mic )
        !           322: {
        !           323:        u32 V[2];               /* V[0] = "l", V[1] = "r" in 802.11 */
        !           324:        union {
        !           325:                u8 byte[12];
        !           326:                u32 word[3];
        !           327:        } cap;
        !           328:        const u8 *ptr = data;
        !           329:        const u8 *end = ptr + len;
        !           330:        int i;
        !           331: 
        !           332:        memcpy ( V, key, sizeof ( V ) );
        !           333:        V[0] = le32_to_cpu ( V[0] );
        !           334:        V[1] = le32_to_cpu ( V[1] );
        !           335: 
        !           336:        /* Feed in header (we assume non-QoS, so Priority = 0) */
        !           337:        memcpy ( &cap.byte[0], da, ETH_ALEN );
        !           338:        memcpy ( &cap.byte[6], sa, ETH_ALEN );
        !           339:        tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
        !           340:        tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
        !           341:        tkip_feed_michael ( V, le32_to_cpu ( cap.word[2] ) );
        !           342:        tkip_feed_michael ( V, 0 );
        !           343: 
        !           344:        /* Feed in data */
        !           345:        while ( ptr + 4 <= end ) {
        !           346:                tkip_feed_michael ( V, le32_to_cpu ( *( u32 * ) ptr ) );
        !           347:                ptr += 4;
        !           348:        }
        !           349: 
        !           350:        /* Add unaligned part and padding */
        !           351:        for ( i = 0; ptr < end; i++ )
        !           352:                cap.byte[i] = *ptr++;
        !           353:        cap.byte[i++] = 0x5a;
        !           354:        for ( ; i < 8; i++ )
        !           355:                cap.byte[i] = 0;
        !           356: 
        !           357:        /* Feed in padding */
        !           358:        tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
        !           359:        tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
        !           360: 
        !           361:        /* Output MIC */
        !           362:        V[0] = cpu_to_le32 ( V[0] );
        !           363:        V[1] = cpu_to_le32 ( V[1] );
        !           364:        memcpy ( mic, V, sizeof ( V ) );
        !           365: }
        !           366: 
        !           367: /**
        !           368:  * Encrypt a packet using TKIP
        !           369:  *
        !           370:  * @v crypto   TKIP cryptosystem
        !           371:  * @v iob      I/O buffer containing cleartext packet
        !           372:  * @ret eiob   I/O buffer containing encrypted packet
        !           373:  */
        !           374: static struct io_buffer * tkip_encrypt ( struct net80211_crypto *crypto,
        !           375:                                         struct io_buffer *iob )
        !           376: {
        !           377:        struct tkip_ctx *ctx = crypto->priv;
        !           378:        struct ieee80211_frame *hdr = iob->data;
        !           379:        struct io_buffer *eiob;
        !           380:        struct arc4_ctx arc4;
        !           381:        u8 key[16];
        !           382:        struct tkip_head head;
        !           383:        u8 mic[8];
        !           384:        u32 icv;
        !           385:        const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
        !           386:        int datalen = iob_len ( iob ) - hdrlen;
        !           387: 
        !           388:        ctx->enc.tsc_lo++;
        !           389:        if ( ctx->enc.tsc_lo == 0 ) {
        !           390:                ctx->enc.tsc_hi++;
        !           391:                ctx->enc.ttak_ok = 0;
        !           392:        }
        !           393: 
        !           394:        tkip_mix_1 ( &ctx->enc, &ctx->tk, hdr->addr2 );
        !           395:        tkip_mix_2 ( &ctx->enc, &ctx->tk, key );
        !           396: 
        !           397:        eiob = alloc_iob ( iob_len ( iob ) + TKIP_HEAD_LEN + TKIP_FOOT_LEN );
        !           398:        if ( ! eiob )
        !           399:                return NULL;
        !           400: 
        !           401:        /* Copy frame header */
        !           402:        memcpy ( iob_put ( eiob, hdrlen ), iob->data, hdrlen );
        !           403:        hdr = eiob->data;
        !           404:        hdr->fc |= IEEE80211_FC_PROTECTED;
        !           405: 
        !           406:        /* Fill in IV and key ID byte, and extended IV */
        !           407:        memcpy ( &head, key, 3 );
        !           408:        head.kid = 0x20;                /* have Extended IV, key ID 0 */
        !           409:        head.tsc_hi = cpu_to_le32 ( ctx->enc.tsc_hi );
        !           410:        memcpy ( iob_put ( eiob, sizeof ( head ) ), &head, sizeof ( head ) );
        !           411: 
        !           412:        /* Copy and encrypt the data */
        !           413:        cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
        !           414:        cipher_encrypt ( &arc4_algorithm, &arc4, iob->data + hdrlen,
        !           415:                         iob_put ( eiob, datalen ), datalen );
        !           416: 
        !           417:        /* Add MIC */
        !           418:        hdr = iob->data;
        !           419:        tkip_michael ( &ctx->tk.mic.tx, hdr->addr3, hdr->addr2,
        !           420:                       iob->data + hdrlen, datalen, mic );
        !           421:        cipher_encrypt ( &arc4_algorithm, &arc4, mic,
        !           422:                         iob_put ( eiob, sizeof ( mic ) ), sizeof ( mic ) );
        !           423: 
        !           424:        /* Add ICV */
        !           425:        icv = crc32_le ( ~0, iob->data + hdrlen, datalen );
        !           426:        icv = crc32_le ( icv, mic, sizeof ( mic ) );
        !           427:        icv = cpu_to_le32 ( ~icv );
        !           428:        cipher_encrypt ( &arc4_algorithm, &arc4, &icv,
        !           429:                         iob_put ( eiob, TKIP_ICV_LEN ), TKIP_ICV_LEN );
        !           430: 
        !           431:        DBGC2 ( ctx, "WPA-TKIP %p: encrypted packet %p -> %p\n", ctx,
        !           432:                iob, eiob );
        !           433: 
        !           434:        return eiob;
        !           435: }
        !           436: 
        !           437: /**
        !           438:  * Decrypt a packet using TKIP
        !           439:  *
        !           440:  * @v crypto   TKIP cryptosystem
        !           441:  * @v eiob     I/O buffer containing encrypted packet
        !           442:  * @ret iob    I/O buffer containing cleartext packet
        !           443:  */
        !           444: static struct io_buffer * tkip_decrypt ( struct net80211_crypto *crypto,
        !           445:                                         struct io_buffer *eiob )
        !           446: {
        !           447:        struct tkip_ctx *ctx = crypto->priv;
        !           448:        struct ieee80211_frame *hdr;
        !           449:        struct io_buffer *iob;
        !           450:        const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
        !           451:        int datalen = iob_len ( eiob ) - hdrlen - TKIP_HEAD_LEN - TKIP_FOOT_LEN;
        !           452:        struct tkip_head *head;
        !           453:        struct arc4_ctx arc4;
        !           454:        u16 rx_tsc_lo;
        !           455:        u8 key[16];
        !           456:        u8 mic[8];
        !           457:        u32 icv, crc;
        !           458: 
        !           459:        iob = alloc_iob ( hdrlen + datalen + TKIP_FOOT_LEN );
        !           460:        if ( ! iob )
        !           461:                return NULL;
        !           462: 
        !           463:        /* Copy frame header */
        !           464:        memcpy ( iob_put ( iob, hdrlen ), eiob->data, hdrlen );
        !           465:        hdr = iob->data;
        !           466:        hdr->fc &= ~IEEE80211_FC_PROTECTED;
        !           467: 
        !           468:        /* Check and update TSC */
        !           469:        head = eiob->data + hdrlen;
        !           470:        rx_tsc_lo = ( head->tsc1 << 8 ) | head->tsc0;
        !           471: 
        !           472:        if ( head->tsc_hi < ctx->dec.tsc_hi ||
        !           473:             ( head->tsc_hi == ctx->dec.tsc_hi &&
        !           474:               rx_tsc_lo <= ctx->dec.tsc_lo ) ) {
        !           475:                DBGC ( ctx, "WPA-TKIP %p: packet received out of order "
        !           476:                       "(%08x:%04x <= %08x:%04x)\n", ctx, head->tsc_hi,
        !           477:                       rx_tsc_lo, ctx->dec.tsc_hi, ctx->dec.tsc_lo );
        !           478:                free_iob ( iob );
        !           479:                return NULL;
        !           480:        }
        !           481:        ctx->dec.tsc_lo = rx_tsc_lo;
        !           482:        if ( ctx->dec.tsc_hi != head->tsc_hi ) {
        !           483:                ctx->dec.ttak_ok = 0;
        !           484:                ctx->dec.tsc_hi = head->tsc_hi;
        !           485:        }
        !           486: 
        !           487:        /* Calculate key */
        !           488:        tkip_mix_1 ( &ctx->dec, &ctx->tk, hdr->addr2 );
        !           489:        tkip_mix_2 ( &ctx->dec, &ctx->tk, key );
        !           490: 
        !           491:        /* Copy-decrypt data, MIC, ICV */
        !           492:        cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
        !           493:        cipher_decrypt ( &arc4_algorithm, &arc4,
        !           494:                         eiob->data + hdrlen + TKIP_HEAD_LEN,
        !           495:                         iob_put ( iob, datalen ), datalen + TKIP_FOOT_LEN );
        !           496: 
        !           497:        /* Check ICV */
        !           498:        icv = le32_to_cpu ( *( u32 * ) ( iob->tail + TKIP_MIC_LEN ) );
        !           499:        crc = ~crc32_le ( ~0, iob->data + hdrlen, datalen + TKIP_MIC_LEN );
        !           500:        if ( crc != icv ) {
        !           501:                DBGC ( ctx, "WPA-TKIP %p CRC mismatch: expect %08x, get %08x\n",
        !           502:                       ctx, icv, crc );
        !           503:                free_iob ( iob );
        !           504:                return NULL;
        !           505:        }
        !           506: 
        !           507:        /* Check MIC */
        !           508:        tkip_michael ( &ctx->tk.mic.rx, hdr->addr1, hdr->addr3,
        !           509:                       iob->data + hdrlen, datalen, mic );
        !           510:        if ( memcmp ( mic, iob->tail, TKIP_MIC_LEN ) != 0 ) {
        !           511:                DBGC ( ctx, "WPA-TKIP %p ALERT! MIC failure\n", ctx );
        !           512:                /* XXX we should do the countermeasures here */
        !           513:                free_iob ( iob );
        !           514:                return NULL;
        !           515:        }
        !           516: 
        !           517:        DBGC2 ( ctx, "WPA-TKIP %p: decrypted packet %p -> %p\n", ctx,
        !           518:                eiob, iob );
        !           519: 
        !           520:        return iob;
        !           521: }
        !           522: 
        !           523: /** TKIP cryptosystem */
        !           524: struct net80211_crypto tkip_crypto __net80211_crypto = {
        !           525:        .algorithm = NET80211_CRYPT_TKIP,
        !           526:        .init = tkip_init,
        !           527:        .encrypt = tkip_encrypt,
        !           528:        .decrypt = tkip_decrypt,
        !           529:        .priv_len = sizeof ( struct tkip_ctx ),
        !           530: };
        !           531: 
        !           532: 
        !           533: 
        !           534: 
        !           535: /**
        !           536:  * Calculate HMAC-MD5 MIC for EAPOL-Key frame
        !           537:  *
        !           538:  * @v kck      Key Confirmation Key, 16 bytes
        !           539:  * @v msg      Message to calculate MIC over
        !           540:  * @v len      Number of bytes to calculate MIC over
        !           541:  * @ret mic    Calculated MIC, 16 bytes long
        !           542:  */
        !           543: static void tkip_kie_mic ( const void *kck, const void *msg, size_t len,
        !           544:                           void *mic )
        !           545: {
        !           546:        struct md5_ctx md5;
        !           547:        u8 kckb[16];
        !           548:        size_t kck_len = 16;
        !           549: 
        !           550:        memcpy ( kckb, kck, kck_len );
        !           551: 
        !           552:        hmac_init ( &md5_algorithm, &md5, kckb, &kck_len );
        !           553:        hmac_update ( &md5_algorithm, &md5, msg, len );
        !           554:        hmac_final ( &md5_algorithm, &md5, kckb, &kck_len, mic );
        !           555: }
        !           556: 
        !           557: /**
        !           558:  * Decrypt key data in EAPOL-Key frame
        !           559:  *
        !           560:  * @v kek      Key Encryption Key, 16 bytes
        !           561:  * @v iv       Initialisation vector, 16 bytes
        !           562:  * @v msg      Message to decrypt
        !           563:  * @v len      Length of message
        !           564:  * @ret msg    Decrypted message in place of original
        !           565:  * @ret len    Unchanged
        !           566:  * @ret rc     Always 0 for success
        !           567:  */
        !           568: static int tkip_kie_decrypt ( const void *kek, const void *iv,
        !           569:                              void *msg, u16 *len )
        !           570: {
        !           571:        u8 key[32];
        !           572:        memcpy ( key, iv, 16 );
        !           573:        memcpy ( key + 16, kek, 16 );
        !           574: 
        !           575:        arc4_skip ( key, 32, 256, msg, msg, *len );
        !           576: 
        !           577:        return 0;
        !           578: }
        !           579: 
        !           580: 
        !           581: /** TKIP-style key integrity and encryption handler */
        !           582: struct wpa_kie tkip_kie __wpa_kie = {
        !           583:        .version = EAPOL_KEY_VERSION_WPA,
        !           584:        .mic = tkip_kie_mic,
        !           585:        .decrypt = tkip_kie_decrypt,
        !           586: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.