[BACK]Return to ieee80211_crypto.c CVS log [TXT][DIR] Up to [local] / sys / net80211

Annotation of sys/net80211/ieee80211_crypto.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ieee80211_crypto.c,v 1.31 2007/08/03 16:51:06 damien Exp $    */
                      2: /*     $NetBSD: ieee80211_crypto.c,v 1.5 2003/12/14 09:56:53 dyoung Exp $      */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2001 Atsushi Onoe
                      6:  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
                      7:  * Copyright (c) 2007 Damien Bergamini
                      8:  * All rights reserved.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. The name of the author may not be used to endorse or promote products
                     19:  *    derived from this software without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: #include "bpfilter.h"
                     34:
                     35: #include <sys/param.h>
                     36: #include <sys/systm.h>
                     37: #include <sys/mbuf.h>
                     38: #include <sys/malloc.h>
                     39: #include <sys/kernel.h>
                     40: #include <sys/socket.h>
                     41: #include <sys/sockio.h>
                     42: #include <sys/endian.h>
                     43: #include <sys/errno.h>
                     44: #include <sys/proc.h>
                     45: #include <sys/sysctl.h>
                     46:
                     47: #include <net/if.h>
                     48: #include <net/if_dl.h>
                     49: #include <net/if_media.h>
                     50: #include <net/if_arp.h>
                     51: #include <net/if_llc.h>
                     52:
                     53: #if NBPFILTER > 0
                     54: #include <net/bpf.h>
                     55: #endif
                     56:
                     57: #ifdef INET
                     58: #include <netinet/in.h>
                     59: #include <netinet/if_ether.h>
                     60: #endif
                     61:
                     62: #include <net80211/ieee80211_var.h>
                     63:
                     64: #include <dev/rndvar.h>
                     65: #include <crypto/arc4.h>
                     66: #include <crypto/md5.h>
                     67: #include <crypto/sha1.h>
                     68: #include <crypto/rijndael.h>
                     69:
                     70: struct vector {
                     71:        const void      *base;
                     72:        size_t          len;
                     73: };
                     74:
                     75: void   ieee80211_crc_init(void);
                     76: u_int32_t ieee80211_crc_update(u_int32_t, const u_int8_t *, int);
                     77: struct mbuf *ieee80211_ccmp_encrypt(struct ieee80211com *, struct mbuf *,
                     78:            struct ieee80211_key *);
                     79: struct mbuf *ieee80211_ccmp_decrypt(struct ieee80211com *, struct mbuf *,
                     80:            struct ieee80211_key *);
                     81: struct mbuf *ieee80211_tkip_encrypt(struct ieee80211com *, struct mbuf *,
                     82:            struct ieee80211_key *);
                     83: struct mbuf *ieee80211_tkip_decrypt(struct ieee80211com *, struct mbuf *,
                     84:            struct ieee80211_key *);
                     85: void   ieee80211_aes_key_wrap(const u_int8_t *, size_t, const u_int8_t *,
                     86:            size_t, u_int8_t *);
                     87: int    ieee80211_aes_key_unwrap(const u_int8_t *, size_t, const u_int8_t *,
                     88:            u_int8_t *, size_t);
                     89: void   ieee80211_hmac_md5_v(const struct vector *, int, const u_int8_t *,
                     90:            size_t, u_int8_t digest[]);
                     91: void   ieee80211_hmac_md5(const u_int8_t *, size_t, const u_int8_t *, size_t,
                     92:            u_int8_t digest[]);
                     93: void   ieee80211_hmac_sha1_v(const struct vector *, int, const u_int8_t *,
                     94:            size_t, u_int8_t digest[]);
                     95: void   ieee80211_hmac_sha1(const u_int8_t *, size_t, const u_int8_t *, size_t,
                     96:            u_int8_t digest[]);
                     97: void   ieee80211_prf(const u_int8_t *, size_t, struct vector *, int,
                     98:            u_int8_t *, size_t);
                     99: void   ieee80211_derive_pmkid(const u_int8_t *, size_t, const u_int8_t *,
                    100:            const u_int8_t *, u_int8_t *);
                    101: void   ieee80211_derive_gtk(const u_int8_t *, size_t, const u_int8_t *,
                    102:            const u_int8_t *, u_int8_t *, size_t);
                    103:
                    104: void
                    105: ieee80211_crypto_attach(struct ifnet *ifp)
                    106: {
                    107:        struct ieee80211com *ic = (void *)ifp;
                    108:
                    109:        ieee80211_crc_init();
                    110:
                    111:        /* initialize 256-bit global key counter to a random value */
                    112:        get_random_bytes(ic->ic_globalcnt, EAPOL_KEY_NONCE_LEN);
                    113: }
                    114:
                    115: void
                    116: ieee80211_crypto_detach(struct ifnet *ifp)
                    117: {
                    118:        struct ieee80211com *ic = (void *)ifp;
                    119:
                    120:        if (ic->ic_wep_ctx != NULL) {
                    121:                free(ic->ic_wep_ctx, M_DEVBUF);
                    122:                ic->ic_wep_ctx = NULL;
                    123:        }
                    124: }
                    125:
                    126: struct mbuf *
                    127: ieee80211_encrypt(struct ieee80211com *ic, struct mbuf *m0,
                    128:     struct ieee80211_node *ni)
                    129: {
                    130:        struct ieee80211_frame *wh;
                    131:        struct ieee80211_key *k;
                    132:
                    133:        /* select the key for encryption */
                    134:        wh = mtod(m0, struct ieee80211_frame *);
                    135:        if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
                    136:            ni->ni_pairwise_cipher == IEEE80211_CIPHER_USEGROUP)
                    137:                k = &ic->ic_nw_keys[ic->ic_wep_txkey];
                    138:        else
                    139:                k = &ni->ni_pairwise_key;
                    140:
                    141:        switch (k->k_cipher) {
                    142:        case IEEE80211_CIPHER_WEP40:
                    143:        case IEEE80211_CIPHER_WEP104:
                    144:                m0 = ieee80211_wep_crypt(&ic->ic_if, m0, 1);
                    145:                break;
                    146:        case IEEE80211_CIPHER_TKIP:
                    147:                m0 = ieee80211_tkip_encrypt(ic, m0, k);
                    148:                break;
                    149:        case IEEE80211_CIPHER_CCMP:
                    150:                m0 = ieee80211_ccmp_encrypt(ic, m0, k);
                    151:                break;
                    152:        default:
                    153:                /* should not get there */
                    154:                m_freem(m0);
                    155:                m0 = NULL;
                    156:        }
                    157:        return m0;
                    158: }
                    159:
                    160: struct mbuf *
                    161: ieee80211_decrypt(struct ieee80211com *ic, struct mbuf *m0,
                    162:     struct ieee80211_node *ni)
                    163: {
                    164:        struct ieee80211_frame *wh;
                    165:        struct ieee80211_key *k;
                    166:
                    167:        /* select the key for decryption */
                    168:        wh = mtod(m0, struct ieee80211_frame *);
                    169:        if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
                    170:            ni->ni_pairwise_cipher == IEEE80211_CIPHER_USEGROUP) {
                    171:                size_t hdrlen = sizeof(*wh);    /* XXX QoS */
                    172:                u_int8_t *ivp = (u_int8_t *)wh + hdrlen;
                    173:                /* key identifier is always located at the same index */
                    174:                int kid = ivp[IEEE80211_WEP_IVLEN] >> 6;
                    175:                k = &ic->ic_nw_keys[kid];
                    176:        } else
                    177:                k = &ni->ni_pairwise_key;
                    178:
                    179:        switch (k->k_cipher) {
                    180:        case IEEE80211_CIPHER_WEP40:
                    181:        case IEEE80211_CIPHER_WEP104:
                    182:                m0 = ieee80211_wep_crypt(&ic->ic_if, m0, 0);
                    183:                break;
                    184:        case IEEE80211_CIPHER_TKIP:
                    185:                m0 = ieee80211_tkip_decrypt(ic, m0, k);
                    186:                break;
                    187:        case IEEE80211_CIPHER_CCMP:
                    188:                m0 = ieee80211_ccmp_decrypt(ic, m0, k);
                    189:                break;
                    190:        default:
                    191:                /* should not get there */
                    192:                m_freem(m0);
                    193:                m0 = NULL;
                    194:        }
                    195:        return m0;
                    196: }
                    197:
                    198: #define IEEE80211_CCMP_HDRLEN  8
                    199: #define IEEE80211_CCMP_MICLEN  8
                    200:
                    201: struct mbuf *
                    202: ieee80211_ccmp_encrypt(struct ieee80211com *ic, struct mbuf *m0,
                    203:     struct ieee80211_key *k)
                    204: {
                    205:        struct ieee80211_frame *wh;
                    206:        size_t hdrlen = sizeof(*wh);    /* XXX QoS */
                    207:        u_int8_t *ivp;
                    208:
                    209:        M_PREPEND(m0, IEEE80211_CCMP_HDRLEN, M_NOWAIT);
                    210:        if (m0 == NULL)
                    211:                return m0;
                    212:        wh = mtod(m0, struct ieee80211_frame *);
                    213:        ovbcopy(mtod(m0, u_int8_t *) + IEEE80211_CCMP_HDRLEN, wh, hdrlen);
                    214:        ivp = (u_int8_t *)wh + hdrlen;
                    215:
                    216:        k->k_tsc++;     /* increment the 48-bit PN */
                    217:        ivp[0] = k->k_tsc;              /* PN0 */
                    218:        ivp[1] = k->k_tsc >> 8;         /* PN1 */
                    219:        ivp[2] = 0;                     /* Rsvd */
                    220:        ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV;    /* KeyID | ExtIV */
                    221:        ivp[4] = k->k_tsc >> 16;        /* PN2 */
                    222:        ivp[5] = k->k_tsc >> 24;        /* PN3 */
                    223:        ivp[6] = k->k_tsc >> 32;        /* PN4 */
                    224:        ivp[7] = k->k_tsc >> 40;        /* PN5 */
                    225:
                    226:        /* XXX encrypt payload if HW encryption not supported */
                    227:
                    228:        return m0;
                    229: }
                    230:
                    231: struct mbuf *
                    232: ieee80211_ccmp_decrypt(struct ieee80211com *ic, struct mbuf *m0,
                    233:     struct ieee80211_key *k)
                    234: {
                    235:        struct ieee80211_frame *wh;
                    236:        size_t hdrlen = sizeof(*wh);    /* XXX QoS */
                    237:        u_int64_t pn;
                    238:        u_int8_t *ivp;
                    239:
                    240:        wh = mtod(m0, struct ieee80211_frame *);
                    241:        ivp = (u_int8_t *)wh + hdrlen;
                    242:
                    243:        /* check that ExtIV bit is be set */
                    244:        if (!(ivp[3] & IEEE80211_WEP_EXTIV)) {
                    245:                m_freem(m0);
                    246:                return NULL;
                    247:        }
                    248:        /* extract the 48-bit PN from the CCMP header */
                    249:        pn = (u_int64_t)ivp[0]       |
                    250:             (u_int64_t)ivp[1] <<  8 |
                    251:             (u_int64_t)ivp[4] << 16 |
                    252:             (u_int64_t)ivp[5] << 24 |
                    253:             (u_int64_t)ivp[6] << 32 |
                    254:             (u_int64_t)ivp[7] << 40;
                    255:        /* NB: the keys are refreshed, we'll never overflow the 48 bits */
                    256:        if (pn <= k->k_rsc) {
                    257:                /* replayed frame, discard */
                    258:                /* XXX statistics */
                    259:                m_freem(m0);
                    260:                return NULL;
                    261:        }
                    262:
                    263:        /* XXX decrypt payload if HW encryption not supported */
                    264:
                    265:        ovbcopy(mtod(m0, u_int8_t *),
                    266:            mtod(m0, u_int8_t *) + IEEE80211_CCMP_HDRLEN, hdrlen);
                    267:        m_adj(m0, IEEE80211_CCMP_HDRLEN);
                    268:        m_adj(m0, -IEEE80211_CCMP_MICLEN);
                    269:
                    270:        /* update last seen packet number */
                    271:        k->k_rsc = pn;
                    272:
                    273:        return m0;
                    274: }
                    275:
                    276: #define IEEE80211_TKIP_HDRLEN  8
                    277: #define IEEE80211_TKIP_MICLEN  8
                    278: #define IEEE80211_TKIP_ICVLEN  4
                    279:
                    280: struct mbuf *
                    281: ieee80211_tkip_encrypt(struct ieee80211com *ic, struct mbuf *m0,
                    282:     struct ieee80211_key *k)
                    283: {
                    284:        struct ieee80211_frame *wh;
                    285:        size_t hdrlen = sizeof(*wh);    /* XXX QoS */
                    286:        u_int8_t *ivp;
                    287:
                    288:        M_PREPEND(m0, IEEE80211_TKIP_HDRLEN, M_NOWAIT);
                    289:        if (m0 == NULL)
                    290:                return m0;
                    291:        wh = mtod(m0, struct ieee80211_frame *);
                    292:        ovbcopy(mtod(m0, u_int8_t *) + IEEE80211_TKIP_HDRLEN, wh, hdrlen);
                    293:        ivp = (u_int8_t *)wh + hdrlen;
                    294:
                    295:        ivp[0] = k->k_tsc >> 8;         /* TSC1 */
                    296:        /* WEP Seed = (TSC1 | 0x20) & 0x7f (see 8.3.2.2) */
                    297:        ivp[1] = (ivp[0] | 0x20) & 0x7f;
                    298:        ivp[2] = k->k_tsc;              /* TSC0 */
                    299:        ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV;    /* KeyID | ExtIV */
                    300:        ivp[4] = k->k_tsc >> 16;        /* TSC2 */
                    301:        ivp[5] = k->k_tsc >> 24;        /* TSC3 */
                    302:        ivp[6] = k->k_tsc >> 32;        /* TSC4 */
                    303:        ivp[7] = k->k_tsc >> 40;        /* TSC5 */
                    304:
                    305:        /* XXX encrypt payload if HW encryption not supported */
                    306:
                    307:        k->k_tsc++;     /* increment the 48-bit TSC */
                    308:
                    309:        return m0;
                    310: }
                    311:
                    312: struct mbuf *
                    313: ieee80211_tkip_decrypt(struct ieee80211com *ic, struct mbuf *m0,
                    314:     struct ieee80211_key *k)
                    315: {
                    316:        struct ieee80211_frame *wh;
                    317:        size_t hdrlen = sizeof(*wh);    /* XXX QoS */
                    318:        u_int64_t tsc;
                    319:        u_int8_t *ivp;
                    320:
                    321:        wh = mtod(m0, struct ieee80211_frame *);
                    322:        ivp = (u_int8_t *)wh + hdrlen;
                    323:
                    324:        /* check that ExtIV bit is be set */
                    325:        if (!(ivp[3] & IEEE80211_WEP_EXTIV)) {
                    326:                m_freem(m0);
                    327:                return NULL;
                    328:        }
                    329:        /* extract the 48-bit TSC from the TKIP header */
                    330:        tsc = (u_int64_t)ivp[2]       |
                    331:              (u_int64_t)ivp[0] <<  8 |
                    332:              (u_int64_t)ivp[4] << 16 |
                    333:              (u_int64_t)ivp[5] << 24 |
                    334:              (u_int64_t)ivp[6] << 32 |
                    335:              (u_int64_t)ivp[7] << 40;
                    336:        /* NB: the keys are refreshed, we'll never overflow the 48 bits */
                    337:        if (tsc <= k->k_rsc) {
                    338:                /* replayed frame, discard */
                    339:                /* XXX statistics */
                    340:                m_freem(m0);
                    341:                return NULL;
                    342:        }
                    343:
                    344:        /* XXX decrypt payload if HW encryption not supported */
                    345:
                    346:        ovbcopy(mtod(m0, u_int8_t *),
                    347:            mtod(m0, u_int8_t *) + IEEE80211_TKIP_HDRLEN, hdrlen);
                    348:        m_adj(m0, IEEE80211_TKIP_HDRLEN);
                    349:        m_adj(m0, -IEEE80211_TKIP_ICVLEN);
                    350:
                    351:        /* update last seen packet number */
                    352:        k->k_rsc = tsc;
                    353:
                    354:        return m0;
                    355: }
                    356:
                    357: /* Round up to a multiple of IEEE80211_WEP_KEYLEN + IEEE80211_WEP_IVLEN */
                    358: #define klen_round(x)                                                  \
                    359:        (((x) + (IEEE80211_WEP_KEYLEN + IEEE80211_WEP_IVLEN - 1)) &     \
                    360:        ~(IEEE80211_WEP_KEYLEN + IEEE80211_WEP_IVLEN - 1))
                    361:
                    362: struct mbuf *
                    363: ieee80211_wep_crypt(struct ifnet *ifp, struct mbuf *m0, int txflag)
                    364: {
                    365:        struct ieee80211com *ic = (void *)ifp;
                    366:        struct mbuf *m, *n, *n0;
                    367:        struct ieee80211_frame *wh;
                    368:        int i, left, len, moff, noff, kid;
                    369:        u_int32_t iv, crc;
                    370:        u_int8_t *ivp;
                    371:        void *ctx;
                    372:        u_int8_t keybuf[klen_round(IEEE80211_WEP_IVLEN + IEEE80211_KEYBUF_SIZE)];
                    373:        u_int8_t crcbuf[IEEE80211_WEP_CRCLEN];
                    374:
                    375:        n0 = NULL;
                    376:        if ((ctx = ic->ic_wep_ctx) == NULL) {
                    377:                ctx = malloc(sizeof(struct rc4_ctx), M_DEVBUF, M_NOWAIT);
                    378:                if (ctx == NULL) {
                    379:                        ic->ic_stats.is_crypto_nomem++;
                    380:                        goto fail;
                    381:                }
                    382:                ic->ic_wep_ctx = ctx;
                    383:        }
                    384:        m = m0;
                    385:        left = m->m_pkthdr.len;
                    386:        MGET(n, M_DONTWAIT, m->m_type);
                    387:        n0 = n;
                    388:        if (n == NULL) {
                    389:                if (txflag)
                    390:                        ic->ic_stats.is_tx_nombuf++;
                    391:                else
                    392:                        ic->ic_stats.is_rx_nombuf++;
                    393:                goto fail;
                    394:        }
                    395:        M_DUP_PKTHDR(n, m);
                    396:        len = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
                    397:        if (txflag) {
                    398:                n->m_pkthdr.len += len;
                    399:        } else {
                    400:                n->m_pkthdr.len -= len;
                    401:                left -= len;
                    402:        }
                    403:        n->m_len = MHLEN;
                    404:        if (n->m_pkthdr.len >= MINCLSIZE) {
                    405:                MCLGET(n, M_DONTWAIT);
                    406:                if (n->m_flags & M_EXT)
                    407:                        n->m_len = n->m_ext.ext_size;
                    408:        }
                    409:        wh = mtod(m, struct ieee80211_frame *);
                    410:        if ((wh->i_fc[0] &
                    411:             (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
                    412:            (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
                    413:                len = sizeof(struct ieee80211_qosframe);
                    414:        else
                    415:                len = sizeof(struct ieee80211_frame);
                    416:        memcpy(mtod(n, caddr_t), wh, len);
                    417:        wh = mtod(n, struct ieee80211_frame *);
                    418:        left -= len;
                    419:        moff = len;
                    420:        noff = len;
                    421:        if (txflag) {
                    422:                kid = ic->ic_wep_txkey;
                    423:                wh->i_fc[1] |= IEEE80211_FC1_WEP;
                    424:                iv = ic->ic_iv ? ic->ic_iv : arc4random();
                    425:                /*
                    426:                 * Skip 'bad' IVs from Fluhrer/Mantin/Shamir:
                    427:                 * (B, 255, N) with 3 <= B < 8
                    428:                 */
                    429:                if (iv >= 0x03ff00 &&
                    430:                    (iv & 0xf8ff00) == 0x00ff00)
                    431:                        iv += 0x000100;
                    432:                ic->ic_iv = iv + 1;
                    433:                /* put iv in little endian to prepare 802.11i */
                    434:                ivp = mtod(n, u_int8_t *) + noff;
                    435:                for (i = 0; i < IEEE80211_WEP_IVLEN; i++) {
                    436:                        ivp[i] = iv & 0xff;
                    437:                        iv >>= 8;
                    438:                }
                    439:                ivp[IEEE80211_WEP_IVLEN] = kid << 6;    /* pad and keyid */
                    440:                noff += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;
                    441:        } else {
                    442:                wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
                    443:                ivp = mtod(m, u_int8_t *) + moff;
                    444:                kid = ivp[IEEE80211_WEP_IVLEN] >> 6;
                    445:                moff += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;
                    446:        }
                    447:
                    448:        /*
                    449:         * Copy the IV and the key material.  The input key has been padded
                    450:         * with zeros by the ioctl.  The output key buffer length is rounded
                    451:         * to a multiple of 64bit to allow variable length keys padded by
                    452:         * zeros.
                    453:         */
                    454:        bzero(&keybuf, sizeof(keybuf));
                    455:        memcpy(keybuf, ivp, IEEE80211_WEP_IVLEN);
                    456:        memcpy(keybuf + IEEE80211_WEP_IVLEN, ic->ic_nw_keys[kid].k_key,
                    457:            ic->ic_nw_keys[kid].k_len);
                    458:        len = klen_round(IEEE80211_WEP_IVLEN + ic->ic_nw_keys[kid].k_len);
                    459:        rc4_keysetup(ctx, keybuf, len);
                    460:
                    461:        /* encrypt with calculating CRC */
                    462:        crc = ~0;
                    463:        while (left > 0) {
                    464:                len = m->m_len - moff;
                    465:                if (len == 0) {
                    466:                        m = m->m_next;
                    467:                        moff = 0;
                    468:                        continue;
                    469:                }
                    470:                if (len > n->m_len - noff) {
                    471:                        len = n->m_len - noff;
                    472:                        if (len == 0) {
                    473:                                MGET(n->m_next, M_DONTWAIT, n->m_type);
                    474:                                if (n->m_next == NULL) {
                    475:                                        if (txflag)
                    476:                                                ic->ic_stats.is_tx_nombuf++;
                    477:                                        else
                    478:                                                ic->ic_stats.is_rx_nombuf++;
                    479:                                        goto fail;
                    480:                                }
                    481:                                n = n->m_next;
                    482:                                n->m_len = MLEN;
                    483:                                if (left >= MINCLSIZE) {
                    484:                                        MCLGET(n, M_DONTWAIT);
                    485:                                        if (n->m_flags & M_EXT)
                    486:                                                n->m_len = n->m_ext.ext_size;
                    487:                                }
                    488:                                noff = 0;
                    489:                                continue;
                    490:                        }
                    491:                }
                    492:                if (len > left)
                    493:                        len = left;
                    494:                rc4_crypt(ctx, mtod(m, caddr_t) + moff,
                    495:                    mtod(n, caddr_t) + noff, len);
                    496:                if (txflag)
                    497:                        crc = ieee80211_crc_update(crc,
                    498:                            mtod(m, u_int8_t *) + moff, len);
                    499:                else
                    500:                        crc = ieee80211_crc_update(crc,
                    501:                            mtod(n, u_int8_t *) + noff, len);
                    502:                left -= len;
                    503:                moff += len;
                    504:                noff += len;
                    505:        }
                    506:        crc = ~crc;
                    507:        if (txflag) {
                    508:                *(u_int32_t *)crcbuf = htole32(crc);
                    509:                if (n->m_len >= noff + sizeof(crcbuf))
                    510:                        n->m_len = noff + sizeof(crcbuf);
                    511:                else {
                    512:                        n->m_len = noff;
                    513:                        MGET(n->m_next, M_DONTWAIT, n->m_type);
                    514:                        if (n->m_next == NULL) {
                    515:                                ic->ic_stats.is_tx_nombuf++;
                    516:                                goto fail;
                    517:                        }
                    518:                        n = n->m_next;
                    519:                        n->m_len = sizeof(crcbuf);
                    520:                        noff = 0;
                    521:                }
                    522:                rc4_crypt(ctx, crcbuf, mtod(n, caddr_t) + noff,
                    523:                    sizeof(crcbuf));
                    524:        } else {
                    525:                n->m_len = noff;
                    526:                for (noff = 0; noff < sizeof(crcbuf); noff += len) {
                    527:                        len = sizeof(crcbuf) - noff;
                    528:                        if (len > m->m_len - moff)
                    529:                                len = m->m_len - moff;
                    530:                        if (len > 0)
                    531:                                rc4_crypt(ctx, mtod(m, caddr_t) + moff,
                    532:                                    crcbuf + noff, len);
                    533:                        m = m->m_next;
                    534:                        moff = 0;
                    535:                }
                    536:                if (crc != letoh32(*(u_int32_t *)crcbuf)) {
                    537: #ifdef IEEE80211_DEBUG
                    538:                        if (ieee80211_debug) {
                    539:                                printf("%s: decrypt CRC error\n",
                    540:                                    ifp->if_xname);
                    541:                                if (ieee80211_debug > 1)
                    542:                                        ieee80211_dump_pkt(n0->m_data,
                    543:                                            n0->m_len, -1, -1);
                    544:                        }
                    545: #endif
                    546:                        ic->ic_stats.is_rx_decryptcrc++;
                    547:                        goto fail;
                    548:                }
                    549:        }
                    550:        m_freem(m0);
                    551:        return n0;
                    552:
                    553:  fail:
                    554:        m_freem(m0);
                    555:        m_freem(n0);
                    556:        return NULL;
                    557: }
                    558:
                    559: /*
                    560:  * CRC 32 -- routine from RFC 2083
                    561:  */
                    562:
                    563: /* Table of CRCs of all 8-bit messages */
                    564: static u_int32_t ieee80211_crc_table[256];
                    565:
                    566: /* Make the table for a fast CRC. */
                    567: void
                    568: ieee80211_crc_init(void)
                    569: {
                    570:        u_int32_t c;
                    571:        int n, k;
                    572:
                    573:        for (n = 0; n < 256; n++) {
                    574:                c = (u_int32_t)n;
                    575:                for (k = 0; k < 8; k++) {
                    576:                        if (c & 1)
                    577:                                c = 0xedb88320UL ^ (c >> 1);
                    578:                        else
                    579:                                c = c >> 1;
                    580:                }
                    581:                ieee80211_crc_table[n] = c;
                    582:        }
                    583: }
                    584:
                    585: /*
                    586:  * Update a running CRC with the bytes buf[0..len-1]--the CRC
                    587:  * should be initialized to all 1's, and the transmitted value
                    588:  * is the 1's complement of the final running CRC
                    589:  */
                    590: u_int32_t
                    591: ieee80211_crc_update(u_int32_t crc, const u_int8_t *buf, int len)
                    592: {
                    593:        const u_int8_t *endbuf;
                    594:
                    595:        for (endbuf = buf + len; buf < endbuf; buf++)
                    596:                crc = ieee80211_crc_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
                    597:        return crc;
                    598: }
                    599:
                    600: /*
                    601:  * AES Key Wrap Algorithm (see RFC 3394).
                    602:  */
                    603: static const u_int8_t aes_key_wrap_iv[8] =
                    604:        { 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6 };
                    605:
                    606: void
                    607: ieee80211_aes_key_wrap(const u_int8_t *kek, size_t kek_len, const u_int8_t *pt,
                    608:     size_t len, u_int8_t *ct)
                    609: {
                    610:        rijndael_ctx ctx;
                    611:        u_int8_t *a, *r, ar[16];
                    612:        u_int64_t t, b[2];
                    613:        size_t i;
                    614:        int j;
                    615:
                    616:        /* allow ciphertext and plaintext to overlap (ct == pt) */
                    617:        ovbcopy(pt, ct + 8, len * 8);
                    618:        a = ct;
                    619:        memcpy(a, aes_key_wrap_iv, 8);  /* default IV */
                    620:
                    621:        rijndael_set_key_enc_only(&ctx, (u_int8_t *)kek, kek_len * 8);
                    622:
                    623:        for (j = 0, t = 1; j < 6; j++) {
                    624:                r = ct + 8;
                    625:                for (i = 0; i < len; i++, t++) {
                    626:                        memcpy(ar, a, 8);
                    627:                        memcpy(ar + 8, r, 8);
                    628:                        rijndael_encrypt(&ctx, ar, (u_int8_t *)b);
                    629:                        b[0] ^= htobe64(t);
                    630:                        memcpy(a, &b[0], 8);
                    631:                        memcpy(r, &b[1], 8);
                    632:
                    633:                        r += 8;
                    634:                }
                    635:        }
                    636: }
                    637:
                    638: int
                    639: ieee80211_aes_key_unwrap(const u_int8_t *kek, size_t kek_len,
                    640:     const u_int8_t *ct, u_int8_t *pt, size_t len)
                    641: {
                    642:        rijndael_ctx ctx;
                    643:        u_int8_t a[8], *r, b[16];
                    644:        u_int64_t t, ar[2];
                    645:        size_t i;
                    646:        int j;
                    647:
                    648:        memcpy(a, ct, 8);
                    649:        /* allow ciphertext and plaintext to overlap (ct == pt) */
                    650:        ovbcopy(ct + 8, pt, len * 8);
                    651:
                    652:        rijndael_set_key(&ctx, (u_int8_t *)kek, kek_len * 8);
                    653:
                    654:        for (j = 0, t = 6 * len; j < 6; j++) {
                    655:                r = pt + (len - 1) * 8;
                    656:                for (i = 0; i < len; i++, t--) {
                    657:                        memcpy(&ar[0], a, 8);
                    658:                        ar[0] ^= htobe64(t);
                    659:                        memcpy(&ar[1], r, 8);
                    660:                        rijndael_decrypt(&ctx, (u_int8_t *)ar, b);
                    661:                        memcpy(a, b, 8);
                    662:                        memcpy(r, b + 8, 8);
                    663:
                    664:                        r -= 8;
                    665:                }
                    666:        }
                    667:        return memcmp(a, aes_key_wrap_iv, 8) != 0;
                    668: }
                    669:
                    670: void
                    671: ieee80211_hmac_md5_v(const struct vector *vec, int vcnt, const u_int8_t *key,
                    672:     size_t key_len, u_int8_t digest[MD5_DIGEST_LENGTH])
                    673: {
                    674:        MD5_CTX ctx;
                    675:        u_int8_t k_pad[MD5_BLOCK_LENGTH];
                    676:        u_int8_t tk[MD5_DIGEST_LENGTH];
                    677:        int i;
                    678:
                    679:        if (key_len > MD5_BLOCK_LENGTH) {
                    680:                MD5Init(&ctx);
                    681:                MD5Update(&ctx, (u_int8_t *)key, key_len);
                    682:                MD5Final(tk, &ctx);
                    683:
                    684:                key = tk;
                    685:                key_len = MD5_DIGEST_LENGTH;
                    686:        }
                    687:
                    688:        bzero(k_pad, sizeof k_pad);
                    689:        bcopy(key, k_pad, key_len);
                    690:        for (i = 0; i < MD5_BLOCK_LENGTH; i++)
                    691:                k_pad[i] ^= 0x36;
                    692:
                    693:        MD5Init(&ctx);
                    694:        MD5Update(&ctx, k_pad, MD5_BLOCK_LENGTH);
                    695:        for (i = 0; i < vcnt; i++)
                    696:                MD5Update(&ctx, (u_int8_t *)vec[i].base, vec[i].len);
                    697:        MD5Final(digest, &ctx);
                    698:
                    699:        bzero(k_pad, sizeof k_pad);
                    700:        bcopy(key, k_pad, key_len);
                    701:        for (i = 0; i < MD5_BLOCK_LENGTH; i++)
                    702:                k_pad[i] ^= 0x5c;
                    703:
                    704:        MD5Init(&ctx);
                    705:        MD5Update(&ctx, k_pad, MD5_BLOCK_LENGTH);
                    706:        MD5Update(&ctx, digest, MD5_DIGEST_LENGTH);
                    707:        MD5Final(digest, &ctx);
                    708: }
                    709:
                    710: void
                    711: ieee80211_hmac_md5(const u_int8_t *text, size_t text_len, const u_int8_t *key,
                    712:     size_t key_len, u_int8_t digest[MD5_DIGEST_LENGTH])
                    713: {
                    714:        struct vector vec;
                    715:        vec.base = text;
                    716:        vec.len  = text_len;
                    717:        ieee80211_hmac_md5_v(&vec, 1, key, key_len, digest);
                    718: }
                    719:
                    720: void
                    721: ieee80211_hmac_sha1_v(const struct vector *vec, int vcnt, const u_int8_t *key,
                    722:     size_t key_len, u_int8_t digest[SHA1_DIGEST_LENGTH])
                    723: {
                    724:        SHA1_CTX ctx;
                    725:        u_int8_t k_pad[SHA1_BLOCK_LENGTH];
                    726:        u_int8_t tk[SHA1_DIGEST_LENGTH];
                    727:        int i;
                    728:
                    729:        if (key_len > SHA1_BLOCK_LENGTH) {
                    730:                SHA1Init(&ctx);
                    731:                SHA1Update(&ctx, (u_int8_t *)key, key_len);
                    732:                SHA1Final(tk, &ctx);
                    733:
                    734:                key = tk;
                    735:                key_len = SHA1_DIGEST_LENGTH;
                    736:        }
                    737:
                    738:        bzero(k_pad, sizeof k_pad);
                    739:        bcopy(key, k_pad, key_len);
                    740:        for (i = 0; i < SHA1_BLOCK_LENGTH; i++)
                    741:                k_pad[i] ^= 0x36;
                    742:
                    743:        SHA1Init(&ctx);
                    744:        SHA1Update(&ctx, k_pad, SHA1_BLOCK_LENGTH);
                    745:        for (i = 0; i < vcnt; i++)
                    746:                SHA1Update(&ctx, (u_int8_t *)vec[i].base, vec[i].len);
                    747:        SHA1Final(digest, &ctx);
                    748:
                    749:        bzero(k_pad, sizeof k_pad);
                    750:        bcopy(key, k_pad, key_len);
                    751:        for (i = 0; i < SHA1_BLOCK_LENGTH; i++)
                    752:                k_pad[i] ^= 0x5c;
                    753:
                    754:        SHA1Init(&ctx);
                    755:        SHA1Update(&ctx, k_pad, SHA1_BLOCK_LENGTH);
                    756:        SHA1Update(&ctx, digest, SHA1_DIGEST_LENGTH);
                    757:        SHA1Final(digest, &ctx);
                    758: }
                    759:
                    760: void
                    761: ieee80211_hmac_sha1(const u_int8_t *text, size_t text_len, const u_int8_t *key,
                    762:     size_t key_len, u_int8_t digest[SHA1_DIGEST_LENGTH])
                    763: {
                    764:        struct vector vec;
                    765:        vec.base = text;
                    766:        vec.len  = text_len;
                    767:        ieee80211_hmac_sha1_v(&vec, 1, key, key_len, digest);
                    768: }
                    769:
                    770: /*
                    771:  * SHA1-based Pseudo-Random Function (see 8.5.1.1).
                    772:  */
                    773: void
                    774: ieee80211_prf(const u_int8_t *key, size_t key_len, struct vector *vec,
                    775:     int vcnt, u_int8_t *output, size_t len)
                    776: {
                    777:        u_int8_t hash[SHA1_DIGEST_LENGTH];
                    778:        u_int8_t count = 0;
                    779:
                    780:        /* single octet count, starts at 0 */
                    781:        vec[vcnt].base = &count;
                    782:        vec[vcnt].len  = 1;
                    783:        vcnt++;
                    784:
                    785:        while (len > SHA1_DIGEST_LENGTH) {
                    786:                ieee80211_hmac_sha1_v(vec, vcnt, key, key_len, output);
                    787:                count++;
                    788:
                    789:                output += SHA1_DIGEST_LENGTH;
                    790:                len -= SHA1_DIGEST_LENGTH;
                    791:        }
                    792:        if (len > 0) {
                    793:                ieee80211_hmac_sha1_v(vec, vcnt, key, key_len, hash);
                    794:                /* truncate HMAC-SHA1 to len bytes */
                    795:                memcpy(output, hash, len);
                    796:        }
                    797: }
                    798:
                    799: /*
                    800:  * Derive Pairwise Transient Key (PTK) (see 8.5.1.2).
                    801:  */
                    802: void
                    803: ieee80211_derive_ptk(const u_int8_t *pmk, size_t pmk_len, const u_int8_t *aa,
                    804:     const u_int8_t *spa, const u_int8_t *anonce, const u_int8_t *snonce,
                    805:     u_int8_t *ptk, size_t ptk_len)
                    806: {
                    807:        struct vector vec[6];   /* +1 for PRF */
                    808:        int ret;
                    809:
                    810:        vec[0].base = "Pairwise key expansion";
                    811:        vec[0].len  = 23;       /* include trailing '\0' */
                    812:
                    813:        ret = memcmp(aa, spa, IEEE80211_ADDR_LEN) < 0;
                    814:        /* Min(AA,SPA) */
                    815:        vec[1].base = ret ? aa : spa;
                    816:        vec[1].len  = IEEE80211_ADDR_LEN;
                    817:        /* Max(AA,SPA) */
                    818:        vec[2].base = ret ? spa : aa;
                    819:        vec[2].len  = IEEE80211_ADDR_LEN;
                    820:
                    821:        ret = memcmp(anonce, snonce, EAPOL_KEY_NONCE_LEN) < 0;
                    822:        /* Min(ANonce,SNonce) */
                    823:        vec[3].base = ret ? anonce : snonce;
                    824:        vec[3].len  = EAPOL_KEY_NONCE_LEN;
                    825:        /* Max(ANonce,SNonce) */
                    826:        vec[4].base = ret ? snonce : anonce;
                    827:        vec[4].len  = EAPOL_KEY_NONCE_LEN;
                    828:
                    829:        ieee80211_prf(pmk, pmk_len, vec, 5, ptk, ptk_len);
                    830: }
                    831:
                    832: /*
                    833:  * Derive Pairwise Master Key Identifier (PMKID) (see 8.5.1.2).
                    834:  */
                    835: void
                    836: ieee80211_derive_pmkid(const u_int8_t *pmk, size_t pmk_len, const u_int8_t *aa,
                    837:     const u_int8_t *spa, u_int8_t *pmkid)
                    838: {
                    839:        struct vector vec[3];
                    840:        u_int8_t hash[SHA1_DIGEST_LENGTH];
                    841:
                    842:        vec[0].base = "PMK Name";
                    843:        vec[0].len  = 8;        /* does *not* include trailing '\0' */
                    844:        vec[1].base = aa;
                    845:        vec[1].len  = IEEE80211_ADDR_LEN;
                    846:        vec[2].base = spa;
                    847:        vec[2].len  = IEEE80211_ADDR_LEN;
                    848:
                    849:        ieee80211_hmac_sha1_v(vec, 3, pmk, pmk_len, hash);
                    850:        /* use the first 128 bits of the HMAC-SHA1 */
                    851:        memcpy(pmkid, hash, IEEE80211_PMKID_LEN);
                    852: }
                    853:
                    854: /*
                    855:  * Derive Group Temporal Key (GTK) (see 8.5.1.3).
                    856:  */
                    857: void
                    858: ieee80211_derive_gtk(const u_int8_t *gmk, size_t gmk_len, const u_int8_t *aa,
                    859:     const u_int8_t *gnonce, u_int8_t *gtk, size_t gtk_len)
                    860: {
                    861:        struct vector vec[4];   /* +1 for PRF */
                    862:
                    863:        vec[0].base = "Group key expansion";
                    864:        vec[0].len  = 20;       /* include trailing '\0' */
                    865:        vec[1].base = aa;
                    866:        vec[1].len  = IEEE80211_ADDR_LEN;
                    867:        vec[2].base = gnonce;
                    868:        vec[2].len  = EAPOL_KEY_NONCE_LEN;
                    869:
                    870:        ieee80211_prf(gmk, gmk_len, vec, 3, gtk, gtk_len);
                    871: }
                    872:
                    873: /* unaligned big endian access */
                    874: #define BE_READ_2(p)                           \
                    875:        ((u_int16_t)                            \
                    876:          ((((const u_int8_t *)(p))[0] << 8) |  \
                    877:           (((const u_int8_t *)(p))[1])))
                    878:
                    879: #define BE_WRITE_2(p, v) do {                  \
                    880:        ((u_int8_t *)(p))[0] = (v) >> 8;        \
                    881:        ((u_int8_t *)(p))[1] = (v) & 0xff;      \
                    882: } while (0)
                    883:
                    884: /*
                    885:  * Compute the Key MIC field of an EAPOL-Key frame using the specified Key
                    886:  * Confirmation Key (KCK).  The hash function can be either HMAC-MD5 or
                    887:  * HMAC-SHA1 depending on the EAPOL-Key Key Descriptor Version.
                    888:  */
                    889: void
                    890: ieee80211_eapol_key_mic(struct ieee80211_eapol_key *key, const u_int8_t *kck)
                    891: {
                    892:        u_int8_t hash[SHA1_DIGEST_LENGTH];
                    893:        u_int16_t len, info;
                    894:
                    895:        len  = BE_READ_2(key->len) + 4;
                    896:        info = BE_READ_2(key->info);
                    897:
                    898:        switch (info & EAPOL_KEY_VERSION_MASK) {
                    899:        case EAPOL_KEY_DESC_V1:
                    900:                ieee80211_hmac_md5((u_int8_t *)key, len, kck, 16, key->mic);
                    901:                break;
                    902:        case EAPOL_KEY_DESC_V2:
                    903:                ieee80211_hmac_sha1((u_int8_t *)key, len, kck, 16, hash);
                    904:                /* truncate HMAC-SHA1 to its 128 MSBs */
                    905:                memcpy(key->mic, hash, EAPOL_KEY_MIC_LEN);
                    906:                break;
                    907:        }
                    908: }
                    909:
                    910: /*
                    911:  * Check the MIC of a received EAPOL-Key frame using the specified Key
                    912:  * Confirmation Key (KCK).
                    913:  */
                    914: int
                    915: ieee80211_eapol_key_check_mic(struct ieee80211_eapol_key *key,
                    916:     const u_int8_t *kck)
                    917: {
                    918:        u_int8_t mic[EAPOL_KEY_MIC_LEN];
                    919:
                    920:        memcpy(mic, key->mic, EAPOL_KEY_MIC_LEN);
                    921:        memset(key->mic, 0, EAPOL_KEY_MIC_LEN);
                    922:        ieee80211_eapol_key_mic(key, kck);
                    923:
                    924:        return memcmp(key->mic, mic, EAPOL_KEY_MIC_LEN) != 0;
                    925: }
                    926:
                    927: /*
                    928:  * Encrypt the Key Data field of an EAPOL-Key frame using the specified Key
                    929:  * Encryption Key (KEK).  The encryption algorithm can be either ARC4 or
                    930:  * AES Key Wrap depending on the EAPOL-Key Key Descriptor Version.
                    931:  */
                    932: void
                    933: ieee80211_eapol_key_encrypt(struct ieee80211com *ic,
                    934:     struct ieee80211_eapol_key *key, const u_int8_t *kek)
                    935: {
                    936:        struct rc4_ctx ctx;
                    937:        u_int8_t keybuf[EAPOL_KEY_IV_LEN + 16];
                    938:        u_int16_t len, info;
                    939:        u_int8_t *data;
                    940:        int n;
                    941:
                    942:        len  = BE_READ_2(key->paylen);
                    943:        info = BE_READ_2(key->info);
                    944:        data = (u_int8_t *)(key + 1);
                    945:
                    946:        switch (info & EAPOL_KEY_VERSION_MASK) {
                    947:        case EAPOL_KEY_DESC_V1:
                    948:                /* set IV to the lower 16 octets of our global key counter */
                    949:                memcpy(key->iv, ic->ic_globalcnt + 16, 16);
                    950:                /* increment our global key counter (256-bit, big-endian) */
                    951:                for (n = 31; n >= 0 && ++ic->ic_globalcnt[n] == 0; n--);
                    952:
                    953:                /* concatenate the EAPOL-Key IV field and the KEK */
                    954:                memcpy(keybuf, key->iv, EAPOL_KEY_IV_LEN);
                    955:                memcpy(keybuf + EAPOL_KEY_IV_LEN, kek, 16);
                    956:
                    957:                rc4_keysetup(&ctx, keybuf, sizeof keybuf);
                    958:                /* discard the first 256 octets of the ARC4 key stream */
                    959:                rc4_skip(&ctx, RC4STATE);
                    960:                rc4_crypt(&ctx, data, data, len);
                    961:                break;
                    962:        case EAPOL_KEY_DESC_V2:
                    963:                if (len < 16 || (len & 7) != 0) {
                    964:                        /* insert padding */
                    965:                        n = (len < 16) ? 16 - len : 8 - (len & 7);
                    966:                        data[len++] = IEEE80211_ELEMID_VENDOR;
                    967:                        memset(&data[len], 0, n - 1);
                    968:                        len += n - 1;
                    969:                }
                    970:                ieee80211_aes_key_wrap(kek, 16, data, len / 8, data);
                    971:                len += 8;       /* AES Key Wrap adds 8 bytes */
                    972:                /* update key data length */
                    973:                BE_WRITE_2(key->paylen, len);
                    974:                /* update packet body length */
                    975:                BE_WRITE_2(key->len, sizeof(*key) + len - 4);
                    976:                break;
                    977:        }
                    978: }
                    979:
                    980: /*
                    981:  * Decrypt the Key Data field of an EAPOL-Key frame using the specified Key
                    982:  * Encryption Key (KEK).  The encryption algorithm can be either ARC4 or
                    983:  * AES Key Wrap depending on the EAPOL-Key Key Descriptor Version.
                    984:  */
                    985: int
                    986: ieee80211_eapol_key_decrypt(struct ieee80211_eapol_key *key,
                    987:     const u_int8_t *kek)
                    988: {
                    989:        struct rc4_ctx ctx;
                    990:        u_int8_t keybuf[EAPOL_KEY_IV_LEN + 16];
                    991:        u_int16_t len, info;
                    992:        u_int8_t *data;
                    993:
                    994:        len  = BE_READ_2(key->paylen);
                    995:        info = BE_READ_2(key->info);
                    996:        data = (u_int8_t *)(key + 1);
                    997:
                    998:        switch (info & EAPOL_KEY_VERSION_MASK) {
                    999:        case EAPOL_KEY_DESC_V1:
                   1000:                /* concatenate the EAPOL-Key IV field and the KEK */
                   1001:                memcpy(keybuf, key->iv, EAPOL_KEY_IV_LEN);
                   1002:                memcpy(keybuf + EAPOL_KEY_IV_LEN, kek, 16);
                   1003:
                   1004:                rc4_keysetup(&ctx, keybuf, sizeof keybuf);
                   1005:                /* discard the first 256 octets of the ARC4 key stream */
                   1006:                rc4_skip(&ctx, RC4STATE);
                   1007:                rc4_crypt(&ctx, data, data, len);
                   1008:                return 0;
                   1009:        case EAPOL_KEY_DESC_V2:
                   1010:                /* Key Data Length must be a multiple of 8 */
                   1011:                if (len < 16 + 8 || (len & 7) != 0)
                   1012:                        return 1;
                   1013:                len -= 8;       /* AES Key Wrap adds 8 bytes */
                   1014:                return ieee80211_aes_key_unwrap(kek, 16, data, data, len / 8);
                   1015:        }
                   1016:
                   1017:        return 1;       /* unknown Key Descriptor Version */
                   1018: }
                   1019:
                   1020: /*
                   1021:  * Return the length in bytes of a cipher suite key (see Table 60).
                   1022:  */
                   1023: int
                   1024: ieee80211_cipher_keylen(enum ieee80211_cipher cipher)
                   1025: {
                   1026:        switch (cipher) {
                   1027:        case IEEE80211_CIPHER_WEP40:
                   1028:                return 5;
                   1029:        case IEEE80211_CIPHER_TKIP:
                   1030:                return 32;
                   1031:        case IEEE80211_CIPHER_CCMP:
                   1032:                return 16;
                   1033:        case IEEE80211_CIPHER_WEP104:
                   1034:                return 13;
                   1035:        default:        /* unknown cipher */
                   1036:                return 0;
                   1037:        }
                   1038: }

CVSweb