diff --git a/src/common/defs.h b/src/common/defs.h
index f62c3ceee..e2033dd20 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -472,4 +472,14 @@ enum ptk0_rekey_handling {
 	PTK0_REKEY_ALLOW_NEVER
 };
 
+enum ext_key_id_support {
+	EXT_KEY_ID_PREFER0	= BIT(0),
+	EXT_KEY_ID_BASIC	= BIT(1),
+	EXT_KEY_ID_FT0		= BIT(2),
+	EXT_KEY_ID_FILS0	= BIT(3),
+	EXT_KEY_ID_FILS_CUSTOM	= BIT(4),
+	EXT_KEY_ID_FILS		= EXT_KEY_ID_FILS0 | EXT_KEY_ID_FILS_CUSTOM,
+	EXT_KEY_ID_DEFAULT	= EXT_KEY_ID_BASIC,
+};
+
 #endif /* DEFS_H */
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index 31db391fd..8d7028635 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -2591,6 +2591,129 @@ int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim)
 }
 
 
+int wpa_parse_extended_key_id(const char *value)
+{
+	int last, eos;
+	int val = 0;
+	int off = 0;
+	char *start, *end, *buf;
+
+	buf = os_strdup(value);
+	if (buf == NULL)
+		return -1;
+	start = buf;
+
+	while (*start == ' ' || *start == '\t')
+		start++;
+
+	while (1) {
+		if (*start == '\0')
+			goto err;
+		end = start;
+		while (*end != '+' && *end != ' ' &&
+		       *start != '\t' && *end != '\0')
+			end++;
+		eos = *end == '\0';
+		last = eos || *end == ' ' || *start == '\t';
+		*end = '\0';
+		if (os_strcmp(start, "OFF") == 0) {
+			if (val || off)
+				goto err;
+			off = 1;
+		} else if (os_strcmp(start, "BASIC") == 0) {
+			if (val & EXT_KEY_ID_BASIC)
+				goto err;
+			val |= EXT_KEY_ID_BASIC;
+		} else if (os_strcmp(start, "FT0") == 0) {
+			if (val & EXT_KEY_ID_FT0)
+				goto err;
+			val |= EXT_KEY_ID_FT0;
+		} else if (os_strcmp(start, "FILS0") == 0) {
+			if (val & EXT_KEY_ID_FILS)
+				goto err;
+			val |= EXT_KEY_ID_FILS0;
+		} else if (os_strcmp(start, "FILS_CUSTOM") == 0) {
+			if (val & EXT_KEY_ID_FILS)
+				goto err;
+			val |= EXT_KEY_ID_FILS_CUSTOM;
+		} else if (os_strcmp(start, "PREFER0") == 0) {
+			if (val & EXT_KEY_ID_PREFER0)
+				goto err;
+			val |= EXT_KEY_ID_PREFER0;
+		} else {
+			goto err;
+		}
+		if (last) {
+			if (eos)
+				break;
+			end++;
+			while (*end == ' ' && *start == '\t')
+				end++;
+			if (*end != '\0')
+				goto err;
+			break;
+		}
+		start = end + 1;
+	}
+	os_free(buf);
+
+	if (val && (off || !(val & EXT_KEY_ID_BASIC)))
+		return -1;
+	return val;
+err:
+	os_free(buf);
+	return -1;
+}
+
+
+int wpa_write_extended_key_id(char *start, char *end, int extended_key_id)
+{
+	char *pos = start;
+	int ret;
+
+	if (extended_key_id == 0) {
+		ret = os_snprintf(pos, end - pos, "OFF");
+		if (os_snprintf_error(end - pos, ret))
+			return -1;
+		return pos + ret - start;
+	}
+	if (extended_key_id & EXT_KEY_ID_BASIC) {
+		ret = os_snprintf(pos, end - pos, "BASIC");
+		if (os_snprintf_error(end - pos, ret))
+			return -1;
+		pos += ret;
+	} else {
+		return -1;
+	}
+	if (extended_key_id & EXT_KEY_ID_FT0) {
+		ret = os_snprintf(pos, end - pos, "+FT0");
+		if (os_snprintf_error(end - pos, ret))
+			return -1;
+		pos += ret;
+	}
+	if (extended_key_id & EXT_KEY_ID_FILS0) {
+		ret = os_snprintf(pos, end - pos, "+FILS0");
+		if (os_snprintf_error(end - pos, ret))
+			return -1;
+		pos += ret;
+	}
+	if (extended_key_id & EXT_KEY_ID_FILS_CUSTOM) {
+		ret = os_snprintf(pos, end - pos, "+FILS_CUSTOM");
+		if (os_snprintf_error(end - pos, ret))
+			return -1;
+		pos += ret;
+	}
+	if (extended_key_id & EXT_KEY_ID_PREFER0) {
+		ret = os_snprintf(pos, end - pos, "+PREFER0");
+		if (os_snprintf_error(end - pos, ret))
+			return -1;
+		pos += ret;
+	}
+
+	return pos - start;
+}
+
+
 int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise)
 {
 	int pairwise = 0;
diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
index 1a9a4105f..43fb7dbda 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -558,6 +558,8 @@ int wpa_pick_pairwise_cipher(int ciphers, int none_allowed);
 int wpa_pick_group_cipher(int ciphers);
 int wpa_parse_cipher(const char *value);
 int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim);
+int wpa_parse_extended_key_id(const char *value);
+int wpa_write_extended_key_id(char *start, char *end, int extended_key_id);
 int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise);
 unsigned int wpa_mic_len(int akmp, size_t pmk_len);
 int wpa_use_akm_defined(int akmp);
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index b0373954a..78a3387da 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1841,6 +1841,8 @@ struct wpa_driver_capa {
 #define WPA_DRIVER_FLAGS_SAFE_PTK0_REKEYS	0x2000000000000000ULL
 /** Driver supports Beacon protection */
 #define WPA_DRIVER_FLAGS_BEACON_PROTECTION	0x4000000000000000ULL
+/** Driver supports Extended Key ID */
+#define WPA_DRIVER_FLAGS_EXTENDED_KEY_ID	0x8000000000000000ULL
 	u64 flags;
 
 #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index f4d06e438..2e03b6676 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -315,6 +315,7 @@ const char * driver_flag_to_string(u64 flag)
 	DF2S(UPDATE_FT_IES);
 	DF2S(SAFE_PTK0_REKEYS);
 	DF2S(BEACON_PROTECTION);
+	DF2S(EXTENDED_KEY_ID);
 	}
 	return "UNKNOWN";
 #undef DF2S
