1 /*
2  * hostapd - PeerKey for Direct Link Setup (DLS)
3  * Copyright (c) 2006-2009, 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 "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "crypto/sha1.h"
14 #include "crypto/sha256.h"
15 #include "crypto/random.h"
16 #include "wpa_auth.h"
17 #include "wpa_auth_i.h"
18 #include "wpa_auth_ie.h"
19 
20 #ifdef CONFIG_PEERKEY
21 
22 struct wpa_stsl_search {
23 	const u8 *addr;
24 	struct wpa_state_machine *sm;
25 };
26 
27 
wpa_stsl_select_sta(struct wpa_state_machine * sm,void * ctx)28 static int wpa_stsl_select_sta(struct wpa_state_machine *sm, void *ctx)
29 {
30 	struct wpa_stsl_search *search = ctx;
31 	if (os_memcmp(search->addr, sm->addr, ETH_ALEN) == 0) {
32 		search->sm = sm;
33 		return 1;
34 	}
35 	return 0;
36 }
37 
38 
wpa_smk_send_error(struct wpa_authenticator * wpa_auth,struct wpa_state_machine * sm,const u8 * peer,u16 mui,u16 error_type)39 static void wpa_smk_send_error(struct wpa_authenticator *wpa_auth,
40 			       struct wpa_state_machine *sm, const u8 *peer,
41 			       u16 mui, u16 error_type)
42 {
43 	u8 kde[2 + RSN_SELECTOR_LEN + ETH_ALEN +
44 	       2 + RSN_SELECTOR_LEN + sizeof(struct rsn_error_kde)];
45 	u8 *pos;
46 	struct rsn_error_kde error;
47 
48 	wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
49 			"Sending SMK Error");
50 
51 	pos = kde;
52 
53 	if (peer) {
54 		pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN,
55 				  NULL, 0);
56 	}
57 
58 	error.mui = host_to_be16(mui);
59 	error.error_type = host_to_be16(error_type);
60 	pos = wpa_add_kde(pos, RSN_KEY_DATA_ERROR,
61 			  (u8 *) &error, sizeof(error), NULL, 0);
62 
63 	__wpa_send_eapol(wpa_auth, sm,
64 			 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
65 			 WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_ERROR,
66 			 NULL, NULL, kde, pos - kde, 0, 0, 0);
67 }
68 
69 
wpa_smk_m1(struct wpa_authenticator * wpa_auth,struct wpa_state_machine * sm,struct wpa_eapol_key * key,const u8 * key_data,size_t key_data_len)70 void wpa_smk_m1(struct wpa_authenticator *wpa_auth,
71 		struct wpa_state_machine *sm, struct wpa_eapol_key *key,
72 		const u8 *key_data, size_t key_data_len)
73 {
74 	struct wpa_eapol_ie_parse kde;
75 	struct wpa_stsl_search search;
76 	u8 *buf, *pos;
77 	size_t buf_len;
78 
79 	if (wpa_parse_kde_ies(key_data, key_data_len, &kde) < 0) {
80 		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M1");
81 		return;
82 	}
83 
84 	if (kde.rsn_ie == NULL || kde.mac_addr == NULL ||
85 	    kde.mac_addr_len < ETH_ALEN) {
86 		wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in "
87 			   "SMK M1");
88 		return;
89 	}
90 
91 	/* Initiator = sm->addr; Peer = kde.mac_addr */
92 
93 	search.addr = kde.mac_addr;
94 	search.sm = NULL;
95 	if (wpa_auth_for_each_sta(wpa_auth, wpa_stsl_select_sta, &search) ==
96 	    0 || search.sm == NULL) {
97 		wpa_printf(MSG_DEBUG, "RSN: SMK handshake with " MACSTR
98 			   " aborted - STA not associated anymore",
99 			   MAC2STR(kde.mac_addr));
100 		wpa_smk_send_error(wpa_auth, sm, kde.mac_addr, STK_MUI_SMK,
101 				   STK_ERR_STA_NR);
102 		return;
103 	}
104 
105 	buf_len = kde.rsn_ie_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;
106 	buf = os_malloc(buf_len);
107 	if (buf == NULL)
108 		return;
109 	/* Initiator RSN IE */
110 	os_memcpy(buf, kde.rsn_ie, kde.rsn_ie_len);
111 	pos = buf + kde.rsn_ie_len;
112 	/* Initiator MAC Address */
113 	pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, sm->addr, ETH_ALEN,
114 			  NULL, 0);
115 
116 	/* SMK M2:
117 	 * EAPOL-Key(S=1, M=1, A=1, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
118 	 *           MIC=MIC, DataKDs=(RSNIE_I, MAC_I KDE)
119 	 */
120 
121 	wpa_auth_logger(wpa_auth, search.sm->addr, LOGGER_DEBUG,
122 			"Sending SMK M2");
123 
124 	__wpa_send_eapol(wpa_auth, search.sm,
125 			 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
126 			 WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE,
127 			 NULL, key->key_nonce, buf, pos - buf, 0, 0, 0);
128 
129 	os_free(buf);
130 }
131 
132 
wpa_send_smk_m4(struct wpa_authenticator * wpa_auth,struct wpa_state_machine * sm,struct wpa_eapol_key * key,struct wpa_eapol_ie_parse * kde,const u8 * smk)133 static void wpa_send_smk_m4(struct wpa_authenticator *wpa_auth,
134 			    struct wpa_state_machine *sm,
135 			    struct wpa_eapol_key *key,
136 			    struct wpa_eapol_ie_parse *kde,
137 			    const u8 *smk)
138 {
139 	u8 *buf, *pos;
140 	size_t buf_len;
141 	u32 lifetime;
142 
143 	/* SMK M4:
144 	 * EAPOL-Key(S=1, M=1, A=0, I=1, K=0, SM=1, KeyRSC=0, Nonce=PNonce,
145 	 *           MIC=MIC, DataKDs=(MAC_I KDE, INonce KDE, SMK KDE,
146 	 *           Lifetime KDE)
147 	 */
148 
149 	buf_len = 2 + RSN_SELECTOR_LEN + ETH_ALEN +
150 		2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN +
151 		2 + RSN_SELECTOR_LEN + PMK_LEN + WPA_NONCE_LEN +
152 		2 + RSN_SELECTOR_LEN + sizeof(lifetime);
153 	pos = buf = os_malloc(buf_len);
154 	if (buf == NULL)
155 		return;
156 
157 	/* Initiator MAC Address */
158 	pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, kde->mac_addr, ETH_ALEN,
159 			  NULL, 0);
160 
161 	/* Initiator Nonce */
162 	pos = wpa_add_kde(pos, RSN_KEY_DATA_NONCE, kde->nonce, WPA_NONCE_LEN,
163 			  NULL, 0);
164 
165 	/* SMK with PNonce */
166 	pos = wpa_add_kde(pos, RSN_KEY_DATA_SMK, smk, PMK_LEN,
167 			  key->key_nonce, WPA_NONCE_LEN);
168 
169 	/* Lifetime */
170 	lifetime = htonl(43200); /* dot11RSNAConfigSMKLifetime */
171 	pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
172 			  (u8 *) &lifetime, sizeof(lifetime), NULL, 0);
173 
174 	wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
175 			"Sending SMK M4");
176 
177 	__wpa_send_eapol(wpa_auth, sm,
178 			 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
179 			 WPA_KEY_INFO_INSTALL | WPA_KEY_INFO_SMK_MESSAGE,
180 			 NULL, key->key_nonce, buf, pos - buf, 0, 1, 0);
181 
182 	os_free(buf);
183 }
184 
185 
wpa_send_smk_m5(struct wpa_authenticator * wpa_auth,struct wpa_state_machine * sm,struct wpa_eapol_key * key,struct wpa_eapol_ie_parse * kde,const u8 * smk,const u8 * peer)186 static void wpa_send_smk_m5(struct wpa_authenticator *wpa_auth,
187 			    struct wpa_state_machine *sm,
188 			    struct wpa_eapol_key *key,
189 			    struct wpa_eapol_ie_parse *kde,
190 			    const u8 *smk, const u8 *peer)
191 {
192 	u8 *buf, *pos;
193 	size_t buf_len;
194 	u32 lifetime;
195 
196 	/* SMK M5:
197 	 * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
198 	 *           MIC=MIC, DataKDs=(RSNIE_P, MAC_P KDE, PNonce, SMK KDE,
199 	 *                             Lifetime KDE))
200 	 */
201 
202 	buf_len = kde->rsn_ie_len +
203 		2 + RSN_SELECTOR_LEN + ETH_ALEN +
204 		2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN +
205 		2 + RSN_SELECTOR_LEN + PMK_LEN + WPA_NONCE_LEN +
206 		2 + RSN_SELECTOR_LEN + sizeof(lifetime);
207 	pos = buf = os_malloc(buf_len);
208 	if (buf == NULL)
209 		return;
210 
211 	/* Peer RSN IE */
212 	os_memcpy(pos, kde->rsn_ie, kde->rsn_ie_len);
213 	pos += kde->rsn_ie_len;
214 
215 	/* Peer MAC Address */
216 	pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN, NULL, 0);
217 
218 	/* PNonce */
219 	pos = wpa_add_kde(pos, RSN_KEY_DATA_NONCE, key->key_nonce,
220 			  WPA_NONCE_LEN, NULL, 0);
221 
222 	/* SMK and INonce */
223 	pos = wpa_add_kde(pos, RSN_KEY_DATA_SMK, smk, PMK_LEN,
224 			  kde->nonce, WPA_NONCE_LEN);
225 
226 	/* Lifetime */
227 	lifetime = htonl(43200); /* dot11RSNAConfigSMKLifetime */
228 	pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
229 			  (u8 *) &lifetime, sizeof(lifetime), NULL, 0);
230 
231 	wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
232 			"Sending SMK M5");
233 
234 	__wpa_send_eapol(wpa_auth, sm,
235 			 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
236 			 WPA_KEY_INFO_SMK_MESSAGE,
237 			 NULL, kde->nonce, buf, pos - buf, 0, 1, 0);
238 
239 	os_free(buf);
240 }
241 
242 
wpa_smk_m3(struct wpa_authenticator * wpa_auth,struct wpa_state_machine * sm,struct wpa_eapol_key * key,const u8 * key_data,size_t key_data_len)243 void wpa_smk_m3(struct wpa_authenticator *wpa_auth,
244 		struct wpa_state_machine *sm, struct wpa_eapol_key *key,
245 		const u8 *key_data, size_t key_data_len)
246 {
247 	struct wpa_eapol_ie_parse kde;
248 	struct wpa_stsl_search search;
249 	u8 smk[32], buf[ETH_ALEN + 8 + 2 * WPA_NONCE_LEN], *pos;
250 
251 	if (wpa_parse_kde_ies(key_data, key_data_len, &kde) < 0) {
252 		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M3");
253 		return;
254 	}
255 
256 	if (kde.rsn_ie == NULL ||
257 	    kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
258 	    kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN) {
259 		wpa_printf(MSG_INFO, "RSN: No RSN IE, MAC address KDE, or "
260 			   "Nonce KDE in SMK M3");
261 		return;
262 	}
263 
264 	/* Peer = sm->addr; Initiator = kde.mac_addr;
265 	 * Peer Nonce = key->key_nonce; Initiator Nonce = kde.nonce */
266 
267 	search.addr = kde.mac_addr;
268 	search.sm = NULL;
269 	if (wpa_auth_for_each_sta(wpa_auth, wpa_stsl_select_sta, &search) ==
270 	    0 || search.sm == NULL) {
271 		wpa_printf(MSG_DEBUG, "RSN: SMK handshake with " MACSTR
272 			   " aborted - STA not associated anymore",
273 			   MAC2STR(kde.mac_addr));
274 		wpa_smk_send_error(wpa_auth, sm, kde.mac_addr, STK_MUI_SMK,
275 				   STK_ERR_STA_NR);
276 		return;
277 	}
278 
279 	if (random_get_bytes(smk, PMK_LEN)) {
280 		wpa_printf(MSG_DEBUG, "RSN: Failed to generate SMK");
281 		return;
282 	}
283 
284 	/* SMK = PRF-256(Random number, "SMK Derivation",
285 	 *               AA || Time || INonce || PNonce)
286 	 */
287 	os_memcpy(buf, wpa_auth->addr, ETH_ALEN);
288 	pos = buf + ETH_ALEN;
289 	wpa_get_ntp_timestamp(pos);
290 	pos += 8;
291 	os_memcpy(pos, kde.nonce, WPA_NONCE_LEN);
292 	pos += WPA_NONCE_LEN;
293 	os_memcpy(pos, key->key_nonce, WPA_NONCE_LEN);
294 #ifdef CONFIG_IEEE80211W
295 	sha256_prf(smk, PMK_LEN, "SMK Derivation", buf, sizeof(buf),
296 		   smk, PMK_LEN);
297 #else /* CONFIG_IEEE80211W */
298 	sha1_prf(smk, PMK_LEN, "SMK Derivation", buf, sizeof(buf),
299 		 smk, PMK_LEN);
300 #endif /* CONFIG_IEEE80211W */
301 
302 	wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", smk, PMK_LEN);
303 
304 	wpa_send_smk_m4(wpa_auth, sm, key, &kde, smk);
305 	wpa_send_smk_m5(wpa_auth, search.sm, key, &kde, smk, sm->addr);
306 
307 	/* Authenticator does not need SMK anymore and it is required to forget
308 	 * it. */
309 	os_memset(smk, 0, sizeof(*smk));
310 }
311 
312 
wpa_smk_error(struct wpa_authenticator * wpa_auth,struct wpa_state_machine * sm,const u8 * key_data,size_t key_data_len)313 void wpa_smk_error(struct wpa_authenticator *wpa_auth,
314 		   struct wpa_state_machine *sm,
315 		   const u8 *key_data, size_t key_data_len)
316 {
317 	struct wpa_eapol_ie_parse kde;
318 	struct wpa_stsl_search search;
319 	struct rsn_error_kde error;
320 	u16 mui, error_type;
321 
322 	if (wpa_parse_kde_ies(key_data, key_data_len, &kde) < 0) {
323 		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");
324 		return;
325 	}
326 
327 	if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
328 	    kde.error == NULL || kde.error_len < sizeof(error)) {
329 		wpa_printf(MSG_INFO, "RSN: No MAC address or Error KDE in "
330 			   "SMK Error");
331 		return;
332 	}
333 
334 	search.addr = kde.mac_addr;
335 	search.sm = NULL;
336 	if (wpa_auth_for_each_sta(wpa_auth, wpa_stsl_select_sta, &search) ==
337 	    0 || search.sm == NULL) {
338 		wpa_printf(MSG_DEBUG, "RSN: Peer STA " MACSTR " not "
339 			   "associated for SMK Error message from " MACSTR,
340 			   MAC2STR(kde.mac_addr), MAC2STR(sm->addr));
341 		return;
342 	}
343 
344 	os_memcpy(&error, kde.error, sizeof(error));
345 	mui = be_to_host16(error.mui);
346 	error_type = be_to_host16(error.error_type);
347 	wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
348 			 "STA reported SMK Error: Peer " MACSTR
349 			 " MUI %d Error Type %d",
350 			 MAC2STR(kde.mac_addr), mui, error_type);
351 
352 	wpa_smk_send_error(wpa_auth, search.sm, sm->addr, mui, error_type);
353 }
354 
355 #endif /* CONFIG_PEERKEY */
356