diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 20a78dac3a4..96f4a461760 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -54,10 +54,16 @@ config BLUETOOTH_CENTRAL select BLUETOOTH_CONN if BLUETOOTH_PERIPHERAL || BLUETOOTH_CENTRAL +config BLUETOOTH_SMP + bool + prompt "Security Manager Protocol support" + default n + config BLUETOOTH_SIGNING bool prompt "Data signing support" default n + depends on BLUETOOTH_SMP help This option enables data signing which is used for transferring authenticated data in an unencrypted connection. diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 75102b4e529..27d443d078f 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -1,10 +1,17 @@ obj-y = buf.o \ hci_core.o -obj-$(CONFIG_BLUETOOTH_CONN) += conn.o \ - l2cap.o \ - keys.o \ - smp.o \ - att.o \ - gatt.o \ - uuid.o +ifeq ($(CONFIG_BLUETOOTH_CONN),y) + obj-y += conn.o \ + l2cap.o \ + att.o \ + gatt.o \ + uuid.o + + ifeq ($(CONFIG_BLUETOOTH_SMP),y) + obj-y += smp.o \ + keys.o + else + obj-y += smp_null.o + endif +endif diff --git a/net/bluetooth/att.c b/net/bluetooth/att.c index b7919af10f5..f6dd2789c35 100644 --- a/net/bluetooth/att.c +++ b/net/bluetooth/att.c @@ -80,7 +80,9 @@ struct bt_att_req { void *user_data; bt_att_destroy_t destroy; struct bt_buf *buf; +#if defined(CONFIG_BLUETOOTH_SMP) bool retrying; +#endif /* CONFIG_BLUETOOTH_SMP */ }; /* ATT channel specific context */ @@ -645,8 +647,14 @@ static uint8_t check_perm(struct bt_conn *conn, const struct bt_gatt_attr *attr, return BT_ATT_ERR_AUTHENTICATION; } - if ((mask & BT_GATT_PERM_ENCRYPT_MASK) && !conn->encrypt) { + if ((mask & BT_GATT_PERM_ENCRYPT_MASK)) { +#if defined(CONFIG_BLUETOOTH_SMP) + if (!conn->encrypt) { + return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION; + } +#else return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION; +#endif /* CONFIG_BLUETOOTH_SMP */ } if (mask & BT_GATT_PERM_AUTHOR) { @@ -1206,6 +1214,7 @@ static uint8_t att_signed_write_cmd(struct bt_conn *conn, struct bt_buf *buf) buf->len - sizeof(struct bt_att_signature)); } +#if defined(CONFIG_BLUETOOTH_SMP) static int att_change_security(struct bt_conn *conn, uint8_t err) { bt_security_t sec; @@ -1227,6 +1236,7 @@ static int att_change_security(struct bt_conn *conn, uint8_t err) return bt_conn_security(conn, sec); } +#endif /* CONFIG_BLUETOOTH_SMP */ static uint8_t att_error_rsp(struct bt_conn *conn, struct bt_buf *buf) { @@ -1249,7 +1259,7 @@ static uint8_t att_error_rsp(struct bt_conn *conn, struct bt_buf *buf) hdr = (void *)req->buf->data; err = rsp->request == hdr->code ? rsp->error : BT_ATT_ERR_UNLIKELY; - +#if defined(CONFIG_BLUETOOTH_SMP) if (req->retrying) goto done; @@ -1259,6 +1269,7 @@ static uint8_t att_error_rsp(struct bt_conn *conn, struct bt_buf *buf) /* Wait security_changed: TODO: Handle fail case */ return 0; } +#endif /* CONFIG_BLUETOOTH_SMP */ done: return att_handle_rsp(conn, NULL, 0, err); @@ -1531,6 +1542,7 @@ static void bt_att_disconnected(struct bt_conn *conn) bt_gatt_disconnected(conn); } +#if defined(CONFIG_BLUETOOTH_SMP) static void security_changed(struct bt_conn *conn, bt_security_t level) { struct bt_att *att = conn->att; @@ -1556,6 +1568,7 @@ static void security_changed(struct bt_conn *conn, bt_security_t level) static struct bt_conn_cb conn_callbacks = { .security_changed = security_changed, }; +#endif /* CONFIG_BLUETOOTH_SMP */ void bt_att_init(void) { @@ -1568,7 +1581,9 @@ void bt_att_init(void) bt_l2cap_chan_register(&chan); +#if defined(CONFIG_BLUETOOTH_SMP) bt_conn_cb_register(&conn_callbacks); +#endif /* CONFIG_BLUETOOTH_SMP */ } uint16_t bt_att_get_mtu(struct bt_conn *conn) @@ -1601,7 +1616,9 @@ int bt_att_send(struct bt_conn *conn, struct bt_buf *buf, bt_att_func_t func, } att->req.buf = bt_buf_clone(buf); +#if defined(CONFIG_BLUETOOTH_SMP) att->req.retrying = false; +#endif /* CONFIG_BLUETOOTH_SMP */ att->req.func = func; att->req.user_data = user_data; att->req.destroy = destroy; diff --git a/net/bluetooth/conn.c b/net/bluetooth/conn.c index b1a85565d03..d92fe013b4a 100644 --- a/net/bluetooth/conn.c +++ b/net/bluetooth/conn.c @@ -104,6 +104,7 @@ static void bt_conn_disconnected(struct bt_conn *conn) } } +#if defined(CONFIG_BLUETOOTH_SMP) void bt_conn_identity_resolved(struct bt_conn *conn) { const bt_addr_le_t *rpa; @@ -132,6 +133,7 @@ void bt_conn_security_changed(struct bt_conn *conn) } } } +#endif /* CONFIG_BLUETOOTH_SMP */ void bt_conn_cb_register(struct bt_conn_cb *cb) { @@ -367,8 +369,10 @@ struct bt_conn *bt_conn_add(const bt_addr_le_t *peer) atomic_set(&conn->ref, 1); bt_addr_le_copy(&conn->dst, peer); +#if defined(CONFIG_BLUETOOTH_SMP) conn->sec_level = BT_SECURITY_LOW; conn->required_sec_level = BT_SECURITY_LOW; +#endif /* CONFIG_BLUETOOTH_SMP */ return conn; } @@ -550,6 +554,7 @@ const bt_addr_le_t *bt_conn_get_dst(const struct bt_conn *conn) return &conn->dst; } +#if defined(CONFIG_BLUETOOTH_SMP) int bt_conn_security(struct bt_conn *conn, bt_security_t sec) { if (conn->state != BT_CONN_CONNECTED) { @@ -594,6 +599,7 @@ int bt_conn_security(struct bt_conn *conn, bt_security_t sec) return -EIO; #endif /* CONFIG_BLUETOOTH_PERIPHERAL */ } +#endif /* CONFIG_BLUETOOTH_SMP */ void bt_conn_set_auto_conn(struct bt_conn *conn, bool auto_conn) { @@ -704,6 +710,7 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer) return conn; } +#if defined(CONFIG_BLUETOOTH_SMP) int bt_conn_le_start_encryption(struct bt_conn *conn, uint64_t rand, uint16_t ediv, const uint8_t *ltk) { @@ -723,6 +730,7 @@ int bt_conn_le_start_encryption(struct bt_conn *conn, uint64_t rand, return bt_hci_cmd_send_sync(BT_HCI_OP_LE_START_ENCRYPTION, buf, NULL); } +#endif /* CONFIG_BLUETOOTH_SMP */ int bt_conn_le_conn_update(struct bt_conn *conn, uint16_t min, uint16_t max, uint16_t latency, uint16_t timeout) diff --git a/net/bluetooth/conn_internal.h b/net/bluetooth/conn_internal.h index ec047cdee8e..fac2a3e8cde 100644 --- a/net/bluetooth/conn_internal.h +++ b/net/bluetooth/conn_internal.h @@ -62,9 +62,11 @@ struct bt_conn { uint8_t pending_pkts; +#if defined(CONFIG_BLUETOOTH_SMP) uint8_t encrypt; bt_security_t sec_level; bt_security_t required_sec_level; +#endif /* CONFIG_BLUETOOTH_SMP */ uint16_t rx_len; struct bt_buf *rx; @@ -118,9 +120,11 @@ struct bt_conn *bt_conn_lookup_state(const bt_addr_le_t *peer, /* Set connection object in certain state and perform action related to state */ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state); +#if defined(CONFIG_BLUETOOTH_SMP) /* rand and ediv should be in BT order */ int bt_conn_le_start_encryption(struct bt_conn *conn, uint64_t rand, uint16_t ediv, const uint8_t *ltk); +#endif /* CONFIG_BLUETOOTH_SMP */ int bt_conn_le_conn_update(struct bt_conn *conn, uint16_t min, uint16_t max, uint16_t latency, uint16_t timeout); @@ -128,8 +132,10 @@ int bt_conn_le_conn_update(struct bt_conn *conn, uint16_t min, uint16_t max, /* Notify higher layers of a new connection */ void bt_conn_connected(struct bt_conn *conn); +#if defined(CONFIG_BLUETOOTH_SMP) /* Notify higher layers that RPA was resolved */ void bt_conn_identity_resolved(struct bt_conn *conn); /* Notify higher layers that connection security changed */ void bt_conn_security_changed(struct bt_conn *conn); +#endif /* CONFIG_BLUETOOTH_SMP */ diff --git a/net/bluetooth/gatt.c b/net/bluetooth/gatt.c index 8330b15ed35..f2c31c01c97 100644 --- a/net/bluetooth/gatt.c +++ b/net/bluetooth/gatt.c @@ -1122,6 +1122,15 @@ static void att_write_rsp(struct bt_conn *conn, uint8_t err, const void *pdu, func(conn, err); } +static bool write_signed_allowed(struct bt_conn *conn) +{ +#if defined(CONFIG_BLUETOOTH_SMP) + return conn->encrypt == 0; +#else + return false; +#endif /* CONFIG_BLUETOOTH_SMP */ +} + int bt_gatt_write_without_response(struct bt_conn *conn, uint16_t handle, const void *data, uint16_t length, bool sign) { @@ -1132,12 +1141,12 @@ int bt_gatt_write_without_response(struct bt_conn *conn, uint16_t handle, return -EINVAL; } - if (!sign || conn->encrypt) { - buf = bt_att_create_pdu(conn, BT_ATT_OP_WRITE_CMD, - sizeof(*cmd) + length); - } else { + if (sign && write_signed_allowed(conn)) { buf = bt_att_create_pdu(conn, BT_ATT_OP_SIGNED_WRITE_CMD, sizeof(*cmd) + length + 12); + } else { + buf = bt_att_create_pdu(conn, BT_ATT_OP_WRITE_CMD, + sizeof(*cmd) + length); } if (!buf) { return -ENOMEM; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 0540874a173..f3434c7161d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -320,7 +320,7 @@ static void analyze_stacks(struct bt_conn *conn, struct bt_conn **ref) /* HCI event processing */ -#if defined(CONFIG_BLUETOOTH_CONN) +#if defined(CONFIG_BLUETOOTH_SMP) static void update_sec_level(struct bt_conn *conn) { struct bt_keys *keys; @@ -370,7 +370,7 @@ static void hci_encrypt_change(struct bt_buf *buf) bt_conn_put(conn); } -#endif /* CONFIG_BLUETOOTH_CONN */ +#endif /* CONFIG_BLUETOOTH_SMP */ static void hci_reset_complete(struct bt_buf *buf) { @@ -513,7 +513,9 @@ static void hci_num_completed_packets(struct bt_buf *buf) } } } +#endif +#if defined(CONFIG_BLUETOOTH_SMP) static void hci_encrypt_key_refresh_complete(struct bt_buf *buf) { struct bt_hci_evt_encrypt_key_refresh_complete *evt = (void *)buf->data; @@ -555,7 +557,14 @@ static void copy_id_addr(struct bt_conn *conn, const bt_addr_le_t *addr) bt_addr_le_copy(&conn->dst, addr); } } +#else +#if defined(CONFIG_BLUETOOTH_CONN) +static void copy_id_addr(struct bt_conn *conn, const bt_addr_le_t *addr) +{ + bt_addr_le_copy(&conn->dst, addr); +} #endif /* CONFIG_BLUETOOTH_CONN */ +#endif /* CONFIG_BLUETOOTH_SMP */ static int bt_hci_start_scanning(uint8_t scan_type) { @@ -797,13 +806,14 @@ static int update_conn_params(struct bt_conn *conn) static struct bt_conn *find_pending_conn(const bt_addr_le_t *addr) { +#if defined(CONFIG_BLUETOOTH_SMP) struct bt_keys *keys; keys = bt_keys_find_irk(addr); if (keys) { return bt_conn_lookup_state(&keys->addr, BT_CONN_CONNECT); } - +#endif /* CONFIG_BLUETOOTH_SMP */ return bt_conn_lookup_state(addr, BT_CONN_CONNECT); } @@ -1045,13 +1055,15 @@ static void le_adv_report(struct bt_buf *buf) int8_t rssi = info->data[info->length]; #if defined(CONFIG_BLUETOOTH_CONN) const bt_addr_le_t *addr; +#if defined(CONFIG_BLUETOOTH_SMP) struct bt_keys *keys; +#endif /* CONFIG_BLUETOOTH_SMP */ #endif /* CONFIG_BLUETOOTH_CONN */ - BT_DBG("%s event %u, len %u, rssi %d dBm\n", bt_addr_le_str(&info->addr), info->evt_type, info->length, rssi); #if defined(CONFIG_BLUETOOTH_CONN) +#if defined(CONFIG_BLUETOOTH_SMP) keys = bt_keys_find_irk(&info->addr); if (keys) { addr = &keys->addr; @@ -1061,6 +1073,9 @@ static void le_adv_report(struct bt_buf *buf) } else { addr = &info->addr; } +#else + addr = &info->addr; +#endif /* CONFIG_BLUETOOTH_SMP */ if (scan_dev_found_cb) { scan_dev_found_cb(addr, rssi, info->evt_type, @@ -1082,7 +1097,7 @@ static void le_adv_report(struct bt_buf *buf) } } -#if defined(CONFIG_BLUETOOTH_CONN) +#if defined(CONFIG_BLUETOOTH_SMP) static void le_ltk_request(struct bt_buf *buf) { struct bt_hci_evt_le_ltk_request *evt = (void *)buf->data; @@ -1139,7 +1154,7 @@ static void le_ltk_request(struct bt_buf *buf) done: bt_conn_put(conn); } -#endif /* CONFIG_BLUETOOTH_CONN */ +#endif /* CONFIG_BLUETOOTH_SMP */ static void hci_le_meta_event(struct bt_buf *buf) { @@ -1155,9 +1170,6 @@ static void hci_le_meta_event(struct bt_buf *buf) case BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE: le_conn_update_complete(buf); break; - case BT_HCI_EVT_LE_LTK_REQUEST: - le_ltk_request(buf); - break; case BT_HCI_EV_LE_REMOTE_FEAT_COMPLETE: le_remote_feat_complete(buf); break; @@ -1165,6 +1177,11 @@ static void hci_le_meta_event(struct bt_buf *buf) le_conn_param_req(buf); break; #endif /* CONFIG_BLUETOOTH_CONN */ +#if defined(CONFIG_BLUETOOTH_SMP) + case BT_HCI_EVT_LE_LTK_REQUEST: + le_ltk_request(buf); + break; +#endif /* CONFIG_BLUETOOTH_SMP */ case BT_HCI_EVT_LE_ADVERTISING_REPORT: le_adv_report(buf); break; @@ -1187,13 +1204,15 @@ static void hci_event(struct bt_buf *buf) case BT_HCI_EVT_DISCONN_COMPLETE: hci_disconn_complete(buf); break; +#endif /* CONFIG_BLUETOOTH_CONN */ +#if defined(CONFIG_BLUETOOTH_SMP) case BT_HCI_EVT_ENCRYPT_CHANGE: hci_encrypt_change(buf); break; case BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE: hci_encrypt_key_refresh_complete(buf); break; -#endif /* CONFIG_BLUETOOTH_CONN */ +#endif /* CONFIG_BLUETOOTH_SMP */ case BT_HCI_EVT_LE_META_EVENT: hci_le_meta_event(buf); break; @@ -1476,12 +1495,12 @@ static int hci_init(void) ev->events[3] |= 0x02; /* Data Buffer Overflow */ ev->events[7] |= 0x20; /* LE Meta-Event */ -#if defined(CONFIG_BLUETOOTH_CONN) +#if defined(CONFIG_BLUETOOTH_SMP) if (bt_dev.le_features[0] & BT_HCI_LE_ENCRYPTION) { ev->events[0] |= 0x80; /* Encryption Change */ ev->events[5] |= 0x80; /* Encryption Key Refresh Complete */ } -#endif /* CONFIG_BLUETOOTH_CONN */ +#endif /* CONFIG_BLUETOOTH_SMP */ bt_hci_cmd_send_sync(BT_HCI_OP_SET_EVENT_MASK, buf, NULL); diff --git a/net/bluetooth/keys.h b/net/bluetooth/keys.h index 7d07a137db1..ecbe2d91f39 100644 --- a/net/bluetooth/keys.h +++ b/net/bluetooth/keys.h @@ -77,6 +77,7 @@ struct bt_keys { #endif /* BLUETOOTH_SIGNING */ }; +#if defined(CONFIG_BLUETOOTH_SMP) struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr); struct bt_keys *bt_keys_get_type(int type, const bt_addr_le_t *addr); void bt_keys_add_type(struct bt_keys *keys, int type); @@ -84,3 +85,9 @@ void bt_keys_clear(struct bt_keys *keys, int type); struct bt_keys *bt_keys_find(int type, const bt_addr_le_t *addr); struct bt_keys *bt_keys_find_irk(const bt_addr_le_t *addr); struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr); +#else +static inline struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr) +{ + return NULL; +} +#endif /* CONFIG_BLUETOOTH_SMP */ diff --git a/net/bluetooth/smp_null.c b/net/bluetooth/smp_null.c new file mode 100644 index 00000000000..7b8e6b203a4 --- /dev/null +++ b/net/bluetooth/smp_null.c @@ -0,0 +1,83 @@ +/** + * @file smp_null.c + * Security Manager Protocol stub + */ + +/* + * Copyright (c) 2015 Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3) Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "l2cap.h" +#include "smp.h" + +int bt_smp_sign_verify(struct bt_conn *conn, struct bt_buf *buf) +{ + return -ENOTSUP; +} + +static void bt_smp_recv(struct bt_conn *conn, struct bt_buf *buf) +{ + struct bt_smp_pairing_fail *rsp; + struct bt_smp_hdr *hdr; + + bt_buf_put(buf); + + /* If a device does not support pairing then it shall respond with + * a Pairing Failed command with the reason set to “Pairing Not + * Supported” when any command is received. + * Core Specification Vol. 3, Part H, 3.3 + */ + + buf = bt_l2cap_create_pdu(conn); + if (!buf) { + return; + } + + hdr = bt_buf_add(buf, sizeof(*hdr)); + hdr->code = BT_SMP_CMD_PAIRING_FAIL; + + rsp = bt_buf_add(buf, sizeof(*rsp)); + rsp->reason = BT_SMP_ERR_PAIRING_NOTSUPP; + + bt_l2cap_send(conn, BT_L2CAP_CID_SMP, buf); +} + +int bt_smp_init(void) +{ + static struct bt_l2cap_chan chan = { + .cid = BT_L2CAP_CID_SMP, + .recv = bt_smp_recv, + }; + + bt_l2cap_chan_register(&chan); + + return 0; +} diff --git a/samples/bluetooth/central/prj_x86.conf b/samples/bluetooth/central/prj_x86.conf index b3a5243d10f..bff3561dd69 100644 --- a/samples/bluetooth/central/prj_x86.conf +++ b/samples/bluetooth/central/prj_x86.conf @@ -3,3 +3,4 @@ CONFIG_BLUETOOTH=y CONFIG_BLUETOOTH_UART=y CONFIG_BLUETOOTH_DEBUG=y CONFIG_BLUETOOTH_CENTRAL=y +CONFIG_BLUETOOTH_SMP=y diff --git a/samples/bluetooth/shell/prj_arm.conf b/samples/bluetooth/shell/prj_arm.conf index bab8667f194..ccbc64f466f 100644 --- a/samples/bluetooth/shell/prj_arm.conf +++ b/samples/bluetooth/shell/prj_arm.conf @@ -6,4 +6,5 @@ CONFIG_BLUETOOTH_DEBUG=y CONFIG_CONSOLE_HANDLER=y CONFIG_BLUETOOTH_CENTRAL=y CONFIG_BLUETOOTH_PERIPHERAL=y +CONFIG_BLUETOOTH_SMP=y CONFIG_BLUETOOTH_SIGNING=y diff --git a/samples/bluetooth/shell/prj_x86.conf b/samples/bluetooth/shell/prj_x86.conf index 8ca03200768..b1db64e7be0 100644 --- a/samples/bluetooth/shell/prj_x86.conf +++ b/samples/bluetooth/shell/prj_x86.conf @@ -6,6 +6,7 @@ CONFIG_BLUETOOTH_UART=y CONFIG_CONSOLE_HANDLER=y CONFIG_BLUETOOTH_CENTRAL=y CONFIG_BLUETOOTH_PERIPHERAL=y +CONFIG_BLUETOOTH_SMP=y CONFIG_BLUETOOTH_SIGNING=y CONFIG_TINYCRYPT=y CONFIG_TINYCRYPT_AES=y diff --git a/samples/bluetooth/tester/prj_arm.conf b/samples/bluetooth/tester/prj_arm.conf index 78a4d445071..57a3667c672 100644 --- a/samples/bluetooth/tester/prj_arm.conf +++ b/samples/bluetooth/tester/prj_arm.conf @@ -5,6 +5,7 @@ CONFIG_BLUETOOTH=y CONFIG_BLUETOOTH_UART=y CONFIG_BLUETOOTH_CENTRAL=y CONFIG_BLUETOOTH_PERIPHERAL=y +CONFIG_BLUETOOTH_SMP=y CONFIG_BLUETOOTH_SIGNING=y CONFIG_BLUETOOTH_DEBUG=y CONFIG_BLUETOOTH_DEBUG_HCI_CORE=y