new SHA-256 based AKMPs.
authordamien <damien@openbsd.org>
Tue, 12 Aug 2008 19:29:07 +0000 (19:29 +0000)
committerdamien <damien@openbsd.org>
Tue, 12 Aug 2008 19:29:07 +0000 (19:29 +0000)
sys/net80211/ieee80211_crypto.c
sys/net80211/ieee80211_crypto.h
sys/net80211/ieee80211_input.c
sys/net80211/ieee80211_ioctl.c
sys/net80211/ieee80211_node.c
sys/net80211/ieee80211_output.c
sys/net80211/ieee80211_pae_input.c
sys/net80211/ieee80211_pae_output.c

index 11668e3..be0fee8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_crypto.c,v 1.49 2008/08/12 18:48:35 damien Exp $    */
+/*     $OpenBSD: ieee80211_crypto.c,v 1.50 2008/08/12 19:29:07 damien Exp $    */
 
 /*-
  * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
@@ -66,7 +66,7 @@ ieee80211_crypto_attach(struct ifnet *ifp)
 
        if (ic->ic_caps & IEEE80211_C_RSN) {
                ic->ic_rsnprotos = IEEE80211_PROTO_WPA | IEEE80211_PROTO_RSN;
-               ic->ic_rsnakms = IEEE80211_AKM_PSK | IEEE80211_AKM_IEEE8021X;
+               ic->ic_rsnakms = IEEE80211_AKM_PSK | IEEE80211_AKM_8021X;
                ic->ic_rsnciphers = IEEE80211_CIPHER_TKIP |
                    IEEE80211_CIPHER_CCMP;
                ic->ic_rsngroupcipher = IEEE80211_CIPHER_TKIP;
index f274333..28c8c6c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_crypto.h,v 1.18 2008/08/12 16:56:45 damien Exp $    */
+/*     $OpenBSD: ieee80211_crypto.h,v 1.19 2008/08/12 19:29:07 damien Exp $    */
 
 /*-
  * Copyright (c) 2007,2008 Damien Bergamini <damien.bergamini@free.fr>
@@ -41,8 +41,12 @@ enum ieee80211_cipher {
  */
 enum ieee80211_akm {
        IEEE80211_AKM_NONE              = 0x00000000,
-       IEEE80211_AKM_IEEE8021X         = 0x00000001,
-       IEEE80211_AKM_PSK               = 0x00000002
+       IEEE80211_AKM_8021X             = 0x00000001,
+       IEEE80211_AKM_PSK               = 0x00000002,
+       IEEE80211_AKM_FBT_8021X         = 0x00000004,   /* 11r */
+       IEEE80211_AKM_FBT_PSK           = 0x00000008,   /* 11r */
+       IEEE80211_AKM_SHA256_8021X      = 0x00000010,   /* 11w */
+       IEEE80211_AKM_SHA256_PSK        = 0x00000020    /* 11w */
 };
 
 #define        IEEE80211_KEYBUF_SIZE   16
index 7163e65..86d22b7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_input.c,v 1.91 2008/08/12 19:21:04 damien Exp $     */
+/*     $OpenBSD: ieee80211_input.c,v 1.92 2008/08/12 19:29:07 damien Exp $     */
 
 /*-
  * Copyright (c) 2001 Atsushi Onoe
@@ -725,14 +725,28 @@ ieee80211_parse_rsn_cipher(const u_int8_t selector[4])
 enum ieee80211_akm
 ieee80211_parse_rsn_akm(const u_int8_t selector[4])
 {
-       /* from IEEE Std 802.11i-2004 - Table 20dc */
-       if (memcmp(selector, MICROSOFT_OUI, 3) == 0 ||  /* WPA */
-           memcmp(selector, IEEE80211_OUI, 3) == 0) {  /* RSN */
+       if (memcmp(selector, MICROSOFT_OUI, 3) == 0) {  /* WPA */
+               switch (selector[3]) {
+               case 1: /* IEEE 802.1X (RSNA default) */
+                       return IEEE80211_AKM_8021X;
+               case 2: /* PSK */
+                       return IEEE80211_AKM_PSK;
+               }
+       } else if (memcmp(selector, IEEE80211_OUI, 3) == 0) {   /* RSN */
+               /* from IEEE Std 802.11i-2004 - Table 20dc */
                switch (selector[3]) {
                case 1: /* IEEE 802.1X (RSNA default) */
-                       return IEEE80211_AKM_IEEE8021X;
+                       return IEEE80211_AKM_8021X;
                case 2: /* PSK */
                        return IEEE80211_AKM_PSK;
+               case 3: /* Fast BSS Transition IEEE 802.1X */
+                       return IEEE80211_AKM_FBT_8021X;
+               case 4: /* Fast BSS Transition PSK */
+                       return IEEE80211_AKM_FBT_PSK;
+               case 5: /* IEEE 802.1X with SHA256 KDF */
+                       return IEEE80211_AKM_SHA256_8021X;
+               case 6: /* PSK with SHA256 KDF */
+                       return IEEE80211_AKM_SHA256_PSK;
                }
        }
        return IEEE80211_AKM_NONE;      /* ignore unknown AKMs */
@@ -765,7 +779,7 @@ ieee80211_parse_rsn_body(struct ieee80211com *ic, const u_int8_t *frm,
        rsn->rsn_groupmgmtcipher = IEEE80211_CIPHER_AES128_CMAC;
        /* if AKM Suite missing, default to 802.1X */
        rsn->rsn_nakms = 1;
-       rsn->rsn_akms = IEEE80211_AKM_IEEE8021X;
+       rsn->rsn_akms = IEEE80211_AKM_8021X;
        /* if RSN capabilities missing, default to 0 */
        rsn->rsn_caps = 0;
 
index bf37963..4445b11 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_ioctl.c,v 1.21 2008/04/16 18:32:15 damien Exp $     */
+/*     $OpenBSD: ieee80211_ioctl.c,v 1.22 2008/08/12 19:29:07 damien Exp $     */
 /*     $NetBSD: ieee80211_ioctl.c,v 1.15 2004/05/06 02:58:16 dyoung Exp $      */
 
 /*-
@@ -243,9 +243,9 @@ ieee80211_ioctl_setwpaparms(struct ieee80211com *ic,
        if (wpa->i_akms & IEEE80211_WPA_AKM_PSK)
                ic->ic_rsnakms |= IEEE80211_AKM_PSK;
        if (wpa->i_akms & IEEE80211_WPA_AKM_IEEE8021X)
-               ic->ic_rsnakms |= IEEE80211_AKM_IEEE8021X;
+               ic->ic_rsnakms |= IEEE80211_AKM_8021X;
        if (ic->ic_rsnakms == 0)        /* set to default (PSK+802.1X) */
-               ic->ic_rsnakms = IEEE80211_AKM_PSK | IEEE80211_AKM_IEEE8021X;
+               ic->ic_rsnakms = IEEE80211_AKM_PSK | IEEE80211_AKM_8021X;
 
        if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_WEP40)
                ic->ic_rsngroupcipher = IEEE80211_CIPHER_WEP40;
@@ -293,7 +293,7 @@ ieee80211_ioctl_getwpaparms(struct ieee80211com *ic,
        wpa->i_akms = 0;
        if (ic->ic_rsnakms & IEEE80211_AKM_PSK)
                wpa->i_akms |= IEEE80211_WPA_AKM_PSK;
-       if (ic->ic_rsnakms & IEEE80211_AKM_IEEE8021X)
+       if (ic->ic_rsnakms & IEEE80211_AKM_8021X)
                wpa->i_akms |= IEEE80211_WPA_AKM_IEEE8021X;
 
        if (ic->ic_rsngroupcipher == IEEE80211_CIPHER_WEP40)
index ff9ff6a..0dd5d7e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_node.c,v 1.42 2008/08/12 19:21:04 damien Exp $      */
+/*     $OpenBSD: ieee80211_node.c,v 1.43 2008/08/12 19:29:07 damien Exp $      */
 /*     $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $       */
 
 /*-
@@ -590,7 +590,7 @@ ieee80211_end_scan(struct ifnet *ifp)
                    (ic->ic_flags & IEEE80211_F_PSK))
                        ni->ni_rsnakms = IEEE80211_AKM_PSK;
                else
-                       ni->ni_rsnakms = IEEE80211_AKM_IEEE8021X;
+                       ni->ni_rsnakms = IEEE80211_AKM_8021X;
 
                /* prefer CCMP over TKIP if the AP supports it */
                ni->ni_rsnciphers &= ic->ic_rsnciphers;
index b794ced..8202ae6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_output.c,v 1.68 2008/08/12 19:21:04 damien Exp $    */
+/*     $OpenBSD: ieee80211_output.c,v 1.69 2008/08/12 19:29:07 damien Exp $    */
 /*     $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $     */
 
 /*-
@@ -867,7 +867,7 @@ ieee80211_add_rsn_body(u_int8_t *frm, struct ieee80211com *ic,
        pcount = frm; frm += 2;
        count = 0;
        /* write AKM Suite List (see Table 20dc) */
-       if (ni->ni_rsnakms & IEEE80211_AKM_IEEE8021X) {
+       if (ni->ni_rsnakms & IEEE80211_AKM_8021X) {
                memcpy(frm, oui, 3); frm += 3;
                *frm++ = 1;
                count++;
@@ -877,6 +877,16 @@ ieee80211_add_rsn_body(u_int8_t *frm, struct ieee80211com *ic,
                *frm++ = 2;
                count++;
        }
+       if (ni->ni_rsnakms & IEEE80211_AKM_SHA256_8021X) {
+               memcpy(frm, oui, 3); frm += 3;
+               *frm++ = 5;
+               count++;
+       }
+       if (ni->ni_rsnakms & IEEE80211_AKM_SHA256_PSK) {
+               memcpy(frm, oui, 3); frm += 3;
+               *frm++ = 6;
+               count++;
+       }
        /* write AKM Suite List Count field */
        LE_WRITE_2(pcount, count);
 
index 9c46df0..3f841df 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_pae_input.c,v 1.9 2008/08/12 18:22:41 damien Exp $  */
+/*     $OpenBSD: ieee80211_pae_input.c,v 1.10 2008/08/12 19:29:07 damien Exp $ */
 
 /*-
  * Copyright (c) 2007,2008 Damien Bergamini <damien.bergamini@free.fr>
@@ -124,7 +124,12 @@ ieee80211_eapol_key_input(struct ieee80211com *ic, struct mbuf *m0,
 
        /* discard EAPOL-Key frames with an unknown descriptor version */
        desc = info & EAPOL_KEY_VERSION_MASK;
-       if (desc != EAPOL_KEY_DESC_V1 && desc != EAPOL_KEY_DESC_V2)
+       if (desc < EAPOL_KEY_DESC_V1 || desc > EAPOL_KEY_DESC_V3)
+               goto done;
+
+       if ((ni->ni_rsnakms == IEEE80211_AKM_SHA256_8021X ||
+            ni->ni_rsnakms == IEEE80211_AKM_SHA256_PSK) &&
+           desc != EAPOL_KEY_DESC_V3)
                goto done;
 
        if ((ni->ni_rsncipher == IEEE80211_CIPHER_CCMP ||
index cef1942..f86e5ac 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_pae_output.c,v 1.8 2008/08/12 19:05:39 damien Exp $ */
+/*     $OpenBSD: ieee80211_pae_output.c,v 1.9 2008/08/12 19:29:07 damien Exp $ */
 
 /*-
  * Copyright (c) 2007,2008 Damien Bergamini <damien.bergamini@free.fr>
@@ -88,8 +88,12 @@ ieee80211_send_eapol_key(struct ieee80211com *ic, struct mbuf *m,
            EAPOL_KEY_DESC_IEEE80211 : EAPOL_KEY_DESC_WPA;
 
        info = BE_READ_2(key->info);
+       /* use V3 descriptor if KDF is SHA256-based */
+       if (ni->ni_rsnakms == IEEE80211_AKM_SHA256_8021X ||
+           ni->ni_rsnakms == IEEE80211_AKM_SHA256_PSK)
+               info |= EAPOL_KEY_DESC_V3;
        /* use V2 descriptor if pairwise or group cipher is CCMP */
-       if (ni->ni_rsncipher == IEEE80211_CIPHER_CCMP ||
+       else if (ni->ni_rsncipher == IEEE80211_CIPHER_CCMP ||
            ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP)
                info |= EAPOL_KEY_DESC_V2;
        else
@@ -285,7 +289,8 @@ ieee80211_send_4way_msg1(struct ieee80211com *ic, struct ieee80211_node *ni)
        frm = (u_int8_t *)&key[1];
        /* WPA does not have PMKID KDE */
        if (ni->ni_rsnprotos == IEEE80211_PROTO_RSN &&
-           ni->ni_rsnakms == IEEE80211_AKM_IEEE8021X) {
+           (ni->ni_rsnakms == IEEE80211_AKM_8021X ||
+            ni->ni_rsnakms == IEEE80211_AKM_SHA256_8021X)) {
                /* XXX retrieve PMKID from the PMKSA cache */
                /* frm = ieee80211_add_pmkid_kde(frm, pmkid); */
        }