From owner-p4-projects@FreeBSD.ORG Wed Dec 15 06:36:12 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 51AF316A4D0; Wed, 15 Dec 2004 06:36:12 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2B82F16A4CE for ; Wed, 15 Dec 2004 06:36:12 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 032FB43D58 for ; Wed, 15 Dec 2004 06:36:12 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id iBF6aBCc017212 for ; Wed, 15 Dec 2004 06:36:11 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id iBF6aBYn017209 for perforce@freebsd.org; Wed, 15 Dec 2004 06:36:11 GMT (envelope-from sam@freebsd.org) Date: Wed, 15 Dec 2004 06:36:11 GMT Message-Id: <200412150636.iBF6aBYn017209@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 67111 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Dec 2004 06:36:12 -0000 http://perforce.freebsd.org/chv.cgi?CH=67111 Change 67111 by sam@sam_ebb on 2004/12/15 06:35:36 Relearn how WPA keying is supposed to work and fix WPA+WME while we're at it: o WPA/802.11i has a unicast key and a group key; in station mode everything is sent with the unicast key--we were consulting the destination mac address and incorrectly using the group key o (perpetuate fallback use of the default tx key to maintain compatibility with the way wpa_supplicant works) o correct EAPOL encryption logic to check unicast key instead of assuming other state implies this With these changes WPA+WME station and ap operation works (but only with newish 5212 parts and only with an unreleased hal). Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211_output.c#26 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211_output.c#26 (text+ko) ==== @@ -386,35 +386,37 @@ return 0; } +#define KEY_UNDEFINED(k) ((k).wk_cipher == &ieee80211_cipher_none) /* - * Return the transmit key to use in sending a frame to the specified - * destination. Multicast traffic always uses the group key which is - * installed the default tx key. Otherwise if a unicast key is set - * we use that. When no unicast key is set we fall back to the default - * transmit key unless WPA is enabled in which case there should be - * a unicast frame so we don't want to use a default key (which in - * this case is the group/multicast key). + * Return the transmit key to use in sending a unicast frame. + * If a unicast key is set we use that. When no unicast key is set + * we fall back to the default transmit key. */ static __inline struct ieee80211_key * -ieee80211_crypto_getkey(struct ieee80211com *ic, - const u_int8_t mac[IEEE80211_ADDR_LEN], struct ieee80211_node *ni) +ieee80211_crypto_getucastkey(struct ieee80211com *ic, struct ieee80211_node *ni) { -#define KEY_UNDEFINED(k) ((k).wk_cipher == &ieee80211_cipher_none) - if (IEEE80211_IS_MULTICAST(mac)) { + if (KEY_UNDEFINED(ni->ni_ucastkey)) { if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE || KEY_UNDEFINED(ic->ic_nw_keys[ic->ic_def_txkey])) return NULL; return &ic->ic_nw_keys[ic->ic_def_txkey]; - } else if (KEY_UNDEFINED(ni->ni_ucastkey)) { - if ((ic->ic_flags & IEEE80211_F_WPA) || - ic->ic_def_txkey == IEEE80211_KEYIX_NONE || - KEY_UNDEFINED(ic->ic_nw_keys[ic->ic_def_txkey])) - return NULL; - return &ic->ic_nw_keys[ic->ic_def_txkey]; } else { return &ni->ni_ucastkey; } -#undef KEY_UNDEFINED +} + +/* + * Return the transmit key to use in sending a multicast frame. + * Multicast traffic always uses the group key which is installed as + * the default tx key. + */ +static __inline struct ieee80211_key * +ieee80211_crypto_getmcastkey(struct ieee80211com *ic, struct ieee80211_node *ni) +{ + if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE || + KEY_UNDEFINED(ic->ic_nw_keys[ic->ic_def_txkey])) + return NULL; + return &ic->ic_nw_keys[ic->ic_def_txkey]; } /* @@ -449,11 +451,15 @@ * routines, but they will/should discard it. */ if (ic->ic_flags & IEEE80211_F_PRIVACY) { - key = ieee80211_crypto_getkey(ic, eh.ether_dhost, ni); + if (ic->ic_opmode == IEEE80211_M_STA || + !IEEE80211_IS_MULTICAST(eh.ether_dhost)) + key = ieee80211_crypto_getucastkey(ic, ni); + else + key = ieee80211_crypto_getmcastkey(ic, ni); if (key == NULL && eh.ether_type != htons(ETHERTYPE_PAE)) { IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, "[%s] no default transmit key (%s) deftxkey %u\n", - ether_sprintf(ni->ni_macaddr), __func__, + ether_sprintf(eh.ether_dhost), __func__, ic->ic_def_txkey); ic->ic_stats.is_tx_nodefkey++; } @@ -536,13 +542,14 @@ htole16(ni->ni_txseqs[0] << IEEE80211_SEQ_SEQ_SHIFT); ni->ni_txseqs[0]++; } - if (eh.ether_type != htons(ETHERTYPE_PAE) || - (key != NULL && (ic->ic_flags & IEEE80211_F_WPA))) { + if (key != NULL) { /* * IEEE 802.1X: send EAPOL frames always in the clear. * WPA/WPA2: encrypt EAPOL keys when pairwise keys are set. */ - if (key != NULL) { + if (eh.ether_type != htons(ETHERTYPE_PAE) || + ((ic->ic_flags & IEEE80211_F_WPA) && + !KEY_UNDEFINED(ni->ni_ucastkey))) { wh->i_fc[1] |= IEEE80211_FC1_WEP; /* XXX do fragmentation */ if (!ieee80211_crypto_enmic(ic, key, m)) { @@ -564,6 +571,7 @@ m_freem(m); return NULL; } +#undef KEY_UNDEFINED /* * Add a supported rates element id to a frame. @@ -1563,7 +1571,7 @@ ni->ni_savedq.ifq_drops, IEEE80211_PS_MAX_QUEUE); #ifdef IEEE80211_DEBUG if (ieee80211_msg_dumppkts(ic)) - ieee80211_dump_pkt(mtod(m, caddr_t), m->m_len, -1, -1); + ieee80211_dump_pkt(ic, mtod(m, caddr_t), m->m_len, -1, -1); #endif m_freem(m); return;