Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
[cascardo/linux.git] / net / bluetooth / smp.c
index 06a082e..4b07acb 100644 (file)
@@ -86,8 +86,8 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
 }
 
 static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
-               u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
-               u8 _rat, bdaddr_t *ra, u8 res[16])
+                 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
+                 u8 _rat, bdaddr_t *ra, u8 res[16])
 {
        u8 p1[16], p2[16];
        int err;
@@ -127,8 +127,8 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
        return err;
 }
 
-static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16],
-                       u8 r1[16], u8 r2[16], u8 _r[16])
+static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
+                 u8 r2[16], u8 _r[16])
 {
        int err;
 
@@ -151,7 +151,7 @@ static int smp_rand(u8 *buf)
 }
 
 static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
-                                               u16 dlen, void *data)
+                                    u16 dlen, void *data)
 {
        struct sk_buff *skb;
        struct l2cap_hdr *lh;
@@ -214,9 +214,8 @@ static __u8 seclevel_to_authreq(__u8 sec_level)
 }
 
 static void build_pairing_cmd(struct l2cap_conn *conn,
-                               struct smp_cmd_pairing *req,
-                               struct smp_cmd_pairing *rsp,
-                               __u8 authreq)
+                             struct smp_cmd_pairing *req,
+                             struct smp_cmd_pairing *rsp, __u8 authreq)
 {
        u8 dist_keys = 0;
 
@@ -250,7 +249,7 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
        struct smp_chan *smp = conn->smp_chan;
 
        if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
-                       (max_key_size < SMP_MIN_ENC_KEY_SIZE))
+           (max_key_size < SMP_MIN_ENC_KEY_SIZE))
                return SMP_ENC_KEY_SIZE;
 
        smp->enc_key_size = max_key_size;
@@ -264,7 +263,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
 
        if (send)
                smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
-                                                               &reason);
+                            &reason);
 
        clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
        mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
@@ -310,8 +309,8 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
        /* If either side has unknown io_caps, use JUST WORKS */
        /* Otherwise, look up method from the table */
        if (!(auth & SMP_AUTH_MITM) ||
-                       local_io > SMP_IO_KEYBOARD_DISPLAY ||
-                       remote_io > SMP_IO_KEYBOARD_DISPLAY)
+           local_io > SMP_IO_KEYBOARD_DISPLAY ||
+           remote_io > SMP_IO_KEYBOARD_DISPLAY)
                method = JUST_WORKS;
        else
                method = gen_method[remote_io][local_io];
@@ -387,13 +386,13 @@ static void confirm_work(struct work_struct *work)
        smp->tfm = tfm;
 
        if (conn->hcon->out)
-               ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, 0,
-                            &conn->hcon->hdev->bdaddr, conn->hcon->dst_type,
-                            &conn->hcon->dst, res);
+               ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
+                            conn->hcon->src_type, &conn->hcon->src,
+                            conn->hcon->dst_type, &conn->hcon->dst, res);
        else
                ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
-                            conn->hcon->dst_type, &conn->hcon->dst, 0,
-                            &conn->hcon->hdev->bdaddr, res);
+                            conn->hcon->dst_type, &conn->hcon->dst,
+                            conn->hcon->src_type, &conn->hcon->src, res);
        if (ret) {
                reason = SMP_UNSPECIFIED;
                goto error;
@@ -427,13 +426,13 @@ static void random_work(struct work_struct *work)
        BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 
        if (hcon->out)
-               ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 0,
-                            &hcon->hdev->bdaddr, hcon->dst_type, &hcon->dst,
-                            res);
+               ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
+                            hcon->src_type, &hcon->src,
+                            hcon->dst_type, &hcon->dst, res);
        else
                ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
-                            hcon->dst_type, &hcon->dst, 0, &hcon->hdev->bdaddr,
-                            res);
+                            hcon->dst_type, &hcon->dst,
+                            hcon->src_type, &hcon->src, res);
        if (ret) {
                reason = SMP_UNSPECIFIED;
                goto error;
@@ -481,7 +480,7 @@ static void random_work(struct work_struct *work)
                swap128(key, stk);
 
                memset(stk + smp->enc_key_size, 0,
-                               SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
+                      SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
 
                hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
                            HCI_SMP_STK_SLAVE, 0, 0, stk, smp->enc_key_size,
@@ -498,7 +497,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 {
        struct smp_chan *smp;
 
-       smp = kzalloc(sizeof(struct smp_chan), GFP_ATOMIC);
+       smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
        if (!smp)
                return NULL;
 
@@ -653,7 +652,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
        memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
 
        if ((req->auth_req & SMP_AUTH_BONDING) &&
-                       (rsp->auth_req & SMP_AUTH_BONDING))
+           (rsp->auth_req & SMP_AUTH_BONDING))
                auth = SMP_AUTH_BONDING;
 
        auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
@@ -688,7 +687,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 
                swap128(smp->prnd, random);
                smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
-                                                               random);
+                            random);
        } else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) {
                queue_work(hdev->workqueue, &smp->confirm);
        } else {
@@ -732,8 +731,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
        hcon->enc_key_size = key->enc_size;
 
        return 1;
-
 }
+
 static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
        struct smp_cmd_security_req *rp = (void *) skb->data;
@@ -743,6 +742,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
        BT_DBG("conn %p", conn);
 
+       if (!(conn->hcon->link_mode & HCI_LM_MASTER))
+               return SMP_CMD_NOTSUPP;
+
        hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
 
        if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
@@ -857,7 +859,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 
        if (hcon->type != LE_LINK) {
                kfree_skb(skb);
-               return -ENOTSUPP;
+               return 0;
        }
 
        if (skb->len < 1) {
@@ -865,7 +867,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
                return -EILSEQ;
        }
 
-       if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) {
+       if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
                err = -ENOTSUPP;
                reason = SMP_PAIRING_NOTSUPP;
                goto done;
@@ -1011,10 +1013,10 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 
                /* Just public address */
                memset(&addrinfo, 0, sizeof(addrinfo));
-               bacpy(&addrinfo.bdaddr, &conn->hcon->hdev->bdaddr);
+               bacpy(&addrinfo.bdaddr, &conn->hcon->src);
 
                smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
-                                                               &addrinfo);
+                            &addrinfo);
 
                *keydist &= ~SMP_DIST_ID_KEY;
        }