-/* $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>
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;
-/* $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>
*/
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
-/* $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
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 */
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;
-/* $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 $ */
/*-
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;
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)
-/* $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 $ */
/*-
(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;
-/* $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 $ */
/*-
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++;
*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);
-/* $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>
/* 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 ||
-/* $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>
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
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); */
}