first fruits - kill l2cap ->memcpy_fromiovec()
[deliverable/linux.git] / net / bluetooth / smp.c
index f09b6b65cf6b22079d6ce60d53f2613ccf6a7745..de7dc7581ff072f5e2361c3506bddaa68d121b6b 100644 (file)
@@ -191,16 +191,13 @@ int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
        return 0;
 }
 
-static int smp_c1(struct smp_chan *smp, 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])
+static int smp_c1(struct crypto_blkcipher *tfm_aes, 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])
 {
-       struct hci_dev *hdev = smp->conn->hcon->hdev;
        u8 p1[16], p2[16];
        int err;
 
-       BT_DBG("%s", hdev->name);
-
        memset(p1, 0, 16);
 
        /* p1 = pres || preq || _rat || _iat */
@@ -218,7 +215,7 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
        u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
 
        /* res = e(k, res) */
-       err = smp_e(smp->tfm_aes, k, res);
+       err = smp_e(tfm_aes, k, res);
        if (err) {
                BT_ERR("Encrypt data error");
                return err;
@@ -228,26 +225,23 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
        u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
 
        /* res = e(k, res) */
-       err = smp_e(smp->tfm_aes, k, res);
+       err = smp_e(tfm_aes, k, res);
        if (err)
                BT_ERR("Encrypt data error");
 
        return err;
 }
 
-static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16],
-                 u8 _r[16])
+static int smp_s1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r1[16],
+                 u8 r2[16], u8 _r[16])
 {
-       struct hci_dev *hdev = smp->conn->hcon->hdev;
        int err;
 
-       BT_DBG("%s", hdev->name);
-
        /* Just least significant octets from r1 and r2 are considered */
        memcpy(_r, r2, 8);
        memcpy(_r + 8, r1, 8);
 
-       err = smp_e(smp->tfm_aes, k, _r);
+       err = smp_e(tfm_aes, k, _r);
        if (err)
                BT_ERR("Encrypt data error");
 
@@ -274,8 +268,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
 
        memset(&msg, 0, sizeof(msg));
 
-       msg.msg_iov = (struct iovec *) &iv;
-       msg.msg_iovlen = 2;
+       iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iv, 2, 1 + len);
 
        l2cap_chan_send(chan, &msg, 1 + len);
 
@@ -389,18 +382,18 @@ static void smp_chan_destroy(struct l2cap_conn *conn)
        /* If pairing failed clean up any keys we might have */
        if (!complete) {
                if (smp->ltk) {
-                       list_del(&smp->ltk->list);
-                       kfree(smp->ltk);
+                       list_del_rcu(&smp->ltk->list);
+                       kfree_rcu(smp->ltk, rcu);
                }
 
                if (smp->slave_ltk) {
-                       list_del(&smp->slave_ltk->list);
-                       kfree(smp->slave_ltk);
+                       list_del_rcu(&smp->slave_ltk->list);
+                       kfree_rcu(smp->slave_ltk, rcu);
                }
 
                if (smp->remote_irk) {
-                       list_del(&smp->remote_irk->list);
-                       kfree(smp->remote_irk);
+                       list_del_rcu(&smp->remote_irk->list);
+                       kfree_rcu(smp->remote_irk, rcu);
                }
        }
 
@@ -520,8 +513,6 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
                set_bit(SMP_FLAG_TK_VALID, &smp->flags);
        }
 
-       hci_dev_lock(hcon->hdev);
-
        if (method == REQ_PASSKEY)
                ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
                                                hcon->type, hcon->dst_type);
@@ -534,8 +525,6 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
                                                hcon->type, hcon->dst_type,
                                                passkey, 0);
 
-       hci_dev_unlock(hcon->hdev);
-
        return ret;
 }
 
@@ -547,7 +536,7 @@ static u8 smp_confirm(struct smp_chan *smp)
 
        BT_DBG("conn %p", conn);
 
-       ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
+       ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
                     conn->hcon->init_addr_type, &conn->hcon->init_addr,
                     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
                     cp.confirm_val);
@@ -578,7 +567,7 @@ static u8 smp_random(struct smp_chan *smp)
 
        BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 
-       ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
+       ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
                     hcon->init_addr_type, &hcon->init_addr,
                     hcon->resp_addr_type, &hcon->resp_addr, confirm);
        if (ret)
@@ -594,7 +583,7 @@ static u8 smp_random(struct smp_chan *smp)
                __le64 rand = 0;
                __le16 ediv = 0;
 
-               smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
+               smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
 
                memset(stk + smp->enc_key_size, 0,
                       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
@@ -613,7 +602,7 @@ static u8 smp_random(struct smp_chan *smp)
                smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
                             smp->prnd);
 
-               smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
+               smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
 
                memset(stk + smp->enc_key_size, 0,
                       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
@@ -665,8 +654,8 @@ static void smp_notify_keys(struct l2cap_conn *conn)
                 * just remove it.
                 */
                if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
-                       list_del(&smp->remote_irk->list);
-                       kfree(smp->remote_irk);
+                       list_del_rcu(&smp->remote_irk->list);
+                       kfree_rcu(smp->remote_irk, rcu);
                        smp->remote_irk = NULL;
                }
        }
@@ -970,7 +959,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
        if (sec_level > conn->hcon->pending_sec_level)
                conn->hcon->pending_sec_level = sec_level;
 
-       /* If we need MITM check that it can be acheived */
+       /* If we need MITM check that it can be achieved */
        if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
                u8 method;
 
@@ -1028,7 +1017,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 
        auth = rsp->auth_req & AUTH_REQ_MASK;
 
-       /* If we need MITM check that it can be acheived */
+       /* If we need MITM check that it can be achieved */
        if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
                u8 method;
 
@@ -1132,18 +1121,20 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
        return true;
 }
 
-bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
+bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
+                            enum smp_key_pref key_pref)
 {
        if (sec_level == BT_SECURITY_LOW)
                return true;
 
-       /* If we're encrypted with an STK always claim insufficient
-        * security. This way we allow the connection to be re-encrypted
-        * with an LTK, even if the LTK provides the same level of
-        * security. Only exception is if we don't have an LTK (e.g.
-        * because of key distribution bits).
+       /* If we're encrypted with an STK but the caller prefers using
+        * LTK claim insufficient security. This way we allow the
+        * connection to be re-encrypted with an LTK, even if the LTK
+        * provides the same level of security. Only exception is if we
+        * don't have an LTK (e.g. because of key distribution bits).
         */
-       if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
+       if (key_pref == SMP_USE_LTK &&
+           test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
            hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
                                 hcon->role))
                return false;
@@ -1177,7 +1168,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
        else
                sec_level = authreq_to_seclevel(auth);
 
-       if (smp_sufficient_security(hcon, sec_level))
+       if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
                return 0;
 
        if (sec_level > hcon->pending_sec_level)
@@ -1227,7 +1218,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
        if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
                return 1;
 
-       if (smp_sufficient_security(hcon, sec_level))
+       if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
                return 1;
 
        if (sec_level > hcon->pending_sec_level)
@@ -1329,7 +1320,6 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 
        skb_pull(skb, sizeof(*rp));
 
-       hci_dev_lock(hdev);
        authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
        ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
                          authenticated, smp->tk, smp->enc_key_size,
@@ -1337,7 +1327,6 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
        smp->ltk = ltk;
        if (!(smp->remote_key_dist & KEY_DIST_MASK))
                smp_distribute_keys(smp);
-       hci_dev_unlock(hdev);
 
        return 0;
 }
@@ -1384,8 +1373,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
 
        skb_pull(skb, sizeof(*info));
 
-       hci_dev_lock(hcon->hdev);
-
        /* Strictly speaking the Core Specification (4.1) allows sending
         * an empty address which would force us to rely on just the IRK
         * as "identity information". However, since such
@@ -1413,8 +1400,6 @@ distribute:
        if (!(smp->remote_key_dist & KEY_DIST_MASK))
                smp_distribute_keys(smp);
 
-       hci_dev_unlock(hcon->hdev);
-
        return 0;
 }
 
@@ -1423,7 +1408,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
        struct smp_cmd_sign_info *rp = (void *) skb->data;
        struct l2cap_chan *chan = conn->smp;
        struct smp_chan *smp = chan->data;
-       struct hci_dev *hdev = conn->hcon->hdev;
        struct smp_csrk *csrk;
 
        BT_DBG("conn %p", conn);
@@ -1436,7 +1420,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
 
        skb_pull(skb, sizeof(*rp));
 
-       hci_dev_lock(hdev);
        csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
        if (csrk) {
                csrk->master = 0x01;
@@ -1444,7 +1427,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
        }
        smp->csrk = csrk;
        smp_distribute_keys(smp);
-       hci_dev_unlock(hdev);
 
        return 0;
 }
@@ -1647,7 +1629,6 @@ static const struct l2cap_ops smp_chan_ops = {
        .suspend                = l2cap_chan_no_suspend,
        .set_shutdown           = l2cap_chan_no_set_shutdown,
        .get_sndtimeo           = l2cap_chan_no_get_sndtimeo,
-       .memcpy_fromiovec       = l2cap_chan_no_memcpy_fromiovec,
 };
 
 static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
@@ -1668,6 +1649,13 @@ static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
        chan->omtu      = pchan->omtu;
        chan->mode      = pchan->mode;
 
+       /* Other L2CAP channels may request SMP routines in order to
+        * change the security level. This means that the SMP channel
+        * lock must be considered in its own category to avoid lockdep
+        * warnings.
+        */
+       atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
+
        BT_DBG("created chan %p", chan);
 
        return chan;
@@ -1689,7 +1677,6 @@ static const struct l2cap_ops smp_root_chan_ops = {
        .resume                 = l2cap_chan_no_resume,
        .set_shutdown           = l2cap_chan_no_set_shutdown,
        .get_sndtimeo           = l2cap_chan_no_get_sndtimeo,
-       .memcpy_fromiovec       = l2cap_chan_no_memcpy_fromiovec,
 };
 
 int smp_register(struct hci_dev *hdev)
@@ -1699,7 +1686,7 @@ int smp_register(struct hci_dev *hdev)
 
        BT_DBG("%s", hdev->name);
 
-       tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
+       tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 0);
        if (IS_ERR(tfm_aes)) {
                int err = PTR_ERR(tfm_aes);
                BT_ERR("Unable to create crypto context");
@@ -1725,6 +1712,9 @@ int smp_register(struct hci_dev *hdev)
        chan->imtu = L2CAP_DEFAULT_MTU;
        chan->ops = &smp_root_chan_ops;
 
+       /* Set correct nesting level for a parent/listening channel */
+       atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
+
        hdev->smp_data = chan;
 
        return 0;
This page took 0.02946 seconds and 5 git commands to generate.