From c7c53e5e265126ee410ebc691efa153d1c1aacd9 Mon Sep 17 00:00:00 2001 From: damien Date: Tue, 12 Aug 2008 19:29:07 +0000 Subject: [PATCH] new SHA-256 based AKMPs. --- sys/net80211/ieee80211_crypto.c | 4 ++-- sys/net80211/ieee80211_crypto.h | 10 +++++++--- sys/net80211/ieee80211_input.c | 26 ++++++++++++++++++++------ sys/net80211/ieee80211_ioctl.c | 8 ++++---- sys/net80211/ieee80211_node.c | 4 ++-- sys/net80211/ieee80211_output.c | 14 ++++++++++++-- sys/net80211/ieee80211_pae_input.c | 9 +++++++-- sys/net80211/ieee80211_pae_output.c | 11 ++++++++--- 8 files changed, 62 insertions(+), 24 deletions(-) diff --git a/sys/net80211/ieee80211_crypto.c b/sys/net80211/ieee80211_crypto.c index 11668e3a10a..be0fee80237 100644 --- a/sys/net80211/ieee80211_crypto.c +++ b/sys/net80211/ieee80211_crypto.c @@ -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 @@ -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; diff --git a/sys/net80211/ieee80211_crypto.h b/sys/net80211/ieee80211_crypto.h index f27433304f2..28c8c6c9731 100644 --- a/sys/net80211/ieee80211_crypto.h +++ b/sys/net80211/ieee80211_crypto.h @@ -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 @@ -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 diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 7163e65f305..86d22b7ee2b 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -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; diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index bf379639e9c..4445b113d5d 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -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) diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index ff9ff6adff0..0dd5d7e277b 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -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; diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index b794ced62fb..8202ae6a7ad 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -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); diff --git a/sys/net80211/ieee80211_pae_input.c b/sys/net80211/ieee80211_pae_input.c index 9c46df076ef..3f841dfd78b 100644 --- a/sys/net80211/ieee80211_pae_input.c +++ b/sys/net80211/ieee80211_pae_input.c @@ -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 @@ -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 || diff --git a/sys/net80211/ieee80211_pae_output.c b/sys/net80211/ieee80211_pae_output.c index cef1942aa0a..f86e5ac4e9f 100644 --- a/sys/net80211/ieee80211_pae_output.c +++ b/sys/net80211/ieee80211_pae_output.c @@ -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 @@ -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); */ } -- 2.20.1