linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event
@ 2014-02-19 12:57 johan.hedberg
  2014-02-19 12:57 ` [PATCH 1/6] Bluetooth: Avoid using GFP_ATOMIC where not necessary johan.hedberg
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: johan.hedberg @ 2014-02-19 12:57 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

This patch set adds support for the New IRK mgmt event and moves the
sending of New LTK events after that event (ensuring they all contain
the Identity Address insted of the RPA).

Johan

----------------------------------------------------------------
Johan Hedberg (6):
      Bluetooth: Avoid using GFP_ATOMIC where not necessary
      Bluetooth: Return added key when adding LTKs and IRKs
      Bluetooth: Move New LTK store hint evaluation into mgmt_new_ltk
      Bluetooth: Track SMP keys in the SMP context
      Bluetooth: Move SMP LTK notification after key distribution
      Bluetooth: Add support for sending New IRK event

 include/net/bluetooth/hci_core.h | 13 ++++++-----
 include/net/bluetooth/mgmt.h     |  7 ++++++
 net/bluetooth/hci_core.c         | 38 +++++++++++--------------------
 net/bluetooth/mgmt.c             | 30 ++++++++++++++++++++-----
 net/bluetooth/smp.c              | 45 +++++++++++++++++++++++++++++--------
 net/bluetooth/smp.h              |  3 +++
 6 files changed, 91 insertions(+), 45 deletions(-)


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

* [PATCH 1/6] Bluetooth: Avoid using GFP_ATOMIC where not necessary
  2014-02-19 12:57 [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event johan.hedberg
@ 2014-02-19 12:57 ` johan.hedberg
  2014-02-19 12:57 ` [PATCH 2/6] Bluetooth: Return added key when adding LTKs and IRKs johan.hedberg
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: johan.hedberg @ 2014-02-19 12:57 UTC (permalink / raw)
  To: linux-bluetooth

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

The various pieces of data cached in the hci_dev structure do not need
to be allocated using GFP_ATOMIC since they are never added from
interrupt context. This patch updates these allocations to use
GFP_KERNEL instead.

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

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e8f61b3fe87c..7e679e085506 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2721,7 +2721,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 		key = old_key;
 	} else {
 		old_key_type = conn ? conn->key_type : 0xff;
-		key = kzalloc(sizeof(*key), GFP_ATOMIC);
+		key = kzalloc(sizeof(*key), GFP_KERNEL);
 		if (!key)
 			return -ENOMEM;
 		list_add(&key->list, &hdev->link_keys);
@@ -2773,7 +2773,7 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
 	if (old_key)
 		key = old_key;
 	else {
-		key = kzalloc(sizeof(*key), GFP_ATOMIC);
+		key = kzalloc(sizeof(*key), GFP_KERNEL);
 		if (!key)
 			return -ENOMEM;
 		list_add(&key->list, &hdev->long_term_keys);
@@ -2938,7 +2938,7 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
 
 	data = hci_find_remote_oob_data(hdev, bdaddr);
 	if (!data) {
-		data = kmalloc(sizeof(*data), GFP_ATOMIC);
+		data = kmalloc(sizeof(*data), GFP_KERNEL);
 		if (!data)
 			return -ENOMEM;
 
@@ -2965,7 +2965,7 @@ int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
 
 	data = hci_find_remote_oob_data(hdev, bdaddr);
 	if (!data) {
-		data = kmalloc(sizeof(*data), GFP_ATOMIC);
+		data = kmalloc(sizeof(*data), GFP_KERNEL);
 		if (!data)
 			return -ENOMEM;
 
-- 
1.8.5.3


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

* [PATCH 2/6] Bluetooth: Return added key when adding LTKs and IRKs
  2014-02-19 12:57 [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event johan.hedberg
  2014-02-19 12:57 ` [PATCH 1/6] Bluetooth: Avoid using GFP_ATOMIC where not necessary johan.hedberg
@ 2014-02-19 12:57 ` johan.hedberg
  2014-02-19 12:57 ` [PATCH 3/6] Bluetooth: Move New LTK store hint evaluation into mgmt_new_ltk johan.hedberg
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: johan.hedberg @ 2014-02-19 12:57 UTC (permalink / raw)
  To: linux-bluetooth

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

The SMP code will need to postpone the mgmt event emission for the IRK
and LTKs. To avoid extra lookups at the end of the key distribution
simply return the added value from the add_ltk and add_irk functions.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h | 11 ++++++-----
 net/bluetooth/hci_core.c         | 21 +++++++++++----------
 2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 64c4e3f0a515..5366dc9e25eb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -787,9 +787,10 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
 struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8],
 			     bool master);
-int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
-		int new_key, u8 authenticated, u8 tk[16], u8 enc_size,
-		__le16 ediv, u8 rand[8]);
+struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			    u8 addr_type, u8 type, int new_key,
+			    u8 authenticated, u8 tk[16], u8 enc_size,
+			    __le16 ediv, u8 rand[8]);
 struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
 				     u8 addr_type, bool master);
 int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type);
@@ -799,8 +800,8 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa);
 struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
 				     u8 addr_type);
-int hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type,
-		u8 val[16], bdaddr_t *rpa);
+struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			    u8 addr_type, u8 val[16], bdaddr_t *rpa);
 void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type);
 void hci_smp_irks_clear(struct hci_dev *hdev);
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 7e679e085506..e23c718d668b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2761,9 +2761,10 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 	return 0;
 }
 
-int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
-		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
-		ediv, u8 rand[8])
+struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			    u8 addr_type, u8 type, int new_key,
+			    u8 authenticated, u8 tk[16], u8 enc_size,
+			    __le16 ediv, u8 rand[8])
 {
 	struct smp_ltk *key, *old_key;
 	bool master = ltk_type_master(type);
@@ -2775,7 +2776,7 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
 	else {
 		key = kzalloc(sizeof(*key), GFP_KERNEL);
 		if (!key)
-			return -ENOMEM;
+			return NULL;
 		list_add(&key->list, &hdev->long_term_keys);
 	}
 
@@ -2789,7 +2790,7 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
 	memcpy(key->rand, rand, sizeof(key->rand));
 
 	if (!new_key)
-		return 0;
+		return key;
 
 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
 		persistent = 0;
@@ -2799,11 +2800,11 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
 	if (type == HCI_SMP_LTK || type == HCI_SMP_LTK_SLAVE)
 		mgmt_new_ltk(hdev, key, persistent);
 
-	return 0;
+	return key;
 }
 
-int hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type,
-		u8 val[16], bdaddr_t *rpa)
+struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
 {
 	struct smp_irk *irk;
 
@@ -2811,7 +2812,7 @@ int hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type,
 	if (!irk) {
 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
 		if (!irk)
-			return -ENOMEM;
+			return NULL;
 
 		bacpy(&irk->bdaddr, bdaddr);
 		irk->addr_type = addr_type;
@@ -2822,7 +2823,7 @@ int hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type,
 	memcpy(irk->val, val, 16);
 	bacpy(&irk->rpa, rpa);
 
-	return 0;
+	return irk;
 }
 
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
-- 
1.8.5.3


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

* [PATCH 3/6] Bluetooth: Move New LTK store hint evaluation into mgmt_new_ltk
  2014-02-19 12:57 [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event johan.hedberg
  2014-02-19 12:57 ` [PATCH 1/6] Bluetooth: Avoid using GFP_ATOMIC where not necessary johan.hedberg
  2014-02-19 12:57 ` [PATCH 2/6] Bluetooth: Return added key when adding LTKs and IRKs johan.hedberg
@ 2014-02-19 12:57 ` johan.hedberg
  2014-02-19 12:57 ` [PATCH 4/6] Bluetooth: Track SMP keys in the SMP context johan.hedberg
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: johan.hedberg @ 2014-02-19 12:57 UTC (permalink / raw)
  To: linux-bluetooth

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

It's simpler (one less if-statement) to just evaluate the appropriate
value for store_hint in the mgmt_new_ltk function than to pass a boolean
parameter to the function. Furthermore, this simplifies moving the mgmt
event emission out from hci_add_ltk in subsequent patches.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h | 2 +-
 net/bluetooth/hci_core.c         | 8 +-------
 net/bluetooth/mgmt.c             | 9 +++++++--
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5366dc9e25eb..8ca95e5e3765 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1211,7 +1211,7 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
 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_new_ltk(struct hci_dev *hdev, struct smp_ltk *key);
 void mgmt_reenable_advertising(struct hci_dev *hdev);
 void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e23c718d668b..60c875267c19 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2768,7 +2768,6 @@ struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
 {
 	struct smp_ltk *key, *old_key;
 	bool master = ltk_type_master(type);
-	u8 persistent;
 
 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master);
 	if (old_key)
@@ -2792,13 +2791,8 @@ struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
 	if (!new_key)
 		return key;
 
-	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
-		persistent = 0;
-	else
-		persistent = 1;
-
 	if (type == HCI_SMP_LTK || type == HCI_SMP_LTK_SLAVE)
-		mgmt_new_ltk(hdev, key, persistent);
+		mgmt_new_ltk(hdev, key);
 
 	return key;
 }
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 747cb9bbc331..ad51da1b6dc2 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4765,13 +4765,18 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
 	mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
 }
 
-void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent)
+void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key)
 {
 	struct mgmt_ev_new_long_term_key ev;
 
 	memset(&ev, 0, sizeof(ev));
 
-	ev.store_hint = persistent;
+	if (key->bdaddr_type == ADDR_LE_DEV_RANDOM &&
+	    (key->bdaddr.b[5] & 0xc0) != 0xc0)
+		ev.store_hint = 0x00;
+	else
+		ev.store_hint = 0x01;
+
 	bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
 	ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
 	ev.key.type = key->authenticated;
-- 
1.8.5.3


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

* [PATCH 4/6] Bluetooth: Track SMP keys in the SMP context
  2014-02-19 12:57 [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event johan.hedberg
                   ` (2 preceding siblings ...)
  2014-02-19 12:57 ` [PATCH 3/6] Bluetooth: Move New LTK store hint evaluation into mgmt_new_ltk johan.hedberg
@ 2014-02-19 12:57 ` johan.hedberg
  2014-02-19 12:57 ` [PATCH 5/6] Bluetooth: Move SMP LTK notification after key distribution johan.hedberg
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: johan.hedberg @ 2014-02-19 12:57 UTC (permalink / raw)
  To: linux-bluetooth

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

As preparation to do mgmt notification in a single place at the end of
the key distribution, store the keys that need to be notified within the
SMP context.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/smp.c | 21 +++++++++++++--------
 net/bluetooth/smp.h |  3 +++
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 27eebca260fa..eaac54be91b1 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -915,6 +915,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 	struct smp_chan *smp = conn->smp_chan;
 	struct hci_dev *hdev = conn->hcon->hdev;
 	struct hci_conn *hcon = conn->hcon;
+	struct smp_ltk *ltk;
 	u8 authenticated;
 
 	BT_DBG("conn %p", conn);
@@ -930,9 +931,10 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	hci_dev_lock(hdev);
 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
-	hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK, 1,
-		    authenticated, smp->tk, smp->enc_key_size,
-		    rp->ediv, rp->rand);
+	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK, 1,
+			  authenticated, smp->tk, smp->enc_key_size,
+			  rp->ediv, rp->rand);
+	smp->ltk = ltk;
 	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
 		smp_distribute_keys(conn, 1);
 	hci_dev_unlock(hdev);
@@ -988,8 +990,8 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
 	else
 		bacpy(&rpa, BDADDR_ANY);
 
-	hci_add_irk(conn->hcon->hdev, &smp->id_addr, smp->id_addr_type,
-		    smp->irk, &rpa);
+	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
+				      smp->id_addr_type, smp->irk, &rpa);
 
 	/* Track the connection based on the Identity Address from now on */
 	bacpy(&hcon->dst, &smp->id_addr);
@@ -1137,6 +1139,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 		struct smp_cmd_encrypt_info enc;
 		struct smp_cmd_master_ident ident;
 		struct hci_conn *hcon = conn->hcon;
+		struct smp_ltk *ltk;
 		u8 authenticated;
 		__le16 ediv;
 
@@ -1147,9 +1150,11 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
 
 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
-		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
-			    HCI_SMP_LTK_SLAVE, 1, authenticated,
-			    enc.ltk, smp->enc_key_size, ediv, ident.rand);
+		ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
+				  HCI_SMP_LTK_SLAVE, 1, authenticated,
+				  enc.ltk, smp->enc_key_size, ediv,
+				  ident.rand);
+		smp->slave_ltk = ltk;
 
 		ident.ediv = ediv;
 
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index 675fd3b21d2c..d8cc543f523c 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -133,6 +133,9 @@ struct smp_chan {
 	bdaddr_t	id_addr;
 	u8		id_addr_type;
 	u8		irk[16];
+	struct smp_ltk	*ltk;
+	struct smp_ltk	*slave_ltk;
+	struct smp_irk	*remote_irk;
 	unsigned long	smp_flags;
 	struct work_struct confirm;
 	struct work_struct random;
-- 
1.8.5.3


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

* [PATCH 5/6] Bluetooth: Move SMP LTK notification after key distribution
  2014-02-19 12:57 [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event johan.hedberg
                   ` (3 preceding siblings ...)
  2014-02-19 12:57 ` [PATCH 4/6] Bluetooth: Track SMP keys in the SMP context johan.hedberg
@ 2014-02-19 12:57 ` johan.hedberg
  2014-02-19 12:57 ` [PATCH 6/6] Bluetooth: Add support for sending New IRK event johan.hedberg
  2014-02-19 16:03 ` [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event Marcel Holtmann
  6 siblings, 0 replies; 9+ messages in thread
From: johan.hedberg @ 2014-02-19 12:57 UTC (permalink / raw)
  To: linux-bluetooth

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

This patch moves the SMP Long Term Key notification over mgmt from the
hci_add_ltk function to smp.c when both sides have completed their key
distribution. This way we are also able to update the identity address
into the mgmt_new_ltk event.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h |  5 ++---
 net/bluetooth/hci_core.c         | 11 ++---------
 net/bluetooth/mgmt.c             |  6 +++---
 net/bluetooth/smp.c              | 29 ++++++++++++++++++++++++-----
 4 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 8ca95e5e3765..59ae04c2684f 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -788,9 +788,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8],
 			     bool master);
 struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
-			    u8 addr_type, u8 type, int new_key,
-			    u8 authenticated, u8 tk[16], u8 enc_size,
-			    __le16 ediv, u8 rand[8]);
+			    u8 addr_type, u8 type, u8 authenticated,
+			    u8 tk[16], u8 enc_size, __le16 ediv, u8 rand[8]);
 struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
 				     u8 addr_type, bool master);
 int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 60c875267c19..3711c7626cb2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2762,9 +2762,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 }
 
 struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
-			    u8 addr_type, u8 type, int new_key,
-			    u8 authenticated, u8 tk[16], u8 enc_size,
-			    __le16 ediv, u8 rand[8])
+			    u8 addr_type, u8 type, u8 authenticated,
+			    u8 tk[16], u8 enc_size, __le16 ediv, u8 rand[8])
 {
 	struct smp_ltk *key, *old_key;
 	bool master = ltk_type_master(type);
@@ -2788,12 +2787,6 @@ struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
 	key->type = type;
 	memcpy(key->rand, rand, sizeof(key->rand));
 
-	if (!new_key)
-		return key;
-
-	if (type == HCI_SMP_LTK || type == HCI_SMP_LTK_SLAVE)
-		mgmt_new_ltk(hdev, key);
-
 	return key;
 }
 
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ad51da1b6dc2..bcfc6da67a5c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4330,9 +4330,9 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
 		else
 			type = HCI_SMP_LTK_SLAVE;
 
-		hci_add_ltk(hdev, &key->addr.bdaddr, addr_type,
-			    type, 0, key->type, key->val,
-			    key->enc_size, key->ediv, key->rand);
+		hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type,
+			    key->type, key->val, key->enc_size, key->ediv,
+			    key->rand);
 	}
 
 	err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0,
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index eaac54be91b1..f05c1b71d99a 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -532,7 +532,7 @@ static void random_work(struct work_struct *work)
 		       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,
+			    HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
 			    ediv, rand);
 	}
 
@@ -931,7 +931,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	hci_dev_lock(hdev);
 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
-	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK, 1,
+	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
 			  authenticated, smp->tk, smp->enc_key_size,
 			  rp->ediv, rp->rand);
 	smp->ltk = ltk;
@@ -1106,6 +1106,25 @@ done:
 	return err;
 }
 
+static void smp_notify_keys(struct l2cap_conn *conn)
+{
+	struct smp_chan *smp = conn->smp_chan;
+	struct hci_conn *hcon = conn->hcon;
+	struct hci_dev *hdev = hcon->hdev;
+
+	if (smp->ltk) {
+		smp->ltk->bdaddr_type = hcon->dst_type;
+		bacpy(&smp->ltk->bdaddr, &hcon->dst);
+		mgmt_new_ltk(hdev, smp->ltk);
+	}
+
+	if (smp->slave_ltk) {
+		smp->slave_ltk->bdaddr_type = hcon->dst_type;
+		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
+		mgmt_new_ltk(hdev, smp->slave_ltk);
+	}
+}
+
 int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 {
 	struct smp_cmd_pairing *req, *rsp;
@@ -1151,9 +1170,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 
 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
 		ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
-				  HCI_SMP_LTK_SLAVE, 1, authenticated,
-				  enc.ltk, smp->enc_key_size, ediv,
-				  ident.rand);
+				  HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
+				  smp->enc_key_size, ediv, ident.rand);
 		smp->slave_ltk = ltk;
 
 		ident.ediv = ediv;
@@ -1197,6 +1215,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 		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_notify_keys(conn);
 		smp_chan_destroy(conn);
 	}
 
-- 
1.8.5.3


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

* [PATCH 6/6] Bluetooth: Add support for sending New IRK event
  2014-02-19 12:57 [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event johan.hedberg
                   ` (4 preceding siblings ...)
  2014-02-19 12:57 ` [PATCH 5/6] Bluetooth: Move SMP LTK notification after key distribution johan.hedberg
@ 2014-02-19 12:57 ` johan.hedberg
  2014-02-19 13:18   ` [PATCH v2 " johan.hedberg
  2014-02-19 16:03 ` [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event Marcel Holtmann
  6 siblings, 1 reply; 9+ messages in thread
From: johan.hedberg @ 2014-02-19 12:57 UTC (permalink / raw)
  To: linux-bluetooth

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

This patch adds the necessary helper function to send the New IRK mgmt
event and makes sure that the function is called at when SMP key
distribution has completed. The event is sent before the New LTK event
so user space knows which remote device to associate with the keys.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h |  1 +
 include/net/bluetooth/mgmt.h     |  7 +++++++
 net/bluetooth/mgmt.c             | 15 +++++++++++++++
 net/bluetooth/smp.c              |  3 +++
 4 files changed, 26 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 59ae04c2684f..3be2905010cd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1211,6 +1211,7 @@ void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
 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);
+void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
 void mgmt_reenable_advertising(struct hci_dev *hdev);
 void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index e4fa13e559e2..2e46251e8aec 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -536,3 +536,10 @@ struct mgmt_ev_passkey_notify {
 	__le32	passkey;
 	__u8	entered;
 } __packed;
+
+#define MGMT_EV_NEW_IRK			0x0018
+struct mgmt_ev_new_irk {
+	__u8     store_hint;
+	bdaddr_t rpa;
+	struct mgmt_irk_info irk;
+} __packed;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index bcfc6da67a5c..1daa837da091 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4792,6 +4792,21 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key)
 	mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), NULL);
 }
 
+void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk)
+{
+	struct mgmt_ev_new_irk ev;
+
+	memset(&ev, 0, sizeof(ev));
+
+	ev.store_hint = 0x01;
+	bacpy(&ev.rpa, &irk->rpa);
+	bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr);
+	ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type);
+	memcpy(ev.irk.val, irk->val, sizeof(irk->val));
+
+	mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
+}
+
 static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
 				  u8 data_len)
 {
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index f05c1b71d99a..e3794592fa66 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1112,6 +1112,9 @@ static void smp_notify_keys(struct l2cap_conn *conn)
 	struct hci_conn *hcon = conn->hcon;
 	struct hci_dev *hdev = hcon->hdev;
 
+	if (smp->irk)
+		mgmt_new_irk(hdev, smp->remote_irk);
+
 	if (smp->ltk) {
 		smp->ltk->bdaddr_type = hcon->dst_type;
 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
-- 
1.8.5.3


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

* [PATCH v2 6/6] Bluetooth: Add support for sending New IRK event
  2014-02-19 12:57 ` [PATCH 6/6] Bluetooth: Add support for sending New IRK event johan.hedberg
@ 2014-02-19 13:18   ` johan.hedberg
  0 siblings, 0 replies; 9+ messages in thread
From: johan.hedberg @ 2014-02-19 13:18 UTC (permalink / raw)
  To: linux-bluetooth

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

This patch adds the necessary helper function to send the New IRK mgmt
event and makes sure that the function is called at when SMP key
distribution has completed. The event is sent before the New LTK event
so user space knows which remote device to associate with the keys.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
v2: Fix checking for correct irk variable before calling mgmt_new_irk

 include/net/bluetooth/hci_core.h |  1 +
 include/net/bluetooth/mgmt.h     |  7 +++++++
 net/bluetooth/mgmt.c             | 15 +++++++++++++++
 net/bluetooth/smp.c              |  3 +++
 4 files changed, 26 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 59ae04c2684f..3be2905010cd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1211,6 +1211,7 @@ void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
 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);
+void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
 void mgmt_reenable_advertising(struct hci_dev *hdev);
 void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index e4fa13e559e2..2e46251e8aec 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -536,3 +536,10 @@ struct mgmt_ev_passkey_notify {
 	__le32	passkey;
 	__u8	entered;
 } __packed;
+
+#define MGMT_EV_NEW_IRK			0x0018
+struct mgmt_ev_new_irk {
+	__u8     store_hint;
+	bdaddr_t rpa;
+	struct mgmt_irk_info irk;
+} __packed;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index bcfc6da67a5c..1daa837da091 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4792,6 +4792,21 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key)
 	mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), NULL);
 }
 
+void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk)
+{
+	struct mgmt_ev_new_irk ev;
+
+	memset(&ev, 0, sizeof(ev));
+
+	ev.store_hint = 0x01;
+	bacpy(&ev.rpa, &irk->rpa);
+	bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr);
+	ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type);
+	memcpy(ev.irk.val, irk->val, sizeof(irk->val));
+
+	mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
+}
+
 static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
 				  u8 data_len)
 {
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index f05c1b71d99a..f06068072bdd 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1112,6 +1112,9 @@ static void smp_notify_keys(struct l2cap_conn *conn)
 	struct hci_conn *hcon = conn->hcon;
 	struct hci_dev *hdev = hcon->hdev;
 
+	if (smp->remote_irk)
+		mgmt_new_irk(hdev, smp->remote_irk);
+
 	if (smp->ltk) {
 		smp->ltk->bdaddr_type = hcon->dst_type;
 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
-- 
1.8.5.3


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

* Re: [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event
  2014-02-19 12:57 [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event johan.hedberg
                   ` (5 preceding siblings ...)
  2014-02-19 12:57 ` [PATCH 6/6] Bluetooth: Add support for sending New IRK event johan.hedberg
@ 2014-02-19 16:03 ` Marcel Holtmann
  6 siblings, 0 replies; 9+ messages in thread
From: Marcel Holtmann @ 2014-02-19 16:03 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)

Hi Johan,

> This patch set adds support for the New IRK mgmt event and moves the
> sending of New LTK events after that event (ensuring they all contain
> the Identity Address insted of the RPA).
> 
> Johan
> 
> ----------------------------------------------------------------
> Johan Hedberg (6):
>      Bluetooth: Avoid using GFP_ATOMIC where not necessary
>      Bluetooth: Return added key when adding LTKs and IRKs
>      Bluetooth: Move New LTK store hint evaluation into mgmt_new_ltk
>      Bluetooth: Track SMP keys in the SMP context
>      Bluetooth: Move SMP LTK notification after key distribution
>      Bluetooth: Add support for sending New IRK event
> 
> include/net/bluetooth/hci_core.h | 13 ++++++-----
> include/net/bluetooth/mgmt.h     |  7 ++++++
> net/bluetooth/hci_core.c         | 38 +++++++++++--------------------
> net/bluetooth/mgmt.c             | 30 ++++++++++++++++++++-----
> net/bluetooth/smp.c              | 45 +++++++++++++++++++++++++++++--------
> net/bluetooth/smp.h              |  3 +++
> 6 files changed, 91 insertions(+), 45 deletions(-)

all 6 patches have been applied to bluetooth-next tree.

Regards

Marcel


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

end of thread, other threads:[~2014-02-19 16:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-19 12:57 [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event johan.hedberg
2014-02-19 12:57 ` [PATCH 1/6] Bluetooth: Avoid using GFP_ATOMIC where not necessary johan.hedberg
2014-02-19 12:57 ` [PATCH 2/6] Bluetooth: Return added key when adding LTKs and IRKs johan.hedberg
2014-02-19 12:57 ` [PATCH 3/6] Bluetooth: Move New LTK store hint evaluation into mgmt_new_ltk johan.hedberg
2014-02-19 12:57 ` [PATCH 4/6] Bluetooth: Track SMP keys in the SMP context johan.hedberg
2014-02-19 12:57 ` [PATCH 5/6] Bluetooth: Move SMP LTK notification after key distribution johan.hedberg
2014-02-19 12:57 ` [PATCH 6/6] Bluetooth: Add support for sending New IRK event johan.hedberg
2014-02-19 13:18   ` [PATCH v2 " johan.hedberg
2014-02-19 16:03 ` [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event Marcel Holtmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).