Browse Source

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 <jouni@qca.qualcomm.com>
Jouni Malinen 11 years ago
parent
commit
dff1e2856d
4 changed files with 20 additions and 6 deletions
  1. 1 0
      src/common/defs.h
  2. 8 0
      src/common/wpa_common.c
  3. 2 1
      src/common/wpa_common.h
  4. 9 5
      src/rsn_supp/wpa.c

+ 1 - 0
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)

+ 8 - 0
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;

+ 2 - 1
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

+ 9 - 5
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,