From dff1e2856d103bd1ad2d72d9ab9cbd3f73e65290 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 23 Jul 2013 21:24:05 +0300 Subject: [PATCH] Initial handling of GTK-not-used cipher suite This prepares wpa_supplicant for accepting cases where the AP does not use group addressed frames. Signed-hostap: Jouni Malinen --- src/common/defs.h | 1 + src/common/wpa_common.c | 8 ++++++++ src/common/wpa_common.h | 3 ++- src/rsn_supp/wpa.c | 14 +++++++++----- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/common/defs.h b/src/common/defs.h index d3e4ff6dc..4c78e70b6 100644 --- a/src/common/defs.h +++ b/src/common/defs.h @@ -33,6 +33,7 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean; #define WPA_CIPHER_BIP_GMAC_128 BIT(11) #define WPA_CIPHER_BIP_GMAC_256 BIT(12) #define WPA_CIPHER_BIP_CMAC_256 BIT(13) +#define WPA_CIPHER_GTK_NOT_USED BIT(14) #define WPA_KEY_MGMT_IEEE8021X BIT(0) #define WPA_KEY_MGMT_PSK BIT(1) diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 03b5b4e19..4f9ef82c2 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -926,6 +926,8 @@ const char * wpa_cipher_txt(int cipher) return "GCMP-256"; case WPA_CIPHER_CCMP_256: return "CCMP-256"; + case WPA_CIPHER_GTK_NOT_USED: + return "GTK_NOT_USED"; default: return "UNKNOWN"; } @@ -1206,6 +1208,8 @@ u32 wpa_cipher_to_suite(int proto, int cipher) if (cipher & WPA_CIPHER_NONE) return (proto == WPA_PROTO_RSN ? RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE); + if (cipher & WPA_CIPHER_GTK_NOT_USED) + return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED; return 0; } @@ -1301,6 +1305,8 @@ int wpa_pick_group_cipher(int ciphers) return WPA_CIPHER_CCMP; if (ciphers & WPA_CIPHER_GCMP) return WPA_CIPHER_GCMP; + if (ciphers & WPA_CIPHER_GTK_NOT_USED) + return WPA_CIPHER_GTK_NOT_USED; if (ciphers & WPA_CIPHER_TKIP) return WPA_CIPHER_TKIP; if (ciphers & WPA_CIPHER_WEP104) @@ -1347,6 +1353,8 @@ int wpa_parse_cipher(const char *value) val |= WPA_CIPHER_WEP40; else if (os_strcmp(start, "NONE") == 0) val |= WPA_CIPHER_NONE; + else if (os_strcmp(start, "GTK_NOT_USED") == 0) + val |= WPA_CIPHER_GTK_NOT_USED; else { os_free(buf); return -1; diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 36e274bf0..d3f61a221 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -25,7 +25,8 @@ WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP_256) #define WPA_ALLOWED_GROUP_CIPHERS \ (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 | \ -WPA_CIPHER_WEP40 | WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP_256) +WPA_CIPHER_WEP40 | WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP_256 | \ +WPA_CIPHER_GTK_NOT_USED) #define WPA_SELECTOR_LEN 4 #define WPA_VERSION 1 diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index d4f86e6f0..109d07bed 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -688,10 +688,11 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, os_memcpy(gd.gtk, gtk, gtk_len); gd.gtk_len = gtk_len; - if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher, - gtk_len, gtk_len, - &gd.key_rsc_len, &gd.alg) || - wpa_supplicant_install_gtk(sm, &gd, key->key_rsc)) { + if (sm->group_cipher != WPA_CIPHER_GTK_NOT_USED && + (wpa_supplicant_check_group_cipher(sm, sm->group_cipher, + gtk_len, gtk_len, + &gd.key_rsc_len, &gd.alg) || + wpa_supplicant_install_gtk(sm, &gd, key->key_rsc))) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Failed to install GTK"); return -1; @@ -1112,7 +1113,10 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, } wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE); - if (ie.gtk && + if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED) { + wpa_supplicant_key_neg_complete(sm, sm->bssid, + key_info & WPA_KEY_INFO_SECURE); + } else if (ie.gtk && wpa_supplicant_pairwise_gtk(sm, key, ie.gtk, ie.gtk_len, key_info) < 0) { wpa_msg(sm->ctx->msg_ctx, MSG_INFO,