Suite B: Add AKM 00-0F-AC:11

This adds definitions for the 128-bit level Suite B AKM 00-0F-AC:11. The
functionality itself is not yet complete, i.e., this commit only
includes parts to negotiate the new AKM.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-11-16 13:20:51 +02:00
parent eec0cc8da2
commit 666497c8e6
17 changed files with 82 additions and 8 deletions

View file

@ -680,6 +680,8 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
else if (os_strcmp(start, "FT-SAE") == 0) else if (os_strcmp(start, "FT-SAE") == 0)
val |= WPA_KEY_MGMT_FT_SAE; val |= WPA_KEY_MGMT_FT_SAE;
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B;
else { else {
wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'", wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
line, start); line, start);

View file

@ -977,6 +977,12 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
pos += ret; pos += ret;
} }
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
ret = os_snprintf(pos, end - pos, "WPA-EAP-SUITE-B ");
if (ret < 0 || ret >= end - pos)
return pos - buf;
pos += ret;
}
ret = os_snprintf(pos, end - pos, "\n"); ret = os_snprintf(pos, end - pos, "\n");
if (ret < 0 || ret >= end - pos) if (ret < 0 || ret >= end - pos)

View file

@ -200,6 +200,11 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
num_suites++; num_suites++;
} }
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
pos += RSN_SELECTOR_LEN;
num_suites++;
}
#ifdef CONFIG_RSN_TESTING #ifdef CONFIG_RSN_TESTING
if (rsn_testing) { if (rsn_testing) {
@ -477,6 +482,8 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X; selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
if (0) { if (0) {
} }
else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
selector = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
else if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) else if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
selector = RSN_AUTH_KEY_MGMT_FT_802_1X; selector = RSN_AUTH_KEY_MGMT_FT_802_1X;
@ -555,6 +562,8 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
} }
if (0) { if (0) {
} }
else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X; sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;

View file

@ -49,6 +49,7 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean;
#define WPA_KEY_MGMT_WAPI_CERT BIT(13) #define WPA_KEY_MGMT_WAPI_CERT BIT(13)
#define WPA_KEY_MGMT_CCKM BIT(14) #define WPA_KEY_MGMT_CCKM BIT(14)
#define WPA_KEY_MGMT_OSEN BIT(15) #define WPA_KEY_MGMT_OSEN BIT(15)
#define WPA_KEY_MGMT_IEEE8021X_SUITE_B BIT(16)
static inline int wpa_key_mgmt_wpa_ieee8021x(int akm) static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
{ {
@ -56,7 +57,8 @@ static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_IEEE8021X |
WPA_KEY_MGMT_CCKM | WPA_KEY_MGMT_CCKM |
WPA_KEY_MGMT_OSEN | WPA_KEY_MGMT_OSEN |
WPA_KEY_MGMT_IEEE8021X_SHA256)); WPA_KEY_MGMT_IEEE8021X_SHA256 |
WPA_KEY_MGMT_IEEE8021X_SUITE_B));
} }
static inline int wpa_key_mgmt_wpa_psk(int akm) static inline int wpa_key_mgmt_wpa_psk(int akm)
@ -85,7 +87,13 @@ static inline int wpa_key_mgmt_sha256(int akm)
{ {
return !!(akm & (WPA_KEY_MGMT_PSK_SHA256 | return !!(akm & (WPA_KEY_MGMT_PSK_SHA256 |
WPA_KEY_MGMT_IEEE8021X_SHA256 | WPA_KEY_MGMT_IEEE8021X_SHA256 |
WPA_KEY_MGMT_OSEN)); WPA_KEY_MGMT_OSEN |
WPA_KEY_MGMT_IEEE8021X_SUITE_B));
}
static inline int wpa_key_mgmt_suite_b(int akm)
{
return !!(akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B);
} }
static inline int wpa_key_mgmt_wpa(int akm) static inline int wpa_key_mgmt_wpa(int akm)

View file

@ -1164,6 +1164,7 @@ enum plink_action_field {
#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04 #define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05 #define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06 #define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
#define WLAN_AKM_SUITE_8021X_SUITE_B 0x000FAC11
#define WLAN_AKM_SUITE_CCKM 0x00409600 #define WLAN_AKM_SUITE_CCKM 0x00409600
#define WLAN_AKM_SUITE_OSEN 0x506f9a01 #define WLAN_AKM_SUITE_OSEN 0x506f9a01

View file

@ -398,6 +398,8 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE) if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE)
return WPA_KEY_MGMT_FT_SAE; return WPA_KEY_MGMT_FT_SAE;
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B)
return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
return 0; return 0;
} }
@ -996,6 +998,8 @@ const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
case WPA_KEY_MGMT_PSK_SHA256: case WPA_KEY_MGMT_PSK_SHA256:
return "WPA2-PSK-SHA256"; return "WPA2-PSK-SHA256";
#endif /* CONFIG_IEEE80211W */ #endif /* CONFIG_IEEE80211W */
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
return "WPA2-EAP-SUITE-B";
default: default:
return "UNKNOWN"; return "UNKNOWN";
} }
@ -1022,6 +1026,8 @@ u32 wpa_akm_to_suite(int akm)
return WLAN_AKM_SUITE_CCKM; return WLAN_AKM_SUITE_CCKM;
if (akm & WPA_KEY_MGMT_OSEN) if (akm & WPA_KEY_MGMT_OSEN)
return WLAN_AKM_SUITE_OSEN; return WLAN_AKM_SUITE_OSEN;
if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
return WLAN_AKM_SUITE_8021X_SUITE_B;
return 0; return 0;
} }

View file

@ -5237,7 +5237,8 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
params->key_mgmt_suite == WPA_KEY_MGMT_CCKM || params->key_mgmt_suite == WPA_KEY_MGMT_CCKM ||
params->key_mgmt_suite == WPA_KEY_MGMT_OSEN || params->key_mgmt_suite == WPA_KEY_MGMT_OSEN ||
params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 || params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) { params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
int mgmt = WLAN_AKM_SUITE_PSK; int mgmt = WLAN_AKM_SUITE_PSK;
switch (params->key_mgmt_suite) { switch (params->key_mgmt_suite) {
@ -5262,6 +5263,9 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
case WPA_KEY_MGMT_OSEN: case WPA_KEY_MGMT_OSEN:
mgmt = WLAN_AKM_SUITE_OSEN; mgmt = WLAN_AKM_SUITE_OSEN;
break; break;
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
mgmt = WLAN_AKM_SUITE_8021X_SUITE_B;
break;
case WPA_KEY_MGMT_PSK: case WPA_KEY_MGMT_PSK:
default: default:
mgmt = WLAN_AKM_SUITE_PSK; mgmt = WLAN_AKM_SUITE_PSK;

View file

@ -242,7 +242,8 @@ static int wpa_supplicant_process_smk_m2(
peerkey->cipher = cipher; peerkey->cipher = cipher;
#ifdef CONFIG_IEEE80211W #ifdef CONFIG_IEEE80211W
if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 | if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 |
WPA_KEY_MGMT_PSK_SHA256)) WPA_KEY_MGMT_PSK_SHA256 |
WPA_KEY_MGMT_IEEE8021X_SUITE_B))
peerkey->use_sha256 = 1; peerkey->use_sha256 = 1;
#endif /* CONFIG_IEEE80211W */ #endif /* CONFIG_IEEE80211W */

View file

@ -298,7 +298,8 @@ void rsn_preauth_candidate_process(struct wpa_sm *sm)
sm->proto != WPA_PROTO_RSN || sm->proto != WPA_PROTO_RSN ||
wpa_sm_get_state(sm) != WPA_COMPLETED || wpa_sm_get_state(sm) != WPA_COMPLETED ||
(sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X && (sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SHA256)) { sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SHA256 &&
sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SUITE_B)) {
wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: not in suitable " wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: not in suitable "
"state for new pre-authentication"); "state for new pre-authentication");
return; /* invalid state for new pre-auth */ return; /* invalid state for new pre-auth */

View file

@ -1925,6 +1925,8 @@ static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
WPA_AUTH_KEY_MGMT_CCKM); WPA_AUTH_KEY_MGMT_CCKM);
case WPA_KEY_MGMT_WPA_NONE: case WPA_KEY_MGMT_WPA_NONE:
return WPA_AUTH_KEY_MGMT_NONE; return WPA_AUTH_KEY_MGMT_NONE;
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
default: default:
return 0; return 0;
} }

View file

@ -173,6 +173,8 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
} else if (key_mgmt == WPA_KEY_MGMT_FT_SAE) { } else if (key_mgmt == WPA_KEY_MGMT_FT_SAE) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
} else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
} else { } else {
wpa_printf(MSG_WARNING, "Invalid key management type (%d).", wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
key_mgmt); key_mgmt);

View file

@ -942,6 +942,9 @@ static void info_print_key_mgmt(char *buf, size_t len, int key_mgmt)
if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256) if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
pos += os_snprintf(pos, end - pos, "%sPSK-SHA256", pos += os_snprintf(pos, end - pos, "%sPSK-SHA256",
pos == buf ? "" : " "); pos == buf ? "" : " ");
if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
pos += os_snprintf(pos, end - pos, "%sEAP-SUITE-B",
pos == buf ? "" : " ");
} }

View file

@ -170,7 +170,7 @@ skip_rsn_wpa:
wpa_printf(MSG_INFO, "STA " MACSTR wpa_printf(MSG_INFO, "STA " MACSTR
" proto=%s%s%s%s" " proto=%s%s%s%s"
"pairwise=%s%s%s%s%s%s%s" "pairwise=%s%s%s%s%s%s%s"
"key_mgmt=%s%s%s%s%s%s%s%s%s" "key_mgmt=%s%s%s%s%s%s%s%s%s%s"
"rsn_capab=%s%s%s%s%s", "rsn_capab=%s%s%s%s%s",
MAC2STR(sta->addr), MAC2STR(sta->addr),
sta->proto == 0 ? "OPEN " : "", sta->proto == 0 ? "OPEN " : "",
@ -197,6 +197,8 @@ skip_rsn_wpa:
sta->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ? sta->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ?
"PSK-SHA256 " : "", "PSK-SHA256 " : "",
sta->key_mgmt & WPA_KEY_MGMT_OSEN ? "OSEN " : "", sta->key_mgmt & WPA_KEY_MGMT_OSEN ? "OSEN " : "",
sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B ?
"EAP-SUITE-B " : "",
sta->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "", sta->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "",
sta->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ? sta->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ?
"NO_PAIRWISE " : "", "NO_PAIRWISE " : "",

View file

@ -535,6 +535,8 @@ static int wpa_config_parse_key_mgmt(const struct parse_data *data,
else if (os_strcmp(start, "OSEN") == 0) else if (os_strcmp(start, "OSEN") == 0)
val |= WPA_KEY_MGMT_OSEN; val |= WPA_KEY_MGMT_OSEN;
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B;
else { else {
wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'", wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
line, start); line, start);
@ -711,6 +713,16 @@ static char * wpa_config_write_key_mgmt(const struct parse_data *data,
} }
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SUITE-B",
pos == buf ? "" : " ");
if (ret < 0 || ret >= end - pos) {
end[-1] = '\0';
return buf;
}
pos += ret;
}
if (pos == buf) { if (pos == buf) {
os_free(buf); os_free(buf);
buf = NULL; buf = NULL;

View file

@ -2155,6 +2155,14 @@ static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
} }
#endif /* CONFIG_IEEE80211W */ #endif /* CONFIG_IEEE80211W */
if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
ret = os_snprintf(pos, end - pos, "%sEAP-SUITE-B",
pos == start ? "" : "+");
if (ret < 0 || ret >= end - pos)
return pos;
pos += ret;
}
pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher); pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
if (data.capabilities & WPA_CAPABILITY_PREAUTH) { if (data.capabilities & WPA_CAPABILITY_PREAUTH) {

View file

@ -3775,7 +3775,7 @@ static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter,
DBusMessageIter iter_dict, variant_iter; DBusMessageIter iter_dict, variant_iter;
const char *group; const char *group;
const char *pairwise[5]; /* max 5 pairwise ciphers is supported */ const char *pairwise[5]; /* max 5 pairwise ciphers is supported */
const char *key_mgmt[7]; /* max 7 key managements may be supported */ const char *key_mgmt[8]; /* max 8 key managements may be supported */
int n; int n;
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
@ -3799,6 +3799,8 @@ static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter,
key_mgmt[n++] = "wpa-ft-eap"; key_mgmt[n++] = "wpa-ft-eap";
if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
key_mgmt[n++] = "wpa-eap-sha256"; key_mgmt[n++] = "wpa-eap-sha256";
if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
key_mgmt[n++] = "wpa-eap-suite-b";
if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE) if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
key_mgmt[n++] = "wpa-none"; key_mgmt[n++] = "wpa-none";

View file

@ -1091,6 +1091,10 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE); sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
if (0) { if (0) {
} else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
wpa_dbg(wpa_s, MSG_DEBUG,
"WPA: using KEY_MGMT 802.1X with Suite B");
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
} else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) { } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X; wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
@ -1927,7 +1931,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
if (wpa_s->conf->key_mgmt_offload) { if (wpa_s->conf->key_mgmt_offload) {
if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X || if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256) params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B)
params.req_key_mgmt_offload = params.req_key_mgmt_offload =
ssid->proactive_key_caching < 0 ? ssid->proactive_key_caching < 0 ?
wpa_s->conf->okc : ssid->proactive_key_caching; wpa_s->conf->okc : ssid->proactive_key_caching;