Re: [PATCH v2 10/10] Bluetooth: Wait for SMP key distribution completion when pairing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Johan,

> When we initiate pairing through mgmt_pair_device the code has so far
> been waiting for a successful HCI Encrypt Change event in order to
> respond to the mgmt command. However, putting privacy into the play we
> actually want the key distribution to be complete before replying so
> that we can include the Identity Address in the mgmt response.
> 
> This patch updates the various hci_conn callbacks for LE in mgmt.c to
> only respond in the case of failure, and adds a new mgmt_smp_complete
> function that the SMP code will call once key distribution has been
> completed.
> 
> Since the smp_chan_destroy function that's used to indicate completion
> and clean up the SMP context can be called from various places,
> including outside of smp.c, the easiest way to track failure vs success
> is a new flag that we set once key distribution has been successfully
> completed.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@xxxxxxxxx>
> ---
> v2: Fix passing correct status value to pairing_complete()
> 
> include/net/bluetooth/hci_core.h |  1 +
> net/bluetooth/mgmt.c             | 27 +++++++++++++++++++++------
> net/bluetooth/smp.c              |  5 +++++
> net/bluetooth/smp.h              |  1 +
> 4 files changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 4461c0051228..64c4e3f0a515 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -1212,6 +1212,7 @@ int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
> int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
> void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
> void mgmt_reenable_advertising(struct hci_dev *hdev);
> +void mgmt_smp_complete(struct hci_conn *conn, bool complete);
> 
> /* HCI info for socket */
> #define hci_pi(sk) ((struct hci_pinfo *) sk)
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index 90aac905a98b..f9ae72ca556d 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -2655,6 +2655,18 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
> 	mgmt_pending_remove(cmd);
> }
> 
> +void mgmt_smp_complete(struct hci_conn *conn, bool complete)
> +{
> +	u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED;
> +	struct pending_cmd *cmd;
> +
> +	cmd = find_pairing(conn);
> +	if (!cmd)
> +		BT_DBG("Unable to find a pending command”);

why do we bother with the debug print here?

> +	else
> +		pairing_complete(cmd, status);

I would just do this:

	if (cmd)
		pairing_complete(cmd, status);

Unless you have future patches that do more work here.

> +}
> +
> static void pairing_complete_cb(struct hci_conn *conn, u8 status)
> {
> 	struct pending_cmd *cmd;
> @@ -2668,7 +2680,7 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
> 		pairing_complete(cmd, mgmt_status(status));
> }
> 
> -static void le_connect_complete_cb(struct hci_conn *conn, u8 status)
> +static void le_pairing_complete_cb(struct hci_conn *conn, u8 status)
> {
> 	struct pending_cmd *cmd;
> 
> @@ -2755,13 +2767,16 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
> 	}
> 
> 	/* For LE, just connecting isn't a proof that the pairing finished */
> -	if (cp->addr.type == BDADDR_BREDR)
> +	if (cp->addr.type == BDADDR_BREDR) {
> 		conn->connect_cfm_cb = pairing_complete_cb;
> -	else
> -		conn->connect_cfm_cb = le_connect_complete_cb;
> +		conn->security_cfm_cb = pairing_complete_cb;
> +		conn->disconn_cfm_cb = pairing_complete_cb;
> +	} else {
> +		conn->connect_cfm_cb = le_pairing_complete_cb;
> +		conn->security_cfm_cb = le_pairing_complete_cb;
> +		conn->disconn_cfm_cb = le_pairing_complete_cb;
> +	}
> 
> -	conn->security_cfm_cb = pairing_complete_cb;
> -	conn->disconn_cfm_cb = pairing_complete_cb;
> 	conn->io_capability = cp->io_cap;
> 	cmd->user_data = conn;
> 
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index faf04bd4263a..9741623de6e7 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -551,9 +551,13 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
> void smp_chan_destroy(struct l2cap_conn *conn)
> {
> 	struct smp_chan *smp = conn->smp_chan;
> +	bool complete;
> 
> 	BUG_ON(!smp);
> 
> +	complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
> +	mgmt_smp_complete(conn->hcon, complete);
> +
> 	kfree(smp);
> 	conn->smp_chan = NULL;
> 	conn->hcon->smp_conn = NULL;
> @@ -1172,6 +1176,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
> 	if (conn->hcon->out || force || !(rsp->init_key_dist & 0x07)) {
> 		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
> 		cancel_delayed_work_sync(&conn->security_timer);
> +		set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
> 		smp_chan_destroy(conn);
> 	}
> 
> diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
> index 8f54c9b152de..675fd3b21d2c 100644
> --- a/net/bluetooth/smp.h
> +++ b/net/bluetooth/smp.h
> @@ -118,6 +118,7 @@ struct smp_cmd_security_req {
> #define SMP_FLAG_TK_VALID	1
> #define SMP_FLAG_CFM_PENDING	2
> #define SMP_FLAG_MITM_AUTH	3
> +#define SMP_FLAG_COMPLETE	4
> 
> struct smp_chan {
> 	struct l2cap_conn *conn;

Regards

Marcel

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux