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