All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Bluetooth: Update SSP OOB data EIR definitions
@ 2015-04-07 11:36 Johan Hedberg
  2015-04-07 11:36 ` [PATCH 2/2] Bluetooth: Add local SSP OOB data to OOB ext data mgmt command Johan Hedberg
  0 siblings, 1 reply; 3+ messages in thread
From: Johan Hedberg @ 2015-04-07 11:36 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

Since Bluetooth 4.1 there are two additional values for SSP OOB data,
namely C-256 and R-256. This patch updates the EIR definitions to take
into account both the 192 and 256 bit variants of C and R.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 3acecf35420b..2f8c830e600c 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -463,12 +463,14 @@ enum {
 #define EIR_NAME_COMPLETE	0x09 /* complete local name */
 #define EIR_TX_POWER		0x0A /* transmit power level */
 #define EIR_CLASS_OF_DEV	0x0D /* Class of Device */
-#define EIR_SSP_HASH_C		0x0E /* Simple Pairing Hash C */
-#define EIR_SSP_RAND_R		0x0F /* Simple Pairing Randomizer R */
+#define EIR_SSP_HASH_C192	0x0E /* Simple Pairing Hash C-192 */
+#define EIR_SSP_RAND_R192	0x0F /* Simple Pairing Randomizer R-192 */
 #define EIR_DEVICE_ID		0x10 /* device ID */
 #define EIR_APPEARANCE		0x19 /* Device appearance */
 #define EIR_LE_BDADDR		0x1B /* LE Bluetooth device address */
 #define EIR_LE_ROLE		0x1C /* LE role */
+#define EIR_SSP_HASH_C256	0x1D /* Simple Pairing Hash C-256 */
+#define EIR_SSP_RAND_R256	0x1E /* Simple Pairing Rand R-256 */
 #define EIR_LE_SC_CONFIRM	0x22 /* LE SC Confirmation Value */
 #define EIR_LE_SC_RANDOM	0x23 /* LE SC Random Value */
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] Bluetooth: Add local SSP OOB data to OOB ext data mgmt command
  2015-04-07 11:36 [PATCH 1/2] Bluetooth: Update SSP OOB data EIR definitions Johan Hedberg
@ 2015-04-07 11:36 ` Johan Hedberg
  2015-04-07 15:59   ` Marcel Holtmann
  0 siblings, 1 reply; 3+ messages in thread
From: Johan Hedberg @ 2015-04-07 11:36 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

The Read Local Out Of Band Extended Data mgmt command is specified to
return the SSP values when given a BR/EDR address type as input
parameter. The returned values may include either the 192-bit variants
of C and R, or their 256-bit variants, or both, depending on the status
of Secure Connections and Secure Connections Only modes. If SSP is not
enabled the command will only return the Class of Device value (like it
has done so far).

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/mgmt.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 149 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 845dfcc43a20..df721370605b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -6466,6 +6466,140 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
 	return eir_len;
 }
 
+static void read_local_oob_ext_data_complete(struct hci_dev *hdev, u8 status,
+					     u16 opcode, struct sk_buff *skb)
+{
+	const struct mgmt_cp_read_local_oob_ext_data *mgmt_cp;
+	struct mgmt_rp_read_local_oob_ext_data *mgmt_rp;
+	u8 *h192, *r192, *h256, *r256;
+	struct mgmt_pending_cmd *cmd;
+	u16 eir_len;
+	int err;
+
+	BT_DBG("%s status %u", hdev->name, status);
+
+	cmd = pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev);
+	if (!cmd)
+		return;
+
+	mgmt_cp = cmd->param;
+
+	if (status) {
+		status = mgmt_status(status);
+		eir_len = 0;
+	} else if (opcode == HCI_OP_READ_LOCAL_OOB_DATA) {
+		struct hci_rp_read_local_oob_data *rp;
+
+		if (skb->len != sizeof(*rp)) {
+			status = MGMT_STATUS_FAILED;
+			eir_len = 0;
+		} else {
+			status = MGMT_STATUS_SUCCESS;
+			rp = (void *) skb->data;
+
+			eir_len = 5 + 18 + 18;
+			h192 = rp->hash;
+			r192 = rp->rand;
+			h256 = NULL;
+			r256 = NULL;
+		}
+	} else {
+		struct hci_rp_read_local_oob_ext_data *rp;
+
+		if (skb->len != sizeof(*rp)) {
+			status = MGMT_STATUS_FAILED;
+			eir_len = 0;
+		} else {
+			status = MGMT_STATUS_SUCCESS;
+			rp = (void *) skb->data;
+
+			if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
+				eir_len = 5 + 18 + 18;
+				h192 = NULL;
+				r192 = NULL;
+			} else {
+				eir_len = 5 + 18 + 18 + 18 + 18;
+				h192 = rp->hash192;
+				r192 = rp->rand192;
+			}
+
+			h256 = rp->hash256;
+			r256 = rp->rand256;
+		}
+	}
+
+	mgmt_rp = kmalloc(sizeof(*mgmt_rp) + eir_len, GFP_KERNEL);
+	if (!mgmt_rp)
+		goto done;
+
+	if (status)
+		goto send_rsp;
+
+	eir_len = eir_append_data(mgmt_rp->eir, 0, EIR_CLASS_OF_DEV,
+				  hdev->dev_class, 3);
+
+	if (h192 && r192) {
+		eir_len = eir_append_data(mgmt_rp->eir, eir_len,
+					  EIR_SSP_HASH_C192, h192, 16);
+		eir_len = eir_append_data(mgmt_rp->eir, eir_len,
+					  EIR_SSP_RAND_R192, r192, 16);
+	}
+
+	if (h256 && r256) {
+		eir_len = eir_append_data(mgmt_rp->eir, eir_len,
+					  EIR_SSP_HASH_C256, h256, 16);
+		eir_len = eir_append_data(mgmt_rp->eir, eir_len,
+					  EIR_SSP_RAND_R256, r256, 16);
+	}
+
+send_rsp:
+	mgmt_rp->type = mgmt_cp->type;
+	mgmt_rp->eir_len = cpu_to_le16(eir_len);
+
+	err = mgmt_cmd_complete(cmd->sk, hdev->id,
+				MGMT_OP_READ_LOCAL_OOB_EXT_DATA, status,
+				mgmt_rp, sizeof(*mgmt_rp) + eir_len);
+	if (err < 0 || status)
+		goto done;
+
+	hci_sock_set_flag(cmd->sk, HCI_MGMT_OOB_DATA_EVENTS);
+
+	err = mgmt_limited_event(MGMT_EV_LOCAL_OOB_DATA_UPDATED, hdev,
+				 mgmt_rp, sizeof(*mgmt_rp) + eir_len,
+				 HCI_MGMT_OOB_DATA_EVENTS, cmd->sk);
+done:
+	kfree(mgmt_rp);
+	mgmt_pending_remove(cmd);
+}
+
+static int read_local_ssp_oob_req(struct hci_dev *hdev, struct sock *sk,
+				  struct mgmt_cp_read_local_oob_ext_data *cp)
+{
+	struct mgmt_pending_cmd *cmd;
+	struct hci_request req;
+	int err;
+
+	cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev,
+			       cp, sizeof(*cp));
+	if (!cmd)
+		return -ENOMEM;
+
+	hci_req_init(&req, hdev);
+
+	if (bredr_sc_enabled(hdev))
+		hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_EXT_DATA, 0, NULL);
+	else
+		hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
+
+	err = hci_req_run_skb(&req, read_local_oob_ext_data_complete);
+	if (err < 0) {
+		mgmt_pending_remove(cmd);
+		return err;
+	}
+
+	return 0;
+}
+
 static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
 				   void *data, u16 data_len)
 {
@@ -6517,9 +6651,21 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
 	eir_len = 0;
 	switch (cp->type) {
 	case BIT(BDADDR_BREDR):
-		eir_len = eir_append_data(rp->eir, eir_len, EIR_CLASS_OF_DEV,
-					  hdev->dev_class, 3);
-		break;
+		if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
+			eir_len = eir_append_data(rp->eir, eir_len,
+						  EIR_CLASS_OF_DEV,
+						  hdev->dev_class, 3);
+			break;
+		}
+
+		err = read_local_ssp_oob_req(hdev, sk, cp);
+		hci_dev_unlock(hdev);
+		if (err) {
+			status = MGMT_STATUS_FAILED;
+			goto complete;
+		}
+
+		goto done;
 	case (BIT(BDADDR_LE_PUBLIC) | BIT(BDADDR_LE_RANDOM)):
 		if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
 		    smp_generate_oob(hdev, hash, rand) < 0) {
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] Bluetooth: Add local SSP OOB data to OOB ext data mgmt command
  2015-04-07 11:36 ` [PATCH 2/2] Bluetooth: Add local SSP OOB data to OOB ext data mgmt command Johan Hedberg
@ 2015-04-07 15:59   ` Marcel Holtmann
  0 siblings, 0 replies; 3+ messages in thread
From: Marcel Holtmann @ 2015-04-07 15:59 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth

Hi Johan,

> The Read Local Out Of Band Extended Data mgmt command is specified to
> return the SSP values when given a BR/EDR address type as input
> parameter. The returned values may include either the 192-bit variants
> of C and R, or their 256-bit variants, or both, depending on the status
> of Secure Connections and Secure Connections Only modes. If SSP is not
> enabled the command will only return the Class of Device value (like it
> has done so far).
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/mgmt.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 149 insertions(+), 3 deletions(-)
> 
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index 845dfcc43a20..df721370605b 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -6466,6 +6466,140 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
> 	return eir_len;
> }
> 
> +static void read_local_oob_ext_data_complete(struct hci_dev *hdev, u8 status,
> +					     u16 opcode, struct sk_buff *skb)
> +{
> +	const struct mgmt_cp_read_local_oob_ext_data *mgmt_cp;
> +	struct mgmt_rp_read_local_oob_ext_data *mgmt_rp;
> +	u8 *h192, *r192, *h256, *r256;
> +	struct mgmt_pending_cmd *cmd;
> +	u16 eir_len;
> +	int err;
> +
> +	BT_DBG("%s status %u", hdev->name, status);
> +
> +	cmd = pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev);
> +	if (!cmd)
> +		return;
> +
> +	mgmt_cp = cmd->param;
> +
> +	if (status) {
> +		status = mgmt_status(status);
> +		eir_len = 0;
> +	} else if (opcode == HCI_OP_READ_LOCAL_OOB_DATA) {
> +		struct hci_rp_read_local_oob_data *rp;
> +
> +		if (skb->len != sizeof(*rp)) {
> +			status = MGMT_STATUS_FAILED;
> +			eir_len = 0;
> +		} else {
> +			status = MGMT_STATUS_SUCCESS;
> +			rp = (void *) skb->data;

I think the coding style proposes (void *)skb->data.

> +
> +			eir_len = 5 + 18 + 18;
> +			h192 = rp->hash;
> +			r192 = rp->rand;
> +			h256 = NULL;
> +			r256 = NULL;
> +		}
> +	} else {
> +		struct hci_rp_read_local_oob_ext_data *rp;
> +
> +		if (skb->len != sizeof(*rp)) {
> +			status = MGMT_STATUS_FAILED;
> +			eir_len = 0;
> +		} else {
> +			status = MGMT_STATUS_SUCCESS;
> +			rp = (void *) skb->data;

Same as above.

> +
> +			if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
> +				eir_len = 5 + 18 + 18;
> +				h192 = NULL;
> +				r192 = NULL;
> +			} else {
> +				eir_len = 5 + 18 + 18 + 18 + 18;
> +				h192 = rp->hash192;
> +				r192 = rp->rand192;
> +			}
> +
> +			h256 = rp->hash256;
> +			r256 = rp->rand256;
> +		}
> +	}
> +
> +	mgmt_rp = kmalloc(sizeof(*mgmt_rp) + eir_len, GFP_KERNEL);
> +	if (!mgmt_rp)
> +		goto done;
> +
> +	if (status)
> +		goto send_rsp;
> +
> +	eir_len = eir_append_data(mgmt_rp->eir, 0, EIR_CLASS_OF_DEV,
> +				  hdev->dev_class, 3);
> +
> +	if (h192 && r192) {
> +		eir_len = eir_append_data(mgmt_rp->eir, eir_len,
> +					  EIR_SSP_HASH_C192, h192, 16);
> +		eir_len = eir_append_data(mgmt_rp->eir, eir_len,
> +					  EIR_SSP_RAND_R192, r192, 16);
> +	}
> +
> +	if (h256 && r256) {
> +		eir_len = eir_append_data(mgmt_rp->eir, eir_len,
> +					  EIR_SSP_HASH_C256, h256, 16);
> +		eir_len = eir_append_data(mgmt_rp->eir, eir_len,
> +					  EIR_SSP_RAND_R256, r256, 16);
> +	}
> +
> +send_rsp:
> +	mgmt_rp->type = mgmt_cp->type;
> +	mgmt_rp->eir_len = cpu_to_le16(eir_len);
> +
> +	err = mgmt_cmd_complete(cmd->sk, hdev->id,
> +				MGMT_OP_READ_LOCAL_OOB_EXT_DATA, status,
> +				mgmt_rp, sizeof(*mgmt_rp) + eir_len);
> +	if (err < 0 || status)
> +		goto done;
> +
> +	hci_sock_set_flag(cmd->sk, HCI_MGMT_OOB_DATA_EVENTS);
> +
> +	err = mgmt_limited_event(MGMT_EV_LOCAL_OOB_DATA_UPDATED, hdev,
> +				 mgmt_rp, sizeof(*mgmt_rp) + eir_len,
> +				 HCI_MGMT_OOB_DATA_EVENTS, cmd->sk);
> +done:
> +	kfree(mgmt_rp);
> +	mgmt_pending_remove(cmd);
> +}
> +
> +static int read_local_ssp_oob_req(struct hci_dev *hdev, struct sock *sk,
> +				  struct mgmt_cp_read_local_oob_ext_data *cp)
> +{
> +	struct mgmt_pending_cmd *cmd;
> +	struct hci_request req;
> +	int err;
> +
> +	cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev,
> +			       cp, sizeof(*cp));
> +	if (!cmd)
> +		return -ENOMEM;
> +
> +	hci_req_init(&req, hdev);
> +
> +	if (bredr_sc_enabled(hdev))
> +		hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_EXT_DATA, 0, NULL);
> +	else
> +		hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
> +
> +	err = hci_req_run_skb(&req, read_local_oob_ext_data_complete);
> +	if (err < 0) {
> +		mgmt_pending_remove(cmd);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
> 				   void *data, u16 data_len)
> {
> @@ -6517,9 +6651,21 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
> 	eir_len = 0;
> 	switch (cp->type) {
> 	case BIT(BDADDR_BREDR):
> -		eir_len = eir_append_data(rp->eir, eir_len, EIR_CLASS_OF_DEV,
> -					  hdev->dev_class, 3);
> -		break;
> +		if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
> +			eir_len = eir_append_data(rp->eir, eir_len,
> +						  EIR_CLASS_OF_DEV,
> +						  hdev->dev_class, 3);
> +			break;
> +		}
> +
> +		err = read_local_ssp_oob_req(hdev, sk, cp);
> +		hci_dev_unlock(hdev);
> +		if (err) {
> +			status = MGMT_STATUS_FAILED;
> +			goto complete;
> +		}
> +
> +		goto done;


So I think in this specific case, doing it with if clauses is cleaner than the break and goto and easier to read:

	if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
		err = read_local_..
		hci_dev_unlock(hdev);
		if (!err)
			goto done;

		status = MGMT_STATUS_..
		goto completed;
	} else {
		eir_len = eir_append_data(..
	}
	break;


> 	case (BIT(BDADDR_LE_PUBLIC) | BIT(BDADDR_LE_RANDOM)):
> 		if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
> 		    smp_generate_oob(hdev, hash, rand) < 0) {

Regards

Marcel


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-04-07 15:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-07 11:36 [PATCH 1/2] Bluetooth: Update SSP OOB data EIR definitions Johan Hedberg
2015-04-07 11:36 ` [PATCH 2/2] Bluetooth: Add local SSP OOB data to OOB ext data mgmt command Johan Hedberg
2015-04-07 15:59   ` Marcel Holtmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.