xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/mesh/src/prov.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
1 /*  Bluetooth Mesh */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 #include "syscfg/syscfg.h"
9 #if MYNEWT_VAL(BLE_MESH_PROV) == 1
10 
11 #include <errno.h>
12 
13 #define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_PROV))
14 #include "host/ble_hs_log.h"
15 
16 #include "mesh/mesh.h"
17 #include "mesh_priv.h"
18 
19 #include <tinycrypt/ecc.h>
20 
21 #include "crypto.h"
22 #include "atomic.h"
23 #include "adv.h"
24 #include "net.h"
25 #include "access.h"
26 #include "foundation.h"
27 #include "proxy.h"
28 #include "prov.h"
29 #include "testing.h"
30 
31 /* 3 transmissions, 20ms interval */
32 #define PROV_XMIT              BT_MESH_TRANSMIT(2, 20)
33 
34 #define AUTH_METHOD_NO_OOB     0x00
35 #define AUTH_METHOD_STATIC     0x01
36 #define AUTH_METHOD_OUTPUT     0x02
37 #define AUTH_METHOD_INPUT      0x03
38 
39 #define OUTPUT_OOB_BLINK       0x00
40 #define OUTPUT_OOB_BEEP        0x01
41 #define OUTPUT_OOB_VIBRATE     0x02
42 #define OUTPUT_OOB_NUMBER      0x03
43 #define OUTPUT_OOB_STRING      0x04
44 
45 #define INPUT_OOB_PUSH         0x00
46 #define INPUT_OOB_TWIST        0x01
47 #define INPUT_OOB_NUMBER       0x02
48 #define INPUT_OOB_STRING       0x03
49 
50 #define PROV_ERR_NONE          0x00
51 #define PROV_ERR_NVAL_PDU      0x01
52 #define PROV_ERR_NVAL_FMT      0x02
53 #define PROV_ERR_UNEXP_PDU     0x03
54 #define PROV_ERR_CFM_FAILED    0x04
55 #define PROV_ERR_RESOURCES     0x05
56 #define PROV_ERR_DECRYPT       0x06
57 #define PROV_ERR_UNEXP_ERR     0x07
58 #define PROV_ERR_ADDR          0x08
59 
60 #define PROV_INVITE            0x00
61 #define PROV_CAPABILITIES      0x01
62 #define PROV_START             0x02
63 #define PROV_PUB_KEY           0x03
64 #define PROV_INPUT_COMPLETE    0x04
65 #define PROV_CONFIRM           0x05
66 #define PROV_RANDOM            0x06
67 #define PROV_DATA              0x07
68 #define PROV_COMPLETE          0x08
69 #define PROV_FAILED            0x09
70 
71 #define PROV_ALG_P256          0x00
72 
73 #define GPCF(gpc)              (gpc & 0x03)
74 #define GPC_START(last_seg)    (((last_seg) << 2) | 0x00)
75 #define GPC_ACK                0x01
76 #define GPC_CONT(seg_id)       (((seg_id) << 2) | 0x02)
77 #define GPC_CTL(op)            (((op) << 2) | 0x03)
78 
79 #define START_PAYLOAD_MAX      20
80 #define CONT_PAYLOAD_MAX       23
81 
82 #define START_LAST_SEG(gpc)    (gpc >> 2)
83 #define CONT_SEG_INDEX(gpc)    (gpc >> 2)
84 
85 #define BEARER_CTL(gpc)        (gpc >> 2)
86 #define LINK_OPEN              0x00
87 #define LINK_ACK               0x01
88 #define LINK_CLOSE             0x02
89 
90 #define CLOSE_REASON_SUCCESS   0x00
91 #define CLOSE_REASON_TIMEOUT   0x01
92 #define CLOSE_REASON_FAILED    0x02
93 
94 #define XACT_SEG_DATA(_seg) (&link.rx.buf->om_data[20 + ((_seg - 1) * 23)])
95 #define XACT_SEG_RECV(_seg) (link.rx.seg &= ~(1 << (_seg)))
96 
97 #define XACT_NVAL              0xff
98 
99 enum {
100 	REMOTE_PUB_KEY,        /* Remote key has been received */
101 	LOCAL_PUB_KEY,         /* Local public key is available */
102 	LINK_ACTIVE,           /* Link has been opened */
103 	HAVE_DHKEY,            /* DHKey has been calcualted */
104 	SEND_CONFIRM,          /* Waiting to send Confirm value */
105 	WAIT_NUMBER,           /* Waiting for number input from user */
106 	WAIT_STRING,           /* Waiting for string input from user */
107 
108 	NUM_FLAGS,
109 };
110 
111 struct prov_link {
112 	ATOMIC_DEFINE(flags, NUM_FLAGS);
113 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
114 	uint16_t conn_handle;    /* GATT connection */
115 #endif
116 	u8_t  dhkey[32];         /* Calculated DHKey */
117 	u8_t  expect;            /* Next expected PDU */
118 
119 	u8_t  oob_method;
120 	u8_t  oob_action;
121 	u8_t  oob_size;
122 
123 	u8_t  conf[16];          /* Remote Confirmation */
124 	u8_t  rand[16];          /* Local Random */
125 	u8_t  auth[16];          /* Authentication Value */
126 
127 	u8_t  conf_salt[16];     /* ConfirmationSalt */
128 	u8_t  conf_key[16];      /* ConfirmationKey */
129 	u8_t  conf_inputs[145];  /* ConfirmationInputs */
130 	u8_t  prov_salt[16];     /* Provisioning Salt */
131 
132 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
133 	u32_t id;                /* Link ID */
134 #endif
135 
136 	struct {
137 		u8_t  id;        /* Transaction ID */
138 		u8_t  prev_id;   /* Previous Transaction ID */
139 		u8_t  seg;       /* Bit-field of unreceived segments */
140 		u8_t  last_seg;  /* Last segment (to check length) */
141 		u8_t  fcs;       /* Expected FCS value */
142 		struct os_mbuf *buf;
143 	} rx;
144 
145 	struct {
146 		/* Start timestamp of the transaction */
147 		s64_t start;
148 
149 		/* Transaction id*/
150 		u8_t id;
151 
152 		/* Pending outgoing buffer(s) */
153 		struct os_mbuf *buf[3];
154 
155 		/* Retransmit timer */
156 		struct k_delayed_work retransmit;
157 	} tx;
158 };
159 
160 struct prov_rx {
161 	u32_t link_id;
162 	u8_t  xact_id;
163 	u8_t  gpc;
164 };
165 
166 #define RETRANSMIT_TIMEOUT   K_MSEC(500)
167 #define BUF_TIMEOUT          K_MSEC(400)
168 #define TRANSACTION_TIMEOUT  K_SECONDS(30)
169 
170 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
171 #define PROV_BUF_HEADROOM 5
172 #else
173 #define PROV_BUF_HEADROOM 0
174 static struct os_mbuf *rx_buf;
175 #endif
176 
177 #define PROV_BUF(len) NET_BUF_SIMPLE(PROV_BUF_HEADROOM + len)
178 
179 static struct prov_link link;
180 
181 static const struct bt_mesh_prov *prov;
182 
183 static void close_link(u8_t err, u8_t reason);
184 
185 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
buf_sent(int err,void * user_data)186 static void buf_sent(int err, void *user_data)
187 {
188 	BT_DBG("buf_sent");
189 
190 	if (!link.tx.buf[0]) {
191 		return;
192 	}
193 
194 	k_delayed_work_submit(&link.tx.retransmit, RETRANSMIT_TIMEOUT);
195 }
196 
197 static struct bt_mesh_send_cb buf_sent_cb = {
198 	.end = buf_sent,
199 };
200 
free_segments(void)201 static void free_segments(void)
202 {
203 	int i;
204 
205 	for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) {
206 		struct os_mbuf *buf = link.tx.buf[i];
207 
208 		if (!buf) {
209 			break;
210 		}
211 
212 		link.tx.buf[i] = NULL;
213 		/* Mark as canceled */
214 		BT_MESH_ADV(buf)->busy = 0;
215 		net_buf_unref(buf);
216 	}
217 }
218 
prov_clear_tx(void)219 static void prov_clear_tx(void)
220 {
221 	BT_DBG("");
222 
223 	k_delayed_work_cancel(&link.tx.retransmit);
224 
225 	free_segments();
226 }
227 
reset_link(void)228 static void reset_link(void)
229 {
230 	atomic_clear_bit(link.flags, LINK_ACTIVE);
231 
232 	prov_clear_tx();
233 
234 	if (prov->link_close) {
235 		prov->link_close(BT_MESH_PROV_ADV);
236 	}
237 
238 	/* Clear everything except the retransmit delayed work config */
239 	memset(&link, 0, offsetof(struct prov_link, tx.retransmit));
240 
241 	link.rx.prev_id = XACT_NVAL;
242 
243 	if (bt_pub_key_get()) {
244 		atomic_set_bit(link.flags, LOCAL_PUB_KEY);
245 	}
246 
247 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
248 	link.rx.buf = bt_mesh_proxy_get_buf();
249 #else
250 	net_buf_simple_init(rx_buf, 0);
251 	link.rx.buf = rx_buf;
252 #endif
253 
254 	/* Disable Attention Timer if it was set */
255 	if (link.conf_inputs[0]) {
256 		bt_mesh_attention(NULL, 0);
257 	}
258 }
259 
adv_buf_create(void)260 static struct os_mbuf *adv_buf_create(void)
261 {
262 	struct os_mbuf *buf;
263 
264 	buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, PROV_XMIT, BUF_TIMEOUT);
265 	if (!buf) {
266 		BT_ERR("Out of provisioning buffers");
267 		assert(0);
268 		return NULL;
269 	}
270 
271 	return buf;
272 }
273 
274 static u8_t pending_ack = XACT_NVAL;
275 
ack_complete(u16_t duration,int err,void * user_data)276 static void ack_complete(u16_t duration, int err, void *user_data)
277 {
278 	BT_DBG("xact %u complete", (u8_t)pending_ack);
279 	pending_ack = XACT_NVAL;
280 }
281 
gen_prov_ack_send(u8_t xact_id)282 static void gen_prov_ack_send(u8_t xact_id)
283 {
284 	static const struct bt_mesh_send_cb cb = {
285 		.start = ack_complete,
286 	};
287 	const struct bt_mesh_send_cb *complete;
288 	struct os_mbuf *buf;
289 
290 	BT_DBG("xact_id %u", xact_id);
291 
292 	if (pending_ack == xact_id) {
293 		BT_DBG("Not sending duplicate ack");
294 		return;
295 	}
296 
297 	buf = adv_buf_create();
298 	if (!buf) {
299 		return;
300 	}
301 
302 	if (pending_ack == XACT_NVAL) {
303 		pending_ack = xact_id;
304 		complete = &cb;
305 	} else {
306 		complete = NULL;
307 	}
308 
309 	net_buf_add_be32(buf, link.id);
310 	net_buf_add_u8(buf, xact_id);
311 	net_buf_add_u8(buf, GPC_ACK);
312 
313 	bt_mesh_adv_send(buf, complete, NULL);
314 	net_buf_unref(buf);
315 }
316 
send_reliable(void)317 static void send_reliable(void)
318 {
319 	int i;
320 
321 	link.tx.start = k_uptime_get();
322 
323 	for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) {
324 		struct os_mbuf *buf = link.tx.buf[i];
325 
326 		if (!buf) {
327 			break;
328 		}
329 
330 		if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) {
331 			bt_mesh_adv_send(buf, NULL, NULL);
332 		} else {
333 			bt_mesh_adv_send(buf, &buf_sent_cb, NULL);
334 		}
335 	}
336 }
337 
bearer_ctl_send(u8_t op,void * data,u8_t data_len)338 static int bearer_ctl_send(u8_t op, void *data, u8_t data_len)
339 {
340 	struct os_mbuf *buf;
341 
342 	BT_DBG("op 0x%02x data_len %u", op, data_len);
343 
344 	prov_clear_tx();
345 
346 	buf = adv_buf_create();
347 	if (!buf) {
348 		return -ENOBUFS;
349 	}
350 
351 	net_buf_add_be32(buf, link.id);
352 	/* Transaction ID, always 0 for Bearer messages */
353 	net_buf_add_u8(buf, 0x00);
354 	net_buf_add_u8(buf, GPC_CTL(op));
355 	net_buf_add_mem(buf, data, data_len);
356 
357 	link.tx.buf[0] = buf;
358 	send_reliable();
359 
360 	return 0;
361 }
362 
last_seg(u8_t len)363 static u8_t last_seg(u8_t len)
364 {
365 	if (len <= START_PAYLOAD_MAX) {
366 		return 0;
367 	}
368 
369 	len -= START_PAYLOAD_MAX;
370 
371 	return 1 + (len / CONT_PAYLOAD_MAX);
372 }
373 
next_transaction_id(void)374 static inline u8_t next_transaction_id(void)
375 {
376 	if (link.tx.id != 0 && link.tx.id != 0xFF) {
377 		return ++link.tx.id;
378 	}
379 
380 	link.tx.id = 0x80;
381 	return link.tx.id;
382 }
383 
prov_send_adv(struct os_mbuf * msg)384 static int prov_send_adv(struct os_mbuf *msg)
385 {
386 	struct os_mbuf *start, *buf;
387 	u8_t seg_len, seg_id;
388 	u8_t xact_id;
389 
390 	BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len));
391 
392 	prov_clear_tx();
393 
394 	start = adv_buf_create();
395 	if (!start) {
396 		return -ENOBUFS;
397 	}
398 
399 	xact_id = next_transaction_id();
400 	net_buf_add_be32(start, link.id);
401 	net_buf_add_u8(start, xact_id);
402 
403 	net_buf_add_u8(start, GPC_START(last_seg(msg->om_len)));
404 	net_buf_add_be16(start, msg->om_len);
405 	net_buf_add_u8(start, bt_mesh_fcs_calc(msg->om_data, msg->om_len));
406 
407 	link.tx.buf[0] = start;
408 
409 	seg_len = min(msg->om_len, START_PAYLOAD_MAX);
410 	BT_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->om_data, seg_len));
411 	net_buf_add_mem(start, msg->om_data, seg_len);
412 	net_buf_simple_pull(msg, seg_len);
413 
414 	buf = start;
415 	for (seg_id = 1; msg->om_len > 0; seg_id++) {
416 		if (seg_id >= ARRAY_SIZE(link.tx.buf)) {
417 			BT_ERR("Too big message");
418 			free_segments();
419 			return -E2BIG;
420 		}
421 
422 		buf = adv_buf_create();
423 		if (!buf) {
424 			free_segments();
425 			return -ENOBUFS;
426 		}
427 
428 		link.tx.buf[seg_id] = buf;
429 
430 		seg_len = min(msg->om_len, CONT_PAYLOAD_MAX);
431 
432 		BT_DBG("seg_id %u len %u: %s", seg_id, seg_len,
433 		       bt_hex(msg->om_data, seg_len));
434 
435 		net_buf_add_be32(buf, link.id);
436 		net_buf_add_u8(buf, xact_id);
437 		net_buf_add_u8(buf, GPC_CONT(seg_id));
438 		net_buf_add_mem(buf, msg->om_data, seg_len);
439 		net_buf_simple_pull(msg, seg_len);
440 	}
441 
442 	send_reliable();
443 
444 	return 0;
445 }
446 
447 #endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */
448 
449 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
prov_send_gatt(struct os_mbuf * msg)450 static int prov_send_gatt(struct os_mbuf *msg)
451 {
452 	if (!link.conn_handle) {
453 		BT_ERR("No connection handle!?");
454 		return -ENOTCONN;
455 	}
456 
457 	return bt_mesh_proxy_send(link.conn_handle, BT_MESH_PROXY_PROV, msg);
458 }
459 #endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */
460 
prov_send(struct os_mbuf * buf)461 static inline int prov_send(struct os_mbuf *buf)
462 {
463 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
464 	if (link.conn_handle) {
465 		return prov_send_gatt(buf);
466 	}
467 #endif
468 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
469 	return prov_send_adv(buf);
470 #else
471 	return 0;
472 #endif
473 }
474 
prov_buf_init(struct os_mbuf * buf,u8_t type)475 static void prov_buf_init(struct os_mbuf *buf, u8_t type)
476 {
477 	net_buf_simple_init(buf, PROV_BUF_HEADROOM);
478 	net_buf_simple_add_u8(buf, type);
479 }
480 
prov_send_fail_msg(u8_t err)481 static void prov_send_fail_msg(u8_t err)
482 {
483 	struct os_mbuf *buf = PROV_BUF(2);
484 
485 	prov_buf_init(buf, PROV_FAILED);
486 	net_buf_simple_add_u8(buf, err);
487 	prov_send(buf);
488 	os_mbuf_free_chain(buf);
489 }
490 
prov_invite(const u8_t * data)491 static void prov_invite(const u8_t *data)
492 {
493 	struct os_mbuf *buf = PROV_BUF(12);
494 
495 	BT_INFO("Attention Duration: %u seconds", data[0]);
496 
497 	if (data[0]) {
498 		bt_mesh_attention(NULL, data[0]);
499 	}
500 
501 	link.conf_inputs[0] = data[0];
502 
503 	prov_buf_init(buf, PROV_CAPABILITIES);
504 
505 	/* Number of Elements supported */
506 	net_buf_simple_add_u8(buf, bt_mesh_elem_count());
507 
508 	/* Supported algorithms - FIPS P-256 Eliptic Curve */
509 	net_buf_simple_add_be16(buf, BIT(PROV_ALG_P256));
510 
511 	/* Public Key Type */
512 	/*PTS OOB*/
513 	net_buf_simple_add_u8(buf, 0x00);
514 
515 	/* Static OOB Type */
516 	net_buf_simple_add_u8(buf, prov->static_val ? BIT(0) : 0x00);
517 
518 	/* Output OOB Size */
519 	net_buf_simple_add_u8(buf, prov->output_size);
520 
521 	/* Output OOB Action */
522 	net_buf_simple_add_be16(buf, prov->output_actions);
523 
524 	/* Input OOB Size */
525 	net_buf_simple_add_u8(buf, prov->input_size);
526 
527 	/* Input OOB Action */
528 	net_buf_simple_add_be16(buf, prov->input_actions);
529 
530 	memcpy(&link.conf_inputs[1], &buf->om_data[1], 11);
531 
532 	if (prov_send(buf)) {
533 		BT_ERR("Failed to send capabilities");
534 		close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
535 		goto done;
536 	}
537 
538 	link.expect = PROV_START;
539 
540 done:
541 	os_mbuf_free_chain(buf);
542 }
543 
prov_capabilities(const u8_t * data)544 static void prov_capabilities(const u8_t *data)
545 {
546 	u16_t algorithms, output_action, input_action;
547 
548 	BT_INFO("Elements: %u", data[0]);
549 
550 	algorithms = sys_get_be16(&data[1]);
551 	BT_INFO("Algorithms:        %u", algorithms);
552 
553 	BT_INFO("Public Key Type:   0x%02x", data[3]);
554 	BT_INFO("Static OOB Type:   0x%02x", data[4]);
555 	BT_INFO("Output OOB Size:   %u", data[5]);
556 
557 	output_action = sys_get_be16(&data[6]);
558 	BT_INFO("Output OOB Action: 0x%04x", output_action);
559 
560 	BT_INFO("Input OOB Size:    %u", data[8]);
561 
562 	input_action = sys_get_be16(&data[9]);
563 	BT_INFO("Input OOB Action:  0x%04x", input_action);
564 }
565 
output_action(u8_t action)566 static bt_mesh_output_action_t output_action(u8_t action)
567 {
568 	switch (action) {
569 	case OUTPUT_OOB_BLINK:
570 		return BT_MESH_BLINK;
571 	case OUTPUT_OOB_BEEP:
572 		return BT_MESH_BEEP;
573 	case OUTPUT_OOB_VIBRATE:
574 		return BT_MESH_VIBRATE;
575 	case OUTPUT_OOB_NUMBER:
576 		return BT_MESH_DISPLAY_NUMBER;
577 	case OUTPUT_OOB_STRING:
578 		return BT_MESH_DISPLAY_STRING;
579 	default:
580 		return BT_MESH_NO_OUTPUT;
581 	}
582 }
583 
input_action(u8_t action)584 static bt_mesh_input_action_t input_action(u8_t action)
585 {
586 	switch (action) {
587 	case INPUT_OOB_PUSH:
588 		return BT_MESH_PUSH;
589 	case INPUT_OOB_TWIST:
590 		return BT_MESH_TWIST;
591 	case INPUT_OOB_NUMBER:
592 		return BT_MESH_ENTER_NUMBER;
593 	case INPUT_OOB_STRING:
594 		return BT_MESH_ENTER_STRING;
595 	default:
596 		return BT_MESH_NO_INPUT;
597 	}
598 }
599 
prov_auth(u8_t method,u8_t action,u8_t size)600 static int prov_auth(u8_t method, u8_t action, u8_t size)
601 {
602 	bt_mesh_output_action_t output;
603 	bt_mesh_input_action_t input;
604 
605 	switch (method) {
606 	case AUTH_METHOD_NO_OOB:
607 		if (action || size) {
608 			return -EINVAL;
609 		}
610 
611 		memset(link.auth, 0, sizeof(link.auth));
612 		return 0;
613 	case AUTH_METHOD_STATIC:
614 		if (action || size) {
615 			return -EINVAL;
616 		}
617 
618 		memcpy(link.auth + 16 - prov->static_val_len,
619 		       prov->static_val, prov->static_val_len);
620 		memset(link.auth, 0, sizeof(link.auth) - prov->static_val_len);
621 		return 0;
622 
623 	case AUTH_METHOD_OUTPUT:
624 		output = output_action(action);
625 		if (!output) {
626 			return -EINVAL;
627 		}
628 
629 		if (!(prov->output_actions & output)) {
630 			return -EINVAL;
631 		}
632 
633 		if (size > prov->output_size) {
634 			return -EINVAL;
635 		}
636 
637 		if (output == BT_MESH_DISPLAY_STRING) {
638 			unsigned char str[9];
639 			u8_t i;
640 
641 			bt_rand(str, size);
642 
643 			/* Normalize to '0' .. '9' & 'A' .. 'Z' */
644 			for (i = 0; i < size; i++) {
645 				str[i] %= 36;
646 				if (str[i] < 10) {
647 					str[i] += '0';
648 				} else {
649 					str[i] += 'A' - 10;
650 				}
651 			}
652 			str[size] = '\0';
653 
654 			memcpy(link.auth, str, size);
655 			memset(link.auth + size, 0, sizeof(link.auth) - size);
656 
657 			return prov->output_string((char *)str);
658 		} else {
659 			u32_t div[8] = { 10, 100, 1000, 10000, 100000,
660 					    1000000, 10000000, 100000000 };
661 			u32_t num;
662 
663 			bt_rand(&num, sizeof(num));
664 			num %= div[size - 1];
665 
666 			sys_put_be32(num, &link.auth[12]);
667 			memset(link.auth, 0, 12);
668 
669 			return prov->output_number(output, num);
670 		}
671 
672 	case AUTH_METHOD_INPUT:
673 		input = input_action(action);
674 		if (!input) {
675 			return -EINVAL;
676 		}
677 
678 		if (!(prov->input_actions & input)) {
679 			return -EINVAL;
680 		}
681 
682 		if (size > prov->input_size) {
683 			return -EINVAL;
684 		}
685 
686 		if (input == BT_MESH_ENTER_STRING) {
687 			atomic_set_bit(link.flags, WAIT_STRING);
688 		} else {
689 			atomic_set_bit(link.flags, WAIT_NUMBER);
690 		}
691 
692 		return prov->input(input, size);
693 
694 	default:
695 		return -EINVAL;
696 	}
697 }
698 
prov_start(const u8_t * data)699 static void prov_start(const u8_t *data)
700 {
701 	BT_INFO("Algorithm:   0x%02x", data[0]);
702 	BT_INFO("Public Key:  0x%02x", data[1]);
703 	BT_INFO("Auth Method: 0x%02x", data[2]);
704 	BT_INFO("Auth Action: 0x%02x", data[3]);
705 	BT_INFO("Auth Size:   0x%02x", data[4]);
706 
707 	if (data[0] != PROV_ALG_P256) {
708 		BT_ERR("Unknown algorithm 0x%02x", data[0]);
709 		prov_send_fail_msg(PROV_ERR_NVAL_FMT);
710 		return;
711 	}
712 
713 	if (data[1] > 0x01) {
714 		BT_ERR("Invalid public key value: 0x%02x", data[1]);
715 		prov_send_fail_msg(PROV_ERR_NVAL_FMT);
716 		return;
717 	}
718 
719 	memcpy(&link.conf_inputs[12], data, 5);
720 
721 	/* TODO: reset link when auth fails? */
722 	link.expect = PROV_PUB_KEY;
723 
724 	if (prov_auth(data[2], data[3], data[4]) < 0) {
725 		BT_ERR("Invalid authentication method: 0x%02x; "
726 			"action: 0x%02x; size: 0x%02x", data[2], data[3],
727 			data[4]);
728 		prov_send_fail_msg(PROV_ERR_NVAL_FMT);
729 	}
730 }
731 
send_confirm(void)732 static void send_confirm(void)
733 {
734 	struct os_mbuf *cfm = PROV_BUF(17);
735 
736 	BT_DBG("ConfInputs[0]   %s", bt_hex(link.conf_inputs, 64));
737 	BT_DBG("ConfInputs[64]  %s", bt_hex(&link.conf_inputs[64], 64));
738 	BT_DBG("ConfInputs[128] %s", bt_hex(&link.conf_inputs[128], 17));
739 
740 	if (bt_mesh_prov_conf_salt(link.conf_inputs, link.conf_salt)) {
741 		BT_ERR("Unable to generate confirmation salt");
742 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
743 		goto done;
744 	}
745 
746 	BT_DBG("ConfirmationSalt: %s", bt_hex(link.conf_salt, 16));
747 
748 	if (bt_mesh_prov_conf_key(link.dhkey, link.conf_salt, link.conf_key)) {
749 		BT_ERR("Unable to generate confirmation key");
750 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
751 		goto done;
752 	}
753 
754 	BT_DBG("ConfirmationKey: %s", bt_hex(link.conf_key, 16));
755 
756 	if (bt_rand(link.rand, 16)) {
757 		BT_ERR("Unable to generate random number");
758 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
759 		goto done;
760 	}
761 
762 	BT_DBG("LocalRandom: %s", bt_hex(link.rand, 16));
763 
764 	prov_buf_init(cfm, PROV_CONFIRM);
765 
766 	if (bt_mesh_prov_conf(link.conf_key, link.rand, link.auth,
767 			      net_buf_simple_add(cfm, 16))) {
768 		BT_ERR("Unable to generate confirmation value");
769 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
770 		goto done;
771 	}
772 
773 	if (prov_send(cfm)) {
774 		BT_ERR("Failed to send Provisioning Confirm");
775 		close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
776 		goto done;
777 	}
778 
779 	link.expect = PROV_RANDOM;
780 
781 done:
782 	os_mbuf_free_chain(cfm);
783 }
784 
send_input_complete(void)785 static void send_input_complete(void)
786 {
787 	struct os_mbuf *buf = PROV_BUF(1);
788 
789 	prov_buf_init(buf, PROV_INPUT_COMPLETE);
790 	prov_send(buf);
791 
792 	os_mbuf_free_chain(buf);
793 }
794 
bt_mesh_input_number(u32_t num)795 int bt_mesh_input_number(u32_t num)
796 {
797 	BT_DBG("%u", num);
798 
799 	if (!atomic_test_and_clear_bit(link.flags, WAIT_NUMBER)) {
800 		return -EINVAL;
801 	}
802 
803 	sys_put_be32(num, &link.auth[12]);
804 
805 	send_input_complete();
806 
807 	if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
808 		return 0;
809 	}
810 
811 	if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
812 		send_confirm();
813 	}
814 
815 	return 0;
816 }
817 
bt_mesh_input_string(const char * str)818 int bt_mesh_input_string(const char *str)
819 {
820 	BT_DBG("%s", str);
821 
822 	if (!atomic_test_and_clear_bit(link.flags, WAIT_STRING)) {
823 		return -EINVAL;
824 	}
825 
826 	strncpy((char *)link.auth, str, prov->input_size);
827 
828 	send_input_complete();
829 
830 	if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
831 		return 0;
832 	}
833 
834 	if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
835 		send_confirm();
836 	}
837 
838 	return 0;
839 }
840 
prov_dh_key_cb(const u8_t key[32])841 static void prov_dh_key_cb(const u8_t key[32])
842 {
843 	BT_DBG("%p", key);
844 
845 	if (!key) {
846 		BT_ERR("DHKey generation failed");
847 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
848 		return;
849 	}
850 
851 	sys_memcpy_swap(link.dhkey, key, 32);
852 
853 	BT_DBG("DHkey: %s", bt_hex(link.dhkey, 32));
854 
855 	atomic_set_bit(link.flags, HAVE_DHKEY);
856 
857 	if (atomic_test_bit(link.flags, WAIT_NUMBER) ||
858 	    atomic_test_bit(link.flags, WAIT_STRING)) {
859 		return;
860 	}
861 
862 	if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
863 		send_confirm();
864 	}
865 }
866 
send_pub_key(void)867 static void send_pub_key(void)
868 {
869 	struct os_mbuf *buf = PROV_BUF(65);
870 	const u8_t *key;
871 
872 	key = bt_pub_key_get();
873 	if (!key) {
874 		BT_ERR("No public key available");
875 		close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
876 		goto done;
877 	}
878 
879 	prov_buf_init(buf, PROV_PUB_KEY);
880 
881 	/* Swap X and Y halves independently to big-endian */
882 	sys_memcpy_swap(net_buf_simple_add(buf, 32), key, 32);
883 	sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32);
884 
885 	memcpy(&link.conf_inputs[81], &buf->om_data[1], 64);
886 
887 	BT_DBG("Local Public Key: %s", bt_hex(&buf->om_data[1], 64));
888 
889 	prov_send(buf);
890 
891 	/* Copy remote key in little-endian for bt_dh_key_gen().
892 	 * X and Y halves are swapped independently.
893 	 */
894 	net_buf_simple_init(buf, 0);
895 	sys_memcpy_swap(buf->om_data, &link.conf_inputs[17], 32);
896 	sys_memcpy_swap(&buf->om_data[32], &link.conf_inputs[49], 32);
897 
898 	if (bt_dh_key_gen(buf->om_data, prov_dh_key_cb)) {
899 		BT_ERR("Failed to generate DHKey");
900 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
901 		goto done;
902 	}
903 
904 	link.expect = PROV_CONFIRM;
905 
906 done:
907 	os_mbuf_free_chain(buf);
908 }
909 
prov_pub_key(const u8_t * data)910 static void prov_pub_key(const u8_t *data)
911 {
912 	BT_INFO("Remote Public Key: %s", bt_hex(data, 64));
913 
914 	memcpy(&link.conf_inputs[17], data, 64);
915 
916 	if (!atomic_test_bit(link.flags, LOCAL_PUB_KEY)) {
917 		/* Clear retransmit timer */
918 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
919 		prov_clear_tx();
920 #endif
921 		atomic_set_bit(link.flags, REMOTE_PUB_KEY);
922 		BT_WARN("Waiting for local public key");
923 		return;
924 	}
925 
926 	send_pub_key();
927 }
928 
pub_key_ready(const u8_t * pkey)929 static void pub_key_ready(const u8_t *pkey)
930 {
931 	if (!pkey) {
932 		BT_WARN("Public key not available");
933 		return;
934 	}
935 
936 	BT_DBG("Local public key ready");
937 
938 	atomic_set_bit(link.flags, LOCAL_PUB_KEY);
939 
940 	if (atomic_test_and_clear_bit(link.flags, REMOTE_PUB_KEY)) {
941 		send_pub_key();
942 	}
943 }
944 
prov_input_complete(const u8_t * data)945 static void prov_input_complete(const u8_t *data)
946 {
947 	BT_DBG("");
948 }
949 
prov_confirm(const u8_t * data)950 static void prov_confirm(const u8_t *data)
951 {
952 	BT_INFO("Remote Confirm: %s", bt_hex(data, 16));
953 
954 	memcpy(link.conf, data, 16);
955 
956 	if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
957 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
958 		prov_clear_tx();
959 #endif
960 		atomic_set_bit(link.flags, SEND_CONFIRM);
961 	} else {
962 		send_confirm();
963 	}
964 }
965 
prov_random(const u8_t * data)966 static void prov_random(const u8_t *data)
967 {
968 	struct os_mbuf *rnd = PROV_BUF(16);
969 	u8_t conf_verify[16];
970 
971 	BT_INFO("Remote Random: %s", bt_hex(data, 16));
972 
973 	if (bt_mesh_prov_conf(link.conf_key, data, link.auth, conf_verify)) {
974 		BT_ERR("Unable to calculate confirmation verification");
975 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
976 		goto done;
977 	}
978 
979 	if (memcmp(conf_verify, link.conf, 16)) {
980 		BT_ERR("Invalid confirmation value");
981 		BT_DBG("Received:   %s", bt_hex(link.conf, 16));
982 		BT_DBG("Calculated: %s",  bt_hex(conf_verify, 16));
983 		close_link(PROV_ERR_CFM_FAILED, CLOSE_REASON_FAILED);
984 		goto done;
985 	}
986 
987 	prov_buf_init(rnd, PROV_RANDOM);
988 	net_buf_simple_add_mem(rnd, link.rand, 16);
989 
990 	if (prov_send(rnd)) {
991 		BT_ERR("Failed to send Provisioning Random");
992 		close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
993 		goto done;
994 	}
995 
996 	if (bt_mesh_prov_salt(link.conf_salt, data, link.rand,
997 			      link.prov_salt)) {
998 		BT_ERR("Failed to generate provisioning salt");
999 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
1000 		goto done;
1001 	}
1002 
1003 	BT_DBG("ProvisioningSalt: %s", bt_hex(link.prov_salt, 16));
1004 
1005 	link.expect = PROV_DATA;
1006 
1007 done:
1008     os_mbuf_free_chain(rnd);
1009 }
1010 
is_pb_gatt(void)1011 static inline bool is_pb_gatt(void)
1012 {
1013 #if MYNEWT_VAL(BLE_MESH_PB_GATT)
1014 	return !!link.conn_handle;
1015 #else
1016 	return false;
1017 #endif
1018 }
1019 
prov_data(const u8_t * data)1020 static void prov_data(const u8_t *data)
1021 {
1022 	struct os_mbuf *msg = PROV_BUF(1);
1023 	u8_t session_key[16];
1024 	u8_t nonce[13];
1025 	u8_t dev_key[16];
1026 	u8_t pdu[25];
1027 	u8_t flags;
1028 	u32_t iv_index;
1029 	u16_t addr;
1030 	u16_t net_idx;
1031 	int err;
1032 	bool identity_enable;
1033 
1034 	BT_DBG("");
1035 
1036 	err = bt_mesh_session_key(link.dhkey, link.prov_salt, session_key);
1037 	if (err) {
1038 		BT_ERR("Unable to generate session key");
1039 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
1040 		goto done;
1041 	}
1042 
1043 	BT_DBG("SessionKey: %s", bt_hex(session_key, 16));
1044 
1045 	err = bt_mesh_prov_nonce(link.dhkey, link.prov_salt, nonce);
1046 	if (err) {
1047 		BT_ERR("Unable to generate session nonce");
1048 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
1049 		goto done;
1050 	}
1051 
1052 	BT_DBG("Nonce: %s", bt_hex(nonce, 13));
1053 
1054 	err = bt_mesh_prov_decrypt(session_key, nonce, data, pdu);
1055 	if (err) {
1056 		BT_ERR("Unable to decrypt provisioning data");
1057 		close_link(PROV_ERR_DECRYPT, CLOSE_REASON_FAILED);
1058 		goto done;
1059 	}
1060 
1061 	err = bt_mesh_dev_key(link.dhkey, link.prov_salt, dev_key);
1062 	if (err) {
1063 		BT_ERR("Unable to generate device key");
1064 		close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
1065 		goto done;
1066 	}
1067 
1068 	BT_DBG("DevKey: %s", bt_hex(dev_key, 16));
1069 
1070 	net_idx = sys_get_be16(&pdu[16]);
1071 	flags = pdu[18];
1072 	iv_index = sys_get_be32(&pdu[19]);
1073 	addr = sys_get_be16(&pdu[23]);
1074 
1075 	BT_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x",
1076 	       net_idx, iv_index, addr);
1077 
1078 	prov_buf_init(msg, PROV_COMPLETE);
1079 	prov_send(msg);
1080 
1081 	/* Ignore any further PDUs on this link */
1082 	link.expect = 0;
1083 
1084 	/* Store info, since bt_mesh_provision() will end up clearing it */
1085 	if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
1086 		identity_enable = is_pb_gatt();
1087 	} else {
1088 		identity_enable = false;
1089 	}
1090 
1091 	bt_mesh_provision(pdu, net_idx, flags, iv_index, addr, dev_key);
1092 
1093 	/* After PB-GATT provisioning we should start advertising
1094 	 * using Node Identity.
1095 	 */
1096 	if (identity_enable) {
1097 		bt_mesh_proxy_identity_enable();
1098 	}
1099 
1100 done:
1101 	os_mbuf_free_chain(msg);
1102 }
1103 
prov_complete(const u8_t * data)1104 static void prov_complete(const u8_t *data)
1105 {
1106 	BT_INFO("");
1107 }
1108 
prov_failed(const u8_t * data)1109 static void prov_failed(const u8_t *data)
1110 {
1111 	BT_WARN("Error: 0x%02x", data[0]);
1112 }
1113 
1114 static const struct {
1115 	void (*func)(const u8_t *data);
1116 	u16_t len;
1117 } prov_handlers[] = {
1118 	{ prov_invite, 1 },
1119 	{ prov_capabilities, 11 },
1120 	{ prov_start, 5, },
1121 	{ prov_pub_key, 64 },
1122 	{ prov_input_complete, 0 },
1123 	{ prov_confirm, 16 },
1124 	{ prov_random, 16 },
1125 	{ prov_data, 33 },
1126 	{ prov_complete, 0 },
1127 	{ prov_failed, 1 },
1128 };
1129 
close_link(u8_t err,u8_t reason)1130 static void close_link(u8_t err, u8_t reason)
1131 {
1132 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
1133 	if (link.conn_handle) {
1134 		bt_mesh_pb_gatt_close(link.conn_handle);
1135 		return;
1136 	}
1137 #endif
1138 
1139 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
1140 	if (err) {
1141 		prov_send_fail_msg(err);
1142 	}
1143 
1144 	link.rx.seg = 0;
1145 	bearer_ctl_send(LINK_CLOSE, &reason, sizeof(reason));
1146 #endif
1147 
1148 	atomic_clear_bit(link.flags, LINK_ACTIVE);
1149 
1150 	/* Disable Attention Timer if it was set */
1151 	if (link.conf_inputs[0]) {
1152 		bt_mesh_attention(NULL, 0);
1153 	}
1154 }
1155 
1156 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
prov_retransmit(struct ble_npl_event * work)1157 static void prov_retransmit(struct ble_npl_event *work)
1158 {
1159 	int i;
1160 
1161 	BT_DBG("");
1162 
1163 	if (!atomic_test_bit(link.flags, LINK_ACTIVE)) {
1164 		BT_WARN("Link not active");
1165 		return;
1166 	}
1167 
1168 	if (k_uptime_get() - link.tx.start > TRANSACTION_TIMEOUT) {
1169 		BT_WARN("Giving up transaction");
1170 		reset_link();
1171 		return;
1172 	}
1173 
1174 	for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) {
1175 		struct os_mbuf *buf = link.tx.buf[i];
1176 
1177 		if (!buf) {
1178 			break;
1179 		}
1180 
1181 		if (BT_MESH_ADV(buf)->busy) {
1182 			continue;
1183 		}
1184 
1185 		BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len));
1186 
1187 		if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) {
1188 			bt_mesh_adv_send(buf, NULL, NULL);
1189 		} else {
1190 			bt_mesh_adv_send(buf, &buf_sent_cb, NULL);
1191 		}
1192 
1193 	}
1194 }
1195 
link_open(struct prov_rx * rx,struct os_mbuf * buf)1196 static void link_open(struct prov_rx *rx, struct os_mbuf *buf)
1197 {
1198 	BT_INFO("link open: len %u", buf->om_len);
1199 
1200 	if (buf->om_len < 16) {
1201 		BT_ERR("Too short bearer open message (len %u)", buf->om_len);
1202 		return;
1203 	}
1204 
1205 	if (atomic_test_bit(link.flags, LINK_ACTIVE)) {
1206 		/* Send another link ack if the provisioner missed the last */
1207 		if (link.id == rx->link_id && link.expect == PROV_INVITE) {
1208 			BT_DBG("Resending link ack");
1209 			bearer_ctl_send(LINK_ACK, NULL, 0);
1210 		} else {
1211 			BT_WARN("Ignoring bearer open: link already active");
1212 		}
1213 
1214 		return;
1215 	}
1216 
1217 	if (memcmp(buf->om_data, prov->uuid, 16)) {
1218 		BT_DBG("Bearer open message not for us");
1219 		return;
1220 	}
1221 
1222 	if (prov->link_open) {
1223 		prov->link_open(BT_MESH_PROV_ADV);
1224 	}
1225 
1226 	link.id = rx->link_id;
1227 	atomic_set_bit(link.flags, LINK_ACTIVE);
1228 	net_buf_simple_init(link.rx.buf, 0);
1229 
1230 	bearer_ctl_send(LINK_ACK, NULL, 0);
1231 
1232 	link.expect = PROV_INVITE;
1233 }
1234 
link_ack(struct prov_rx * rx,struct os_mbuf * buf)1235 static void link_ack(struct prov_rx *rx, struct os_mbuf *buf)
1236 {
1237 	BT_INFO("Link ack: len %u", buf->om_len);
1238 }
1239 
link_close(struct prov_rx * rx,struct os_mbuf * buf)1240 static void link_close(struct prov_rx *rx, struct os_mbuf *buf)
1241 {
1242 	BT_INFO("Link close: len %u", buf->om_len);
1243 
1244 	reset_link();
1245 }
1246 
gen_prov_ctl(struct prov_rx * rx,struct os_mbuf * buf)1247 static void gen_prov_ctl(struct prov_rx *rx, struct os_mbuf *buf)
1248 {
1249 	BT_DBG("op 0x%02x len %u", BEARER_CTL(rx->gpc), buf->om_len);
1250 
1251 	switch (BEARER_CTL(rx->gpc)) {
1252 	case LINK_OPEN:
1253 		link_open(rx, buf);
1254 		break;
1255 	case LINK_ACK:
1256 		if (!atomic_test_bit(link.flags, LINK_ACTIVE)) {
1257 			return;
1258 		}
1259 
1260 		link_ack(rx, buf);
1261 		break;
1262 	case LINK_CLOSE:
1263 		if (!atomic_test_bit(link.flags, LINK_ACTIVE)) {
1264 			return;
1265 		}
1266 
1267 		link_close(rx, buf);
1268 		break;
1269 	default:
1270 		BT_ERR("Unknown bearer opcode: 0x%02x", BEARER_CTL(rx->gpc));
1271 
1272 		if (IS_ENABLED(CONFIG_BT_TESTING)) {
1273 			bt_test_mesh_prov_invalid_bearer(BEARER_CTL(rx->gpc));
1274 		}
1275 
1276 		return;
1277 	}
1278 }
1279 
prov_msg_recv(void)1280 static void prov_msg_recv(void)
1281 {
1282 	u8_t type = link.rx.buf->om_data[0];
1283 
1284 	BT_DBG("type 0x%02x len %u", type, link.rx.buf->om_len);
1285 
1286 	if (!bt_mesh_fcs_check(link.rx.buf, link.rx.fcs)) {
1287 		BT_ERR("Incorrect FCS");
1288 		return;
1289 	}
1290 
1291 	gen_prov_ack_send(link.rx.id);
1292 	link.rx.prev_id = link.rx.id;
1293 	link.rx.id = 0;
1294 
1295 	if (type != PROV_FAILED && type != link.expect) {
1296 		BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect);
1297 		prov_send_fail_msg(PROV_ERR_UNEXP_PDU);
1298 		return;
1299 	}
1300 
1301 	if (type >= ARRAY_SIZE(prov_handlers)) {
1302 		BT_ERR("Unknown provisioning PDU type 0x%02x", type);
1303 		close_link(PROV_ERR_NVAL_PDU, CLOSE_REASON_FAILED);
1304 		return;
1305 	}
1306 
1307 	if (1 + prov_handlers[type].len != link.rx.buf->om_len) {
1308 		BT_ERR("Invalid length %u for type 0x%02x",
1309 		       link.rx.buf->om_len, type);
1310 		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1311 		return;
1312 	}
1313 
1314 	prov_handlers[type].func(&link.rx.buf->om_data[1]);
1315 }
1316 
gen_prov_cont(struct prov_rx * rx,struct os_mbuf * buf)1317 static void gen_prov_cont(struct prov_rx *rx, struct os_mbuf *buf)
1318 {
1319 	u8_t seg = CONT_SEG_INDEX(rx->gpc);
1320 
1321 	BT_DBG("len %u, seg_index %u", buf->om_len, seg);
1322 
1323 	if (!link.rx.seg && link.rx.prev_id == rx->xact_id) {
1324 		BT_WARN("Resending ack");
1325 		gen_prov_ack_send(rx->xact_id);
1326 		return;
1327 	}
1328 
1329 	if (rx->xact_id != link.rx.id) {
1330 		BT_WARN("Data for unknown transaction (%u != %u)",
1331 			rx->xact_id, link.rx.id);
1332 		return;
1333 	}
1334 
1335 	if (seg > link.rx.last_seg) {
1336 		BT_ERR("Invalid segment index %u", seg);
1337 		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1338 		return;
1339 	} else if (seg == link.rx.last_seg) {
1340 		u8_t expect_len;
1341 
1342 		expect_len = (link.rx.buf->om_len - 20 -
1343 			      (23 * (link.rx.last_seg - 1)));
1344 		if (expect_len != buf->om_len) {
1345 			BT_ERR("Incorrect last seg len: %u != %u",
1346 			       expect_len, buf->om_len);
1347 			close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1348 			return;
1349 		}
1350 	}
1351 
1352 	if (!(link.rx.seg & BIT(seg))) {
1353 		BT_WARN("Ignoring already received segment");
1354 		return;
1355 	}
1356 
1357 	memcpy(XACT_SEG_DATA(seg), buf->om_data, buf->om_len);
1358 	XACT_SEG_RECV(seg);
1359 
1360 	if (!link.rx.seg) {
1361 		prov_msg_recv();
1362 	}
1363 }
1364 
gen_prov_ack(struct prov_rx * rx,struct os_mbuf * buf)1365 static void gen_prov_ack(struct prov_rx *rx, struct os_mbuf *buf)
1366 {
1367 	BT_DBG("len %u", buf->om_len);
1368 
1369 	if (!link.tx.buf[0]) {
1370 		return;
1371 	}
1372 
1373 	if (rx->xact_id == link.tx.id) {
1374 		prov_clear_tx();
1375 	}
1376 }
1377 
gen_prov_start(struct prov_rx * rx,struct os_mbuf * buf)1378 static void gen_prov_start(struct prov_rx *rx, struct os_mbuf *buf)
1379 {
1380 	u16_t trailing_space = 0;
1381 
1382 	if (link.rx.seg) {
1383 		BT_WARN("Got Start while there are unreceived segments");
1384 		return;
1385 	}
1386 
1387 	if (link.rx.prev_id == rx->xact_id) {
1388 		BT_WARN("Resending ack");
1389 		gen_prov_ack_send(rx->xact_id);
1390 		return;
1391 	}
1392 
1393 	trailing_space = OS_MBUF_TRAILINGSPACE(link.rx.buf);
1394 
1395 	link.rx.buf->om_len = net_buf_simple_pull_be16(buf);
1396 	link.rx.id  = rx->xact_id;
1397 	link.rx.fcs = net_buf_simple_pull_u8(buf);
1398 
1399 	BT_DBG("len %u last_seg %u total_len %u fcs 0x%02x", buf->om_len,
1400 	       START_LAST_SEG(rx->gpc), link.rx.buf->om_len, link.rx.fcs);
1401 
1402 	if (link.rx.buf->om_len < 1) {
1403 		BT_ERR("Ignoring zero-length provisioning PDU");
1404 		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1405 		return;
1406 	}
1407 
1408 	if (link.rx.buf->om_len > trailing_space) {
1409 		BT_ERR("Too large provisioning PDU (%u bytes)",
1410 		       link.rx.buf->om_len);
1411 		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1412 		return;
1413 	}
1414 
1415 	if (START_LAST_SEG(rx->gpc) > 0 && link.rx.buf->om_len <= 20) {
1416 		BT_ERR("Too small total length for multi-segment PDU");
1417 		close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1418 		return;
1419 	}
1420 
1421 	link.rx.seg = (1 << (START_LAST_SEG(rx->gpc) + 1)) - 1;
1422 	link.rx.last_seg = START_LAST_SEG(rx->gpc);
1423 	memcpy(link.rx.buf->om_data, buf->om_data, buf->om_len);
1424 	XACT_SEG_RECV(0);
1425 
1426 	if (!link.rx.seg) {
1427 		prov_msg_recv();
1428 	}
1429 }
1430 
1431 static const struct {
1432 	void (*const func)(struct prov_rx *rx, struct os_mbuf *buf);
1433 	const u8_t require_link;
1434 	const u8_t min_len;
1435 } gen_prov[] = {
1436 	{ gen_prov_start, true, 3 },
1437 	{ gen_prov_ack, true, 0 },
1438 	{ gen_prov_cont, true, 0 },
1439 	{ gen_prov_ctl, false, 0 },
1440 };
1441 
gen_prov_recv(struct prov_rx * rx,struct os_mbuf * buf)1442 static void gen_prov_recv(struct prov_rx *rx, struct os_mbuf *buf)
1443 {
1444 	if (buf->om_len < gen_prov[GPCF(rx->gpc)].min_len) {
1445 		BT_ERR("Too short GPC message type %u", GPCF(rx->gpc));
1446 		return;
1447 	}
1448 
1449 	if (!atomic_test_bit(link.flags, LINK_ACTIVE) &&
1450 	    gen_prov[GPCF(rx->gpc)].require_link) {
1451 		BT_DBG("Ignoring message that requires active link");
1452 		return;
1453 	}
1454 
1455 	BT_INFO("prov_action: %d", GPCF(rx->gpc));
1456 	gen_prov[GPCF(rx->gpc)].func(rx, buf);
1457 }
1458 
bt_mesh_pb_adv_recv(struct os_mbuf * buf)1459 void bt_mesh_pb_adv_recv(struct os_mbuf *buf)
1460 {
1461 	struct prov_rx rx;
1462 
1463 	if (!bt_prov_active() && bt_mesh_is_provisioned()) {
1464 		BT_DBG("Ignoring provisioning PDU - already provisioned");
1465 		return;
1466 	}
1467 
1468 	if (buf->om_len < 6) {
1469 		BT_WARN("Too short provisioning packet (len %u)", buf->om_len);
1470 		return;
1471 	}
1472 
1473 	rx.link_id = net_buf_simple_pull_be32(buf);
1474 	rx.xact_id = net_buf_simple_pull_u8(buf);
1475 	rx.gpc = net_buf_simple_pull_u8(buf);
1476 
1477 	BT_DBG("link_id 0x%08x xact_id %u", rx.link_id, rx.xact_id);
1478 
1479 	if (atomic_test_bit(link.flags, LINK_ACTIVE) && link.id != rx.link_id) {
1480 		BT_DBG("Ignoring mesh beacon for unknown link");
1481 		return;
1482 	}
1483 
1484 	gen_prov_recv(&rx, buf);
1485 }
1486 #endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */
1487 
1488 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
bt_mesh_pb_gatt_recv(uint16_t conn_handle,struct os_mbuf * buf)1489 int bt_mesh_pb_gatt_recv(uint16_t conn_handle, struct os_mbuf *buf)
1490 {
1491 	u8_t type;
1492 
1493 	BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len));
1494 
1495 	if (link.conn_handle != conn_handle) {
1496 		BT_WARN("Data for unexpected connection");
1497 		return -ENOTCONN;
1498 	}
1499 
1500 	if (buf->om_len < 1) {
1501 		BT_WARN("Too short provisioning packet (len %u)", buf->om_len);
1502 		return -EINVAL;
1503 	}
1504 
1505 	type = net_buf_simple_pull_u8(buf);
1506 	if (type != PROV_FAILED && type != link.expect) {
1507 		BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect);
1508 		prov_send_fail_msg(PROV_ERR_UNEXP_PDU);
1509 		return -EINVAL;
1510 	}
1511 
1512 	if (type >= ARRAY_SIZE(prov_handlers)) {
1513 		BT_ERR("Unknown provisioning PDU type 0x%02x", type);
1514 		return -EINVAL;
1515 	}
1516 
1517 	if (prov_handlers[type].len != buf->om_len) {
1518 		BT_ERR("Invalid length %u for type 0x%02x", buf->om_len, type);
1519 		return -EINVAL;
1520 	}
1521 
1522 	prov_handlers[type].func(buf->om_data);
1523 
1524 	return 0;
1525 }
1526 
bt_mesh_pb_gatt_open(uint16_t conn_handle)1527 int bt_mesh_pb_gatt_open(uint16_t conn_handle)
1528 {
1529 	BT_DBG("conn_handle %d", conn_handle);
1530 
1531 	if (atomic_test_and_set_bit(link.flags, LINK_ACTIVE)) {
1532 		BT_ERR("Link already opened?");
1533 		return -EBUSY;
1534 	}
1535 
1536 	link.conn_handle = conn_handle;
1537 	link.expect = PROV_INVITE;
1538 
1539 	if (prov->link_open) {
1540 		prov->link_open(BT_MESH_PROV_GATT);
1541 	}
1542 
1543 	return 0;
1544 }
1545 
bt_mesh_pb_gatt_close(uint16_t conn_handle)1546 int bt_mesh_pb_gatt_close(uint16_t conn_handle)
1547 {
1548 	bool pub_key;
1549 
1550 	BT_DBG("conn_handle %d", conn_handle);
1551 
1552 	if (link.conn_handle != conn_handle) {
1553 		BT_ERR("Not connected");
1554 		return -ENOTCONN;
1555 	}
1556 
1557 	/* Disable Attention Timer if it was set */
1558 	if (link.conf_inputs[0]) {
1559 		bt_mesh_attention(NULL, 0);
1560 	}
1561 
1562 	if (prov->link_close) {
1563 		prov->link_close(BT_MESH_PROV_GATT);
1564 	}
1565 
1566 //	bt_conn_unref(conn_handle);
1567 
1568 	pub_key = atomic_test_bit(link.flags, LOCAL_PUB_KEY);
1569 	memset(&link, 0, sizeof(link));
1570 
1571 	if (pub_key) {
1572 		atomic_set_bit(link.flags, LOCAL_PUB_KEY);
1573 	}
1574 
1575 	return 0;
1576 }
1577 #endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */
1578 
bt_mesh_prov_get(void)1579 const struct bt_mesh_prov *bt_mesh_prov_get(void)
1580 {
1581 	return prov;
1582 }
1583 
bt_prov_active(void)1584 bool bt_prov_active(void)
1585 {
1586 	return atomic_test_bit(link.flags, LINK_ACTIVE);
1587 }
1588 
bt_mesh_prov_init(const struct bt_mesh_prov * prov_info)1589 int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info)
1590 {
1591 	static struct bt_pub_key_cb pub_key_cb = {
1592 		.func = pub_key_ready,
1593 	};
1594 	int err;
1595 
1596 #if !(MYNEWT_VAL(BLE_MESH_PB_GATT))
1597 	rx_buf = NET_BUF_SIMPLE(65);
1598 #endif
1599 
1600 	if (!prov_info) {
1601 		BT_ERR("No provisioning context provided");
1602 		return -EINVAL;
1603 	}
1604 
1605 	err = bt_pub_key_gen(&pub_key_cb);
1606 	if (err) {
1607 		BT_ERR("Failed to generate public key (%d)", err);
1608 		return err;
1609 	}
1610 
1611 	prov = prov_info;
1612 
1613 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
1614 	k_delayed_work_init(&link.tx.retransmit, prov_retransmit);
1615 	link.rx.prev_id = XACT_NVAL;
1616 
1617 #if !(MYNEWT_VAL(BLE_MESH_PB_GATT))
1618 	net_buf_simple_init(rx_buf, 0);
1619 	link.rx.buf = rx_buf;
1620 #endif
1621 
1622 #endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */
1623 
1624 	return 0;
1625 }
1626 
bt_mesh_prov_reset_link(void)1627 void bt_mesh_prov_reset_link(void) {
1628 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
1629     link.rx.buf = bt_mesh_proxy_get_buf();
1630 #else
1631     net_buf_simple_init(rx_buf, 0);
1632     link.rx.buf = rx_buf;
1633 #endif
1634 }
1635 
bt_mesh_prov_complete(u16_t net_idx,u16_t addr)1636 void bt_mesh_prov_complete(u16_t net_idx, u16_t addr)
1637 {
1638 	if (prov->complete) {
1639 		prov->complete(net_idx, addr);
1640 	}
1641 }
1642 
bt_mesh_prov_reset(void)1643 void bt_mesh_prov_reset(void)
1644 {
1645 	if (prov->reset) {
1646 		prov->reset();
1647 	}
1648 }
1649 
1650 #endif //MYNEWT_VAL(BLE_MESH_PROV) == 1
1651