xref: /freebsd/contrib/wpa/src/nan/nan_module_tests.c (revision 71e72c9e91c4b8007a4292e09669e8b549c29e97)
1 /*
2  * NAN NDP/NDL state machine testing
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 "utils/includes.h"
10 #include "utils/common.h"
11 #include "common/nan_defs.h"
12 #include "drivers/driver.h"
13 #include "nan_i.h"
14 #include "nan_module_tests.h"
15 #include "crypto/sha256.h"
16 #include "crypto/sha384.h"
17 #include "crypto/crypto.h"
18 
19 #define NAN_TEST_MAX_NAF_LEN     1024
20 #define NAN_TEST_MAX_PEERS       20
21 #define NAN_TEST_MAX_ACTIONS     30
22 #define NAN_TEST_MIN_SLOTS       12
23 #define NAN_TEST_MAX_LATENCY     3
24 #define NAN_TEST_PUBLISH_INST_ID 12
25 
26 static const u8 g_pub_nmi[] = { 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
27 static const u8 g_pub_ndi[] = { 0x00, 0xAA, 0xAA, 0x00, 0x00, 0x00 };
28 static const u8 g_sub_nmi[] = { 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB };
29 static const u8 g_sub_ndi[] = { 0x00, 0xBB, 0xBB, 0xBB, 0x00, 0x00 };
30 
31 /**
32  * struct nan_test_action - NAN test action context
33  * @list: Used for global actions list
34  * @dev: NAN device for which the action is intended
35  * @cb: Callback to be called for the action
36  * @ctx: Parameter for the callback function
37  *
38  * The test utility uses actions to handle asynchronous events between the
39  * devices and internally to the local device. When an event is triggered
40  * outside of the NAN module context, the event is wrapped by an action item and
41  * is processed asynchronously. Examples:
42  *
43  * NAF transmission: when a NAF is transmitted by a device, it is translated to
44  * 2 asynchronous actions: one action to indicate Tx status to the transmitting
45  * device and one to indicate an Rx frame to the peer device.
46  *
47  * NDP event: when an NDP event is fired by the NAN module, it is translated to
48  * an asynchronous action to the local device.
49  */
50 struct nan_test_action {
51 	struct dl_list list;
52 	struct nan_device *dev;
53 	int (*cb)(struct nan_device *dev, void *ctx);
54 	void *ctx;
55 };
56 
57 /**
58  * nan_test_tx_status_action - NAN test Tx status action context
59  * @data: Copy of the original NAF
60  * @acked: True iff the NAF was acked
61  * @dst: Destination of the NAF
62  */
63 struct nan_test_tx_status_action {
64 	const struct wpabuf *data;
65 	bool acked;
66 	u8 dst[ETH_ALEN];
67 };
68 
69 /**
70  * nan_test_ndp_notify - NAN test NDP notification handling
71  * @type: Notification type
72  * @ndp_id: NDP identifier
73  * @ssi: Service specific information
74  * @ssi_len: Length of service specific information
75  */
76 struct nan_test_ndp_notify {
77 	enum nan_test_ndp_notify_type type;
78 	struct nan_ndp_id ndp_id;
79 	const u8 *ssi;
80 	size_t ssi_len;
81 };
82 
83 /**
84  * nan_test_global - Global context for the NAN testing
85  * @devs: List of devices. See &struct nan_device.
86  * @actions: tracks the NAN actions
87  * @elems: Default HT/VHT/HE capabilities elements
88  */
89 struct nan_test_global {
90 	struct dl_list devs;
91 	struct dl_list actions;
92 	struct wpabuf *elems;
93 };
94 
95 #define DEV_NOT_INIT_ERR(_dev)                                        \
96 do {                                                                  \
97 	if (!(_dev) || !(_dev)->nan)  {                               \
98 		wpa_printf(MSG_ERROR,                                 \
99 			   "NAN: %s: device not initialized",         \
100 			   __func__);                                 \
101 		return -1;                                            \
102 	}                                                             \
103 } while (0)
104 
105 #define DEV_NOT_INIT_ERR_VOID(_dev)                                   \
106 do {                                                                  \
107 	if (!(_dev) || !(_dev)->nan)  {                               \
108 		wpa_printf(MSG_ERROR,                                 \
109 			   "NAN: %s: device not initialized",         \
110 			   __func__);                                 \
111 		return;                                               \
112 	}                                                             \
113 } while (0)
114 
115 
116 /**
117  * nan_test_global_init - Initialize NAN test global data structures
118  * @global: NAN test global data structure
119  */
nan_test_global_init(struct nan_test_global * global)120 static void nan_test_global_init(struct nan_test_global *global)
121 {
122 	u8 elems[] = {
123 		/* HT capabilities */
124 		0x2d, 0x1a, 0x7e, 0x10, 0x1b, 0xff, 0xff, 0x00,
125 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 		0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 		0x00, 0x00, 0x00, 0x00,
128 
129 		/* VHT capabilities */
130 		0xbf, 0x0c, 0xfa, 0x04, 0x80, 0x03, 0xaa, 0xaa,
131 		0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
132 
133 		/* HE capabilities */
134 		0xff, 0x1e, 0x23, 0x01, 0x78, 0xc8, 0x1a, 0x40,
135 		0x00, 0x1c, 0xbf, 0xce, 0x00, 0x00, 0x00, 0x00,
136 		0x00, 0x00, 0x00, 0x00, 0xfa, 0xff, 0xfa, 0xff,
137 		0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff,
138 	};
139 
140 	wpa_printf(MSG_INFO, "%s: Enter", __func__);
141 	os_memset(global, 0, sizeof(struct nan_test_global));
142 	dl_list_init(&global->devs);
143 	dl_list_init(&global->actions);
144 
145 	global->elems = wpabuf_alloc_copy(elems, sizeof(elems));
146 
147 	wpa_printf(MSG_INFO, "%s: Done\n", __func__);
148 }
149 
150 
151 /**
152  * nan_test_dev_deinit - De-initialize NAN device
153  * @dev: NAN device
154  */
nan_test_dev_deinit(struct nan_device * dev)155 static void nan_test_dev_deinit(struct nan_device *dev)
156 {
157 	DEV_NOT_INIT_ERR_VOID(dev);
158 
159 	os_free(dev->pot_avail);
160 	nan_stop(dev->nan);
161 	nan_deinit(dev->nan);
162 	os_memset(dev, 0, sizeof(struct nan_device));
163 }
164 
165 
166 /**
167  * nan_test_global_deinit - De-initialize NAN test global data structures
168  * @global: NAN test global data structure
169  */
nan_test_global_deinit(struct nan_test_global * global)170 static void nan_test_global_deinit(struct nan_test_global *global)
171 {
172 	struct nan_device *dev, *next;
173 	struct nan_test_action *action, *action_next;
174 
175 	wpa_printf(MSG_INFO, "%s: Enter", __func__);
176 
177 	dl_list_for_each_safe(dev, next, &global->devs, struct nan_device,
178 			      list) {
179 		dl_list_del(&dev->list);
180 		nan_test_dev_deinit(dev);
181 		os_free(dev);
182 	}
183 
184 	dl_list_for_each_safe(action, action_next, &global->actions,
185 			      struct nan_test_action, list) {
186 		dl_list_del(&dev->list);
187 		os_free(action->ctx);
188 		os_free(action);
189 	}
190 
191 	wpabuf_free(global->elems);
192 }
193 
194 
195 /**
196  * nan_test_add_action - Add a NAN test action to the list of actions
197  * @global: NAN test global data structure
198  * @dev: NAN device for which the action is intended
199  * @cb: Callback to be called for the action
200  * @ctx: Parameter for the callback function
201  * Returns: A pointer to the newly added action, or NULL on failure
202  */
203 static struct nan_test_action *
nan_test_add_action(struct nan_test_global * global,struct nan_device * dev,int (* cb)(struct nan_device * dev,void * ctx),void * ctx)204 nan_test_add_action(struct nan_test_global *global,
205 		    struct nan_device *dev,
206 		    int (*cb)(struct nan_device *dev, void *ctx),
207 		    void *ctx)
208 {
209 	struct nan_test_action *action;
210 
211 	action = os_malloc(sizeof(struct nan_test_action));
212 	if (!action) {
213 		wpa_printf(MSG_ERROR, "NAN Test: Failed to allocate action");
214 		return NULL;
215 	}
216 
217 	action->dev = dev;
218 	action->cb = cb;
219 	action->ctx = ctx;
220 
221 	dl_list_add_tail(&global->actions, &action->list);
222 	return action;
223 }
224 
225 
226 /**
227  * nan_test_run_actions - Iterate over all NAN test actions and execute them
228  * @global: NAN test global data structure
229  * Returns: 0 in success, -1 on error
230  *
231  * Runs as longs as there are actions to run. Exists where there are no more
232  * action to perform or on error.
233  */
nan_test_run_actions(struct nan_test_global * global)234 static int nan_test_run_actions(struct nan_test_global *global)
235 {
236 	u32 n_actions = 0;
237 
238 	wpa_printf(MSG_INFO, "%s: Running actions", __func__);
239 
240 	while (!dl_list_empty(&global->actions)) {
241 		struct nan_test_action *action =
242 			dl_list_first(&global->actions, struct nan_test_action,
243 				      list);
244 		int ret;
245 
246 		dl_list_del(&action->list);
247 
248 		if (++n_actions > NAN_TEST_MAX_ACTIONS) {
249 			wpa_printf(MSG_ERROR,
250 				   "NAN Test action: Too many actions executed");
251 			return -1;
252 		}
253 
254 		if (!action->cb || !action->dev) {
255 			wpa_printf(MSG_ERROR,
256 				   "NAN Test action: Invalid action");
257 			return -1;
258 		}
259 
260 		wpa_printf(MSG_INFO, "%s: ===> NAN Test action <===",
261 			   action->dev->name);
262 		ret = action->cb(action->dev, action->ctx);
263 
264 		/*
265 		 * The action context should be freed by the callback function
266 		 * that understands the content of the context and can properly
267 		 * handle it.
268 		 */
269 		os_free(action);
270 
271 		if (ret) {
272 			wpa_printf(MSG_ERROR, "NAN Test action: FAILED");
273 			return ret;
274 		}
275 	}
276 
277 	wpa_printf(MSG_INFO, "%s: Running actions done", __func__);
278 	return 0;
279 }
280 
281 
nan_test_start_cb(void * ctx,const struct nan_cluster_config * config)282 static int nan_test_start_cb(void *ctx, const struct nan_cluster_config *config)
283 {
284 	struct nan_device *dev = ctx;
285 
286 	DEV_NOT_INIT_ERR(dev);
287 
288 	return 0;
289 }
290 
291 
292 /*
293  * nan_test_stop_cb - Stop the NAN device.
294  * @ctx: Pointer to the &struct nan_device
295  */
nan_test_stop_cb(void * ctx)296 static void nan_test_stop_cb(void *ctx)
297 {
298 	struct nan_device *dev = ctx;
299 
300 	DEV_NOT_INIT_ERR_VOID(dev);
301 
302 	wpa_printf(MSG_INFO, "%s: %s: Done", __func__, dev->name);
303 }
304 
305 
nan_test_nan_ndp_action(struct nan_device * dev,void * ctx)306 static int nan_test_nan_ndp_action(struct nan_device *dev, void *ctx)
307 {
308 	struct nan_ndp_params *params = ctx;
309 	int ret;
310 
311 	wpa_printf(MSG_INFO, "%s: %s: type=%u, peer_nmi=" MACSTR,
312 		   dev->name, __func__, params->type,
313 		   MAC2STR(params->ndp_id.peer_nmi));
314 
315 	ret = nan_handle_ndp_setup(dev->nan, params);
316 
317 	os_free(params);
318 
319 	return ret;
320 }
321 
322 
323 /*
324  * nan_ndp_notify_action - Default NAN NDP notification handling
325  * @dev: NAN device
326  * @ctx: Pointer to &struct nan_test_ndp_notify
327  */
nan_ndp_notify_action(struct nan_device * dev,void * ctx)328 static int nan_ndp_notify_action(struct nan_device *dev, void *ctx)
329 {
330 	struct nan_test_ndp_notify *notify = ctx;
331 	struct nan_test_action *action;
332 	int ret;
333 
334 	wpa_printf(MSG_INFO, "%s: %s: type=%u, peer_nmi=" MACSTR,
335 		   dev->name, __func__, notify->type,
336 		   MAC2STR(notify->ndp_id.peer_nmi));
337 
338 	ret = -1;
339 	if (notify->type == NAN_TEST_NDP_NOTIFY_REQUEST) {
340 		struct nan_ndp_params *params;
341 		struct nan_device *curd;
342 		bool found = false;
343 
344 		dl_list_for_each(curd, &dev->global->devs, struct nan_device,
345 				 list) {
346 			if (ether_addr_equal(curd->nmi,
347 					     notify->ndp_id.peer_nmi)) {
348 				found = true;
349 				break;
350 			}
351 		}
352 
353 		if (!found) {
354 			wpa_printf(MSG_ERROR, "Peer device not found");
355 			ret = -1;
356 			goto out;
357 		}
358 
359 		params = os_zalloc(sizeof(struct nan_ndp_params));
360 		if (!params) {
361 			ret = -1;
362 			goto out;
363 		}
364 
365 		params->type = NAN_NDP_ACTION_RESP;
366 		os_memcpy(params->ndp_id.peer_nmi, notify->ndp_id.peer_nmi,
367 			  ETH_ALEN);
368 		os_memcpy(params->ndp_id.init_ndi, notify->ndp_id.init_ndi,
369 			  ETH_ALEN);
370 		params->ndp_id.id = notify->ndp_id.id;
371 		params->qos.min_slots = NAN_TEST_MIN_SLOTS;
372 		params->qos.max_latency = NAN_TEST_MAX_LATENCY;
373 
374 		if (dev->conf->ndp_confs[dev->n_ndps].accept_request) {
375 			wpa_printf(MSG_INFO, "%s: Accepting request",
376 				   dev->name);
377 
378 			os_memcpy(params->u.resp.resp_ndi, dev->ndi, ETH_ALEN);
379 			params->u.resp.status = NAN_NDP_STATUS_ACCEPTED;
380 			dev->conf->schedule_cb(&params->sched);
381 			params->sched.elems = dev->global->elems;
382 			params->sched_valid = 1;
383 
384 			params->sec.csid =
385 				dev->conf->ndp_confs[dev->n_ndps].csid;
386 			os_memcpy(params->sec.pmk, dev->conf->pmk, PMK_LEN);
387 		} else {
388 			wpa_printf(MSG_INFO, "%s: Rejecting request",
389 				   dev->name);
390 
391 			params->u.resp.status = NAN_NDP_STATUS_REJECTED;
392 			params->u.resp.reason_code =
393 				dev->conf->ndp_confs[dev->n_ndps].reason;
394 		}
395 
396 		action = nan_test_add_action(dev->global, dev,
397 					     nan_test_nan_ndp_action,
398 					     params);
399 		if (action)
400 			ret = 0;
401 	} else if (notify->type == NAN_TEST_NDP_NOTIFY_RESPONSE) {
402 		struct nan_ndp_params *params;
403 
404 		params = os_zalloc(sizeof(struct nan_ndp_params));
405 		if (!params) {
406 			ret = -1;
407 			goto out;
408 		}
409 
410 		params->type = NAN_NDP_ACTION_CONF;
411 		os_memcpy(params->ndp_id.peer_nmi, notify->ndp_id.peer_nmi,
412 			  ETH_ALEN);
413 		os_memcpy(params->ndp_id.init_ndi, notify->ndp_id.init_ndi,
414 			  ETH_ALEN);
415 		params->ndp_id.id = notify->ndp_id.id;
416 
417 		params->qos.min_slots = NAN_TEST_MIN_SLOTS;
418 		params->qos.max_latency = NAN_TEST_MAX_LATENCY;
419 
420 		if (dev->conf->ndp_confs[dev->n_ndps].accept_request) {
421 			wpa_printf(MSG_INFO, "%s: Accepting response",
422 				   dev->name);
423 
424 			os_memcpy(params->u.resp.resp_ndi, dev->ndi, ETH_ALEN);
425 			params->u.resp.status = NAN_NDP_STATUS_ACCEPTED;
426 
427 			if (!dev->conf->schedule_conf_cb) {
428 				wpa_printf(MSG_ERROR,
429 					   "%s: No schedule conf cb defined",
430 					   dev->name);
431 				os_free(params);
432 				ret = -1;
433 				goto out;
434 			}
435 
436 			dev->conf->schedule_conf_cb(&params->sched);
437 			params->sched.elems = dev->global->elems;
438 			params->sched_valid = 1;
439 
440 			params->sec.csid =
441 				dev->conf->ndp_confs[dev->n_ndps].csid;
442 			os_memcpy(params->sec.pmk, dev->conf->pmk, PMK_LEN);
443 		} else {
444 			wpa_printf(MSG_INFO, "%s: Rejecting response",
445 				   dev->name);
446 
447 			params->u.resp.status = NAN_NDP_STATUS_REJECTED;
448 			params->u.resp.reason_code =
449 				dev->conf->ndp_confs[dev->n_ndps].reason;
450 		}
451 
452 		action = nan_test_add_action(dev->global, dev,
453 					     nan_test_nan_ndp_action,
454 					     params);
455 		if (action)
456 			ret = 0;
457 	} else if (notify->type ==
458 		   dev->conf->ndp_confs[dev->n_ndps].expected_result) {
459 		ret = 0;
460 		if (notify->type == NAN_TEST_NDP_NOTIFY_CONNECTED) {
461 			if (dev->conf->ndp_confs[dev->n_ndps].
462 			    term_once_connected) {
463 				struct nan_ndp_params *params;
464 
465 				wpa_printf(MSG_INFO,
466 					   "%s: Connected successfully. Now term",
467 					   dev->name);
468 
469 				params = os_zalloc(sizeof(*params));
470 				if (!params) {
471 					ret = -1;
472 					goto out;
473 				}
474 
475 				params->type = NAN_NDP_ACTION_TERM;
476 				os_memcpy(params->ndp_id.peer_nmi,
477 					  notify->ndp_id.peer_nmi,
478 					  ETH_ALEN);
479 				os_memcpy(params->ndp_id.init_ndi,
480 					  notify->ndp_id.init_ndi,
481 					  ETH_ALEN);
482 				params->ndp_id.id = notify->ndp_id.id;
483 
484 				action = nan_test_add_action(
485 					dev->global, dev,
486 					nan_test_nan_ndp_action, params);
487 				if (action)
488 					ret = 0;
489 			}
490 		}
491 	} else if (notify->type == NAN_TEST_NDP_NOTIFY_DISCONNECTED &&
492 		   dev->connected_notify_received) {
493 		wpa_printf(MSG_INFO,
494 			   "%s: Disconnected after connected as expected. Test case done",
495 			   dev->name);
496 		ret = 0;
497 	} else {
498 		wpa_printf(MSG_ERROR,
499 			   "%s: Unexpected notify: type=%u expected=%u",
500 			   dev->name, notify->type,
501 			   dev->conf->ndp_confs[dev->n_ndps].expected_result);
502 		ret = -1;
503 	}
504 
505 out:
506 	os_free((void *) notify->ssi);
507 	os_free(notify);
508 	return ret;
509 }
510 
511 
nan_test_ndp_action(struct nan_device * dev,enum nan_test_ndp_notify_type type,struct nan_ndp_id * ndp_id,u8 publish_inst_id,const u8 * ssi,size_t ssi_len,enum nan_cipher_suite_id csid,const u8 * pmkid)512 static void nan_test_ndp_action(struct nan_device *dev, enum
513 				nan_test_ndp_notify_type type,
514 				struct nan_ndp_id *ndp_id,
515 				u8 publish_inst_id,
516 				const u8 *ssi, size_t ssi_len,
517 				enum nan_cipher_suite_id csid,
518 				const u8 *pmkid)
519 {
520 	struct nan_test_ndp_notify *notify;
521 
522 	DEV_NOT_INIT_ERR_VOID(dev);
523 
524 	wpa_printf(MSG_INFO, "%s: %s: Enter: type=%u",
525 		   dev->name, __func__, type);
526 
527 	notify = os_zalloc(sizeof(struct nan_test_ndp_notify));
528 	if (!notify) {
529 		wpa_printf(MSG_ERROR,
530 			   "Failed allocation: nan_test_ndp_notify");
531 		return;
532 	}
533 
534 	notify->type = type;
535 	os_memcpy(&notify->ndp_id, ndp_id, sizeof(notify->ndp_id));
536 
537 	if (ssi && ssi_len) {
538 		notify->ssi = os_memdup(ssi, ssi_len);
539 		if (!notify->ssi) {
540 			wpa_printf(MSG_ERROR, "Failed allocation: ssi");
541 			os_free(notify);
542 			return;
543 		}
544 		notify->ssi_len = ssi_len;
545 	}
546 
547 	if (nan_test_add_action(dev->global, dev, nan_ndp_notify_action,
548 				notify))
549 		return;
550 
551 	os_free((void *) notify->ssi);
552 	os_free(notify);
553 }
554 
555 
556 /**
557  * nan_test_ndp_action_notfi_cb - Callback for NDP request
558  * @ctx: Pointer to &struct nan_device
559  * @params: NDP action notification parameters
560  *
561  * The handling of the event is done asynchronously through the NAN test actions
562  * processing.
563  */
564 static void
nan_test_ndp_action_notfi_cb(void * ctx,struct nan_ndp_action_notif_params * params)565 nan_test_ndp_action_notfi_cb(void *ctx,
566 			     struct nan_ndp_action_notif_params *params)
567 {
568 	struct nan_device *dev = ctx;
569 	enum nan_test_ndp_notify_type type;
570 
571 	DEV_NOT_INIT_ERR_VOID(dev);
572 
573 	if (params->is_request)
574 		type = NAN_TEST_NDP_NOTIFY_REQUEST;
575 	else
576 		type = NAN_TEST_NDP_NOTIFY_RESPONSE;
577 
578 	nan_test_ndp_action(dev, type, &params->ndp_id,
579 			    params->publish_inst_id, params->ssi,
580 			    params->ssi_len, params->csid, params->pmkid);
581 }
582 
583 
584 /**
585  * nan_test_ndp_connected_cb - Callback for NDP connected
586  * @ctx: Pointer to &struct nan_device
587  * @params: NDP action notification parameters
588  * Returns: 0 on success, -1 on failure
589  *
590  * The handling of the event is done asynchronously through the NAN test actions
591  * processing.
592  */
nan_test_ndp_connected_cb(void * ctx,struct nan_ndp_connection_params * params)593 static int nan_test_ndp_connected_cb(void *ctx,
594 				     struct nan_ndp_connection_params *params)
595 {
596 	struct nan_device *dev = ctx;
597 	struct nan_peer_schedule sched;
598 	struct nan_peer_potential_avail pot;
599 
600 	DEV_NOT_INIT_ERR(dev);
601 
602 	wpa_printf(MSG_INFO,
603 		   "%s: %s: Enter. local_ndi=" MACSTR " peer_ndi=" MACSTR,
604 		   dev->name, __func__,
605 		   MAC2STR(params->local_ndi), MAC2STR(params->peer_ndi));
606 
607 	nan_peer_get_schedule_info(dev->nan, params->ndp_id.peer_nmi, &sched);
608 	nan_peer_get_pot_avail(dev->nan, params->ndp_id.peer_nmi, &pot);
609 
610 	if (nan_peer_get_tk(dev->nan, params->ndp_id.peer_nmi,
611 			    params->peer_ndi, params->local_ndi,
612 			    dev->tk, &dev->tk_len, &dev->csid) == 0) {
613 		wpa_hexdump(MSG_DEBUG, "NAN Test: TK", dev->tk, dev->tk_len);
614 
615 		if (dev->csid !=
616 		    dev->conf->ndp_confs[dev->n_ndps].expected_csid) {
617 			wpa_printf(MSG_ERROR,
618 				   "%s: Unexpected CSID: got %u expected %u",
619 				   dev->name, dev->csid,
620 				   dev->conf->ndp_confs[dev->n_ndps].
621 				   expected_csid);
622 			return -1;
623 		}
624 	}
625 
626 	nan_test_ndp_action(dev, NAN_TEST_NDP_NOTIFY_CONNECTED, &params->ndp_id,
627 			    0, params->ssi, params->ssi_len, NAN_CS_NONE, NULL);
628 
629 	dev->connected_notify_received = true;
630 
631 	return 0;
632 }
633 
634 
635 /**
636  * nan_test_ndp_disconnected_cb - Callback for NDP disconnected
637  * @ctx: Pointer to &struct nan_device
638  * @ndp_id: NDP identifier
639  * @local_ndi: Local NDI address
640  * @peer_ndi: Peer NDI address
641  * @reason: Reason for disconnection
642  * @locally_generated: true if locally generated, false if triggered by peer
643  * @remove_sta: true if the NDI station should be removed
644  * @failure: true if NDP setup failed, false if graceful disconnection
645  * @gtk_id: GTK key ID used for the NDP; 0 if no GTK was used
646  *
647  * The handling of the event is done asynchronously through the NAN test actions
648  * processing.
649  */
nan_test_ndp_disconnected_cb(void * ctx,struct nan_ndp_id * ndp_id,const u8 * local_ndi,const u8 * peer_ndi,enum nan_reason reason,bool locally_generated,bool remove_sta,bool failure,u8 gtk_id)650 static void nan_test_ndp_disconnected_cb(void *ctx, struct nan_ndp_id *ndp_id,
651 					 const u8 *local_ndi,
652 					 const u8 *peer_ndi,
653 					 enum nan_reason reason,
654 					 bool locally_generated,
655 					 bool remove_sta,
656 					 bool failure,
657 					 u8 gtk_id)
658 {
659 	struct nan_device *dev = ctx;
660 
661 	DEV_NOT_INIT_ERR_VOID(dev);
662 
663 	wpa_printf(MSG_INFO, "%s: %s: Enter", dev->name, __func__);
664 
665 	nan_test_ndp_action(dev, NAN_TEST_NDP_NOTIFY_DISCONNECTED,
666 			    ndp_id, 0, NULL, 0, NAN_CS_NONE, NULL);
667 
668 	dev->disconnected_notify_received = true;
669 }
670 
671 
672 /**
673  * nan_test_send_naf_cb_action - NAN test action to send a NAN to a device
674  * @dev: NAN device
675  * @ctx: Pointer to a buffer holding the NAF to be sent
676  */
nan_test_send_naf_cb_action(struct nan_device * dev,void * ctx)677 static int nan_test_send_naf_cb_action(struct nan_device *dev, void *ctx)
678 {
679 	struct wpabuf *data = ctx;
680 	int ret;
681 
682 	DEV_NOT_INIT_ERR(dev);
683 
684 	wpa_printf(MSG_INFO, "%s: %s: Enter", dev->name, __func__);
685 	wpa_hexdump(MSG_DEBUG, "NAN Test: NAF:", wpabuf_head(data),
686 		    wpabuf_len(data));
687 
688 	ret = nan_action_rx(dev->nan, wpabuf_head(data), wpabuf_len(data));
689 	wpabuf_free(data);
690 	return ret;
691 }
692 
693 
694 /**
695  * nan_test_tx_status_action - NAN test action to send Tx status to a device
696  * @dev: NAN device
697  * @ctx: Pointer to &struct nan_test_tx_status_action
698  */
nan_test_tx_status_action(struct nan_device * dev,void * ctx)699 static int nan_test_tx_status_action(struct nan_device *dev, void *ctx)
700 {
701 	struct nan_test_tx_status_action *tx_status = ctx;
702 	int ret;
703 
704 	DEV_NOT_INIT_ERR(dev);
705 
706 	wpa_printf(MSG_INFO, "%s: %s: enter", dev->name, __func__);
707 
708 	ret = nan_tx_status(dev->nan, tx_status->dst,
709 			    wpabuf_head(tx_status->data),
710 			    wpabuf_len(tx_status->data), tx_status->acked);
711 
712 	wpabuf_free((struct wpabuf *)tx_status->data);
713 	os_free(tx_status);
714 	return ret;
715 }
716 
717 
718 /**
719  * nan_test_send_naf_cb - NAN send NAF callback function
720  * @ctx: Pointer to &struct nan_device
721  * @dst: Destination NAN Management Interface address
722  * @src: Source NAN Management Interface address
723  * @cluster_id: NAN Cluster ID
724  *
725  * The callback builds the management frame and creates the following NAN test
726  * actions:
727  * - NAN test tx status action: to be sent to the transmitting device
728  * - NAN test send NAF action: to be sent to the destination device.
729  */
nan_test_send_naf_cb(void * ctx,const u8 * dst,const u8 * src,const u8 * cluster_id,struct wpabuf * buf)730 static int nan_test_send_naf_cb(void *ctx, const u8 *dst, const u8 *src,
731 				const u8 *cluster_id, struct wpabuf *buf)
732 {
733 	struct nan_device *dev = ctx;
734 	struct nan_device *curd;
735 	struct ieee80211_hdr *hdr;
736 	struct wpabuf *data = NULL;
737 	struct nan_test_tx_status_action *tx_status = NULL;
738 	struct nan_test_action *dev_action, *cur_action;
739 	bool found = false;
740 
741 	DEV_NOT_INIT_ERR(dev);
742 
743 	if (!dst)
744 		return -1;
745 
746 	wpa_printf(MSG_INFO, "%s: %s: Enter " MACSTR, __func__, dev->name,
747 		   MAC2STR(dst));
748 
749 	dl_list_for_each(curd, &dev->global->devs, struct nan_device, list) {
750 		if (ether_addr_equal(curd->nmi, dst) ||
751 		    ether_addr_equal(curd->ndi, dst)) {
752 			found = true;
753 			break;
754 		}
755 	}
756 
757 	if (!found) {
758 		wpa_printf(MSG_ERROR, "%s: Destination device not found",
759 			   __func__);
760 		return -1;
761 	}
762 
763 	/* Prepare action to send the frame to the peer */
764 	data = wpabuf_alloc(sizeof(struct ieee80211_hdr) + wpabuf_len(buf));
765 	if (!data) {
766 		wpa_printf(MSG_ERROR, "%s: Failed to allocate NAF", __func__);
767 		return -1;
768 	}
769 
770 	hdr = wpabuf_put(data, sizeof(struct ieee80211_hdr));
771 	hdr->frame_control =
772 		IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
773 
774 	os_memcpy(hdr->addr1, dst, ETH_ALEN);
775 	if (!src)
776 		os_memcpy(hdr->addr2, dev->nmi, ETH_ALEN);
777 	else
778 		os_memcpy(hdr->addr2, src, ETH_ALEN);
779 	if (cluster_id)
780 		os_memcpy(hdr->addr3, cluster_id, ETH_ALEN);
781 
782 	wpabuf_put_data(data, wpabuf_head(buf), wpabuf_len(buf));
783 
784 	/* Prepare action to send Tx status */
785 	tx_status = os_malloc(sizeof(struct nan_test_tx_status_action));
786 	if (!tx_status) {
787 		wpa_printf(MSG_ERROR, "%s: Failed to allocate Tx status",
788 			   __func__);
789 		goto fail;
790 	}
791 
792 	tx_status->data = wpabuf_dup(data);
793 	if (!tx_status->data) {
794 		wpa_printf(MSG_ERROR, "%s: Failed to allocate Tx status data",
795 			   __func__);
796 		goto fail;
797 	}
798 
799 	os_memcpy(tx_status->dst, dst, ETH_ALEN);
800 	tx_status->acked = 1;
801 
802 	/* First send the TX status */
803 	dev_action = nan_test_add_action(dev->global, dev,
804 					 nan_test_tx_status_action, tx_status);
805 	if (!dev_action)
806 		goto fail;
807 
808 	/* And then deliver the frame */
809 	cur_action = nan_test_add_action(curd->global, curd,
810 					 nan_test_send_naf_cb_action, data);
811 	if (!cur_action)
812 		goto fail;
813 
814 	return 0;
815 
816 fail:
817 	wpabuf_free(data);
818 	if (tx_status)
819 		wpabuf_free((struct wpabuf *) tx_status->data);
820 
821 	os_free(tx_status);
822 
823 	return -1;
824 }
825 
826 
827 /**
828  * nan_test_get_chans_cb - Get NAN supported channels callback
829  * @ctx: Pointer to &struct nan_device
830  * @map_id: Channel map identifier
831  * @chans: Pointer to &struct nan_channels to be filled with supported channels
832  */
nan_test_get_chans_cb(void * ctx,u8 map_id,struct nan_channels * chans)833 static int nan_test_get_chans_cb(void *ctx, u8 map_id,
834 				 struct nan_channels *chans)
835 {
836 	struct nan_device *dev = ctx;
837 
838 	DEV_NOT_INIT_ERR(dev);
839 
840 	wpa_printf(MSG_INFO, "%s: %s: Enter", dev->name, __func__);
841 
842 	return dev->conf->get_chans_cb(chans);
843 }
844 
845 
846 /**
847  * nan_test_is_valid_publish_id_cb - Check if the publish instance ID is valid
848  * @ctx: Pointer to &struct nan_device
849  * @instance_id: Publish instance ID
850  * @service_id: Buffer to be filled with the service ID
851  * Returns true if the instance ID is valid, false otherwise
852  */
nan_test_is_valid_publish_id_cb(void * ctx,u8 instance_id,u8 * service_id)853 static bool nan_test_is_valid_publish_id_cb(void *ctx, u8 instance_id,
854 					    u8 *service_id)
855 {
856 	if (instance_id != NAN_TEST_PUBLISH_INST_ID)
857 		return false;
858 
859 	os_memset(service_id, 0xaa, NAN_SERVICE_ID_LEN);
860 	return true;
861 }
862 
863 
864 /*
865  * nan_test_set_peer_schedule_cb - Set peer schedule callback
866  *
867  * @ctx: Pointer to &struct nan_device
868  * @sched: Pointer to &struct nan_peer_schedule to be filled
869  */
870 static int
nan_test_set_peer_schedule_cb(void * ctx,const u8 * nmi_addr,bool new_sta,u16 cdw,u8 sequence_id,u16 max_channel_switch_time,const struct nan_peer_schedule * sched,const struct wpabuf * ulw_elems)871 nan_test_set_peer_schedule_cb(void *ctx, const u8 *nmi_addr, bool new_sta,
872 			      u16 cdw, u8 sequence_id,
873 			      u16 max_channel_switch_time,
874 			      const struct nan_peer_schedule *sched,
875 			      const struct wpabuf *ulw_elems)
876 {
877 	struct nan_device *dev = (struct nan_device *)ctx;
878 
879 	DEV_NOT_INIT_ERR(dev);
880 
881 	wpa_printf(MSG_INFO, "%s: %s: Enter", dev->name, __func__);
882 	wpa_printf(MSG_INFO, "%s: nmi_addr=" MACSTR
883 		   " new_sta=%d cdw=%u sequence_id=%u max_channel_switch_time=%u",
884 		   dev->name, MAC2STR(nmi_addr), new_sta, cdw, sequence_id,
885 		   max_channel_switch_time);
886 
887 	return 0;
888 }
889 
890 
891 /**
892  * nan_test_dev_init - Initialize a test device instance
893  * @dev: the instance of the device to initialize
894  */
nan_test_dev_init(struct nan_device * dev)895 static int nan_test_dev_init(struct nan_device *dev)
896 {
897 	struct nan_config nan;
898 
899 	os_memset(&nan, 0, sizeof(nan));
900 	os_memcpy(nan.nmi_addr, dev->nmi, ETH_ALEN);
901 	nan.cb_ctx = dev;
902 
903 	nan.start = nan_test_start_cb;
904 	nan.stop = nan_test_stop_cb;
905 	nan.ndp_action_notif = nan_test_ndp_action_notfi_cb;
906 	nan.ndp_connected = nan_test_ndp_connected_cb;
907 	nan.ndp_disconnected = nan_test_ndp_disconnected_cb;
908 	nan.send_naf = nan_test_send_naf_cb;
909 	nan.get_chans = nan_test_get_chans_cb;
910 	nan.is_valid_publish_id = nan_test_is_valid_publish_id_cb;
911 	nan.set_peer_schedule = nan_test_set_peer_schedule_cb;
912 
913 	/* Awake on every DW on 2 GHz and 5 GHz */
914 	nan.dev_capa.cdw_info = 0x9;
915 	nan.dev_capa.supported_bands = NAN_DEV_CAPA_SBAND_2G |
916 		NAN_DEV_CAPA_SBAND_5G |
917 		NAN_DEV_CAPA_SBAND_6G;
918 
919 	nan.dev_capa.op_mode = NAN_DEV_CAPA_OP_MODE_PHY_MODE;
920 	nan.dev_capa.n_antennas = 0x22;
921 	nan.dev_capa.channel_switch_time = 10;
922 	nan.dev_capa.capa = 0;
923 
924 	nan.dev_capa_ext_reg_info = 0;
925 	nan.pairing_cfg.npk_caching = true;
926 	nan.pairing_cfg.pairing_setup = true;
927 
928 	dev->nan = nan_init(&nan);
929 	if (!dev->nan) {
930 		wpa_printf(MSG_DEBUG, "NAN: Failed to init");
931 		return -1;
932 	}
933 
934 	return 0;
935 }
936 
937 
938 /**
939  * nan_test_start_dev - Start a NAN test device
940  * @global: NAN test global data structure
941  * @name: Name of the device
942  * @nmi: NAN Management interface address
943  * @ndi: NAN Data interface address
944  * @cconf: NAN cluster configuration
945  * @dconf: Test device configuration
946  */
947 static struct nan_device *
nan_test_start_dev(struct nan_test_global * global,const char * name,const u8 * nmi,const u8 * ndi,struct nan_cluster_config * conf,const struct nan_test_dev_conf * dconf)948 nan_test_start_dev(struct nan_test_global *global,
949 		   const char *name, const u8 *nmi,
950 		   const u8 *ndi,
951 		   struct nan_cluster_config *conf,
952 		   const struct nan_test_dev_conf *dconf)
953 {
954 	struct nan_device *dev;
955 	int ret;
956 	size_t nlen;
957 
958 	dev = os_zalloc(sizeof(struct nan_device));
959 	if (!dev)
960 		return NULL;
961 
962 	nlen = os_strlen(name);
963 	if (nlen >= sizeof(dev->name))
964 		nlen = sizeof(dev->name) - 1;
965 	os_memcpy(dev->name, name, nlen);
966 	os_memcpy(dev->nmi, nmi, sizeof(dev->nmi));
967 	os_memcpy(dev->ndi, ndi, sizeof(dev->ndi));
968 	dl_list_init(&dev->list);
969 	dev->global = global;
970 
971 	if (dconf->pot_avail_len) {
972 		dev->pot_avail = os_memdup(dconf->pot_avail,
973 					   dconf->pot_avail_len);
974 		if (!dev->pot_avail)
975 			goto fail;
976 		dev->pot_avail_len = dconf->pot_avail_len;
977 	}
978 
979 	ret = nan_test_dev_init(dev);
980 	if (ret)
981 		goto fail;
982 
983 	dev->conf = dconf;
984 	ret = nan_start(dev->nan, conf);
985 	if (ret)
986 		goto fail;
987 
988 	dl_list_add(&global->devs, &dev->list);
989 	return dev;
990 
991 fail:
992 	nan_test_dev_deinit(dev);
993 	os_free(dev);
994 	return NULL;
995 }
996 
997 
998 /**
999  * nan_test_setup_devices - Setup the test devices
1000  * @global: NAN test global data structure
1001  * @pub_conf: Publisher test configuration
1002  * @sub_conf: Subscriber test configuration
1003  */
1004 static struct nan_device *
nan_test_setup_devices(struct nan_test_global * global,const struct nan_test_dev_conf * pub_conf,const struct nan_test_dev_conf * sub_conf)1005 nan_test_setup_devices(struct nan_test_global *global,
1006 		       const struct nan_test_dev_conf *pub_conf,
1007 		       const struct nan_test_dev_conf *sub_conf)
1008 {
1009 	struct nan_cluster_config cconf = {
1010 		.master_pref = 2,
1011 		.dual_band = 1,
1012 	};
1013 	/*
1014 	 * Device attributes containing:
1015 	 * 1. Device capability attribute (ID=0x0F, len=10):
1016 	 *    - map_id=0
1017 	 *    - cdw_info=0x0009 (awake on every DW on 2G and 5G)
1018 	 *    - supported_bands=0x07 (2G, 5G, 6G)
1019 	 *    - op_mode=0x01
1020 	 *    - n_antennas=0x22
1021 	 *    - channel_switch_time=0x000a (10)
1022 	 *    - capa=0x00
1023 	 * 2. Availability attribute (ID=0x12, len=12)
1024 	 */
1025 	const u8 attrs[] = {
1026 		/* Device capability attribute */
1027 		0x0f, 0x09, 0x00, 0x00, 0x09, 0x00, 0x07, 0x01,
1028 		0x22, 0x0a, 0x00, 0x00,
1029 		/* Availability attribute */
1030 		0x12, 0x0c, 0x00, 0x01, 0x20, 0x00, 0x07, 0x00,
1031 		0x1a, 0x00, 0x11, 0x51, 0xff, 0x07, 0x00,
1032 	};
1033 
1034 	struct nan_device *pub, *sub;
1035 
1036 	wpa_printf(MSG_INFO, "%s: Enter\n", __func__);
1037 
1038 	pub = nan_test_start_dev(global, "publisher", g_pub_nmi, g_pub_ndi,
1039 				 &cconf, pub_conf);
1040 	if (!pub)
1041 		goto fail;
1042 
1043 	sub = nan_test_start_dev(global, "subscriber", g_sub_nmi, g_sub_ndi,
1044 				 &cconf, sub_conf);
1045 	if (!sub)
1046 		goto fail;
1047 
1048 	nan_add_peer(pub->nan, g_sub_nmi, attrs, sizeof(attrs));
1049 	nan_add_peer(sub->nan, g_pub_nmi, attrs, sizeof(attrs));
1050 
1051 	wpa_printf(MSG_INFO, "\n%s: Done\n", __func__);
1052 	return sub;
1053 
1054 fail:
1055 	wpa_printf(MSG_INFO, "\n%s: Fail\n", __func__);
1056 	return NULL;
1057 }
1058 
1059 
nan_test_ndp_request(struct nan_device * sub,const u8 * pub_nmi)1060 static int nan_test_ndp_request(struct nan_device *sub, const u8 *pub_nmi)
1061 {
1062 	struct nan_ndp_params *params;
1063 	struct nan_test_action *action;
1064 
1065 	DEV_NOT_INIT_ERR(sub);
1066 
1067 	params = os_zalloc(sizeof(struct nan_ndp_params));
1068 	if (!params) {
1069 		wpa_printf(MSG_ERROR, "Failed allocation: nan_ndp_params");
1070 		return -1;
1071 	}
1072 
1073 	params->type = NAN_NDP_ACTION_REQ;
1074 	os_memcpy(params->ndp_id.peer_nmi, pub_nmi, ETH_ALEN);
1075 	os_memcpy(params->ndp_id.init_ndi, sub->ndi, ETH_ALEN);
1076 	params->ndp_id.id = ++sub->counter;
1077 	params->qos.min_slots = NAN_TEST_MIN_SLOTS;
1078 	params->qos.max_latency = NAN_TEST_MAX_LATENCY;
1079 	params->sec.csid = sub->conf->ndp_confs[sub->n_ndps].csid;
1080 	os_memcpy(params->sec.pmk, sub->conf->pmk, PMK_LEN);
1081 
1082 	/* Use the device specific schedule callback */
1083 	sub->conf->schedule_cb(&params->sched);
1084 	params->sched_valid = 1;
1085 	params->sched.elems = sub->global->elems;
1086 
1087 	params->u.req.publish_inst_id = NAN_TEST_PUBLISH_INST_ID;
1088 	os_memset(params->u.req.service_id, 0xaa, NAN_SERVICE_ID_LEN);
1089 
1090 	action = nan_test_add_action(sub->global, sub, nan_test_nan_ndp_action,
1091 				     params);
1092 	if (action)
1093 		return 0;
1094 
1095 	wpa_printf(MSG_ERROR, "Failed adding NDP request action");
1096 	os_free(params);
1097 
1098 	return -1;
1099 }
1100 
1101 
1102 /**
1103  * nan_test_ndp_setup - test NDP setup
1104  * @global: NAN test global data structure
1105  * @pub_conf: Publisher test configuration
1106  * @sub_conf: Subscriber test configuration
1107  *
1108  * Create the test devices, perform the basic publish/subscribe/match to allow
1109  * NDP establishment and trigger an NDP request flow based on the actions
1110  * mechanism.
1111  */
1112 static struct nan_device *
nan_test_ndp_setup(struct nan_test_global * global,const struct nan_test_dev_conf * pub_conf,const struct nan_test_dev_conf * sub_conf)1113 nan_test_ndp_setup(struct nan_test_global *global,
1114 		   const struct nan_test_dev_conf *pub_conf,
1115 		   const struct nan_test_dev_conf *sub_conf)
1116 {
1117 	if (pub_conf->n_ndps != sub_conf->n_ndps || !pub_conf->n_ndps ||
1118 	    pub_conf->n_ndps >= NAN_MAX_NUM_NDPS) {
1119 		wpa_printf(MSG_DEBUG,
1120 			   "NAN Test: Publisher and Subscriber n_ndps mismatch or invalid");
1121 		return NULL;
1122 	}
1123 
1124 	return nan_test_setup_devices(global, pub_conf, sub_conf);
1125 }
1126 
1127 
nan_test_verify_expected_result(struct nan_device * dev)1128 static int nan_test_verify_expected_result(struct nan_device *dev)
1129 {
1130 	DEV_NOT_INIT_ERR(dev);
1131 
1132 	if (dev->conf->ndp_confs[dev->n_ndps].expected_result ==
1133 	    NAN_TEST_NDP_NOTIFY_CONNECTED &&
1134 	    !dev->connected_notify_received) {
1135 		wpa_printf(MSG_ERROR,
1136 			   "%s: Expected connected notify not received",
1137 			   dev->name);
1138 		return -1;
1139 	}
1140 
1141 	if (dev->conf->ndp_confs[dev->n_ndps].expected_result ==
1142 	    NAN_TEST_NDP_NOTIFY_DISCONNECTED &&
1143 	    !dev->disconnected_notify_received) {
1144 		wpa_printf(MSG_ERROR,
1145 			   "%s: Expected disconnected notify not received",
1146 			   dev->name);
1147 		return -1;
1148 	}
1149 
1150 	return 0;
1151 }
1152 
1153 
nan_test_iteration_done(struct nan_test_global * global)1154 static int nan_test_iteration_done(struct nan_test_global *global)
1155 {
1156 	struct nan_device *dev;
1157 	u8 tk[NAN_TK_MAX_LEN];
1158 	size_t tk_len = 0;
1159 	enum nan_cipher_suite_id csid;
1160 	int ret;
1161 
1162 	os_memset(tk, 0, sizeof(tk));
1163 
1164 	dl_list_for_each(dev, &global->devs, struct nan_device, list) {
1165 		ret = nan_test_verify_expected_result(dev);
1166 
1167 		if (ret)
1168 			return ret;
1169 
1170 		if (tk_len == 0 && dev->tk_len > 0) {
1171 			os_memcpy(tk, dev->tk, dev->tk_len);
1172 			tk_len = dev->tk_len;
1173 			csid = dev->csid;
1174 		} else if (dev->tk_len > 0) {
1175 			if (tk_len != dev->tk_len ||
1176 			    csid != dev->csid ||
1177 			    os_memcmp(tk, dev->tk, tk_len) != 0) {
1178 				wpa_printf(MSG_ERROR,
1179 					   "%s: TK mismatch with other device",
1180 					   dev->name);
1181 				return -1;
1182 			}
1183 
1184 			wpa_printf(MSG_INFO, "%s: TK matches with other device",
1185 				   dev->name);
1186 		}
1187 
1188 		dev->connected_notify_received = false;
1189 		dev->disconnected_notify_received = false;
1190 
1191 		os_memset(dev->tk, 0, sizeof(dev->tk));
1192 		dev->tk_len = 0;
1193 
1194 		dev->n_ndps++;
1195 	}
1196 
1197 	return 0;
1198 }
1199 
1200 
1201 /**
1202  * nan_test_run - Run the NAN tests
1203  * Iterates over all tests cases and for each test case initializes the global
1204  * context, creates the NAN devices and perform the test case.
1205  */
nan_test_run(void)1206 static int nan_test_run(void)
1207 {
1208 	struct nan_test_global global;
1209 	const struct nan_test_case *curr_tc;
1210 	bool all_failed = false;
1211 
1212 	while ((curr_tc = nan_test_case_get_next())) {
1213 		struct nan_device *sub;
1214 		bool failed = false;
1215 		size_t i;
1216 
1217 		wpa_printf(MSG_INFO,
1218 			   "\n======> NAN TEST CASE: %s <======\n",
1219 			   curr_tc->name);
1220 
1221 		nan_test_global_init(&global);
1222 		sub = nan_test_ndp_setup(&global,
1223 					 &curr_tc->pub_conf,
1224 					 &curr_tc->sub_conf);
1225 		if (!sub) {
1226 			wpa_printf(MSG_ERROR,
1227 				   "NAN Test: Failed to setup devices");
1228 			nan_test_global_deinit(&global);
1229 			failed = true;
1230 			continue;
1231 		}
1232 
1233 		for (i = 0; i < sub->conf->n_ndps; i++) {
1234 			int ret = nan_test_ndp_request(sub, g_pub_nmi);
1235 
1236 			if (!ret)
1237 				ret = nan_test_run_actions(&global);
1238 
1239 			if (!ret)
1240 				ret = nan_test_iteration_done(&global);
1241 
1242 			wpa_printf(MSG_INFO,
1243 				   "\n======> NAN TEST CASE: %s: iter=%zu: result=%s <======\n",
1244 				   curr_tc->name, i,
1245 				   ret ? "FAILED" : "SUCCESS");
1246 
1247 			if (ret) {
1248 				failed = true;
1249 				break;
1250 			}
1251 		}
1252 
1253 		wpa_printf(MSG_INFO,
1254 			   "\n======> NAN TEST CASE: %s: Done. Result=%s <======\n",
1255 			   curr_tc->name, failed ? "FAILED" : "SUCCESS");
1256 
1257 		all_failed |= failed;
1258 
1259 		nan_test_global_deinit(&global);
1260 	}
1261 
1262 	return all_failed ? -1 : 0;
1263 }
1264 
1265 
1266 static const u8 nan_key[32] = {
1267 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1268 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1269 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1270 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1271 };
1272 
1273 static u8 nan_addrs[][ETH_ALEN] = {
1274 	{
1275 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
1276 	},
1277 	{
1278 		0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
1279 	},
1280 };
1281 
1282 static u8 nan_nonce[][WPA_NONCE_LEN] = {
1283 	{
1284 		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
1285 		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
1286 		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
1287 		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
1288 	},
1289 	{
1290 		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
1291 		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
1292 		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
1293 		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
1294 	},
1295 };
1296 
1297 static struct nan_ptk nan_ptk_128 = {
1298 	.kck =	{
1299 		0x67, 0x40, 0x47, 0x6f, 0x9c, 0xb4, 0xcd, 0xee,
1300 		0xfb, 0xc7, 0xad, 0x25, 0x78, 0xd5, 0x5e, 0xb2,
1301 	},
1302 	.kek = {
1303 		0xe5, 0xc7, 0x55, 0xbb, 0x4e, 0x4f, 0xd7, 0xbb,
1304 		0xdb, 0x19, 0xa5, 0xb3, 0x6c, 0xcc, 0x77, 0xe3,
1305 	},
1306 	.tk = {
1307 		0xe2, 0x7f, 0xfc, 0x7b, 0xa2, 0xd6, 0xb2, 0x44,
1308 		0x63, 0x4a, 0x0c, 0xf2, 0x09, 0xf8, 0x06, 0x9a,
1309 	},
1310 	.kck_len = 16,
1311 	.kek_len = 16,
1312 	.tk_len = 16,
1313 };
1314 
1315 static struct nan_ptk nan_ptk_256 = {
1316 	.kck =	{
1317 		0x72, 0x70, 0xd5, 0xdc, 0x05, 0x44, 0x8a, 0xb4,
1318 		0x1a, 0x73, 0xe5, 0x51, 0x56, 0xa0, 0x78, 0x3a,
1319 		0x33, 0x74, 0x62, 0x4e, 0x81, 0xe0, 0x39, 0xf8,
1320 	},
1321 	.kek = {
1322 		0x55, 0x3e, 0x2c, 0x8a, 0x0b, 0xab, 0xfc, 0xe1,
1323 		0xf9, 0x45, 0xfb, 0xa7, 0xa6, 0xc9, 0x0c, 0x77,
1324 		0x76, 0x64, 0x6b, 0xaa, 0xc0, 0x59, 0x7c, 0xd6,
1325 		0xa4, 0x99, 0x31, 0xf2, 0x6e, 0xbf, 0x0e, 0x49,
1326 	},
1327 	.tk = {
1328 		0x44, 0x61, 0x12, 0xba, 0x4c, 0x25, 0x8b, 0xe5,
1329 		0x29, 0x33, 0x8f, 0x77, 0x45, 0x55, 0x13, 0x87,
1330 		0x69, 0x61, 0xf4, 0x33, 0xad, 0x87, 0x47, 0xbb,
1331 		0xa1, 0xd6, 0x5b, 0x4d, 0xaf, 0x0a, 0x37, 0x5a
1332 	},
1333 	.kck_len = 24,
1334 	.kek_len = 32,
1335 	.tk_len = 32,
1336 };
1337 
1338 static const u8 nan_service_id[NAN_SERVICE_ID_LEN] = {
1339 	0x48, 0xda, 0x63, 0xdc, 0xde, 0x19,
1340 };
1341 
1342 static u8 nan_pmkid_128[PMKID_LEN] = {
1343 	0xcf, 0x4f, 0x64, 0x44, 0xd8, 0xe2, 0xc4, 0xef,
1344 	0xa4, 0xf3, 0xa6, 0x51, 0xf3, 0x0f, 0x63, 0x4f,
1345 };
1346 
1347 static u8 nan_pmkid_256[PMKID_LEN] = {
1348 	0x08, 0x11, 0x23, 0xc8, 0x57, 0x52, 0x6a, 0x09,
1349 	0x6d, 0x46, 0x48, 0x2b, 0xa8, 0x02, 0xfc, 0x28,
1350 };
1351 
1352 static u8 nan_crypto_sha256_digest[SHA256_MAC_LEN] = {
1353 	0xde, 0x7a, 0xa9, 0x34, 0x0d, 0x1d, 0xbb, 0x73,
1354 	0x4d, 0x4d, 0x5a, 0xcb, 0x6b, 0xe4, 0xed, 0xc9,
1355 	0x0a, 0x16, 0x37, 0xaa, 0x1e, 0x5a, 0x34, 0x2e,
1356 	0x58, 0xdd, 0x0b, 0x30, 0x4b, 0xa4, 0x8c, 0x32,
1357 };
1358 
1359 static u8 nan_crypto_sha384_digest[SHA384_MAC_LEN] = {
1360 	0xb1, 0xf9, 0x75, 0xbd, 0x80, 0x84, 0x21, 0x35,
1361 	0xc2, 0x38, 0xf7, 0x0d, 0x03, 0x32, 0x38, 0xe7,
1362 	0xbb, 0x55, 0x39, 0x21, 0xf5, 0xb3, 0xbd, 0x5c,
1363 	0x93, 0x78, 0x52, 0x61, 0x6f, 0x83, 0x58, 0x2d,
1364 	0xdc, 0x0d, 0xe2, 0x25, 0x5e, 0x72, 0x6c, 0x95,
1365 	0xd0, 0xcb, 0x09, 0xef, 0x2a, 0x8f, 0x08, 0x17,
1366 };
1367 
1368 static const char sha_data[] =
1369 	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
1370 
1371 static u8 sha256_digest[] = {
1372 	0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
1373 	0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
1374 	0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
1375 	0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1,
1376 };
1377 
1378 static u8 sha384_digest[] = {
1379 	0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39,
1380 	0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39,
1381 	0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab,
1382 	0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6,
1383 	0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f,
1384 	0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b,
1385 };
1386 
1387 #define NAN_CRYPTO_FAIL(_ret)                                       \
1388 	if (_ret) {                                                 \
1389 		wpa_printf(MSG_ERROR,                               \
1390 			   "NAN Crypto test fail: %s:%d",           \
1391 			   __func__, __LINE__);                     \
1392 		return -1;                                          \
1393 	}
1394 
1395 
nan_test_crypto_key_mic(void)1396 static int nan_test_crypto_key_mic(void)
1397 {
1398 	u8 digest[SHA384_MAC_LEN];
1399 	u8 *data = nan_nonce[0];
1400 	size_t data_len = sizeof(nan_nonce[0]);
1401 
1402 	NAN_CRYPTO_FAIL(nan_crypto_key_mic(data, data_len, nan_key,
1403 					   sizeof(nan_key), NAN_CS_SK_CCM_128,
1404 					   digest));
1405 
1406 	NAN_CRYPTO_FAIL(os_memcmp(digest, nan_crypto_sha256_digest,
1407 				  NAN_KEY_MIC_LEN));
1408 
1409 	os_memset(digest, 0, sizeof(digest));
1410 
1411 	NAN_CRYPTO_FAIL(nan_crypto_key_mic(data, data_len, nan_key,
1412 					   sizeof(nan_key), NAN_CS_SK_GCM_256,
1413 					   digest));
1414 	NAN_CRYPTO_FAIL(os_memcmp(digest, nan_crypto_sha384_digest,
1415 				  NAN_KEY_MIC_24_LEN));
1416 
1417 	return 0;
1418 }
1419 
1420 
nan_test_crypto_pmkid(void)1421 static int nan_test_crypto_pmkid(void)
1422 {
1423 	u8 pmkid[PMKID_LEN];
1424 
1425 	NAN_CRYPTO_FAIL(nan_crypto_calc_pmkid(nan_key, nan_addrs[0],
1426 					      nan_addrs[1], nan_service_id,
1427 					      NAN_CS_SK_CCM_128, pmkid));
1428 
1429 	NAN_CRYPTO_FAIL(os_memcmp(pmkid, nan_pmkid_128, sizeof(pmkid)));
1430 
1431 	NAN_CRYPTO_FAIL(nan_crypto_calc_pmkid(nan_key, nan_addrs[0],
1432 					      nan_addrs[1], nan_service_id,
1433 					      NAN_CS_SK_GCM_256, pmkid));
1434 
1435 	NAN_CRYPTO_FAIL(os_memcmp(pmkid, nan_pmkid_256, sizeof(pmkid)));
1436 
1437 	return 0;
1438 }
1439 
1440 
nan_test_ptk(void)1441 static int nan_test_ptk(void)
1442 {
1443 	struct nan_ptk tptk;
1444 
1445 	os_memset(&tptk, 0, sizeof(tptk));
1446 
1447 	NAN_CRYPTO_FAIL(nan_crypto_pmk_to_ptk(nan_key,
1448 					      nan_addrs[0], nan_addrs[1],
1449 					      nan_nonce[0], nan_nonce[1],
1450 					      &tptk, NAN_CS_SK_CCM_128));
1451 
1452 	NAN_CRYPTO_FAIL(os_memcmp(&tptk, &nan_ptk_128, sizeof(tptk)));
1453 
1454 	os_memset(&tptk, 0, sizeof(tptk));
1455 
1456 	NAN_CRYPTO_FAIL(nan_crypto_pmk_to_ptk(nan_key,
1457 					      nan_addrs[0], nan_addrs[1],
1458 					      nan_nonce[0], nan_nonce[1],
1459 					      &tptk, NAN_CS_SK_GCM_256));
1460 
1461 	NAN_CRYPTO_FAIL(os_memcmp(&tptk, &nan_ptk_256, sizeof(tptk)));
1462 
1463 	return 0;
1464 }
1465 
1466 
nan_test_crypto_auth_token(void)1467 static int nan_test_crypto_auth_token(void)
1468 {
1469 	u8 digest[SHA384_MAC_LEN];
1470 	const u8 *data = (const u8 *) sha_data;
1471 	size_t len = os_strlen(sha_data);
1472 
1473 	NAN_CRYPTO_FAIL(nan_crypto_calc_auth_token(NAN_CS_SK_CCM_128, data,
1474 						   len, digest));
1475 	NAN_CRYPTO_FAIL(os_memcmp(digest, sha256_digest, NAN_AUTH_TOKEN_LEN));
1476 
1477 	os_memset(digest, 0, sizeof(digest));
1478 
1479 	NAN_CRYPTO_FAIL(nan_crypto_calc_auth_token(NAN_CS_SK_GCM_256, data, len,
1480 						   digest));
1481 	NAN_CRYPTO_FAIL(os_memcmp(digest, sha384_digest, NAN_AUTH_TOKEN_LEN));
1482 
1483 	return 0;
1484 }
1485 
1486 
nan_test_derive_nd_pmk(void)1487 static int nan_test_derive_nd_pmk(void)
1488 {
1489 	u8 pmk[PMK_LEN];
1490 	/* Wi-Fi Aware spec v4.0, Appendix M.1 - Test Vector 1 */
1491 	const char *pwd = "NAN";
1492 	const u8 service_id[NAN_SERVICE_ID_LEN] = {
1493 		0x2b, 0x9c, 0x45, 0x0f, 0x66, 0x71,
1494 	};
1495 	const u8 nmi[ETH_ALEN] = {
1496 		0x02, 0x90, 0x4c, 0x12, 0xd0, 0x01,
1497 	};
1498 	const u8 expected_pmk_ccm128[PMK_LEN] = {
1499 		0xee, 0x35, 0x85, 0x06, 0x30, 0x56, 0xd1, 0x64,
1500 		0xd1, 0x54, 0x54, 0xad, 0x39, 0x01, 0x0d, 0x4e,
1501 		0x26, 0x40, 0xb0, 0xd8, 0x2f, 0xb2, 0x4a, 0x2d,
1502 		0x68, 0x99, 0x86, 0x2d, 0x27, 0x3c, 0x68, 0xbf,
1503 	};
1504 
1505 	NAN_CRYPTO_FAIL(nan_crypto_derive_nd_pmk(pwd, service_id,
1506 						 NAN_CS_SK_CCM_128, nmi, pmk));
1507 	NAN_CRYPTO_FAIL(os_memcmp(pmk, expected_pmk_ccm128, PMK_LEN));
1508 
1509 	return 0;
1510 }
1511 
nan_test_crypto(void)1512 int nan_test_crypto(void)
1513 {
1514 	NAN_CRYPTO_FAIL(nan_test_crypto_key_mic());
1515 	NAN_CRYPTO_FAIL(nan_test_crypto_pmkid());
1516 	NAN_CRYPTO_FAIL(nan_test_ptk());
1517 	NAN_CRYPTO_FAIL(nan_test_crypto_auth_token());
1518 	NAN_CRYPTO_FAIL(nan_test_derive_nd_pmk());
1519 
1520 	return 0;
1521 }
1522 
1523 
nan_module_tests(void)1524 int nan_module_tests(void)
1525 {
1526 	if (nan_test_crypto())
1527 		return -1;
1528 
1529 	return nan_test_run();
1530 }
1531