aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/smp.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 82443b95f24e..ffbfdd9e5738 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -197,14 +197,34 @@ static __u8 seclevel_to_authreq(__u8 level)
197} 197}
198 198
199static void build_pairing_cmd(struct l2cap_conn *conn, 199static void build_pairing_cmd(struct l2cap_conn *conn,
200 struct smp_cmd_pairing *cmd, __u8 authreq) 200 struct smp_cmd_pairing *req,
201 struct smp_cmd_pairing *rsp,
202 __u8 authreq)
201{ 203{
202 cmd->io_capability = conn->hcon->io_capability; 204 u8 dist_keys;
203 cmd->oob_flag = SMP_OOB_NOT_PRESENT; 205
204 cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE; 206 dist_keys = 0;
205 cmd->init_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN; 207 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) {
206 cmd->resp_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN; 208 dist_keys = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
207 cmd->auth_req = authreq; 209 authreq |= SMP_AUTH_BONDING;
210 }
211
212 if (rsp == NULL) {
213 req->io_capability = conn->hcon->io_capability;
214 req->oob_flag = SMP_OOB_NOT_PRESENT;
215 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
216 req->init_key_dist = dist_keys;
217 req->resp_key_dist = dist_keys;
218 req->auth_req = authreq;
219 return;
220 }
221
222 rsp->io_capability = conn->hcon->io_capability;
223 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
224 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
225 rsp->init_key_dist = req->init_key_dist & dist_keys;
226 rsp->resp_key_dist = req->resp_key_dist & dist_keys;
227 rsp->auth_req = authreq;
208} 228}
209 229
210static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) 230static 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)
233 return SMP_OOB_NOT_AVAIL; 253 return SMP_OOB_NOT_AVAIL;
234 254
235 /* We didn't start the pairing, so no requirements */ 255 /* We didn't start the pairing, so no requirements */
236 build_pairing_cmd(conn, &rsp, SMP_AUTH_NONE); 256 build_pairing_cmd(conn, req, &rsp, SMP_AUTH_NONE);
237 257
238 key_size = min(req->max_key_size, rsp.max_key_size); 258 key_size = min(req->max_key_size, rsp.max_key_size);
239 if (check_enc_key_size(conn, key_size)) 259 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)
412 skb_pull(skb, sizeof(*rp)); 432 skb_pull(skb, sizeof(*rp));
413 433
414 memset(&cp, 0, sizeof(cp)); 434 memset(&cp, 0, sizeof(cp));
415 build_pairing_cmd(conn, &cp, rp->auth_req); 435 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
416 436
417 conn->preq[0] = SMP_CMD_PAIRING_REQ; 437 conn->preq[0] = SMP_CMD_PAIRING_REQ;
418 memcpy(&conn->preq[1], &cp, sizeof(cp)); 438 memcpy(&conn->preq[1], &cp, sizeof(cp));
@@ -454,7 +474,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
454 if (hcon->link_mode & HCI_LM_MASTER) { 474 if (hcon->link_mode & HCI_LM_MASTER) {
455 struct smp_cmd_pairing cp; 475 struct smp_cmd_pairing cp;
456 476
457 build_pairing_cmd(conn, &cp, authreq); 477 build_pairing_cmd(conn, &cp, NULL, authreq);
458 conn->preq[0] = SMP_CMD_PAIRING_REQ; 478 conn->preq[0] = SMP_CMD_PAIRING_REQ;
459 memcpy(&conn->preq[1], &cp, sizeof(cp)); 479 memcpy(&conn->preq[1], &cp, sizeof(cp));
460 480