1 /*
2 * Wi-Fi Aware - NAN Data link security
3 * Copyright (C) 2025 Intel Corporation
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 #include "utils/common.h"
11 #include "common/ieee802_11_common.h"
12 #include "nan_i.h"
13
14
15 /*
16 * nan_sec_reset - Reset security state
17 * @nan: NAN module context from nan_init()
18 * @ndp_sec: NDP security context to reset
19 */
nan_sec_reset(struct nan_data * nan,struct nan_ndp_sec * ndp_sec)20 void nan_sec_reset(struct nan_data *nan, struct nan_ndp_sec *ndp_sec)
21 {
22 os_memset(ndp_sec, 0, sizeof(*ndp_sec));
23 }
24
25
nan_sec_dump(const struct nan_data * nan,const struct nan_peer * peer)26 static void nan_sec_dump(const struct nan_data *nan,
27 const struct nan_peer *peer)
28 {
29 const struct nan_ndp_sec *s = &peer->ndp_setup.sec;
30
31 wpa_printf(MSG_DEBUG, "NAN: SEC: present=%u, valid=%u",
32 s->present, s->valid);
33 wpa_printf(MSG_DEBUG, "NAN: SEC: i_csid=%u, i_instance_id=%u",
34 s->i_csid, s->i_instance_id);
35 wpa_printf(MSG_DEBUG, "NAN: SEC: r_csid=%u, r_instance_id=%u",
36 s->r_csid, s->r_instance_id);
37 }
38
39
nan_sec_rx_m1_verify(struct nan_data * nan,const struct nan_attrs * attrs)40 static int nan_sec_rx_m1_verify(struct nan_data *nan,
41 const struct nan_attrs *attrs)
42 {
43 const struct nan_sec_ctxt *sc;
44 size_t expected_len;
45
46 expected_len = sizeof(struct nan_cipher_suite_info) +
47 sizeof(struct nan_cipher_suite);
48
49 if (!attrs->cipher_suite_info ||
50 attrs->cipher_suite_info_len < expected_len) {
51 wpa_printf(MSG_DEBUG,
52 "NAN: SEC: Missing valid cipher suite attribute");
53 return -1;
54 }
55
56 /* Need at least one PMKID */
57 expected_len = sizeof(struct nan_sec_ctxt) + PMKID_LEN;
58
59 if (!attrs->sec_ctxt_info || attrs->sec_ctxt_info_len < expected_len) {
60 wpa_printf(MSG_DEBUG,
61 "NAN: SEC: Missing valid security context attribute");
62 return -1;
63 }
64
65 sc = (const struct nan_sec_ctxt *) attrs->sec_ctxt_info;
66 if (sc->scid != NAN_SEC_CTX_TYPE_ND_PMKID ||
67 le_to_host16(sc->len) != PMKID_LEN) {
68 wpa_printf(MSG_DEBUG,
69 "NAN: SEC: Got unknown security context");
70 return -1;
71 }
72
73 return 0;
74 }
75
76
nan_sec_parse_csia(const u8 * csia,size_t csia_len,u8 * instance_id,u8 * capab,u8 * csid,u8 * gtk_csid)77 static int nan_sec_parse_csia(const u8 *csia, size_t csia_len, u8 *instance_id,
78 u8 *capab, u8 *csid, u8 *gtk_csid)
79 {
80 const struct nan_cipher_suite_info *cs_info =
81 (const struct nan_cipher_suite_info *) csia;
82 const u8 *cs_buf = cs_info->cs;
83 const struct nan_cipher_suite *cs;
84
85 if (!csia || csia_len < sizeof(*cs_info)) {
86 wpa_printf(MSG_DEBUG, "NAN: SEC: Invalid CSIA attribute");
87 return -1;
88 }
89
90 *instance_id = 0;
91 *capab = cs_info->capab;
92 csia_len -= sizeof(*cs_info);
93
94 *csid = NAN_CS_NONE;
95 *gtk_csid = NAN_CS_NONE;
96
97 while (csia_len >= sizeof(*cs)) {
98 cs = (const struct nan_cipher_suite *) cs_buf;
99 if (*instance_id && cs->instance_id != *instance_id) {
100 wpa_printf(MSG_DEBUG,
101 "NAN: SEC: Multiple instance IDs in CSIA");
102 return -1;
103 }
104
105 *instance_id = cs->instance_id;
106
107 if (cs->csid == NAN_CS_GTK_CCMP_128 ||
108 cs->csid == NAN_CS_GTK_GCMP_256) {
109 if (*gtk_csid != NAN_CS_NONE) {
110 wpa_printf(MSG_DEBUG,
111 "NAN: SEC: Multiple GTK CSIDs in CSIA");
112 return -1;
113 }
114
115 *gtk_csid = cs->csid;
116 } else {
117 if (*csid != NAN_CS_NONE) {
118 wpa_printf(MSG_DEBUG,
119 "NAN: SEC: Multiple CSIDs in CSIA");
120 return -1;
121 }
122
123 if (!NAN_CS_IS_VALID_NDP(cs->csid)) {
124 wpa_printf(MSG_DEBUG,
125 "NAN: SEC: Unsupported cipher suite=%u",
126 cs->csid);
127 return -1;
128 }
129
130 *csid = cs->csid;
131 }
132
133 cs_buf += sizeof(*cs);
134 csia_len -= sizeof(*cs);
135 }
136
137 if (*csid == NAN_CS_NONE) {
138 wpa_printf(MSG_DEBUG, "NAN: SEC: No valid CSID in CSIA");
139 return -1;
140 }
141
142 return 0;
143 }
144
145
nan_sec_rx_m1(struct nan_data * nan,struct nan_peer * peer,const struct nan_msg * msg,const struct wpa_eapol_key * key)146 static int nan_sec_rx_m1(struct nan_data *nan, struct nan_peer *peer,
147 const struct nan_msg *msg,
148 const struct wpa_eapol_key *key)
149 {
150 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
151 const struct nan_sec_ctxt *sc;
152 u8 instance_id;
153 int ret;
154
155 if (peer->ndp_setup.state != NAN_NDP_STATE_REQ_RECV) {
156 wpa_printf(MSG_DEBUG, "NAN: SEC: Not expecting m1");
157 return -1;
158 }
159
160 ret = nan_sec_rx_m1_verify(nan, &msg->attrs);
161 if (ret)
162 return ret;
163
164 sc = (const struct nan_sec_ctxt *) msg->attrs.sec_ctxt_info;
165
166 instance_id = sc->instance_id;
167 if (ndp_sec->i_instance_id && instance_id &&
168 ndp_sec->i_instance_id != instance_id) {
169 wpa_printf(MSG_DEBUG, "NAN: SEC: Mismatched instance ID");
170 return -1;
171 }
172
173 os_memcpy(ndp_sec->i_pmkid, sc->ctxt, PMKID_LEN);
174
175 /* Save initiator's nonce */
176 os_memcpy(ndp_sec->i_nonce, key->key_nonce, WPA_NONCE_LEN);
177
178 /* Save the replay counter */
179 os_memcpy(ndp_sec->replaycnt, key->replay_counter,
180 sizeof(key->replay_counter));
181
182 /* Store the authentication token, that is required for m3 MIC */
183 if (msg->len < 24)
184 return -1;
185 ret = nan_crypto_calc_auth_token(ndp_sec->i_csid,
186 (const u8 *) &msg->mgmt->u,
187 msg->len - 24, ndp_sec->auth_token);
188 if (ret)
189 return ret;
190
191 /* The flow will continue, once higher layer ACK the NDP setup */
192 ndp_sec->valid = true;
193 return 0;
194 }
195
196
nan_sec_key_mic_ver(struct nan_data * nan,const u8 * buf,size_t len,const struct wpa_eapol_key * key,const u8 * kck,size_t kck_len,u8 csid)197 static int nan_sec_key_mic_ver(struct nan_data *nan, const u8 *buf, size_t len,
198 const struct wpa_eapol_key *key,
199 const u8 *kck, size_t kck_len, u8 csid)
200 {
201 u8 mic[NAN_KEY_MIC_24_LEN];
202 u8 *pos = (u8 *) (key + 1);
203 u8 mic_len;
204 int ret;
205
206 os_memset(mic, 0, sizeof(mic));
207
208 if (NAN_CS_IS_128(csid))
209 mic_len = NAN_KEY_MIC_LEN;
210 else if (NAN_CS_IS_256(csid))
211 mic_len = NAN_KEY_MIC_24_LEN;
212 else
213 return -1;
214
215 os_memcpy(mic, pos, mic_len);
216 os_memset(pos, 0, mic_len);
217
218 ret = nan_crypto_key_mic(buf, len, kck, kck_len, csid, pos);
219 if (ret)
220 return ret;
221
222 if (os_memcmp_const(mic, pos, mic_len) != 0) {
223 wpa_printf(MSG_DEBUG, "NAN: SEC: MIC verification failed");
224 return -1;
225 }
226
227 return 0;
228 }
229
230
nan_sec_rx_m2(struct nan_data * nan,struct nan_peer * peer,const struct nan_msg * msg,const struct wpa_eapol_key * key)231 static int nan_sec_rx_m2(struct nan_data *nan, struct nan_peer *peer,
232 const struct nan_msg *msg,
233 const struct wpa_eapol_key *key)
234 {
235 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
236 struct nan_ndp *ndp = peer->ndp_setup.ndp;
237 struct nan_ptk tptk;
238 const u8 *pos;
239 int ret;
240
241 if (peer->ndp_setup.state != NAN_NDP_STATE_RES_RECV) {
242 wpa_printf(MSG_DEBUG, "NAN: SEC: Not expecting m2");
243 return -1;
244 }
245
246 if (ndp_sec->i_csid != ndp_sec->r_csid) {
247 wpa_printf(MSG_DEBUG, "NAN: SEC: i_csid != r_csid (%u, %u)",
248 ndp_sec->i_csid, ndp_sec->r_csid);
249 return -1;
250 }
251
252 /* Save responder's nonce */
253 os_memcpy(ndp_sec->r_nonce, key->key_nonce, WPA_NONCE_LEN);
254
255 /* Note: Replay counter should have been verified by the caller */
256
257 /* PTK should be derived using NDI addresses */
258 ret = nan_crypto_pmk_to_ptk(ndp_sec->pmk,
259 ndp->init_ndi, ndp->resp_ndi,
260 ndp_sec->i_nonce, ndp_sec->r_nonce,
261 &tptk, ndp_sec->i_csid);
262 if (ret) {
263 wpa_printf(MSG_DEBUG, "NAN: SEC: m2 failed to derive PTK");
264 return ret;
265 }
266
267 /*
268 * Due to the different MIC size, need to handle the fields starting
269 * with the MIC differently.
270 */
271 pos = (const u8 *) (key + 1);
272 if (NAN_CS_IS_128(ndp_sec->i_csid))
273 pos += NAN_KEY_MIC_LEN;
274 else
275 pos += NAN_KEY_MIC_24_LEN;
276
277 if (WPA_GET_BE16(pos))
278 wpa_printf(MSG_DEBUG, "NAN: SEC: TODO: m2 key data");
279
280 /* Verify MIC */
281 if (msg->len < 24)
282 return -1;
283 ret = nan_sec_key_mic_ver(nan, (const u8 *) &msg->mgmt->u,
284 msg->len - 24, key,
285 tptk.kck, tptk.kck_len,
286 ndp_sec->i_csid);
287 if (ret)
288 return ret;
289
290 /* MIC is verified; save PTK */
291 os_memcpy(&ndp_sec->ptk, &tptk, sizeof(tptk));
292 forced_memzero(&tptk, sizeof(tptk));
293
294 /* Increment the replay counter here to prevent replays */
295 WPA_PUT_BE64(ndp_sec->replaycnt,
296 WPA_GET_BE64(ndp_sec->replaycnt) + 1);
297 return 0;
298 }
299
300
nan_sec_rx_m3(struct nan_data * nan,struct nan_peer * peer,const struct nan_msg * msg,const struct wpa_eapol_key * key)301 static int nan_sec_rx_m3(struct nan_data *nan, struct nan_peer *peer,
302 const struct nan_msg *msg,
303 const struct wpa_eapol_key *key)
304 {
305 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
306 u8 mic[NAN_KEY_MIC_24_LEN];
307 u8 *buf;
308 u8 mic_len;
309 u8 *pos;
310 int ret;
311
312 if (peer->ndp_setup.state != NAN_NDP_STATE_CON_RECV) {
313 wpa_printf(MSG_DEBUG, "NAN: SEC: Not expecting m3");
314 return -1;
315 }
316
317 /* Note: Replay counter should have been verified by caller */
318
319 /* Verify the i_nonce did not change */
320 if (os_memcmp(key->key_nonce, ndp_sec->i_nonce, WPA_NONCE_LEN) != 0) {
321 wpa_printf(MSG_DEBUG, "NAN: SEC: m3 key nonce mismatch");
322 return -1;
323 }
324
325 /*
326 * In case of m3, the MIC is calculated over the frame body
327 * concatenated with the authentication token.
328 */
329 if (msg->len < 24)
330 return -1;
331 buf = os_malloc(msg->len - 24 + NAN_AUTH_TOKEN_LEN);
332 if (!buf)
333 return -ENOBUFS;
334
335 /*
336 * Due to the different MIC size, need to handle the fields starting
337 * with the mic differently
338 */
339 pos = (u8 *) (key + 1);
340 if (NAN_CS_IS_128(ndp_sec->i_csid))
341 mic_len = NAN_KEY_MIC_LEN;
342 else
343 mic_len = NAN_KEY_MIC_24_LEN;
344
345 if (WPA_GET_BE16(pos + mic_len))
346 wpa_printf(MSG_DEBUG, "NAN: SEC: TODO: m3 key data");
347
348 /* Copy MIC and os_memset it */
349 os_memcpy(mic, pos, mic_len);
350 os_memset(pos, 0, mic_len);
351 os_memcpy(buf, ndp_sec->auth_token, NAN_AUTH_TOKEN_LEN);
352 os_memcpy(buf + NAN_AUTH_TOKEN_LEN, (const u8 *) &msg->mgmt->u,
353 msg->len - 24);
354
355 ret = nan_crypto_key_mic(buf, msg->len - 24 + NAN_AUTH_TOKEN_LEN,
356 ndp_sec->ptk.kck, ndp_sec->ptk.kck_len,
357 ndp_sec->i_csid, pos);
358 os_free(buf);
359
360 if (ret) {
361 wpa_printf(MSG_DEBUG, "NAN: SEC: m3 MIC calculation failed");
362 return ret;
363 }
364
365 if (os_memcmp_const(mic, pos, mic_len) != 0) {
366 wpa_printf(MSG_DEBUG, "NAN: SEC: m3 MIC verification failed");
367 return -1;
368 }
369
370 forced_memzero(mic, sizeof(mic));
371
372 /* Save replay counter */
373 os_memcpy(ndp_sec->replaycnt, key->replay_counter,
374 sizeof(key->replay_counter));
375 return 0;
376 }
377
378
nan_sec_rx_m4(struct nan_data * nan,struct nan_peer * peer,const struct nan_msg * msg,const struct wpa_eapol_key * key)379 static int nan_sec_rx_m4(struct nan_data *nan, struct nan_peer *peer,
380 const struct nan_msg *msg,
381 const struct wpa_eapol_key *key)
382 {
383 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
384 u8 *pos = (u8 *) (key + 1);
385 int ret;
386
387 if (peer->ndp_setup.state != NAN_NDP_STATE_DONE) {
388 wpa_printf(MSG_DEBUG, "NAN: SEC: Not expecting m4");
389 return -1;
390 }
391
392 /* Note: replay counter should have been verified by caller */
393
394 /*
395 * Due to the different MIC size, need to handle the fields starting
396 * with the mic differently
397 */
398 if (NAN_CS_IS_128(ndp_sec->i_csid))
399 pos += NAN_KEY_MIC_LEN;
400 else
401 pos += NAN_KEY_MIC_24_LEN;
402
403 if (WPA_GET_BE16(pos))
404 wpa_printf(MSG_DEBUG, "NAN: SEC: TODO: m4 key data");
405
406 /* Verify MIC */
407 if (msg->len < 24)
408 return -1;
409 ret = nan_sec_key_mic_ver(nan, (const u8 *) &msg->mgmt->u,
410 msg->len - 24, key,
411 ndp_sec->ptk.kck, ndp_sec->ptk.kck_len,
412 ndp_sec->i_csid);
413 if (ret)
414 return ret;
415
416 /* Increment the replay counter here to prevent replays */
417 WPA_PUT_BE64(ndp_sec->replaycnt,
418 WPA_GET_BE64(ndp_sec->replaycnt) + 1);
419
420 /* Security negotiation done */
421 return 0;
422 }
423
424
nan_sec_rx_key_data(struct nan_data * nan,struct nan_peer * peer,u8 peer_capab,const u8 * enc_key_data,size_t key_data_len)425 static int nan_sec_rx_key_data(struct nan_data *nan,
426 struct nan_peer *peer, u8 peer_capab,
427 const u8 *enc_key_data, size_t key_data_len)
428 {
429 struct wpabuf *key_data = NULL;
430 struct wpa_eapol_ie_parse ie;
431 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
432 int ret = -1;
433 int cipher;
434 unsigned int key_len;
435 enum wpa_alg alg;
436
437 if (((peer_capab & NAN_CS_INFO_CAPA_GTK_SUPP_MASK) >>
438 NAN_CS_INFO_CAPA_GTK_SUPP_POS) == NAN_CS_INFO_CAPA_GTK_SUPP_NONE &&
439 ndp_sec->peer_gtk.csid == NAN_CS_NONE) {
440 wpa_printf(MSG_DEBUG,
441 "NAN: SEC: Peer does not support GTK/IGTK/BIGTK, ignore key data");
442 return 0;
443 }
444
445 if (peer_capab & NAN_CS_INFO_CAPA_IGTK_USE_NCS_BIP_GMAC_256) {
446 cipher = WPA_CIPHER_BIP_GMAC_256;
447 alg = WPA_ALG_BIP_GMAC_256;
448 } else {
449 cipher = WPA_CIPHER_AES_128_CMAC;
450 alg = WPA_ALG_BIP_CMAC_128;
451 }
452
453 key_len = wpa_cipher_key_len(cipher);
454
455 key_data = nan_crypto_decrypt_key_data(ndp_sec->ptk.kek,
456 ndp_sec->ptk.kek_len,
457 enc_key_data, key_data_len);
458 if (!key_data) {
459 wpa_printf(MSG_DEBUG, "NAN: SEC: Failed to decrypt key data");
460 return -1;
461 }
462
463 if (wpa_parse_kde_ies(wpabuf_head(key_data), wpabuf_len(key_data),
464 &ie) < 0) {
465 wpa_printf(MSG_DEBUG,
466 "NAN: SEC: Failed to parse decrypted key data");
467 goto fail;
468 }
469
470 if (ie.igtk && ie.igtk_len) {
471 const struct wpa_igtk_kde *igtk_kde =
472 (const struct wpa_igtk_kde *) ie.igtk;
473 u16 key_idx;
474
475 if (ie.igtk_len != WPA_IGTK_KDE_PREFIX_LEN + key_len) {
476 wpa_printf(MSG_DEBUG,
477 "NAN: SEC: Invalid IGTK KDE length: %zu (expected %u)",
478 ie.igtk_len,
479 WPA_IGTK_KDE_PREFIX_LEN + key_len);
480 goto fail;
481 }
482
483 /* Key ID must be 4 or 5, see Wi-Fi Aware Specification v4.0,
484 * section 7.1.3.3
485 */
486 key_idx = WPA_GET_LE16(igtk_kde->keyid);
487 if (key_idx < 4 || key_idx > 5) {
488 wpa_printf(MSG_DEBUG,
489 "NAN: SEC: Invalid IGTK key index: %u",
490 key_idx);
491 goto fail;
492 }
493
494 if (nan->cfg->set_group_key(nan->cfg->cb_ctx, alg,
495 peer->nmi_addr, key_idx,
496 igtk_kde->pn, igtk_kde->igtk,
497 key_len, KEY_FLAG_GROUP_RX) < 0) {
498 wpa_printf(MSG_DEBUG,
499 "NAN: SEC: Failed to install IGTK");
500 goto fail;
501 }
502
503 peer->igtk_id = key_idx;
504 wpa_hexdump_key(MSG_DEBUG, "NAN: SEC: Received IGTK",
505 igtk_kde->igtk, key_len);
506 }
507
508 if (ie.bigtk && ie.bigtk_len) {
509 const struct wpa_bigtk_kde *bigtk_kde =
510 (const struct wpa_bigtk_kde *) ie.bigtk;
511 u16 key_idx;
512
513 if (ie.bigtk_len != WPA_BIGTK_KDE_PREFIX_LEN + key_len) {
514 wpa_printf(MSG_DEBUG,
515 "NAN: SEC: Invalid BIGTK KDE length: %zu (expected %d)",
516 ie.bigtk_len,
517 WPA_BIGTK_KDE_PREFIX_LEN + key_len);
518 goto fail;
519 }
520
521 key_idx = WPA_GET_LE16(bigtk_kde->keyid);
522 if (key_idx < 6 || key_idx > 7) {
523 wpa_printf(MSG_DEBUG,
524 "NAN: SEC: Invalid BIGTK key index: %u",
525 key_idx);
526 goto fail;
527 }
528
529 if (nan->cfg->set_group_key(nan->cfg->cb_ctx, alg,
530 peer->nmi_addr, key_idx,
531 bigtk_kde->pn, bigtk_kde->bigtk,
532 key_len, KEY_FLAG_GROUP_RX) < 0) {
533 wpa_printf(MSG_DEBUG,
534 "NAN: SEC: Failed to install BIGTK");
535 goto fail;
536 }
537
538 peer->bigtk_id = key_idx;
539 wpa_hexdump_key(MSG_DEBUG, "NAN: SEC: Received BIGTK",
540 bigtk_kde->bigtk, key_len);
541 }
542
543 if (ie.gtk && ie.gtk_len) {
544 const struct wpa_gtk_kde *gtk_kde =
545 (const struct wpa_gtk_kde *) ie.gtk;
546 int gtk_cipher = ndp_sec->peer_gtk.csid == NAN_CS_GTK_GCMP_256 ?
547 WPA_CIPHER_GCMP_256 : WPA_CIPHER_CCMP;
548 size_t gtk_len = wpa_cipher_key_len(gtk_cipher);
549
550 if (ie.gtk_len != WPA_GTK_KDE_PREFIX_LEN + gtk_len) {
551 wpa_printf(MSG_DEBUG,
552 "NAN: SEC: Invalid GTK KDE length: %zu (expected %zu)",
553 ie.gtk_len,
554 WPA_GTK_KDE_PREFIX_LEN + gtk_len);
555 goto fail;
556 }
557
558 /* GTK key ID must be 1 or 2, see Wi-Fi Aware Specification
559 * v4.0, section 7.1.3.2.
560 */
561 if (gtk_kde->keyid < 1 || gtk_kde->keyid > 2) {
562 wpa_printf(MSG_DEBUG,
563 "NAN: SEC: Invalid GTK key index: %u",
564 gtk_kde->keyid);
565 goto fail;
566 }
567
568 ndp_sec->peer_gtk.id = gtk_kde->keyid;
569 os_memcpy(ndp_sec->peer_gtk.gtk.gtk, gtk_kde->gtk, gtk_len);
570 ndp_sec->peer_gtk.gtk.gtk_len = gtk_len;
571 wpa_hexdump_key(MSG_DEBUG, "NAN: SEC: Received GTK",
572 gtk_kde->gtk, gtk_len);
573 }
574
575 ret = 0;
576 fail:
577 wpabuf_clear_free(key_data);
578 return ret;
579 }
580
581
582 /**
583 * nan_sec_rx - Handle security context for Rx frames
584 * @nan: NAN module context from nan_init()
585 * @peer: Peer from which the original message was received
586 * @msg: Parsed NAN Action frame
587 * Returns: 0 on success, negative on failure
588 */
nan_sec_rx(struct nan_data * nan,struct nan_peer * peer,struct nan_msg * msg)589 int nan_sec_rx(struct nan_data *nan, struct nan_peer *peer,
590 struct nan_msg *msg)
591 {
592 struct nan_ndp_setup *ndp_setup = &peer->ndp_setup;
593 struct nan_ndp_sec *ndp_sec = &ndp_setup->sec;
594 struct wpa_eapol_key *key;
595 struct nan_shared_key *shared_key_desc;
596 size_t shared_key_desc_len;
597 u16 info, desc, key_data_len;
598 size_t total_len;
599 u8 instance_id, cipher, capab, gtk_csid = NAN_CS_NONE;
600 u8 *pos;
601 int ret;
602
603 wpa_printf(MSG_DEBUG, "NAN: SEC: NDP security Rx");
604 nan_sec_dump(nan, peer);
605
606 if (!ndp_sec->present) {
607 if (!ndp_sec->valid)
608 return 0;
609
610 wpa_printf(MSG_DEBUG,
611 "NAN: SEC: NDP with security but present=0");
612 return -1;
613 }
614
615 shared_key_desc = (struct nan_shared_key *) msg->attrs.shared_key_desc;
616 shared_key_desc_len = msg->attrs.shared_key_desc_len;
617
618 /* Shared key descriptor mandatory in all messages */
619 if (!shared_key_desc || !shared_key_desc_len) {
620 wpa_printf(MSG_DEBUG,
621 "NAN: SEC: No shared key descriptor attribute");
622 return -1;
623 }
624
625 /*
626 * As the shared key type depends on the cipher suite negotiated, need
627 * to get the cipher suite to validate the proper length of the
628 * descriptor.
629 */
630 if (msg->oui_subtype == NAN_SUBTYPE_DATA_PATH_REQUEST ||
631 msg->oui_subtype == NAN_SUBTYPE_DATA_PATH_RESPONSE) {
632 if (nan_sec_parse_csia(msg->attrs.cipher_suite_info,
633 msg->attrs.cipher_suite_info_len,
634 &instance_id, &capab, &cipher,
635 >k_csid)) {
636 wpa_printf(MSG_DEBUG,
637 "NAN: SEC: Missing/bad cipher suite attribute");
638 return -1;
639 }
640 } else {
641 cipher = ndp_sec->i_csid;
642 }
643
644 key = (struct wpa_eapol_key *) shared_key_desc->key;
645 pos = (u8 *) (key + 1);
646
647 total_len = sizeof(*key) + 2;
648
649 if (NAN_CS_IS_128(cipher)) {
650 if (shared_key_desc_len <
651 sizeof(struct nan_shared_key) + sizeof(*key) +
652 NAN_KEY_MIC_LEN + 2) {
653 wpa_printf(MSG_DEBUG,
654 "NAN: SEC: Shared key descriptor too small");
655 return -1;
656 }
657
658 key_data_len = WPA_GET_BE16(pos + NAN_KEY_MIC_LEN);
659 total_len += NAN_KEY_MIC_LEN + key_data_len;
660 pos += NAN_KEY_MIC_LEN + 2;
661
662 if (total_len >
663 (shared_key_desc_len - sizeof(struct nan_shared_key))) {
664 wpa_printf(MSG_DEBUG,
665 "NAN: SEC: Invalid shared key: payload len");
666 return -1;
667 }
668 } else {
669 if (shared_key_desc_len <
670 (sizeof(struct nan_shared_key) + sizeof(*key) +
671 NAN_KEY_MIC_24_LEN + 2)) {
672 wpa_printf(MSG_DEBUG,
673 "NAN: SEC: Shared key (24) descriptor too small");
674 return -1;
675 }
676
677 key_data_len = WPA_GET_BE16(pos + NAN_KEY_MIC_24_LEN);
678 total_len += NAN_KEY_MIC_24_LEN + key_data_len;
679 pos += NAN_KEY_MIC_24_LEN + 2;
680
681 if (total_len >
682 (shared_key_desc_len - sizeof(struct nan_shared_key))) {
683 wpa_printf(MSG_DEBUG,
684 "NAN: SEC: Invalid shared key (24): payload len");
685 return -1;
686 }
687 }
688
689 /*
690 * Note: Only the fields before the MIC are accessed in the function, so
691 * it is safe to continue with the key pointer.
692 */
693
694 /* Note: According to the NAN specification the following fields should
695 * be ignored:
696 * key->len: as the key length is derived from the cipher suite.
697 * key->iv: not needed for AES Key WRAP
698 */
699 if (key->type != NAN_KEY_DESC) {
700 wpa_printf(MSG_DEBUG,
701 "NAN: SEC: Invalid shared key: key descriptor=0x%x",
702 key->type);
703 return -1;
704 }
705
706 info = WPA_GET_BE16(key->key_info);
707
708 /* Discard EAPOL-Key frames with an unknown descriptor version */
709 desc = info & WPA_KEY_INFO_TYPE_MASK;
710 if (desc != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
711 wpa_printf(MSG_DEBUG,
712 "NAN: SEC: Invalid shared key: invalid key version=0x%x",
713 desc);
714 return -1;
715 }
716
717 if (ndp_sec->replaycnt_ok &&
718 WPA_GET_BE64(key->replay_counter) <
719 WPA_GET_BE64(ndp_sec->replaycnt)) {
720 wpa_printf(MSG_DEBUG,
721 "NAN: SEC: Replay counter did not increase");
722 return -1;
723 }
724
725 if (info & WPA_KEY_INFO_REQUEST) {
726 wpa_printf(MSG_DEBUG,
727 "NAN: SEC: Invalid shared key: key request not supported");
728 return -1;
729 }
730
731 if (!(info & WPA_KEY_INFO_KEY_TYPE)) {
732 wpa_printf(MSG_DEBUG,
733 "NAN: SEC: Invalid shared key: group handshake not supported");
734 return -1;
735 }
736
737 if (gtk_csid != NAN_CS_NONE) {
738 wpa_printf(MSG_DEBUG, "NAN: SEC: Peer GTK CSID=%u", gtk_csid);
739
740 os_memcpy(ndp_sec->peer_gtk_rsc, key->key_rsc,
741 sizeof(key->key_rsc));
742 ndp_sec->peer_gtk.csid = gtk_csid;
743 }
744
745 switch (msg->oui_subtype) {
746 case NAN_SUBTYPE_DATA_PATH_REQUEST:
747 if (!(info & WPA_KEY_INFO_ACK))
748 return -1;
749
750 ndp_sec->i_capab = capab;
751 ndp_sec->i_csid = cipher;
752 ndp_sec->i_instance_id = instance_id;
753 ret = nan_sec_rx_m1(nan, peer, msg, key);
754 break;
755 case NAN_SUBTYPE_DATA_PATH_RESPONSE:
756 if (!(info & WPA_KEY_INFO_MIC))
757 return -1;
758
759 ndp_sec->r_capab = capab;
760 ndp_sec->r_csid = cipher;
761 ndp_sec->r_instance_id = instance_id;
762 ret = nan_sec_rx_m2(nan, peer, msg, key);
763 break;
764 case NAN_SUBTYPE_DATA_PATH_CONFIRM:
765 if (!(info & WPA_KEY_INFO_MIC) ||
766 !(info & WPA_KEY_INFO_ACK) ||
767 !(info & WPA_KEY_INFO_SECURE))
768 return -1;
769 ret = nan_sec_rx_m3(nan, peer, msg, key);
770
771 /* Ignore unencrypted key data */
772 if (!ret && key_data_len > 0 &&
773 (info & WPA_KEY_INFO_ENCR_KEY_DATA))
774 ret = nan_sec_rx_key_data(nan, peer,
775 ndp_sec->i_capab, pos,
776 key_data_len);
777 break;
778 case NAN_SUBTYPE_DATA_PATH_KEY_INSTALL:
779 if (!(info & WPA_KEY_INFO_MIC) ||
780 !(info & WPA_KEY_INFO_SECURE))
781 return -1;
782 ret = nan_sec_rx_m4(nan, peer, msg, key);
783
784 /* Ignore unencrypted key data */
785 if (!ret && key_data_len > 0 &&
786 (info & WPA_KEY_INFO_ENCR_KEY_DATA))
787 ret = nan_sec_rx_key_data(nan, peer,
788 ndp_sec->r_capab, pos,
789 key_data_len);
790 break;
791 default:
792 wpa_printf(MSG_DEBUG, "NAN: SEC: Invalid frame OUI subtype");
793 return -1;
794 }
795
796 if (ret)
797 return ret;
798
799 instance_id = shared_key_desc->publish_id;
800 if (ndp_sec->i_instance_id && instance_id &&
801 ndp_sec->i_instance_id != instance_id) {
802 wpa_printf(MSG_DEBUG,
803 "NAN: SEC: Mismatch instance ID in shared key descriptor");
804 return -1;
805 }
806
807 return 0;
808 }
809
810
811 /*
812 * nan_sec_add_m1_attrs - Add security attributes to NAN message 1
813 * @nan: NAN module context from nan_init()
814 * @peer: Peer which is the recipient of the message
815 * @buf: Buffer to which the attribute should be added
816 * Returns: 0 on success, negative on failure
817 *
818 * In addition to building the attributes, the function also initializes the
819 * security context for the NDP security exchange. Assumes that the following
820 * are already set:
821 * - initiator CSID
822 * - PMK
823 * - NDP puslish ID
824 * - initiator address
825 * - peer_nmi
826 */
nan_sec_add_m1_attrs(struct nan_data * nan,struct nan_peer * peer,struct wpabuf * buf)827 static int nan_sec_add_m1_attrs(struct nan_data *nan, struct nan_peer *peer,
828 struct wpabuf *buf)
829 {
830 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
831 struct wpa_eapol_key *key;
832 struct nan_cipher_suite cs[2];
833 size_t cs_len = 1;
834 u16 info;
835 size_t key_len = sizeof(struct wpa_eapol_key) + 2;
836 int ret;
837
838 if (NAN_CS_IS_128(ndp_sec->i_csid))
839 key_len += NAN_KEY_MIC_LEN;
840 else if (NAN_CS_IS_256(ndp_sec->i_csid))
841 key_len += NAN_KEY_MIC_24_LEN;
842 else
843 return -1;
844
845 /* Initialize the initiator security state */
846 if (os_get_random(ndp_sec->i_nonce, sizeof(ndp_sec->i_nonce)) < 0)
847 return -1;
848 ndp_sec->i_capab = nan->cfg->security_capab;
849 ndp_sec->i_instance_id = peer->ndp_setup.publish_inst_id;
850
851 /* Compute the PMKID */
852 ret = nan_crypto_calc_pmkid(ndp_sec->pmk,
853 nan->cfg->nmi_addr,
854 peer->nmi_addr,
855 peer->ndp_setup.service_id,
856 ndp_sec->i_csid, ndp_sec->i_pmkid);
857 if (ret) {
858 wpa_printf(MSG_DEBUG, "NAN: SEC: Failed to compute PMKID (m1)");
859 return ret;
860 }
861
862 /* Cipher suite information */
863 cs[0].csid = ndp_sec->i_csid;
864 cs[0].instance_id = ndp_sec->i_instance_id;
865
866 if (ndp_sec->local_gtk.csid != NAN_CS_NONE) {
867 cs[1].csid = ndp_sec->local_gtk.csid;
868 cs[1].instance_id = ndp_sec->i_instance_id;
869 cs_len++;
870 }
871
872 nan_add_csia(buf, ndp_sec->i_capab, cs_len, cs);
873
874 /* Security context information */
875 wpabuf_put_u8(buf, NAN_ATTR_SCIA);
876 wpabuf_put_le16(buf, sizeof(struct nan_sec_ctxt) + PMKID_LEN);
877
878 wpabuf_put_le16(buf, PMKID_LEN);
879 wpabuf_put_u8(buf, NAN_SEC_CTX_TYPE_ND_PMKID);
880 wpabuf_put_u8(buf, ndp_sec->i_instance_id);
881 wpabuf_put_data(buf, ndp_sec->i_pmkid, PMKID_LEN);
882
883 /* Shared key descriptor */
884 wpabuf_put_u8(buf, NAN_ATTR_SHARED_KEY_DESCR);
885 wpabuf_put_le16(buf, sizeof(struct nan_shared_key) + key_len);
886 wpabuf_put_u8(buf, ndp_sec->i_instance_id);
887
888 key = (struct wpa_eapol_key *) wpabuf_put(buf, key_len);
889 os_memset(key, 0, key_len);
890
891 key->type = NAN_KEY_DESC;
892 info = WPA_KEY_INFO_TYPE_AKM_DEFINED | WPA_KEY_INFO_KEY_TYPE |
893 WPA_KEY_INFO_ACK;
894 WPA_PUT_BE16(key->key_info, info);
895
896 /* Copy the initiator nonce */
897 os_memcpy(key->key_nonce, ndp_sec->i_nonce, WPA_NONCE_LEN);
898
899 /* Key length is zero (it can be deduced from the cipher suite) */
900
901 /* Initialize replay counter */
902 WPA_PUT_BE64(ndp_sec->replaycnt, 1ULL);
903 os_memcpy(key->replay_counter, ndp_sec->replaycnt,
904 sizeof(key->replay_counter));
905 ndp_sec->replaycnt_ok = true;
906
907 ndp_sec->valid = true;
908 return 0;
909 }
910
911
912 /*
913 * nan_sec_add_m2_attrs - Add security attributes to NAN message 2
914 * @nan: NAN module context from nan_init()
915 * @peer: Peer which is the recipient of the message
916 * @buf: Buffer to which the attribute should be added
917 * Returns: 0 on success, negative on failure
918 */
nan_sec_add_m2_attrs(struct nan_data * nan,struct nan_peer * peer,struct wpabuf * buf)919 static int nan_sec_add_m2_attrs(struct nan_data *nan, struct nan_peer *peer,
920 struct wpabuf *buf)
921 {
922 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
923 struct wpa_eapol_key *key;
924 struct nan_cipher_suite cs[2];
925 size_t cs_len = 1;
926
927 u16 info;
928 size_t key_len;
929
930 key_len = sizeof(struct wpa_eapol_key) + 2;
931 if (NAN_CS_IS_128(ndp_sec->i_csid))
932 key_len += NAN_KEY_MIC_LEN;
933 else if (NAN_CS_IS_256(ndp_sec->i_csid))
934 key_len += NAN_KEY_MIC_24_LEN;
935 else
936 return -1;
937
938 /* Cipher suite information */
939 cs[0].csid = ndp_sec->r_csid;
940 cs[0].instance_id = ndp_sec->r_instance_id;
941
942 if (ndp_sec->local_gtk.csid != NAN_CS_NONE) {
943 cs[1].csid = ndp_sec->local_gtk.csid;
944 cs[1].instance_id = ndp_sec->r_instance_id;
945 cs_len++;
946 }
947 nan_add_csia(buf, ndp_sec->r_capab, cs_len, cs);
948
949 /* Security context information */
950 wpabuf_put_u8(buf, NAN_ATTR_SCIA);
951 wpabuf_put_le16(buf, sizeof(struct nan_sec_ctxt) + PMKID_LEN);
952
953 wpabuf_put_le16(buf, PMKID_LEN);
954 wpabuf_put_u8(buf, NAN_SEC_CTX_TYPE_ND_PMKID);
955 wpabuf_put_u8(buf, ndp_sec->r_instance_id);
956 wpabuf_put_data(buf, ndp_sec->r_pmkid, PMKID_LEN);
957
958 if (peer->ndp_setup.status == NAN_NDP_STATUS_REJECTED)
959 return 0;
960
961 /* Shared key descriptor */
962 wpabuf_put_u8(buf, NAN_ATTR_SHARED_KEY_DESCR);
963 wpabuf_put_le16(buf, sizeof(struct nan_shared_key) + key_len);
964 wpabuf_put_u8(buf, ndp_sec->r_instance_id);
965
966 key = (struct wpa_eapol_key *) wpabuf_put(buf, key_len);
967 os_memset(key, 0, key_len);
968
969 key->type = NAN_KEY_DESC;
970 info = WPA_KEY_INFO_TYPE_AKM_DEFINED | WPA_KEY_INFO_KEY_TYPE |
971 WPA_KEY_INFO_MIC;
972 WPA_PUT_BE16(key->key_info, info);
973
974 /* Copy the responders's nonce */
975 os_memcpy(key->key_nonce, ndp_sec->r_nonce, WPA_NONCE_LEN);
976
977 /*
978 * Key length is zero (it can be deduced from the cipher suite).
979 * No additional data is added.
980 */
981
982 /* Copy replay counter */
983 os_memcpy(key->replay_counter, ndp_sec->replaycnt,
984 sizeof(key->replay_counter));
985 ndp_sec->replaycnt_ok = true;
986
987 return 0;
988 }
989
990
nan_sec_igtk_kde(struct nan_data * nan,struct wpabuf * buf)991 static int nan_sec_igtk_kde(struct nan_data *nan, struct wpabuf *buf)
992 {
993 u8 tsc[RSN_PN_LEN];
994
995 if (nan->cfg->get_seqnum(nan->cfg->cb_ctx, nan->igtk_id, tsc,
996 NULL) < 0) {
997 wpa_printf(MSG_INFO, "NAN: Failed to get IGTK seqnum");
998 return -1;
999 }
1000
1001 nan_add_kde_hdr(buf, RSN_KEY_DATA_IGTK,
1002 WPA_IGTK_KDE_PREFIX_LEN + nan->igtk.igtk_len);
1003 wpabuf_put_le16(buf, nan->igtk_id);
1004 wpabuf_put_data(buf, tsc, RSN_PN_LEN);
1005 wpabuf_put_data(buf, nan->igtk.igtk, nan->igtk.igtk_len);
1006 return 0;
1007 }
1008
1009
nan_sec_bigtk_kde(struct nan_data * nan,struct nan_ndp_sec * ndp_sec,struct wpabuf * buf)1010 static int nan_sec_bigtk_kde(struct nan_data *nan, struct nan_ndp_sec *ndp_sec,
1011 struct wpabuf *buf)
1012 {
1013 u8 tsc[RSN_PN_LEN];
1014
1015 if (((ndp_sec->i_capab & NAN_CS_INFO_CAPA_GTK_SUPP_MASK) >>
1016 NAN_CS_INFO_CAPA_GTK_SUPP_POS) != NAN_CS_INFO_CAPA_GTK_SUPP_ALL) {
1017 wpa_printf(MSG_DEBUG,
1018 "NAN: BIGTK not supported by initiator");
1019 return 0;
1020 }
1021
1022 if (((ndp_sec->r_capab & NAN_CS_INFO_CAPA_GTK_SUPP_MASK) >>
1023 NAN_CS_INFO_CAPA_GTK_SUPP_POS) != NAN_CS_INFO_CAPA_GTK_SUPP_ALL) {
1024 wpa_printf(MSG_DEBUG,
1025 "NAN: BIGTK not supported by responder");
1026 return 0;
1027 }
1028
1029 if (nan->cfg->get_seqnum(nan->cfg->cb_ctx, nan->bigtk_id, tsc,
1030 NULL) < 0) {
1031 wpa_printf(MSG_DEBUG, "NAN: Failed to get BIGTK seqnum");
1032 return -1;
1033 }
1034
1035 nan_add_kde_hdr(buf, RSN_KEY_DATA_BIGTK,
1036 WPA_BIGTK_KDE_PREFIX_LEN + nan->bigtk.bigtk_len);
1037 wpabuf_put_le16(buf, nan->bigtk_id);
1038 wpabuf_put_data(buf, tsc, sizeof(tsc));
1039 wpabuf_put_data(buf, nan->bigtk.bigtk, nan->bigtk.bigtk_len);
1040 return 0;
1041 }
1042
1043
nan_sec_gtk_kde(struct nan_data * nan,struct wpabuf * buf,struct nan_ndp_sec * ndp_sec)1044 static int nan_sec_gtk_kde(struct nan_data *nan, struct wpabuf *buf,
1045 struct nan_ndp_sec *ndp_sec)
1046 {
1047 if (!ndp_sec->local_gtk.gtk.gtk_len)
1048 return 0;
1049
1050 if (ndp_sec->local_gtk.id > 3) {
1051 wpa_printf(MSG_DEBUG, "NAN: Invalid GTK Key ID %u",
1052 ndp_sec->local_gtk.id);
1053 return -1;
1054 }
1055
1056 nan_add_kde_hdr(buf, RSN_KEY_DATA_GROUPKEY,
1057 WPA_GTK_KDE_PREFIX_LEN +
1058 ndp_sec->local_gtk.gtk.gtk_len);
1059 wpabuf_put_u8(buf, ndp_sec->local_gtk.id);
1060 wpabuf_put_u8(buf, 0);
1061 wpabuf_put_data(buf, ndp_sec->local_gtk.gtk.gtk,
1062 ndp_sec->local_gtk.gtk.gtk_len);
1063
1064 return 0;
1065 }
1066
1067
nan_sec_igtk_supported(struct nan_ndp_sec * ndp_sec)1068 static bool nan_sec_igtk_supported(struct nan_ndp_sec *ndp_sec)
1069 {
1070 return ((ndp_sec->i_capab & NAN_CS_INFO_CAPA_GTK_SUPP_MASK) >>
1071 NAN_CS_INFO_CAPA_GTK_SUPP_POS) !=
1072 NAN_CS_INFO_CAPA_GTK_SUPP_NONE &&
1073 ((ndp_sec->r_capab & NAN_CS_INFO_CAPA_GTK_SUPP_MASK) >>
1074 NAN_CS_INFO_CAPA_GTK_SUPP_POS) !=
1075 NAN_CS_INFO_CAPA_GTK_SUPP_NONE;
1076 }
1077
1078
1079 #define NAN_KDES_MAX_LEN \
1080 (KDE_HDR_LEN + sizeof(struct wpa_igtk_kde) + KDE_HDR_LEN + \
1081 sizeof(struct wpa_bigtk_kde) + KDE_HDR_LEN + \
1082 sizeof(struct wpa_gtk_kde))
1083
nan_sec_add_kdes(struct nan_data * nan,struct nan_ndp_sec * ndp_sec,struct wpabuf * buf)1084 static int nan_sec_add_kdes(struct nan_data *nan, struct nan_ndp_sec *ndp_sec,
1085 struct wpabuf *buf)
1086 {
1087 struct wpabuf *kde_buf;
1088 struct wpabuf *enc_kde;
1089 int ret = -1;
1090
1091 if (!nan_sec_igtk_supported(ndp_sec) &&
1092 ndp_sec->local_gtk.gtk.gtk_len == 0) {
1093 wpa_printf(MSG_DEBUG,
1094 "NAN: GTK/IGTK not supported for this NDP");
1095 return 0;
1096 }
1097
1098 if (!ndp_sec->ptk.kek_len) {
1099 wpa_printf(MSG_DEBUG,
1100 "NAN: SEC: No KEK available to encrypt KDEs");
1101 return -1;
1102 }
1103
1104 kde_buf = wpabuf_alloc(NAN_KDES_MAX_LEN);
1105 if (!kde_buf) {
1106 wpa_printf(MSG_INFO, "NAN: SEC: Failed to allocate KDE buffer");
1107 return -1;
1108 }
1109
1110 if (nan_sec_igtk_kde(nan, kde_buf) < 0)
1111 goto fail;
1112
1113 if (nan_sec_bigtk_kde(nan, ndp_sec, kde_buf) < 0)
1114 goto fail;
1115
1116 if (nan_sec_gtk_kde(nan, kde_buf, ndp_sec) < 0)
1117 goto fail;
1118
1119 enc_kde = nan_crypto_encrypt_key_data(kde_buf, ndp_sec->ptk.kek,
1120 ndp_sec->ptk.kek_len);
1121 if (!enc_kde) {
1122 wpa_printf(MSG_INFO, "NAN: SEC: Failed to encrypt KDEs");
1123 goto fail;
1124 }
1125
1126 wpabuf_put_buf(buf, enc_kde);
1127 ret = wpabuf_len(enc_kde);
1128 wpabuf_free(enc_kde);
1129 fail:
1130 wpabuf_clear_free(kde_buf);
1131 return ret;
1132 }
1133
1134
1135 /*
1136 * nan_sec_add_key_attrs - Add security key attributes to NAN message
1137 * @nan: NAN module context from nan_init()
1138 * @peer: Peer which is the recipient of the message
1139 * @buf: Buffer to which the attribute should be added
1140 * @instance_id: Instance ID to use
1141 * @nonce: Nonce to use
1142 * @is_ack: Whether to include ACK flag in key info
1143 * Returns: 0 on success, negative on failure
1144 */
nan_sec_add_key_attrs(struct nan_data * nan,struct nan_peer * peer,struct wpabuf * buf,u8 instance_id,const u8 * nonce,bool is_ack)1145 static int nan_sec_add_key_attrs(struct nan_data *nan, struct nan_peer *peer,
1146 struct wpabuf *buf, u8 instance_id,
1147 const u8 *nonce, bool is_ack)
1148 {
1149 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
1150 struct wpa_eapol_key *key;
1151 u16 info;
1152 size_t key_len = sizeof(struct wpa_eapol_key);
1153 u8 *key_len_pos;
1154 int kde_len;
1155 u8 *key_data_len_pos;
1156
1157 if (NAN_CS_IS_128(ndp_sec->i_csid))
1158 key_len += NAN_KEY_MIC_LEN;
1159 else if (NAN_CS_IS_256(ndp_sec->i_csid))
1160 key_len += NAN_KEY_MIC_24_LEN;
1161 else
1162 return -1;
1163
1164 /* Shared key descriptor */
1165 wpabuf_put_u8(buf, NAN_ATTR_SHARED_KEY_DESCR);
1166 key_len_pos = wpabuf_put(buf, 2);
1167 wpabuf_put_u8(buf, instance_id);
1168
1169 key = (struct wpa_eapol_key *) wpabuf_put(buf, key_len);
1170 os_memset(key, 0, key_len);
1171
1172 key->type = NAN_KEY_DESC;
1173
1174 os_memcpy(key->key_nonce, nonce, WPA_NONCE_LEN);
1175
1176 /*
1177 * Copy replay counter. It was already incremented while processing m2
1178 * so no need to increment it again.
1179 */
1180 os_memcpy(key->replay_counter, ndp_sec->replaycnt,
1181 sizeof(key->replay_counter));
1182
1183 /* Add KDEs to the key data and set key length accordingly */
1184 key_data_len_pos = wpabuf_put(buf, 2);
1185
1186 kde_len = nan_sec_add_kdes(nan, ndp_sec, buf);
1187 if (kde_len < 0) {
1188 wpa_printf(MSG_DEBUG,
1189 "NAN: SEC: Failed to add KDEs to m3");
1190 return -1;
1191 }
1192
1193 /* When GTK is present, the Key RSC field is set to the GTK RSC */
1194 if (ndp_sec->local_gtk.gtk.gtk_len) {
1195 const u8 *local_ndi;
1196 struct nan_ndp *pndp = peer->ndp_setup.ndp;
1197
1198 if (pndp->initiator)
1199 local_ndi = pndp->init_ndi;
1200 else
1201 local_ndi = pndp->resp_ndi;
1202
1203 if (nan->cfg->get_seqnum(nan->cfg->cb_ctx,
1204 ndp_sec->local_gtk.id, key->key_rsc,
1205 local_ndi) < 0) {
1206 wpa_printf(MSG_DEBUG,
1207 "NAN: SEC: Failed to get GTK seqnum");
1208 return -1;
1209 }
1210 }
1211
1212 info = WPA_KEY_INFO_TYPE_AKM_DEFINED | WPA_KEY_INFO_KEY_TYPE |
1213 WPA_KEY_INFO_MIC | WPA_KEY_INFO_INSTALL | WPA_KEY_INFO_SECURE;
1214 if (is_ack)
1215 info |= WPA_KEY_INFO_ACK;
1216 if (kde_len)
1217 info |= WPA_KEY_INFO_ENCR_KEY_DATA;
1218
1219 WPA_PUT_BE16(key->key_info, info);
1220
1221 WPA_PUT_LE16(key_len_pos,
1222 sizeof(struct nan_shared_key) + key_len + 2 + kde_len);
1223 WPA_PUT_BE16(key_data_len_pos, kde_len);
1224 return 0;
1225 }
1226
1227
1228 /*
1229 * nan_sec_add_m3_attrs - Add security attributes to NAN message 3
1230 * @nan: NAN module context from nan_init()
1231 * @peer: Peer which is the recipient of the message
1232 * @buf: Buffer to which the attribute should be added
1233 * Returns: 0 on success, negative on failure
1234 */
nan_sec_add_m3_attrs(struct nan_data * nan,struct nan_peer * peer,struct wpabuf * buf)1235 static int nan_sec_add_m3_attrs(struct nan_data *nan, struct nan_peer *peer,
1236 struct wpabuf *buf)
1237 {
1238 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
1239
1240 return nan_sec_add_key_attrs(nan, peer, buf, ndp_sec->i_instance_id,
1241 ndp_sec->i_nonce, true);
1242 }
1243
1244
1245 /*
1246 * nan_sec_add_m4_attrs - Add security attributes to NAN message 4
1247 * @nan: NAN module context from nan_init()
1248 * @peer: Peer which is the recipient of the message
1249 * @buf: Buffer to which the attribute should be added
1250 * Returns: 0 on success, negative on failure
1251 */
nan_sec_add_m4_attrs(struct nan_data * nan,struct nan_peer * peer,struct wpabuf * buf)1252 static int nan_sec_add_m4_attrs(struct nan_data *nan, struct nan_peer *peer,
1253 struct wpabuf *buf)
1254 {
1255 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
1256
1257 return nan_sec_add_key_attrs(nan, peer, buf, ndp_sec->r_instance_id,
1258 ndp_sec->r_nonce, false);
1259 }
1260
1261
1262 /**
1263 * nan_sec_add_attrs - Add security attributes to NAN message
1264 * @nan: NAN module context from nan_init()
1265 * @peer: Peer which is the recipient of the message
1266 * @subtype: Frame subtype
1267 * @buf: Buffer to which the attribute should be added
1268 * Returns: 0 on success, negative on failure
1269 */
nan_sec_add_attrs(struct nan_data * nan,struct nan_peer * peer,enum nan_subtype subtype,struct wpabuf * buf)1270 int nan_sec_add_attrs(struct nan_data *nan, struct nan_peer *peer,
1271 enum nan_subtype subtype, struct wpabuf *buf)
1272 {
1273 /* NDP establishment is not in progress */
1274 if (!peer->ndp_setup.ndp)
1275 return 0;
1276
1277 wpa_printf(MSG_DEBUG, "NAN: SEC: Add security attributes");
1278 nan_sec_dump(nan, peer);
1279
1280 /* No security configuration */
1281 if (!NAN_CS_IS_VALID_NDP(peer->ndp_setup.sec.i_csid))
1282 return 0;
1283
1284 switch (subtype) {
1285 case NAN_SUBTYPE_DATA_PATH_REQUEST:
1286 return nan_sec_add_m1_attrs(nan, peer, buf);
1287 case NAN_SUBTYPE_DATA_PATH_RESPONSE:
1288 return nan_sec_add_m2_attrs(nan, peer, buf);
1289 case NAN_SUBTYPE_DATA_PATH_CONFIRM:
1290 return nan_sec_add_m3_attrs(nan, peer, buf);
1291 case NAN_SUBTYPE_DATA_PATH_KEY_INSTALL:
1292 return nan_sec_add_m4_attrs(nan, peer, buf);
1293 case NAN_SUBTYPE_DATA_PATH_TERMINATION:
1294 break;
1295 default:
1296 return -1;
1297 }
1298
1299 return 0;
1300 }
1301
1302
1303 /**
1304 * nan_sec_init_resp - Initialize security context for responder
1305 * @nan: NAN module context from nan_init()
1306 * @peer: Peer with whom the NDP is being established
1307 * Returns: 0 on success, negative on failure
1308 *
1309 * The function initializes the security context for the NDP security
1310 * exchange for the responder. Assumes that the following re already set:
1311 * - Initiator CSID
1312 * - Responder CSID
1313 * - PMK
1314 * - NDP publish ID
1315 * - Initiator address
1316 * - Responder address
1317 */
nan_sec_init_resp(struct nan_data * nan,struct nan_peer * peer)1318 int nan_sec_init_resp(struct nan_data *nan, struct nan_peer *peer)
1319 {
1320 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
1321 struct nan_ndp *ndp = peer->ndp_setup.ndp;
1322 int ret;
1323
1324 if (ndp_sec->i_csid != ndp_sec->r_csid)
1325 return -1;
1326
1327 /* Initialize the responder's security state */
1328 if (os_get_random(ndp_sec->r_nonce, sizeof(ndp_sec->r_nonce)) < 0)
1329 return -1;
1330 ndp_sec->r_capab = nan->cfg->security_capab;
1331 ndp_sec->r_instance_id = peer->ndp_setup.publish_inst_id;
1332
1333 if (ndp_sec->i_instance_id != ndp_sec->r_instance_id) {
1334 wpa_printf(MSG_DEBUG,
1335 "NAN: SEC: Service instance IDs are different (m2)");
1336 return -1;
1337 }
1338
1339 /* Compute the PMKID */
1340 ret = nan_crypto_calc_pmkid(ndp_sec->pmk, peer->nmi_addr,
1341 nan->cfg->nmi_addr,
1342 peer->ndp_setup.service_id,
1343 ndp_sec->r_csid, ndp_sec->r_pmkid);
1344 if (ret) {
1345 wpa_printf(MSG_DEBUG, "NAN: SEC: Failed to compute PMKID (m2)");
1346 return -1;
1347 }
1348
1349 /* Sanity check */
1350 if (os_memcmp(ndp_sec->i_pmkid, ndp_sec->r_pmkid, PMKID_LEN) != 0) {
1351 wpa_printf(MSG_DEBUG,
1352 "NAN: SEC: m2: Local PMKID differs from remote");
1353 return -1;
1354 }
1355
1356 /* PTK should be derived using the NDI address */
1357 ret = nan_crypto_pmk_to_ptk(ndp_sec->pmk,
1358 ndp->init_ndi, ndp->resp_ndi,
1359 ndp_sec->i_nonce, ndp_sec->r_nonce,
1360 &ndp_sec->ptk, ndp_sec->i_csid);
1361
1362 wpa_printf(MSG_DEBUG,
1363 "NAN: SEC: Derived PTK for responder (m2). ret=%d",
1364 ret);
1365
1366 return ret;
1367 }
1368
1369
1370 /*
1371 * nan_sec_pre_tx - Handle security aspects before sending a NDP NAF
1372 * @nan: NAN module context from nan_init()
1373 * @peer: Peer with whom the NDP is being established
1374 * @buf: Buffer holding the NAF body (not including the IEEE 802.11 header)
1375 * Returns: 0 on success, and a negative error value on failure.
1376 *
1377 * Note: The NAF content should not be altered after the function returns,
1378 * as the function might have signed the frame body, i.e., updated the MIC
1379 * field.
1380 */
nan_sec_pre_tx(struct nan_data * nan,struct nan_peer * peer,struct wpabuf * buf)1381 int nan_sec_pre_tx(struct nan_data *nan, struct nan_peer *peer,
1382 struct wpabuf *buf)
1383 {
1384 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
1385 struct nan_attrs attrs;
1386 struct nan_shared_key *shared_key_desc;
1387 struct wpa_eapol_key *key;
1388 u8 *data, *tmp, *mic_ptr;
1389 size_t len;
1390 u8 subtype;
1391 int ret;
1392
1393 /* NDP establishment is not in progress */
1394 if (!peer->ndp_setup.ndp ||
1395 peer->ndp_setup.status == NAN_NDP_STATUS_REJECTED)
1396 return 0;
1397
1398 /* No security configuration */
1399 if (!ndp_sec->valid)
1400 return 0;
1401
1402 wpa_printf(MSG_DEBUG, "NAN: SEC: NDP setup state=%u (pre Tx)",
1403 peer->ndp_setup.state);
1404
1405 data = wpabuf_mhead_u8(buf);
1406 len = wpabuf_len(buf);
1407
1408 if (len < 7) {
1409 wpa_printf(MSG_DEBUG,
1410 "NAN: SEC: Buffer is too short=%zu (pre Tx)", len);
1411 return -1;
1412 }
1413
1414 /* The subtype is the 7th octet. See nan_action_build_header() */
1415 subtype = data[6];
1416
1417 wpa_printf(MSG_DEBUG, "NAN: SEC: subtype=0x%x (pre Tx)", subtype);
1418
1419 switch (subtype) {
1420 case NAN_SUBTYPE_DATA_PATH_REQUEST:
1421 case NAN_SUBTYPE_DATA_PATH_RESPONSE:
1422 case NAN_SUBTYPE_DATA_PATH_CONFIRM:
1423 case NAN_SUBTYPE_DATA_PATH_KEY_INSTALL:
1424 break;
1425 default:
1426 return -1;
1427 }
1428
1429 /*
1430 * First get a pointer to the shared key descriptor attribute and
1431 * validate it.
1432 */
1433 ret = nan_parse_attrs(nan, data + 7, len - 7, &attrs);
1434 if (ret)
1435 return ret;
1436
1437 if (!attrs.shared_key_desc ||
1438 attrs.shared_key_desc_len <
1439 sizeof(*shared_key_desc) + (sizeof(*key) + 2 + NAN_KEY_MIC_LEN)) {
1440 wpa_printf(MSG_DEBUG,
1441 "NAN: SEC: Invalid shared key descriptor attribute");
1442 return -1;
1443 }
1444
1445 shared_key_desc = (struct nan_shared_key *) attrs.shared_key_desc;
1446 key = (struct wpa_eapol_key *) shared_key_desc->key;
1447 mic_ptr = (u8 *) (key + 1);
1448 nan_attrs_clear(nan, &attrs);
1449
1450 switch (subtype) {
1451 case NAN_SUBTYPE_DATA_PATH_REQUEST:
1452 if (peer->ndp_setup.state != NAN_NDP_STATE_START)
1453 wpa_printf(MSG_DEBUG,
1454 "NAN: SEC: Request invalid state (pre Tx)");
1455
1456 /* Save the authentication token for m3. */
1457 ret = nan_crypto_calc_auth_token(ndp_sec->i_csid, data, len,
1458 ndp_sec->auth_token);
1459 break;
1460 case NAN_SUBTYPE_DATA_PATH_RESPONSE:
1461 if (peer->ndp_setup.state != NAN_NDP_STATE_REQ_RECV)
1462 wpa_printf(MSG_DEBUG,
1463 "NAN: SEC: Pre Tx response invalid state");
1464
1465 /* Calculate MIC over the frame body. */
1466 ret = nan_crypto_key_mic(data, len,
1467 ndp_sec->ptk.kck,
1468 ndp_sec->ptk.kck_len,
1469 ndp_sec->i_csid, mic_ptr);
1470 break;
1471 case NAN_SUBTYPE_DATA_PATH_CONFIRM:
1472 if (peer->ndp_setup.state != NAN_NDP_STATE_RES_RECV)
1473 wpa_printf(MSG_DEBUG,
1474 "NAN: SEC: Confirm invalid state (pre Tx)");
1475
1476 /*
1477 * Calculate MIC over the frame body concatenated with
1478 * authentication token.
1479 */
1480 tmp = os_malloc(len + NAN_AUTH_TOKEN_LEN);
1481 if (!tmp)
1482 return -1;
1483
1484 os_memcpy(tmp, ndp_sec->auth_token, NAN_AUTH_TOKEN_LEN);
1485 os_memcpy(tmp + NAN_AUTH_TOKEN_LEN, data, len);
1486
1487 ret = nan_crypto_key_mic(tmp, len + NAN_AUTH_TOKEN_LEN,
1488 ndp_sec->ptk.kck,
1489 ndp_sec->ptk.kck_len,
1490 ndp_sec->i_csid, mic_ptr);
1491 os_free(tmp);
1492 break;
1493 case NAN_SUBTYPE_DATA_PATH_KEY_INSTALL:
1494 if (peer->ndp_setup.state != NAN_NDP_STATE_CON_RECV)
1495 wpa_printf(MSG_DEBUG,
1496 "NAN: SEC: Key install invalid state (pre Tx)");
1497
1498 /* Calculate MIC over the frame body */
1499 ret = nan_crypto_key_mic(data, len,
1500 ndp_sec->ptk.kck,
1501 ndp_sec->ptk.kck_len,
1502 ndp_sec->i_csid, mic_ptr);
1503 break;
1504 }
1505
1506 return ret;
1507 }
1508
1509
1510 /**
1511 * nan_sec_get_strength - Get security strength level for a cipher suite
1512 * @csid: Cipher suite ID
1513 * @pairing_akmp: AKMP used for pairing (to distinguish SAE vs opportunistic)
1514 * Returns: Security strength level (higher = stronger), 0 for no security
1515 *
1516 * Per Wi-Fi Aware Specification v4.0 section 7.4, security strength ordering
1517 * (from highest to lowest):
1518 * - CSID 8 (NCS-PK-PASN-256) using a password (SAE)
1519 * - CSID 7 (NCS-PK-PASN-128) using a password (SAE)
1520 * - CSID 2 (NCS-SK-256) using a PSK/Passphrase
1521 * - CSID 1 (NCS-SK-128) using a PSK/Passphrase
1522 * - CSID 8 (NCS-PK-PASN-256) using opportunistic bootstrapping (PASN)
1523 * - CSID 7 (NCS-PK-PASN-128) using opportunistic bootstrapping (PASN)
1524 * - No security
1525 */
nan_sec_get_strength(enum nan_cipher_suite_id csid,int pairing_akmp)1526 static int nan_sec_get_strength(enum nan_cipher_suite_id csid, int pairing_akmp)
1527 {
1528 bool is_opportunistic = pairing_akmp == WPA_KEY_MGMT_PASN;
1529
1530 switch (csid) {
1531 case NAN_CS_PK_PASN_256:
1532 return is_opportunistic ? 2 : 6;
1533 case NAN_CS_PK_PASN_128:
1534 return is_opportunistic ? 1 : 5;
1535 case NAN_CS_SK_GCM_256:
1536 return 4;
1537 case NAN_CS_SK_CCM_128:
1538 return 3;
1539 case NAN_CS_NONE:
1540 default:
1541 return 0;
1542 }
1543 }
1544
1545
1546 /*
1547 * nan_sec_ndp_store_keys - Store the NDP keys after successful NDP
1548 * establishment
1549 *
1550 * @nan: NAN module context from nan_init()
1551 * @peer: NAN peer for which the NDP was established
1552 * @peer_ndi: NDI address of the peer for the NDP that was just established
1553 * @local_ndi: Local NDI address for the NDP that was just established
1554 *
1555 * Returns: true if keys were stored, false otherwise
1556 */
nan_sec_ndp_store_keys(struct nan_data * nan,struct nan_peer * peer,const u8 * peer_ndi,const u8 * local_ndi)1557 bool nan_sec_ndp_store_keys(struct nan_data *nan, struct nan_peer *peer,
1558 const u8 *peer_ndi, const u8 *local_ndi)
1559 {
1560 struct nan_ndp *ndp = peer->ndp_setup.ndp;
1561 struct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;
1562 struct nan_peer_sec_info_entry *cur, *next;
1563 int new_strength, cur_strength;
1564 int new_akmp = 0;
1565
1566 if (!ndp || !ndp_sec->valid || !ndp_sec->i_csid ||
1567 peer->ndp_setup.state != NAN_NDP_STATE_DONE)
1568 return false;
1569
1570 if (!NAN_CS_IS_VALID_NDP(ndp_sec->i_csid))
1571 return false;
1572
1573 /* Get AKMP for the new security association */
1574 if (peer->pairing.flags & NAN_PAIRING_FLAG_PAIRED)
1575 new_akmp = peer->pairing.pairing_akmp;
1576
1577 new_strength = nan_sec_get_strength(ndp_sec->i_csid, new_akmp);
1578
1579 dl_list_for_each_safe(cur, next, &peer->info.sec,
1580 struct nan_peer_sec_info_entry, list) {
1581 if (!ether_addr_equal(peer_ndi, cur->peer_ndi) ||
1582 !ether_addr_equal(local_ndi, cur->local_ndi))
1583 continue;
1584
1585 /*
1586 * Per Wi-Fi Aware Specification v4.0 section 7.4:
1587 * The security configuration should be updated if the new
1588 * security strength is same or greater than the existing SA.
1589 * Otherwise, the existing higher-strength SA continues to be
1590 * used and any key material derived for the NDP setup shall be
1591 * discarded.
1592 */
1593 cur_strength = nan_sec_get_strength(cur->csid,
1594 cur->pairing_akmp);
1595
1596 wpa_printf(MSG_DEBUG,
1597 "NAN: SEC: Comparing strength: new=%d (csid=%u, akmp=0x%x) vs. cur=%d (csid=%u, akmp=0x%x)",
1598 new_strength, ndp_sec->i_csid, new_akmp,
1599 cur_strength, cur->csid, cur->pairing_akmp);
1600
1601 if (new_strength >= cur_strength)
1602 goto store;
1603
1604 wpa_printf(MSG_DEBUG,
1605 "NAN: SEC: New security weaker than existing, discarding keys");
1606 return false;
1607 }
1608
1609 cur = os_zalloc(sizeof(*cur));
1610 if (!cur) {
1611 wpa_printf(MSG_INFO,
1612 "NAN: SEC: Failed memory allocation for security info");
1613 return false;
1614 }
1615
1616 dl_list_add(&peer->info.sec, &cur->list);
1617 os_memcpy(cur->peer_ndi, peer_ndi, ETH_ALEN);
1618 os_memcpy(cur->local_ndi, local_ndi, ETH_ALEN);
1619
1620 store:
1621 wpa_printf(MSG_DEBUG, "NAN: SEC: Store security information");
1622
1623 cur->csid = ndp_sec->i_csid;
1624 if (peer->pairing.flags & NAN_PAIRING_FLAG_PAIRED)
1625 cur->pairing_akmp = peer->pairing.pairing_akmp;
1626 os_memcpy(cur->pmkid, ndp_sec->i_pmkid, PMKID_LEN);
1627 os_memcpy(cur->pmk, ndp_sec->pmk, PMK_LEN);
1628 os_memcpy(&cur->ptk, &ndp_sec->ptk, sizeof(cur->ptk));
1629
1630 return true;
1631 }
1632
1633
nan_sec_get_tk(struct nan_data * nan,struct nan_peer * peer,const u8 * peer_ndi,const u8 * local_ndi,u8 * tk,size_t * tk_len,enum nan_cipher_suite_id * csid)1634 int nan_sec_get_tk(struct nan_data *nan, struct nan_peer *peer,
1635 const u8 *peer_ndi, const u8 *local_ndi,
1636 u8 *tk, size_t *tk_len, enum nan_cipher_suite_id *csid)
1637 {
1638 struct nan_peer_sec_info_entry *cur;
1639
1640 dl_list_for_each(cur, &peer->info.sec,
1641 struct nan_peer_sec_info_entry, list) {
1642 if (!ether_addr_equal(peer_ndi, cur->peer_ndi) ||
1643 !ether_addr_equal(local_ndi, cur->local_ndi))
1644 continue;
1645
1646 os_memcpy(tk, &cur->ptk.tk, cur->ptk.tk_len);
1647 *tk_len = cur->ptk.tk_len;
1648 *csid = cur->csid;
1649 return 0;
1650 }
1651
1652 return -1;
1653 }
1654