1 /*
2 * Copyright (c) 2017 Nordic Semiconductor ASA
3 * Copyright (c) 2015 Intel Corporation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <stdint.h>
9
10 #include <zephyr/sys/byteorder.h>
11
12 #include <zephyr/bluetooth/buf.h>
13 #include <zephyr/bluetooth/hci.h>
14 #include <zephyr/bluetooth/addr.h>
15
16 #include "common/bt_str.h"
17
18 #include "keys.h"
19
20 #include "hci_core.h"
21 #include "conn_internal.h"
22
23 #define LOG_LEVEL CONFIG_BT_HCI_CORE_LOG_LEVEL
24 #include <zephyr/logging/log.h>
25 LOG_MODULE_REGISTER(bt_ssp);
26
27 enum pairing_method {
28 LEGACY, /* Legacy (pre-SSP) pairing */
29 JUST_WORKS, /* JustWorks pairing */
30 PASSKEY_INPUT, /* Passkey Entry input */
31 PASSKEY_DISPLAY, /* Passkey Entry display */
32 PASSKEY_CONFIRM, /* Passkey confirm */
33 };
34
35 /* based on table 5.7, Core Spec 4.2, Vol.3 Part C, 5.2.2.6 */
36 static const uint8_t ssp_method[4 /* remote */][4 /* local */] = {
37 { JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS },
38 { JUST_WORKS, PASSKEY_CONFIRM, PASSKEY_INPUT, JUST_WORKS },
39 { PASSKEY_DISPLAY, PASSKEY_DISPLAY, PASSKEY_INPUT, JUST_WORKS },
40 { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS },
41 };
42
pin_code_neg_reply(const bt_addr_t * bdaddr)43 static int pin_code_neg_reply(const bt_addr_t *bdaddr)
44 {
45 struct bt_hci_cp_pin_code_neg_reply *cp;
46 struct net_buf *buf;
47
48 LOG_DBG("");
49
50 buf = bt_hci_cmd_create(BT_HCI_OP_PIN_CODE_NEG_REPLY, sizeof(*cp));
51 if (!buf) {
52 return -ENOBUFS;
53 }
54
55 cp = net_buf_add(buf, sizeof(*cp));
56 bt_addr_copy(&cp->bdaddr, bdaddr);
57
58 return bt_hci_cmd_send_sync(BT_HCI_OP_PIN_CODE_NEG_REPLY, buf, NULL);
59 }
60
pin_code_reply(struct bt_conn * conn,const char * pin,uint8_t len)61 static int pin_code_reply(struct bt_conn *conn, const char *pin, uint8_t len)
62 {
63 struct bt_hci_cp_pin_code_reply *cp;
64 struct net_buf *buf;
65
66 LOG_DBG("");
67
68 buf = bt_hci_cmd_create(BT_HCI_OP_PIN_CODE_REPLY, sizeof(*cp));
69 if (!buf) {
70 return -ENOBUFS;
71 }
72
73 cp = net_buf_add(buf, sizeof(*cp));
74
75 bt_addr_copy(&cp->bdaddr, &conn->br.dst);
76 cp->pin_len = len;
77 strncpy((char *)cp->pin_code, pin, sizeof(cp->pin_code));
78
79 return bt_hci_cmd_send_sync(BT_HCI_OP_PIN_CODE_REPLY, buf, NULL);
80 }
81
bt_conn_auth_pincode_entry(struct bt_conn * conn,const char * pin)82 int bt_conn_auth_pincode_entry(struct bt_conn *conn, const char *pin)
83 {
84 size_t len;
85
86 if (!bt_auth) {
87 return -EINVAL;
88 }
89
90 if (conn->type != BT_CONN_TYPE_BR) {
91 return -EINVAL;
92 }
93
94 len = strlen(pin);
95 if (len > 16) {
96 return -EINVAL;
97 }
98
99 if (conn->required_sec_level == BT_SECURITY_L3 && len < 16) {
100 LOG_WRN("PIN code for %s is not 16 bytes wide", bt_addr_str(&conn->br.dst));
101 return -EPERM;
102 }
103
104 /* Allow user send entered PIN to remote, then reset user state. */
105 if (!atomic_test_and_clear_bit(conn->flags, BT_CONN_USER)) {
106 return -EPERM;
107 }
108
109 if (len == 16) {
110 atomic_set_bit(conn->flags, BT_CONN_BR_LEGACY_SECURE);
111 }
112
113 return pin_code_reply(conn, pin, len);
114 }
115
pin_code_req(struct bt_conn * conn)116 static void pin_code_req(struct bt_conn *conn)
117 {
118 if (bt_auth && bt_auth->pincode_entry) {
119 bool secure = false;
120
121 if (conn->required_sec_level == BT_SECURITY_L3) {
122 secure = true;
123 }
124
125 atomic_set_bit(conn->flags, BT_CONN_USER);
126 atomic_set_bit(conn->flags, BT_CONN_BR_PAIRING);
127 bt_auth->pincode_entry(conn, secure);
128 } else {
129 pin_code_neg_reply(&conn->br.dst);
130 }
131 }
132
get_io_capa(void)133 static uint8_t get_io_capa(void)
134 {
135 if (!bt_auth) {
136 return BT_IO_NO_INPUT_OUTPUT;
137 }
138
139 if (bt_auth->passkey_confirm && bt_auth->passkey_display) {
140 return BT_IO_DISPLAY_YESNO;
141 }
142
143 if (bt_auth->passkey_entry) {
144 return BT_IO_KEYBOARD_ONLY;
145 }
146
147 if (bt_auth->passkey_display) {
148 return BT_IO_DISPLAY_ONLY;
149 }
150
151 return BT_IO_NO_INPUT_OUTPUT;
152 }
153
ssp_pair_method(const struct bt_conn * conn)154 static uint8_t ssp_pair_method(const struct bt_conn *conn)
155 {
156 return ssp_method[conn->br.remote_io_capa][get_io_capa()];
157 }
158
ssp_get_auth(const struct bt_conn * conn)159 static uint8_t ssp_get_auth(const struct bt_conn *conn)
160 {
161 /* Validate no bond auth request, and if valid use it. */
162 if ((conn->br.remote_auth == BT_HCI_NO_BONDING) ||
163 ((conn->br.remote_auth == BT_HCI_NO_BONDING_MITM) &&
164 (ssp_pair_method(conn) > JUST_WORKS))) {
165 return conn->br.remote_auth;
166 }
167
168 /* Local & remote have enough IO capabilities to get MITM protection. */
169 if (ssp_pair_method(conn) > JUST_WORKS) {
170 return conn->br.remote_auth | BT_MITM;
171 }
172
173 /* No MITM protection possible so ignore remote MITM requirement. */
174 return (conn->br.remote_auth & ~BT_MITM);
175 }
176
ssp_confirm_reply(struct bt_conn * conn)177 static int ssp_confirm_reply(struct bt_conn *conn)
178 {
179 struct bt_hci_cp_user_confirm_reply *cp;
180 struct net_buf *buf;
181
182 LOG_DBG("");
183
184 buf = bt_hci_cmd_create(BT_HCI_OP_USER_CONFIRM_REPLY, sizeof(*cp));
185 if (!buf) {
186 return -ENOBUFS;
187 }
188
189 cp = net_buf_add(buf, sizeof(*cp));
190 bt_addr_copy(&cp->bdaddr, &conn->br.dst);
191
192 return bt_hci_cmd_send_sync(BT_HCI_OP_USER_CONFIRM_REPLY, buf, NULL);
193 }
194
ssp_confirm_neg_reply(struct bt_conn * conn)195 static int ssp_confirm_neg_reply(struct bt_conn *conn)
196 {
197 struct bt_hci_cp_user_confirm_reply *cp;
198 struct net_buf *buf;
199
200 LOG_DBG("");
201
202 buf = bt_hci_cmd_create(BT_HCI_OP_USER_CONFIRM_NEG_REPLY, sizeof(*cp));
203 if (!buf) {
204 return -ENOBUFS;
205 }
206
207 cp = net_buf_add(buf, sizeof(*cp));
208 bt_addr_copy(&cp->bdaddr, &conn->br.dst);
209
210 return bt_hci_cmd_send_sync(BT_HCI_OP_USER_CONFIRM_NEG_REPLY, buf,
211 NULL);
212 }
213
ssp_pairing_complete(struct bt_conn * conn,uint8_t status)214 static void ssp_pairing_complete(struct bt_conn *conn, uint8_t status)
215 {
216 if (!status) {
217 bool bond = !atomic_test_bit(conn->flags, BT_CONN_BR_NOBOND);
218 struct bt_conn_auth_info_cb *listener, *next;
219
220 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_auth_info_cbs, listener,
221 next, node) {
222 if (listener->pairing_complete) {
223 listener->pairing_complete(conn, bond);
224 }
225 }
226 } else {
227 struct bt_conn_auth_info_cb *listener, *next;
228
229 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_auth_info_cbs, listener,
230 next, node) {
231 if (listener->pairing_complete) {
232 listener->pairing_complete(conn, status);
233 }
234 }
235 }
236 }
237
ssp_auth(struct bt_conn * conn,uint32_t passkey)238 static void ssp_auth(struct bt_conn *conn, uint32_t passkey)
239 {
240 conn->br.pairing_method = ssp_pair_method(conn);
241
242 /*
243 * If local required security is HIGH then MITM is mandatory.
244 * MITM protection is no achievable when SSP 'justworks' is applied.
245 */
246 if (conn->required_sec_level > BT_SECURITY_L2 &&
247 conn->br.pairing_method == JUST_WORKS) {
248 LOG_DBG("MITM protection infeasible for required security");
249 ssp_confirm_neg_reply(conn);
250 return;
251 }
252
253 switch (conn->br.pairing_method) {
254 case PASSKEY_CONFIRM:
255 atomic_set_bit(conn->flags, BT_CONN_USER);
256 bt_auth->passkey_confirm(conn, passkey);
257 break;
258 case PASSKEY_DISPLAY:
259 atomic_set_bit(conn->flags, BT_CONN_USER);
260 bt_auth->passkey_display(conn, passkey);
261 break;
262 case PASSKEY_INPUT:
263 atomic_set_bit(conn->flags, BT_CONN_USER);
264 bt_auth->passkey_entry(conn);
265 break;
266 case JUST_WORKS:
267 /*
268 * When local host works as pairing acceptor and 'justworks'
269 * model is applied then notify user about such pairing request.
270 * [BT Core 4.2 table 5.7, Vol 3, Part C, 5.2.2.6]
271 */
272 if (bt_auth && bt_auth->pairing_confirm &&
273 !atomic_test_bit(conn->flags,
274 BT_CONN_BR_PAIRING_INITIATOR)) {
275 atomic_set_bit(conn->flags, BT_CONN_USER);
276 bt_auth->pairing_confirm(conn);
277 break;
278 }
279 ssp_confirm_reply(conn);
280 break;
281 default:
282 break;
283 }
284 }
285
ssp_passkey_reply(struct bt_conn * conn,unsigned int passkey)286 static int ssp_passkey_reply(struct bt_conn *conn, unsigned int passkey)
287 {
288 struct bt_hci_cp_user_passkey_reply *cp;
289 struct net_buf *buf;
290
291 LOG_DBG("");
292
293 buf = bt_hci_cmd_create(BT_HCI_OP_USER_PASSKEY_REPLY, sizeof(*cp));
294 if (!buf) {
295 return -ENOBUFS;
296 }
297
298 cp = net_buf_add(buf, sizeof(*cp));
299 bt_addr_copy(&cp->bdaddr, &conn->br.dst);
300 cp->passkey = sys_cpu_to_le32(passkey);
301
302 return bt_hci_cmd_send_sync(BT_HCI_OP_USER_PASSKEY_REPLY, buf, NULL);
303 }
304
ssp_passkey_neg_reply(struct bt_conn * conn)305 static int ssp_passkey_neg_reply(struct bt_conn *conn)
306 {
307 struct bt_hci_cp_user_passkey_neg_reply *cp;
308 struct net_buf *buf;
309
310 LOG_DBG("");
311
312 buf = bt_hci_cmd_create(BT_HCI_OP_USER_PASSKEY_NEG_REPLY, sizeof(*cp));
313 if (!buf) {
314 return -ENOBUFS;
315 }
316
317 cp = net_buf_add(buf, sizeof(*cp));
318 bt_addr_copy(&cp->bdaddr, &conn->br.dst);
319
320 return bt_hci_cmd_send_sync(BT_HCI_OP_USER_PASSKEY_NEG_REPLY, buf,
321 NULL);
322 }
323
conn_auth(struct bt_conn * conn)324 static int conn_auth(struct bt_conn *conn)
325 {
326 struct bt_hci_cp_auth_requested *auth;
327 struct net_buf *buf;
328
329 LOG_DBG("");
330
331 buf = bt_hci_cmd_create(BT_HCI_OP_AUTH_REQUESTED, sizeof(*auth));
332 if (!buf) {
333 return -ENOBUFS;
334 }
335
336 auth = net_buf_add(buf, sizeof(*auth));
337 auth->handle = sys_cpu_to_le16(conn->handle);
338
339 atomic_set_bit(conn->flags, BT_CONN_BR_PAIRING_INITIATOR);
340
341 return bt_hci_cmd_send_sync(BT_HCI_OP_AUTH_REQUESTED, buf, NULL);
342 }
343
bt_ssp_start_security(struct bt_conn * conn)344 int bt_ssp_start_security(struct bt_conn *conn)
345 {
346 if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING)) {
347 return -EBUSY;
348 }
349
350 if (conn->required_sec_level > BT_SECURITY_L3) {
351 return -ENOTSUP;
352 }
353
354 if (get_io_capa() == BT_IO_NO_INPUT_OUTPUT &&
355 conn->required_sec_level > BT_SECURITY_L2) {
356 return -EINVAL;
357 }
358
359 return conn_auth(conn);
360 }
361
bt_ssp_auth_passkey_entry(struct bt_conn * conn,unsigned int passkey)362 int bt_ssp_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey)
363 {
364 /* User entered passkey, reset user state. */
365 if (!atomic_test_and_clear_bit(conn->flags, BT_CONN_USER)) {
366 return -EPERM;
367 }
368
369 if (conn->br.pairing_method == PASSKEY_INPUT) {
370 return ssp_passkey_reply(conn, passkey);
371 }
372
373 return -EINVAL;
374 }
375
bt_ssp_auth_passkey_confirm(struct bt_conn * conn)376 int bt_ssp_auth_passkey_confirm(struct bt_conn *conn)
377 {
378 /* Allow user confirm passkey value, then reset user state. */
379 if (!atomic_test_and_clear_bit(conn->flags, BT_CONN_USER)) {
380 return -EPERM;
381 }
382
383 return ssp_confirm_reply(conn);
384 }
385
bt_ssp_auth_pairing_confirm(struct bt_conn * conn)386 int bt_ssp_auth_pairing_confirm(struct bt_conn *conn)
387 {
388 return ssp_confirm_reply(conn);
389 }
390
bt_ssp_auth_cancel(struct bt_conn * conn)391 int bt_ssp_auth_cancel(struct bt_conn *conn)
392 {
393 /* Allow user cancel authentication, then reset user state. */
394 if (!atomic_test_and_clear_bit(conn->flags, BT_CONN_USER)) {
395 return -EPERM;
396 }
397
398 switch (conn->br.pairing_method) {
399 case JUST_WORKS:
400 case PASSKEY_CONFIRM:
401 return ssp_confirm_neg_reply(conn);
402 case PASSKEY_INPUT:
403 return ssp_passkey_neg_reply(conn);
404 case PASSKEY_DISPLAY:
405 return bt_conn_disconnect(conn,
406 BT_HCI_ERR_AUTH_FAIL);
407 case LEGACY:
408 return pin_code_neg_reply(&conn->br.dst);
409 default:
410 break;
411 }
412
413 return -EINVAL;
414 }
415
bt_hci_pin_code_req(struct net_buf * buf)416 void bt_hci_pin_code_req(struct net_buf *buf)
417 {
418 struct bt_hci_evt_pin_code_req *evt = (void *)buf->data;
419 struct bt_conn *conn;
420
421 LOG_DBG("");
422
423 conn = bt_conn_lookup_addr_br(&evt->bdaddr);
424 if (!conn) {
425 LOG_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr));
426 return;
427 }
428
429 pin_code_req(conn);
430 bt_conn_unref(conn);
431 }
432
bt_hci_link_key_notify(struct net_buf * buf)433 void bt_hci_link_key_notify(struct net_buf *buf)
434 {
435 struct bt_hci_evt_link_key_notify *evt = (void *)buf->data;
436 struct bt_conn *conn;
437
438 conn = bt_conn_lookup_addr_br(&evt->bdaddr);
439 if (!conn) {
440 LOG_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr));
441 return;
442 }
443
444 LOG_DBG("%s, link type 0x%02x", bt_addr_str(&evt->bdaddr), evt->key_type);
445
446 if (!conn->br.link_key) {
447 conn->br.link_key = bt_keys_get_link_key(&evt->bdaddr);
448 }
449 if (!conn->br.link_key) {
450 LOG_ERR("Can't update keys for %s", bt_addr_str(&evt->bdaddr));
451 bt_conn_unref(conn);
452 return;
453 }
454
455 /* clear any old Link Key flags */
456 conn->br.link_key->flags = 0U;
457
458 switch (evt->key_type) {
459 case BT_LK_COMBINATION:
460 /*
461 * Setting Combination Link Key as AUTHENTICATED means it was
462 * successfully generated by 16 digits wide PIN code.
463 */
464 if (atomic_test_and_clear_bit(conn->flags,
465 BT_CONN_BR_LEGACY_SECURE)) {
466 conn->br.link_key->flags |= BT_LINK_KEY_AUTHENTICATED;
467 }
468 memcpy(conn->br.link_key->val, evt->link_key, 16);
469 break;
470 case BT_LK_AUTH_COMBINATION_P192:
471 conn->br.link_key->flags |= BT_LINK_KEY_AUTHENTICATED;
472 __fallthrough;
473 case BT_LK_UNAUTH_COMBINATION_P192:
474 /* Mark no-bond so that link-key is removed on disconnection */
475 if (ssp_get_auth(conn) < BT_HCI_DEDICATED_BONDING) {
476 atomic_set_bit(conn->flags, BT_CONN_BR_NOBOND);
477 }
478
479 memcpy(conn->br.link_key->val, evt->link_key, 16);
480 break;
481 case BT_LK_AUTH_COMBINATION_P256:
482 conn->br.link_key->flags |= BT_LINK_KEY_AUTHENTICATED;
483 __fallthrough;
484 case BT_LK_UNAUTH_COMBINATION_P256:
485 conn->br.link_key->flags |= BT_LINK_KEY_SC;
486
487 /* Mark no-bond so that link-key is removed on disconnection */
488 if (ssp_get_auth(conn) < BT_HCI_DEDICATED_BONDING) {
489 atomic_set_bit(conn->flags, BT_CONN_BR_NOBOND);
490 }
491
492 memcpy(conn->br.link_key->val, evt->link_key, 16);
493 break;
494 default:
495 LOG_WRN("Unsupported Link Key type %u", evt->key_type);
496 (void)memset(conn->br.link_key->val, 0,
497 sizeof(conn->br.link_key->val));
498 break;
499 }
500
501 if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
502 !atomic_test_bit(conn->flags, BT_CONN_BR_NOBOND)) {
503 bt_keys_link_key_store(conn->br.link_key);
504 }
505
506 bt_conn_unref(conn);
507 }
508
link_key_neg_reply(const bt_addr_t * bdaddr)509 void link_key_neg_reply(const bt_addr_t *bdaddr)
510 {
511 struct bt_hci_cp_link_key_neg_reply *cp;
512 struct net_buf *buf;
513
514 LOG_DBG("");
515
516 buf = bt_hci_cmd_create(BT_HCI_OP_LINK_KEY_NEG_REPLY, sizeof(*cp));
517 if (!buf) {
518 LOG_ERR("Out of command buffers");
519 return;
520 }
521
522 cp = net_buf_add(buf, sizeof(*cp));
523 bt_addr_copy(&cp->bdaddr, bdaddr);
524 bt_hci_cmd_send_sync(BT_HCI_OP_LINK_KEY_NEG_REPLY, buf, NULL);
525 }
526
link_key_reply(const bt_addr_t * bdaddr,const uint8_t * lk)527 void link_key_reply(const bt_addr_t *bdaddr, const uint8_t *lk)
528 {
529 struct bt_hci_cp_link_key_reply *cp;
530 struct net_buf *buf;
531
532 LOG_DBG("");
533
534 buf = bt_hci_cmd_create(BT_HCI_OP_LINK_KEY_REPLY, sizeof(*cp));
535 if (!buf) {
536 LOG_ERR("Out of command buffers");
537 return;
538 }
539
540 cp = net_buf_add(buf, sizeof(*cp));
541 bt_addr_copy(&cp->bdaddr, bdaddr);
542 memcpy(cp->link_key, lk, 16);
543 bt_hci_cmd_send_sync(BT_HCI_OP_LINK_KEY_REPLY, buf, NULL);
544 }
545
bt_hci_link_key_req(struct net_buf * buf)546 void bt_hci_link_key_req(struct net_buf *buf)
547 {
548 struct bt_hci_evt_link_key_req *evt = (void *)buf->data;
549 struct bt_conn *conn;
550
551 LOG_DBG("%s", bt_addr_str(&evt->bdaddr));
552
553 conn = bt_conn_lookup_addr_br(&evt->bdaddr);
554 if (!conn) {
555 LOG_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr));
556 link_key_neg_reply(&evt->bdaddr);
557 return;
558 }
559
560 if (!conn->br.link_key) {
561 conn->br.link_key = bt_keys_find_link_key(&evt->bdaddr);
562 }
563
564 if (!conn->br.link_key) {
565 link_key_neg_reply(&evt->bdaddr);
566 bt_conn_unref(conn);
567 return;
568 }
569
570 /*
571 * Enforce regenerate by controller stronger link key since found one
572 * in database not covers requested security level.
573 */
574 if (!(conn->br.link_key->flags & BT_LINK_KEY_AUTHENTICATED) &&
575 conn->required_sec_level > BT_SECURITY_L2) {
576 link_key_neg_reply(&evt->bdaddr);
577 bt_conn_unref(conn);
578 return;
579 }
580
581 link_key_reply(&evt->bdaddr, conn->br.link_key->val);
582 bt_conn_unref(conn);
583 }
584
io_capa_neg_reply(const bt_addr_t * bdaddr,const uint8_t reason)585 void io_capa_neg_reply(const bt_addr_t *bdaddr, const uint8_t reason)
586 {
587 struct bt_hci_cp_io_capability_neg_reply *cp;
588 struct net_buf *resp_buf;
589
590 resp_buf = bt_hci_cmd_create(BT_HCI_OP_IO_CAPABILITY_NEG_REPLY,
591 sizeof(*cp));
592 if (!resp_buf) {
593 LOG_ERR("Out of command buffers");
594 return;
595 }
596
597 cp = net_buf_add(resp_buf, sizeof(*cp));
598 bt_addr_copy(&cp->bdaddr, bdaddr);
599 cp->reason = reason;
600 bt_hci_cmd_send_sync(BT_HCI_OP_IO_CAPABILITY_NEG_REPLY, resp_buf, NULL);
601 }
602
bt_hci_io_capa_resp(struct net_buf * buf)603 void bt_hci_io_capa_resp(struct net_buf *buf)
604 {
605 struct bt_hci_evt_io_capa_resp *evt = (void *)buf->data;
606 struct bt_conn *conn;
607
608 LOG_DBG("remote %s, IOcapa 0x%02x, auth 0x%02x", bt_addr_str(&evt->bdaddr), evt->capability,
609 evt->authentication);
610
611 if (evt->authentication > BT_HCI_GENERAL_BONDING_MITM) {
612 LOG_ERR("Invalid remote authentication requirements");
613 io_capa_neg_reply(&evt->bdaddr,
614 BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL);
615 return;
616 }
617
618 if (evt->capability > BT_IO_NO_INPUT_OUTPUT) {
619 LOG_ERR("Invalid remote io capability requirements");
620 io_capa_neg_reply(&evt->bdaddr,
621 BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL);
622 return;
623 }
624
625 conn = bt_conn_lookup_addr_br(&evt->bdaddr);
626 if (!conn) {
627 LOG_ERR("Unable to find conn for %s", bt_addr_str(&evt->bdaddr));
628 return;
629 }
630
631 conn->br.remote_io_capa = evt->capability;
632 conn->br.remote_auth = evt->authentication;
633 atomic_set_bit(conn->flags, BT_CONN_BR_PAIRING);
634 bt_conn_unref(conn);
635 }
636
bt_hci_io_capa_req(struct net_buf * buf)637 void bt_hci_io_capa_req(struct net_buf *buf)
638 {
639 struct bt_hci_evt_io_capa_req *evt = (void *)buf->data;
640 struct net_buf *resp_buf;
641 struct bt_conn *conn;
642 struct bt_hci_cp_io_capability_reply *cp;
643 uint8_t auth;
644
645 LOG_DBG("");
646
647 conn = bt_conn_lookup_addr_br(&evt->bdaddr);
648 if (!conn) {
649 LOG_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr));
650 return;
651 }
652
653 resp_buf = bt_hci_cmd_create(BT_HCI_OP_IO_CAPABILITY_REPLY,
654 sizeof(*cp));
655 if (!resp_buf) {
656 LOG_ERR("Out of command buffers");
657 bt_conn_unref(conn);
658 return;
659 }
660
661 /*
662 * Set authentication requirements when acting as pairing initiator to
663 * 'dedicated bond' with MITM protection set if local IO capa
664 * potentially allows it, and for acceptor, based on local IO capa and
665 * remote's authentication set.
666 */
667 if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING_INITIATOR)) {
668 if (get_io_capa() != BT_IO_NO_INPUT_OUTPUT) {
669 auth = BT_HCI_DEDICATED_BONDING_MITM;
670 } else {
671 auth = BT_HCI_DEDICATED_BONDING;
672 }
673 } else {
674 auth = ssp_get_auth(conn);
675 }
676
677 cp = net_buf_add(resp_buf, sizeof(*cp));
678 bt_addr_copy(&cp->bdaddr, &evt->bdaddr);
679 cp->capability = get_io_capa();
680 cp->authentication = auth;
681 cp->oob_data = 0U;
682 bt_hci_cmd_send_sync(BT_HCI_OP_IO_CAPABILITY_REPLY, resp_buf, NULL);
683 bt_conn_unref(conn);
684 }
685
bt_hci_ssp_complete(struct net_buf * buf)686 void bt_hci_ssp_complete(struct net_buf *buf)
687 {
688 struct bt_hci_evt_ssp_complete *evt = (void *)buf->data;
689 struct bt_conn *conn;
690
691 LOG_DBG("status 0x%02x", evt->status);
692
693 conn = bt_conn_lookup_addr_br(&evt->bdaddr);
694 if (!conn) {
695 LOG_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr));
696 return;
697 }
698
699 ssp_pairing_complete(conn, bt_security_err_get(evt->status));
700 if (evt->status) {
701 bt_conn_disconnect(conn, BT_HCI_ERR_AUTH_FAIL);
702 }
703
704 bt_conn_unref(conn);
705 }
706
bt_hci_user_confirm_req(struct net_buf * buf)707 void bt_hci_user_confirm_req(struct net_buf *buf)
708 {
709 struct bt_hci_evt_user_confirm_req *evt = (void *)buf->data;
710 struct bt_conn *conn;
711
712 conn = bt_conn_lookup_addr_br(&evt->bdaddr);
713 if (!conn) {
714 LOG_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr));
715 return;
716 }
717
718 ssp_auth(conn, sys_le32_to_cpu(evt->passkey));
719 bt_conn_unref(conn);
720 }
721
bt_hci_user_passkey_notify(struct net_buf * buf)722 void bt_hci_user_passkey_notify(struct net_buf *buf)
723 {
724 struct bt_hci_evt_user_passkey_notify *evt = (void *)buf->data;
725 struct bt_conn *conn;
726
727 LOG_DBG("");
728
729 conn = bt_conn_lookup_addr_br(&evt->bdaddr);
730 if (!conn) {
731 LOG_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr));
732 return;
733 }
734
735 ssp_auth(conn, sys_le32_to_cpu(evt->passkey));
736 bt_conn_unref(conn);
737 }
738
bt_hci_user_passkey_req(struct net_buf * buf)739 void bt_hci_user_passkey_req(struct net_buf *buf)
740 {
741 struct bt_hci_evt_user_passkey_req *evt = (void *)buf->data;
742 struct bt_conn *conn;
743
744 conn = bt_conn_lookup_addr_br(&evt->bdaddr);
745 if (!conn) {
746 LOG_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr));
747 return;
748 }
749
750 ssp_auth(conn, 0);
751 bt_conn_unref(conn);
752 }
753
link_encr(const uint16_t handle)754 static void link_encr(const uint16_t handle)
755 {
756 struct bt_hci_cp_set_conn_encrypt *encr;
757 struct net_buf *buf;
758
759 LOG_DBG("");
760
761 buf = bt_hci_cmd_create(BT_HCI_OP_SET_CONN_ENCRYPT, sizeof(*encr));
762 if (!buf) {
763 LOG_ERR("Out of command buffers");
764 return;
765 }
766
767 encr = net_buf_add(buf, sizeof(*encr));
768 encr->handle = sys_cpu_to_le16(handle);
769 encr->encrypt = 0x01;
770
771 bt_hci_cmd_send_sync(BT_HCI_OP_SET_CONN_ENCRYPT, buf, NULL);
772 }
773
bt_hci_auth_complete(struct net_buf * buf)774 void bt_hci_auth_complete(struct net_buf *buf)
775 {
776 struct bt_hci_evt_auth_complete *evt = (void *)buf->data;
777 struct bt_conn *conn;
778 uint16_t handle = sys_le16_to_cpu(evt->handle);
779
780 LOG_DBG("status 0x%02x, handle %u", evt->status, handle);
781
782 conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_BR);
783 if (!conn) {
784 LOG_ERR("Can't find conn for handle %u", handle);
785 return;
786 }
787
788 if (evt->status) {
789 /*
790 * Inform layers above HCI about non-zero authentication
791 * status to make them able cleanup pending jobs.
792 */
793 bt_conn_security_changed(conn, evt->status,
794 bt_security_err_get(evt->status));
795 } else {
796 link_encr(handle);
797 }
798
799 bt_conn_unref(conn);
800 }
801