1 /*
2  * wpa_supplicant - WPA/RSN IE and KDE processing
3  * Copyright (c) 2003-2018, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 #include "wpa.h"
13 #include "pmksa_cache.h"
14 #include "common/ieee802_11_defs.h"
15 #include "wpa_i.h"
16 #include "wpa_ie.h"
17 
18 
19 /**
20  * wpa_parse_wpa_ie - Parse WPA/RSN IE
21  * @wpa_ie: Pointer to WPA or RSN IE
22  * @wpa_ie_len: Length of the WPA/RSN IE
23  * @data: Pointer to data area for parsing results
24  * Returns: 0 on success, -1 on failure
25  *
26  * Parse the contents of WPA or RSN IE and write the parsed data into data.
27  */
wpa_parse_wpa_ie(const u8 * wpa_ie,size_t wpa_ie_len,struct wpa_ie_data * data)28 int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
29 		     struct wpa_ie_data *data)
30 {
31 	if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN)
32 		return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
33 	if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
34 	    wpa_ie[1] >= 4 &&
35 	    WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE)
36 		return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
37 	if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
38 	    wpa_ie[1] >= 4 &&
39 	    WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_2_IE_VENDOR_TYPE)
40 		return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
41 	return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
42 }
43 
44 
wpa_gen_wpa_ie_wpa(u8 * wpa_ie,size_t wpa_ie_len,int pairwise_cipher,int group_cipher,int key_mgmt)45 static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
46 			      int pairwise_cipher, int group_cipher,
47 			      int key_mgmt)
48 {
49 	u8 *pos;
50 	struct wpa_ie_hdr *hdr;
51 	u32 suite;
52 
53 	if (wpa_ie_len < sizeof(*hdr) + WPA_SELECTOR_LEN +
54 	    2 + WPA_SELECTOR_LEN + 2 + WPA_SELECTOR_LEN)
55 		return -1;
56 
57 	hdr = (struct wpa_ie_hdr *) wpa_ie;
58 	hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC;
59 	RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE);
60 	WPA_PUT_LE16(hdr->version, WPA_VERSION);
61 	pos = (u8 *) (hdr + 1);
62 
63 	suite = wpa_cipher_to_suite(WPA_PROTO_WPA, group_cipher);
64 	if (suite == 0) {
65 		wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
66 			   group_cipher);
67 		return -1;
68 	}
69 	RSN_SELECTOR_PUT(pos, suite);
70 	pos += WPA_SELECTOR_LEN;
71 
72 	*pos++ = 1;
73 	*pos++ = 0;
74 	suite = wpa_cipher_to_suite(WPA_PROTO_WPA, pairwise_cipher);
75 	if (suite == 0 ||
76 	    (!wpa_cipher_valid_pairwise(pairwise_cipher) &&
77 	     pairwise_cipher != WPA_CIPHER_NONE)) {
78 		wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
79 			   pairwise_cipher);
80 		return -1;
81 	}
82 	RSN_SELECTOR_PUT(pos, suite);
83 	pos += WPA_SELECTOR_LEN;
84 
85 	*pos++ = 1;
86 	*pos++ = 0;
87 	if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
88 		RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
89 	} else if (key_mgmt == WPA_KEY_MGMT_PSK) {
90 		RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
91 	} else if (key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
92 		RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_NONE);
93 	} else if (key_mgmt == WPA_KEY_MGMT_CCKM) {
94 		RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_CCKM);
95 	} else {
96 		wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
97 			   key_mgmt);
98 		return -1;
99 	}
100 	pos += WPA_SELECTOR_LEN;
101 
102 	/* WPA Capabilities; use defaults, so no need to include it */
103 
104 	hdr->len = (pos - wpa_ie) - 2;
105 
106 	WPA_ASSERT((size_t) (pos - wpa_ie) <= wpa_ie_len);
107 
108 	return pos - wpa_ie;
109 }
110 
111 
rsn_supp_capab(struct wpa_sm * sm)112 u16 rsn_supp_capab(struct wpa_sm *sm)
113 {
114 	u16 capab = 0;
115 
116 	if (sm->wmm_enabled) {
117 		/* Advertise 16 PTKSA replay counters when using WMM */
118 		capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
119 	}
120 	if (sm->mfp)
121 		capab |= WPA_CAPABILITY_MFPC;
122 	if (sm->mfp == 2)
123 		capab |= WPA_CAPABILITY_MFPR;
124 	if (sm->ocv)
125 		capab |= WPA_CAPABILITY_OCVC;
126 	if (sm->ext_key_id)
127 		capab |= WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST;
128 
129 	return capab;
130 }
131 
132 
wpa_gen_wpa_ie_rsn(u8 * rsn_ie,size_t rsn_ie_len,int pairwise_cipher,int group_cipher,int key_mgmt,int mgmt_group_cipher,struct wpa_sm * sm)133 static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
134 			      int pairwise_cipher, int group_cipher,
135 			      int key_mgmt, int mgmt_group_cipher,
136 			      struct wpa_sm *sm)
137 {
138 	u8 *pos;
139 	struct rsn_ie_hdr *hdr;
140 	u32 suite;
141 
142 	if (rsn_ie_len < sizeof(*hdr) + RSN_SELECTOR_LEN +
143 	    2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN + 2 +
144 	    (sm->cur_pmksa ? 2 + PMKID_LEN : 0)) {
145 		wpa_printf(MSG_DEBUG, "RSN: Too short IE buffer (%lu bytes)",
146 			   (unsigned long) rsn_ie_len);
147 		return -1;
148 	}
149 
150 	hdr = (struct rsn_ie_hdr *) rsn_ie;
151 	hdr->elem_id = WLAN_EID_RSN;
152 	WPA_PUT_LE16(hdr->version, RSN_VERSION);
153 	pos = (u8 *) (hdr + 1);
154 
155 	suite = wpa_cipher_to_suite(WPA_PROTO_RSN, group_cipher);
156 	if (suite == 0) {
157 		wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
158 			   group_cipher);
159 		return -1;
160 	}
161 	RSN_SELECTOR_PUT(pos, suite);
162 	pos += RSN_SELECTOR_LEN;
163 
164 	*pos++ = 1;
165 	*pos++ = 0;
166 	suite = wpa_cipher_to_suite(WPA_PROTO_RSN, pairwise_cipher);
167 	if (suite == 0 ||
168 	    (!wpa_cipher_valid_pairwise(pairwise_cipher) &&
169 	     pairwise_cipher != WPA_CIPHER_NONE)) {
170 		wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
171 			   pairwise_cipher);
172 		return -1;
173 	}
174 	RSN_SELECTOR_PUT(pos, suite);
175 	pos += RSN_SELECTOR_LEN;
176 
177 	*pos++ = 1;
178 	*pos++ = 0;
179 	if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
180 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
181 	} else if (key_mgmt == WPA_KEY_MGMT_PSK) {
182 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X);
183 	} else if (key_mgmt == WPA_KEY_MGMT_CCKM) {
184 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_CCKM);
185 #ifdef CONFIG_IEEE80211R
186 	} else if (key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
187 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
188 #ifdef CONFIG_SHA384
189 	} else if (key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X_SHA384) {
190 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384);
191 #endif /* CONFIG_SHA384 */
192 	} else if (key_mgmt == WPA_KEY_MGMT_FT_PSK) {
193 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
194 #endif /* CONFIG_IEEE80211R */
195 	} else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SHA256) {
196 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
197 	} else if (key_mgmt == WPA_KEY_MGMT_PSK_SHA256) {
198 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
199 #ifdef CONFIG_SAE
200 	} else if (key_mgmt == WPA_KEY_MGMT_SAE) {
201 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
202 	} else if (key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) {
203 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE_EXT_KEY);
204 	} else if (key_mgmt == WPA_KEY_MGMT_FT_SAE) {
205 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
206 	} else if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
207 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY);
208 #endif /* CONFIG_SAE */
209 	} else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
210 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192);
211 	} else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
212 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
213 #ifdef CONFIG_FILS
214 	} else if (key_mgmt & WPA_KEY_MGMT_FILS_SHA256) {
215 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256);
216 	} else if (key_mgmt & WPA_KEY_MGMT_FILS_SHA384) {
217 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384);
218 #ifdef CONFIG_IEEE80211R
219 	} else if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {
220 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA256);
221 	} else if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) {
222 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384);
223 #endif /* CONFIG_IEEE80211R */
224 #endif /* CONFIG_FILS */
225 #ifdef CONFIG_OWE
226 	} else if (key_mgmt & WPA_KEY_MGMT_OWE) {
227 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OWE);
228 #endif /* CONFIG_OWE */
229 #ifdef CONFIG_DPP
230 	} else if (key_mgmt & WPA_KEY_MGMT_DPP) {
231 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_DPP);
232 #endif /* CONFIG_DPP */
233 #ifdef CONFIG_SHA384
234 	} else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SHA384) {
235 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA384);
236 #endif /* CONFIG_SHA384 */
237 	} else {
238 		wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
239 			   key_mgmt);
240 		return -1;
241 	}
242 	pos += RSN_SELECTOR_LEN;
243 
244 	/* RSN Capabilities */
245 	WPA_PUT_LE16(pos, rsn_supp_capab(sm));
246 	pos += 2;
247 
248 	if (sm->cur_pmksa) {
249 		/* PMKID Count (2 octets, little endian) */
250 		*pos++ = 1;
251 		*pos++ = 0;
252 		/* PMKID */
253 		os_memcpy(pos, sm->cur_pmksa->pmkid, PMKID_LEN);
254 		pos += PMKID_LEN;
255 	}
256 
257 	if (wpa_cipher_valid_mgmt_group(mgmt_group_cipher)) {
258 		if (!sm->cur_pmksa) {
259 			/* PMKID Count */
260 			WPA_PUT_LE16(pos, 0);
261 			pos += 2;
262 		}
263 
264 		/* Management Group Cipher Suite */
265 		RSN_SELECTOR_PUT(pos, wpa_cipher_to_suite(WPA_PROTO_RSN,
266 							  mgmt_group_cipher));
267 		pos += RSN_SELECTOR_LEN;
268 	}
269 
270 	hdr->len = (pos - rsn_ie) - 2;
271 
272 	WPA_ASSERT((size_t) (pos - rsn_ie) <= rsn_ie_len);
273 
274 	return pos - rsn_ie;
275 }
276 
277 
278 /**
279  * wpa_gen_wpa_ie - Generate WPA/RSN IE based on current security policy
280  * @sm: Pointer to WPA state machine data from wpa_sm_init()
281  * @wpa_ie: Pointer to memory area for the generated WPA/RSN IE
282  * @wpa_ie_len: Maximum length of the generated WPA/RSN IE
283  * Returns: Length of the generated WPA/RSN IE or -1 on failure
284  */
wpa_gen_wpa_ie(struct wpa_sm * sm,u8 * wpa_ie,size_t wpa_ie_len)285 int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len)
286 {
287 	if (sm->proto == WPA_PROTO_RSN)
288 		return wpa_gen_wpa_ie_rsn(wpa_ie, wpa_ie_len,
289 					  sm->pairwise_cipher,
290 					  sm->group_cipher,
291 					  sm->key_mgmt, sm->mgmt_group_cipher,
292 					  sm);
293 	else
294 		return wpa_gen_wpa_ie_wpa(wpa_ie, wpa_ie_len,
295 					  sm->pairwise_cipher,
296 					  sm->group_cipher,
297 					  sm->key_mgmt);
298 }
299 
300 
wpa_gen_rsnxe(struct wpa_sm * sm,u8 * rsnxe,size_t rsnxe_len)301 int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len)
302 {
303 	u8 *pos = rsnxe;
304 	u32 capab = 0, tmp;
305 	size_t flen;
306 
307 	if (wpa_key_mgmt_sae(sm->key_mgmt) &&
308 	    (sm->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||
309 	     sm->sae_pwe == SAE_PWE_BOTH || sm->sae_pk)) {
310 		capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
311 #ifdef CONFIG_SAE_PK
312 		if (sm->sae_pk)
313 			capab |= BIT(WLAN_RSNX_CAPAB_SAE_PK);
314 #endif /* CONFIG_SAE_PK */
315 	}
316 
317 	if (sm->secure_ltf)
318 		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
319 	if (sm->secure_rtt)
320 		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
321 	if (sm->prot_range_neg)
322 		capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
323 	if (sm->ssid_protection)
324 		capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION);
325 	if (sm->spp_amsdu)
326 		capab |= BIT(WLAN_RSNX_CAPAB_SPP_A_MSDU);
327 
328 	if (!capab)
329 		return 0; /* no supported extended RSN capabilities */
330 	tmp = capab;
331 	flen = 0;
332 	while (tmp) {
333 		flen++;
334 		tmp >>= 8;
335 	}
336 	if (rsnxe_len < 2 + flen)
337 		return -1;
338 	capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
339 
340 	*pos++ = WLAN_EID_RSNX;
341 	*pos++ = flen;
342 	while (capab) {
343 		*pos++ = capab & 0xff;
344 		capab >>= 8;
345 	}
346 
347 	return pos - rsnxe;
348 }
349