static int l2cap_change_security(struct bt_l2cap_le_chan *chan, uint16_t err) { switch (err) { case BT_L2CAP_ERR_ENCRYPTION: if (chan->chan.required_sec_level >= BT_SECURITY_MEDIUM) { return -EALREADY; } chan->chan.required_sec_level = BT_SECURITY_MEDIUM; break; case BT_L2CAP_ERR_AUTHENTICATION: if (chan->chan.required_sec_level < BT_SECURITY_MEDIUM) { chan->chan.required_sec_level = BT_SECURITY_MEDIUM; } else if (chan->chan.required_sec_level < BT_SECURITY_HIGH) { chan->chan.required_sec_level = BT_SECURITY_HIGH; } else if (chan->chan.required_sec_level < BT_SECURITY_FIPS) { chan->chan.required_sec_level = BT_SECURITY_FIPS; } else { return -EALREADY; } break; default: return -EINVAL; } return bt_conn_security(chan->chan.conn, chan->chan.required_sec_level); }
void on_nble_sm_security_request_evt(const struct nble_sm_security_request_evt *evt) { struct bt_conn *conn; struct bt_smp *smp; BT_DBG(""); conn = bt_conn_lookup_handle(evt->conn_handle); if (!conn) { BT_ERR("Unable to find conn for handle %u", evt->conn_handle); return; } smp = smp_chan_get(conn); if (!smp) { BT_ERR("No smp"); bt_conn_unref(conn); return; } BT_DBG("conn %p remote_io %u mitm %u", conn, evt->sec_param.remote_io, evt->sec_param.mitm); smp->method = legacy_get_pair_method(smp, evt->sec_param.remote_io); if (smp->method == JUST_WORKS && nble.auth && nble.auth->pairing_confirm) { atomic_set_bit(&smp->flags, SMP_FLAG_USER); nble.auth->pairing_confirm(smp->conn); goto done; } if (evt->sec_param.mitm) { bt_conn_security(conn, BT_SECURITY_HIGH); } else { bt_conn_security(conn, BT_SECURITY_MEDIUM); } done: atomic_set_bit(&smp->flags, SMP_FLAG_SEC_REQ); bt_conn_unref(conn); }
static void connected(struct bt_conn *conn, uint8_t err) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); if (err) { printk("Failed to connect to %s (%u)\n", addr, err); return; } printk("Connected %s\n", addr); if (bt_conn_security(conn, BT_SECURITY_FIPS)) { printk("Failed to set security\n"); } }
static int att_change_security(struct bt_conn *conn, uint8_t err) { bt_security_t sec; switch (err) { case BT_ATT_ERR_INSUFFICIENT_ENCRYPTION: if (conn->sec_level >= BT_SECURITY_MEDIUM) return -EALREADY; sec = BT_SECURITY_MEDIUM; break; case BT_ATT_ERR_AUTHENTICATION: if (conn->sec_level >= BT_SECURITY_HIGH) return -EALREADY; sec = BT_SECURITY_HIGH; break; default: return -EINVAL; } return bt_conn_security(conn, sec); }
static int cmd_security(int argc, char *argv[]) { int err, sec; if (!default_conn) { printk("Not connected\n"); return 0; } if (argc < 2) { return -EINVAL; } sec = *argv[1] - '0'; err = bt_conn_security(default_conn, sec); if (err) { printk("Setting security failed (err %d)\n", err); } return 0; }
static void pair(const uint8_t *data, uint16_t len) { struct bt_conn *conn; uint8_t status; conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data); if (!conn) { status = BTP_STATUS_FAILED; goto rsp; } if (bt_conn_security(conn, BT_SECURITY_MEDIUM)) { status = BTP_STATUS_FAILED; bt_conn_unref(conn); goto rsp; } bt_conn_unref(conn); status = BTP_STATUS_SUCCESS; rsp: tester_rsp(BTP_SERVICE_ID_GAP, GAP_PAIR, CONTROLLER_INDEX, status); }