|
@@ -197,14 +197,34 @@ static __u8 seclevel_to_authreq(__u8 level)
|
|
}
|
|
}
|
|
|
|
|
|
static void build_pairing_cmd(struct l2cap_conn *conn,
|
|
static void build_pairing_cmd(struct l2cap_conn *conn,
|
|
- struct smp_cmd_pairing *cmd, __u8 authreq)
|
|
|
|
|
|
+ struct smp_cmd_pairing *req,
|
|
|
|
+ struct smp_cmd_pairing *rsp,
|
|
|
|
+ __u8 authreq)
|
|
{
|
|
{
|
|
- cmd->io_capability = conn->hcon->io_capability;
|
|
|
|
- cmd->oob_flag = SMP_OOB_NOT_PRESENT;
|
|
|
|
- cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE;
|
|
|
|
- cmd->init_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
|
|
|
|
- cmd->resp_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
|
|
|
|
- cmd->auth_req = authreq;
|
|
|
|
|
|
+ u8 dist_keys;
|
|
|
|
+
|
|
|
|
+ dist_keys = 0;
|
|
|
|
+ if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) {
|
|
|
|
+ dist_keys = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
|
|
|
|
+ authreq |= SMP_AUTH_BONDING;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (rsp == NULL) {
|
|
|
|
+ req->io_capability = conn->hcon->io_capability;
|
|
|
|
+ req->oob_flag = SMP_OOB_NOT_PRESENT;
|
|
|
|
+ req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
|
|
|
|
+ req->init_key_dist = dist_keys;
|
|
|
|
+ req->resp_key_dist = dist_keys;
|
|
|
|
+ req->auth_req = authreq;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rsp->io_capability = conn->hcon->io_capability;
|
|
|
|
+ rsp->oob_flag = SMP_OOB_NOT_PRESENT;
|
|
|
|
+ rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
|
|
|
|
+ rsp->init_key_dist = req->init_key_dist & dist_keys;
|
|
|
|
+ rsp->resp_key_dist = req->resp_key_dist & dist_keys;
|
|
|
|
+ rsp->auth_req = authreq;
|
|
}
|
|
}
|
|
|
|
|
|
static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
|
|
static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
|
|
@@ -233,7 +253,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
|
|
return SMP_OOB_NOT_AVAIL;
|
|
return SMP_OOB_NOT_AVAIL;
|
|
|
|
|
|
/* We didn't start the pairing, so no requirements */
|
|
/* We didn't start the pairing, so no requirements */
|
|
- build_pairing_cmd(conn, &rsp, SMP_AUTH_NONE);
|
|
|
|
|
|
+ build_pairing_cmd(conn, req, &rsp, SMP_AUTH_NONE);
|
|
|
|
|
|
key_size = min(req->max_key_size, rsp.max_key_size);
|
|
key_size = min(req->max_key_size, rsp.max_key_size);
|
|
if (check_enc_key_size(conn, key_size))
|
|
if (check_enc_key_size(conn, key_size))
|
|
@@ -412,7 +432,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
|
|
skb_pull(skb, sizeof(*rp));
|
|
skb_pull(skb, sizeof(*rp));
|
|
|
|
|
|
memset(&cp, 0, sizeof(cp));
|
|
memset(&cp, 0, sizeof(cp));
|
|
- build_pairing_cmd(conn, &cp, rp->auth_req);
|
|
|
|
|
|
+ build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
|
|
|
|
|
|
conn->preq[0] = SMP_CMD_PAIRING_REQ;
|
|
conn->preq[0] = SMP_CMD_PAIRING_REQ;
|
|
memcpy(&conn->preq[1], &cp, sizeof(cp));
|
|
memcpy(&conn->preq[1], &cp, sizeof(cp));
|
|
@@ -454,7 +474,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
|
|
if (hcon->link_mode & HCI_LM_MASTER) {
|
|
if (hcon->link_mode & HCI_LM_MASTER) {
|
|
struct smp_cmd_pairing cp;
|
|
struct smp_cmd_pairing cp;
|
|
|
|
|
|
- build_pairing_cmd(conn, &cp, authreq);
|
|
|
|
|
|
+ build_pairing_cmd(conn, &cp, NULL, authreq);
|
|
conn->preq[0] = SMP_CMD_PAIRING_REQ;
|
|
conn->preq[0] = SMP_CMD_PAIRING_REQ;
|
|
memcpy(&conn->preq[1], &cp, sizeof(cp));
|
|
memcpy(&conn->preq[1], &cp, sizeof(cp));
|
|
|
|
|