* Re: [RFC v2 2/9] Bluetooth: Implement the first SMP commands
From: Vinicius Costa Gomes @ 2010-12-07 22:05 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth, Anderson Briglia
In-Reply-To: <20101207160307.GB2944@vigoh>
Hi Gustavo,
On 14:03 Tue 07 Dec, Gustavo F. Padovan wrote:
> Hi Vinicius,
>
> * Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2010-12-06 18:43:45 -0300]:
>
> > These simple commands will allow the SMP procedure to be started
> > and terminated with a not supported error. This is the first step
> > toward something useful.
> >
> > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> > ---
> > include/net/bluetooth/smp.h | 4 +
> > net/bluetooth/Makefile | 1 +
> > net/bluetooth/{l2cap.c => l2cap_core.c} | 0
>
> I want a separated patch for the l2cap.c rename.
>
Sure. Will do.
> > net/bluetooth/smp.c | 144 +++++++++++++++++++++++++++++++
> > 4 files changed, 149 insertions(+), 0 deletions(-)
> > rename net/bluetooth/{l2cap.c => l2cap_core.c} (100%)
> > create mode 100644 net/bluetooth/smp.c
> >
> > diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
> > index 8f2edbf..b9603cc 100644
> > --- a/include/net/bluetooth/smp.h
> > +++ b/include/net/bluetooth/smp.h
> > @@ -73,4 +73,8 @@ struct smp_cmd_security_req {
> > #define SMP_UNSPECIFIED 0x08
> > #define SMP_REPEATED_ATTEMPTS 0x09
> >
> > +/* SMP Commands */
> > +int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
> > +int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
> > +
> > #endif /* __SMP_H */
> > diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
> > index d1e433f..d138b23 100644
> > --- a/net/bluetooth/Makefile
> > +++ b/net/bluetooth/Makefile
> > @@ -11,3 +11,4 @@ obj-$(CONFIG_BT_CMTP) += cmtp/
> > obj-$(CONFIG_BT_HIDP) += hidp/
> >
> > bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o
> > +l2cap-objs := l2cap_core.o smp.o
> > diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap_core.c
> > similarity index 100%
> > rename from net/bluetooth/l2cap.c
> > rename to net/bluetooth/l2cap_core.c
> > diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> > new file mode 100644
> > index 0000000..e427d11
> > --- /dev/null
> > +++ b/net/bluetooth/smp.c
> > @@ -0,0 +1,144 @@
> > +/*
> > + BlueZ - Bluetooth protocol stack for Linux
> > + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
> > +
> > + This program is free software; you can redistribute it and/or modify
> > + it under the terms of the GNU General Public License version 2 as
> > + published by the Free Software Foundation;
> > +
> > + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> > + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
> > + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
> > + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
> > + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> > + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> > + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> > +
> > + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
> > + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
> > + SOFTWARE IS DISCLAIMED.
> > +*/
> > +
> > +#include <net/bluetooth/bluetooth.h>
> > +#include <net/bluetooth/hci_core.h>
> > +#include <net/bluetooth/l2cap.h>
> > +#include <net/bluetooth/smp.h>
> > +
> > +static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
> > + u16 dlen, void *data)
> > +{
> > + struct sk_buff *skb;
> > + struct l2cap_hdr *lh;
> > + int len;
> > +
> > + len = L2CAP_HDR_SIZE + 1 + dlen;
> > +
> > + if (len > conn->mtu)
> > + return NULL;
> > +
> > + skb = bt_skb_alloc(len, GFP_ATOMIC);
> > + if (!skb)
> > + return NULL;
> > +
> > + lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
> > + lh->len = cpu_to_le16(1 + dlen);
> > + lh->cid = cpu_to_le16(L2CAP_CID_SMP);
> > +
> > + memcpy(skb_put(skb, 1), &code, 1);
> > +
> > + memcpy(skb_put(skb, dlen), data, dlen);
> > +
> > + return skb;
> > +}
> > +
> > +static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
> > +{
> > + struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
> > +
> > + BT_DBG("code 0x%2.2x", code);
> > +
> > + if (!skb)
> > + return;
> > +
> > + hci_send_acl(conn->hcon, skb, 0);
> > +}
> > +
> > +int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
> > +{
> > + __u8 authreq;
> > +
> > + BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
> > +
> > + switch (sec_level) {
> > + case BT_SECURITY_MEDIUM:
> > + /* Encrypted, no MITM protection */
> > + authreq = 0x01;
> > + break;
> > +
> > + case BT_SECURITY_HIGH:
> > + /* Bonding, MITM protection */
> > + authreq = 0x05;
> > + break;
> > +
> > + case BT_SECURITY_LOW:
> > + default:
> > + return 1;
> > + }
> > +
> > + if (conn->hcon->link_mode & HCI_LM_MASTER) {
> > + struct smp_cmd_pairing cp;
> > + cp.io_capability = 0x00;
> > + cp.oob_flag = 0x00;
> > + cp.max_key_size = 16;
> > + cp.init_key_dist = 0x00;
> > + cp.resp_key_dist = 0x00;
> > + cp.auth_req = authreq;
> > + smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
> > + } else {
> > + struct smp_cmd_security_req cp;
> > + cp.auth_req = authreq;
> > + smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
> > +{
> > + __u8 code = skb->data[0];
> > + __u8 reason;
> > + int err = 0;
> > +
> > + skb_pull(skb, 1);
> > +
> > + switch (code) {
> > + case SMP_CMD_PAIRING_REQ:
> > + reason = SMP_PAIRING_NOTSUPP;
> > + smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, 1, &reason);
> > + err = -1;
>
> Don't use -1, use a proper error macro here.
Sure.
>
> > + break;
> > +
> > + case SMP_CMD_PAIRING_FAIL:
> > + break;
> > +
> > + case SMP_CMD_PAIRING_RSP:
> > + case SMP_CMD_PAIRING_CONFIRM:
> > + case SMP_CMD_PAIRING_RANDOM:
> > + case SMP_CMD_ENCRYPT_INFO:
> > + case SMP_CMD_MASTER_IDENT:
> > + case SMP_CMD_IDENT_INFO:
> > + case SMP_CMD_IDENT_ADDR_INFO:
> > + case SMP_CMD_SIGN_INFO:
> > + case SMP_CMD_SECURITY_REQ:
> > + default:
> > + BT_DBG("Unknown command code 0x%2.2x", code);
> > +
> > + reason = SMP_CMD_NOTSUPP;
> > + smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, 1, &reason);
> > + err = -1;
>
> Same here.
Ok.
>
> --
> Gustavo F. Padovan
> http://profusion.mobi
Cheers,
--
Vinicius
^ permalink raw reply
* Re: [PATCH v2 1/5] Add device type to identify LE, BR/EDR or dual mode devices
From: Johan Hedberg @ 2010-12-07 22:04 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1291757440-15217-1-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
On Tue, Dec 07, 2010, Claudio Takahasi wrote:
> If EIR Flags field is sent in the advertising data, it can be used
> to detect the operation mode. If the remote device is dual mode,
> GAP operation mode defines that it shall follow the connectable
> mode for BR/EDR and non-connectable mode for LE. This patch forces
> service discovery protocol prior to Discover All Primary Services.
> ---
> src/adapter.c | 55 +++++++++++++++++++++++++++++++++++++++----------------
> src/adapter.h | 3 ---
> src/device.c | 12 ++++++------
> src/device.h | 11 +++++++++--
> 4 files changed, 54 insertions(+), 27 deletions(-)
Thanks for these updates. I've now pushed all five patches (v2 of 1-3)
upstream.
Johan
^ permalink raw reply
* Re: [PATCH v2] Remove automatic battery state change on attribute example
From: Johan Hedberg @ 2010-12-07 21:53 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1291758098-31350-1-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
On Tue, Dec 07, 2010, Claudio Takahasi wrote:
> Legacy code implemented to test Indication and Notification
> ---
> attrib/example.c | 19 -------------------
> 1 files changed, 0 insertions(+), 19 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* [PATCH v2] Remove automatic battery state change on attribute example
From: Claudio Takahasi @ 2010-12-07 21:41 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <20101207213537.GA30415@jh-x301>
Legacy code implemented to test Indication and Notification
---
attrib/example.c | 19 -------------------
1 files changed, 0 insertions(+), 19 deletions(-)
diff --git a/attrib/example.c b/attrib/example.c
index 4307804..6987fac 100644
--- a/attrib/example.c
+++ b/attrib/example.c
@@ -59,22 +59,6 @@
#define FMT_KILOGRAM_UUID 0xA010
#define FMT_HANGING_UUID 0xA011
-static guint timeout_id = 0;
-
-static gboolean change_battery_state(gpointer user_data)
-{
- static uint8_t state = 0x05;
- uuid_t uuid;
- uint8_t atval[1];
-
- /* Battery state is being increased every 10 seconds. */
- atval[0] = state++;
- sdp_uuid16_create(&uuid, BATTERY_STATE_UUID);
- attrib_db_update(0x0110, &uuid, atval, 1);
-
- return TRUE;
-}
-
static int register_attributes(void)
{
const char *devname = "Example Device";
@@ -170,8 +154,6 @@ static int register_attributes(void)
atval[1] = 0x00;
attrib_db_add(0x0111, &uuid, ATT_NONE, ATT_AUTHENTICATION, atval, 2);
- timeout_id = g_timeout_add_seconds(10, change_battery_state, NULL);
-
/* Thermometer: primary service definition */
sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
u16 = htons(THERM_HUMIDITY_SVC_UUID);
@@ -436,5 +418,4 @@ int server_example_init(void)
void server_example_exit(void)
{
- g_source_remove(timeout_id);
}
--
1.7.3.2
^ permalink raw reply related
* Re: [PATCH] Remove automatic battery state change on attribute example
From: Johan Hedberg @ 2010-12-07 21:35 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1291386290-2521-1-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
On Fri, Dec 03, 2010, Claudio Takahasi wrote:
> Legacy code implemented to test Indication and Notification
> ---
> attrib/example.c | 19 -------------------
> 1 files changed, 0 insertions(+), 19 deletions(-)
Sorry, but you'll need to rebase this one since it doesn't apply anymore
cleanly (due to the "Initial attribute permission implementation"
patch).
Johan
^ permalink raw reply
* [PATCH v2 3/5] Make EIR type an optional argument for bt_extract_eir_name
From: Claudio Takahasi @ 2010-12-07 21:33 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1291386532-4985-3-git-send-email-claudio.takahasi@openbossa.org>
---
src/adapter.c | 3 +--
src/glib-helper.c | 5 +++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 102aad7..b581674 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3142,8 +3142,7 @@ void adapter_update_device_from_info(struct btd_adapter *adapter,
(GCompareFunc) dev_rssi_cmp);
if (info->length) {
- uint8_t type;
- char *tmp_name = bt_extract_eir_name(info->data, &type);
+ char *tmp_name = bt_extract_eir_name(info->data, NULL);
if (tmp_name) {
g_free(dev->name);
dev->name = tmp_name;
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 927fb7c..e71841b 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -744,9 +744,10 @@ char *bt_extract_eir_name(uint8_t *data, uint8_t *type)
if (data[0] == 0)
return NULL;
- *type = data[1];
+ if (type)
+ *type = data[1];
- switch (*type) {
+ switch (data[1]) {
case EIR_NAME_SHORT:
case EIR_NAME_COMPLETE:
if (!g_utf8_validate((char *) (data + 2), data[0] - 1, NULL))
--
1.7.3.2
^ permalink raw reply related
* [PATCH v2 2/5] Check if the remote LE is connectable when creating a device
From: Claudio Takahasi @ 2010-12-07 21:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1291386532-4985-2-git-send-email-claudio.takahasi@openbossa.org>
Before issue Discover All Primary Service the advertising event type
needs to be evaluated to avoid connection attempts to non-connectable
devices. For non-connectable devices, CreateDevice creates the device
instance however no Services/UUIDs will be exposed.
---
src/adapter.c | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index b3270ce..102aad7 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -56,6 +56,9 @@
#include "agent.h"
#include "storage.h"
+#define ADV_TYPE_IND 0x00
+#define ADV_TYPE_DIRECT_IND 0x01
+
#define IO_CAPABILITY_DISPLAYONLY 0x00
#define IO_CAPABILITY_DISPLAYYESNO 0x01
#define IO_CAPABILITY_KEYBOARDONLY 0x02
@@ -1706,6 +1709,17 @@ static device_type_t flags2type(uint8_t flags)
return DEVICE_TYPE_DUALMODE;
}
+static gboolean event_is_connectable(uint8_t type)
+{
+ switch (type) {
+ case ADV_TYPE_IND:
+ case ADV_TYPE_DIRECT_IND:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
static DBusMessage *create_device(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -1741,6 +1755,20 @@ static DBusMessage *create_device(DBusConnection *conn,
if (!device)
return NULL;
+ if (type == DEVICE_TYPE_LE && !event_is_connectable(dev->evt_type)) {
+ /* Device is not connectable */
+ const char *path = device_get_path(device);
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(msg);
+
+ dbus_message_append_args(reply,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ return reply;
+ }
+
err = device_browse(device, conn, msg, NULL, FALSE);
if (err < 0)
return failed_strerror(msg, -err);
--
1.7.3.2
^ permalink raw reply related
* [PATCH v2 1/5] Add device type to identify LE, BR/EDR or dual mode devices
From: Claudio Takahasi @ 2010-12-07 21:30 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <AANLkTinFBtVhu0j6xcHsH6XQZM8J-UeHSG2fOJJ-otcJ@mail.gmail.com>
If EIR Flags field is sent in the advertising data, it can be used
to detect the operation mode. If the remote device is dual mode,
GAP operation mode defines that it shall follow the connectable
mode for BR/EDR and non-connectable mode for LE. This patch forces
service discovery protocol prior to Discover All Primary Services.
---
src/adapter.c | 55 +++++++++++++++++++++++++++++++++++++++----------------
src/adapter.h | 3 ---
src/device.c | 12 ++++++------
src/device.h | 11 +++++++++--
4 files changed, 54 insertions(+), 27 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 62afc0c..b3270ce 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1196,16 +1196,17 @@ sdp_list_t *adapter_get_services(struct btd_adapter *adapter)
return adapter->services;
}
-struct btd_device *adapter_create_device(DBusConnection *conn,
- struct btd_adapter *adapter,
- const char *address, gboolean le)
+static struct btd_device *adapter_create_device(DBusConnection *conn,
+ struct btd_adapter *adapter,
+ const char *address,
+ device_type_t type)
{
struct btd_device *device;
const char *path;
DBG("%s", address);
- device = device_create(conn, adapter, address, le);
+ device = device_create(conn, adapter, address, type);
if (!device)
return NULL;
@@ -1264,7 +1265,8 @@ struct btd_device *adapter_get_device(DBusConnection *conn,
if (device)
return device;
- return adapter_create_device(conn, adapter, address, FALSE);
+ return adapter_create_device(conn, adapter, address,
+ DEVICE_TYPE_BREDR);
}
static gboolean stop_scanning(gpointer user_data)
@@ -1686,6 +1688,24 @@ static DBusMessage *cancel_device_creation(DBusConnection *conn,
return dbus_message_new_method_return(msg);
}
+static device_type_t flags2type(uint8_t flags)
+{
+ /* Inferring the remote type based on the EIR Flags field */
+
+ /* For LE only and dual mode the following flags must be zero */
+ if (flags & (EIR_SIM_CONTROLLER | EIR_SIM_HOST))
+ return DEVICE_TYPE_UNKNOWN;
+
+ /* Limited or General discoverable mode bit must be enabled */
+ if (!(flags & (EIR_LIM_DISC | EIR_GEN_DISC)))
+ return DEVICE_TYPE_UNKNOWN;
+
+ if (flags & EIR_BREDR_UNSUP)
+ return DEVICE_TYPE_LE;
+ else
+ return DEVICE_TYPE_DUALMODE;
+}
+
static DBusMessage *create_device(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -1693,8 +1713,8 @@ static DBusMessage *create_device(DBusConnection *conn,
struct btd_device *device;
struct remote_dev_info *dev, match;
const gchar *address;
- gboolean le;
int err;
+ device_type_t type;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
DBUS_TYPE_INVALID) == FALSE)
@@ -1715,9 +1735,9 @@ static DBusMessage *create_device(DBusConnection *conn,
match.name_status = NAME_ANY;
dev = adapter_search_found_devices(adapter, &match);
- le = dev ? dev->le : FALSE;
+ type = dev && dev->flags ? flags2type(dev->flags) : DEVICE_TYPE_BREDR;
- device = adapter_create_device(conn, adapter, address, le);
+ device = adapter_create_device(conn, adapter, address, type);
if (!device)
return NULL;
@@ -2013,7 +2033,7 @@ static void create_stored_device_from_profiles(char *key, char *value,
key, (GCompareFunc) device_address_cmp))
return;
- device = device_create(connection, adapter, key, FALSE);
+ device = device_create(connection, adapter, key, DEVICE_TYPE_BREDR);
if (!device)
return;
@@ -2036,7 +2056,7 @@ static void create_stored_device_from_linkkeys(char *key, char *value,
(GCompareFunc) device_address_cmp))
return;
- device = device_create(connection, adapter, key, FALSE);
+ device = device_create(connection, adapter, key, DEVICE_TYPE_BREDR);
if (device) {
device_set_temporary(device, FALSE);
adapter->devices = g_slist_append(adapter->devices, device);
@@ -2053,7 +2073,7 @@ static void create_stored_device_from_blocked(char *key, char *value,
key, (GCompareFunc) device_address_cmp))
return;
- device = device_create(connection, adapter, key, FALSE);
+ device = device_create(connection, adapter, key, DEVICE_TYPE_BREDR);
if (device) {
device_set_temporary(device, FALSE);
adapter->devices = g_slist_append(adapter->devices, device);
@@ -3054,16 +3074,19 @@ static struct remote_dev_info *get_found_dev(struct btd_adapter *adapter,
return dev;
}
-static uint8_t extract_eir_flags(uint8_t *eir_data)
+static gboolean extract_eir_flags(uint8_t *flags, uint8_t *eir_data)
{
if (eir_data[0] == 0)
- return 0;
+ return FALSE;
if (eir_data[1] != EIR_FLAGS)
- return 0;
+ return FALSE;
/* For now, only one octet is used for flags */
- return eir_data[2];
+ if (flags)
+ *flags = eir_data[2];
+
+ return TRUE;
}
void adapter_update_device_from_info(struct btd_adapter *adapter,
@@ -3098,7 +3121,7 @@ void adapter_update_device_from_info(struct btd_adapter *adapter,
dev->name = tmp_name;
}
- dev->flags = extract_eir_flags(info->data);
+ extract_eir_flags(info->data, &dev->flags);
}
/* FIXME: check if other information was changed before emitting the
diff --git a/src/adapter.h b/src/adapter.h
index b189b27..3a2cf9c 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -108,9 +108,6 @@ struct btd_device *adapter_find_connection(struct btd_adapter *adapter, uint16_t
void adapter_remove_device(DBusConnection *conn, struct btd_adapter *adapter,
struct btd_device *device,
gboolean remove_storage);
-struct btd_device *adapter_create_device(DBusConnection *conn,
- struct btd_adapter *adapter,
- const char *address, gboolean le);
int adapter_resolve_names(struct btd_adapter *adapter);
diff --git a/src/device.c b/src/device.c
index 5326e3f..50fb83c 100644
--- a/src/device.c
+++ b/src/device.c
@@ -107,7 +107,7 @@ struct browse_req {
struct btd_device {
bdaddr_t bdaddr;
- gboolean le;
+ device_type_t type;
gchar *path;
char name[MAX_NAME_LENGTH + 1];
char *alias;
@@ -212,7 +212,7 @@ static void browse_request_cancel(struct browse_req *req)
adapter_get_address(adapter, &src);
- if (device->le == FALSE)
+ if (device->type != DEVICE_TYPE_LE)
bt_cancel_discovery(&src, &device->bdaddr);
device->browse = NULL;
@@ -964,8 +964,8 @@ void device_set_secmode3_conn(struct btd_device *device, gboolean enable)
}
struct btd_device *device_create(DBusConnection *conn,
- struct btd_adapter *adapter,
- const gchar *address, gboolean le)
+ struct btd_adapter *adapter,
+ const gchar *address, device_type_t type)
{
gchar *address_up;
struct btd_device *device;
@@ -993,7 +993,7 @@ struct btd_device *device_create(DBusConnection *conn,
str2ba(address, &device->bdaddr);
device->adapter = adapter;
- device->le = le;
+ device->type = type;
adapter_get_address(adapter, &src);
ba2str(&src, srcaddr);
read_device_name(srcaddr, address, device->name);
@@ -1656,7 +1656,7 @@ int device_browse(struct btd_device *device, DBusConnection *conn,
if (device->browse)
return -EBUSY;
- if (device->le)
+ if (device->type == DEVICE_TYPE_LE)
req = browse_primary(device, &err);
else
req = browse_sdp(device, search, reverse, &err);
diff --git a/src/device.h b/src/device.h
index a5b6273..784e931 100644
--- a/src/device.h
+++ b/src/device.h
@@ -34,9 +34,16 @@ typedef enum {
AUTH_TYPE_AUTO,
} auth_type_t;
+typedef enum {
+ DEVICE_TYPE_UNKNOWN,
+ DEVICE_TYPE_BREDR,
+ DEVICE_TYPE_LE,
+ DEVICE_TYPE_DUALMODE
+} device_type_t;
+
struct btd_device *device_create(DBusConnection *conn,
- struct btd_adapter *adapter,
- const gchar *address, gboolean le);
+ struct btd_adapter *adapter,
+ const gchar *address, device_type_t type);
void device_set_name(struct btd_device *device, const char *name);
void device_get_name(struct btd_device *device, char *name, size_t len);
void device_remove(struct btd_device *device, gboolean remove_stored);
--
1.7.3.2
^ permalink raw reply related
* Re: [PATCH 1/3] Fix possible crash when processing session callback
From: Johan Hedberg @ 2010-12-07 21:17 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1291734061-24408-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Tue, Dec 07, 2010, Luiz Augusto von Dentz wrote:
> If the callback removes the pending data it cause this:
>
> ==20639== Invalid read of size 4
> ==20639== at 0x80553E9: free_pending (session.c:112)
> ==20639== by 0x8056C83: session_request_reply (session.c:837)
> ==20639== by 0x412F7E0: ??? (in /lib/libdbus-1.so.3.5.2)
> ==20639== by 0x411D975: ??? (in /lib/libdbus-1.so.3.5.2)
> ==20639== by 0x4120B81: dbus_connection_dispatch (in /lib/libdbus-1.so.3.5.2)
> ==20639== by 0x804C27F: message_dispatch (mainloop.c:80)
> ==20639== by 0x407EFCB: ??? (in /lib/libglib-2.0.so.0.2600.1)
> ==20639== by 0x407E854: g_main_context_dispatch (in /lib/libglib-2.0.so.0.2600.1)
> ==20639== by 0x4082667: ??? (in /lib/libglib-2.0.so.0.2600.1)
> ==20639== by 0x4082BA6: g_main_loop_run (in /lib/libglib-2.0.so.0.2600.1)
> ==20639== by 0x8055171: main (main.c:625)
> ==20639== Address 0x4363c88 is 0 bytes inside a block of size 12 free'd
> ==20639== at 0x40257ED: free (vg_replace_malloc.c:366)
> ==20639== by 0x4087485: g_free (in /lib/libglib-2.0.so.0.2600.1)
> ==20639== by 0x80553FE: free_pending (session.c:115)
> ==20639== by 0x805543C: agent_free (session.c:127)
> ==20639== by 0x80566A6: session_free (session.c:149)
> ==20639== by 0x8056BCA: session_terminate_transfer (session.c:914)
> ==20639== by 0x8056F61: session_prepare_put (session.c:1397)
> ==20639== by 0x8056C74: session_request_reply (session.c:835)
> ==20639== by 0x412F7E0: ??? (in /lib/libdbus-1.so.3.5.2)
> ==20639== by 0x411D975: ??? (in /lib/libdbus-1.so.3.5.2)
> ==20639== by 0x4120B81: dbus_connection_dispatch (in /lib/libdbus-1.so.3.5.2)
> ==20639== by 0x804C27F: message_dispatch (mainloop.c:80)
>
> To fix this agent->pending is now reset to NULL before calling the
> callback, so even if the session is terminated it won't cause a free to
> pending data, which is fine since it is latter freed on callback return.
> ---
> client/session.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
Patches 1 and 2 have been pushed. For the third one (as we discussed
offline) I'm still waiting for an update to fix the format string
specifier for off_t.
Johan
^ permalink raw reply
* Re: [PATCH 1/9] Create btd_error_invalid_args()
From: Johan Hedberg @ 2010-12-07 21:16 UTC (permalink / raw)
To: Gustavo F. Padovan, linux-bluetooth
In-Reply-To: <20101207210511.GB25558@jh-x301>
Hi,
On Tue, Dec 07, 2010, Johan Hedberg wrote:
> This as well as the second patch (ERROR_NOT_SUPPORTED) have been pushed
> upstream.
Actually I messed up with which patch is which and also pushed the one I
didn't really like (the NOT_SUPPORTED one). So all nine patches are now
upstream. However, as I pointed out in the other mail, please consider
the drawback of making completely generic functions for all errors. In
some cases it might make sense to att least be able to provide a context
specific custom message (and I'd be glad to accept patches that do
that).
Johan
^ permalink raw reply
* Re: [PATCH 1/9] Create btd_error_invalid_args()
From: Johan Hedberg @ 2010-12-07 21:05 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1291662648-10651-1-git-send-email-padovan@profusion.mobi>
Hi Gustavo,
On Mon, Dec 06, 2010, Gustavo F. Padovan wrote:
> DBus error handling in BlueZ is a mess. This is the first patch to unify
> all DBus error handling like in ConnMan and oFono. This unifies all
> .InvalidArguments errors.
> ---
> attrib/client.c | 20 ++++++-----------
> audio/gateway.c | 8 +-----
> audio/headset.c | 18 +++++----------
> audio/media.c | 9 ++-----
> audio/telephony-dummy.c | 25 ++++++++------------
> audio/telephony-maemo5.c | 11 ++------
> audio/telephony-maemo6.c | 11 ++------
> audio/transport.c | 14 +++--------
> health/hdp.c | 54 ++++++++++++----------------------------------
> network/server.c | 7 ------
> plugins/service.c | 8 +------
> serial/port.c | 8 ------
> serial/proxy.c | 19 +++++-----------
> src/adapter.c | 52 +++++++++++++++++++------------------------
> src/device.c | 22 ++++++------------
> src/error.c | 7 ++++++
> src/error.h | 2 +
> src/manager.c | 7 ------
> 18 files changed, 99 insertions(+), 203 deletions(-)
This as well as the second patch (ERROR_NOT_SUPPORTED) have been pushed
upstream.
Johan
^ permalink raw reply
* Re: [PATCH 3/9] Add btd_error_not_supported()
From: Johan Hedberg @ 2010-12-07 21:03 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1291662648-10651-3-git-send-email-padovan@profusion.mobi>
Hi Gustavo,
On Mon, Dec 06, 2010, Gustavo F. Padovan wrote:
> - return g_dbus_create_error(msg,
> - ERROR_INTERFACE ".NotSupported",
> - "Kernel lacks blacklist support");
> + return btd_error_not_supported(msg);
I'm not sure I agree with this. The specific error message would give
hints to the user that he might need to update his kernel but the
generic one doesn't give any such hints. Couldn't you have the
btd_error_not_supported function take one extra cont char *msg
parameter? I had a little bit similar feelings about the ALREADY_EXISTS
patch (which I already pushed) but here the issue of loosing the
specifics of the error is more obvious.
Johan
^ permalink raw reply
* Re: [PATCH] Fix writing to GAttrib socket without POLLOUT event
From: Johan Hedberg @ 2010-12-07 20:58 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1291400928-12114-1-git-send-email-vinicius.gomes@openbossa.org>
Hi Vinicius,
On Fri, Dec 03, 2010, Vinicius Costa Gomes wrote:
> If the GIOChannel is in the buffered state (the default) the watch
> function is called without receiving a POLLOUT from the socket. GLib
> adds a G_IO_OUT condition just because there is space in the GIOChannel
> internal buffer.
>
> The solution is disabling the internal buffer, which in turn, makes the
> call of g_io_channel_flush() useless.
> ---
> attrib/gattrib.c | 3 +--
> 1 files changed, 1 insertions(+), 2 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH v2 0/3] Basic attribute permission support
From: Johan Hedberg @ 2010-12-07 20:57 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1291400782-24736-1-git-send-email-anderson.lizardo@openbossa.org>
Hi Lizardo,
On Fri, Dec 03, 2010, Anderson Lizardo wrote:
> Changes since V1:
>
> * Simplified permission scheme according to discussion on IRC.
> * Fixed incorrect error sent by server.
>
> This patchset adds initial support for attribute permission checks. Currently,
> only access and authentication permissions are checked. Authorization
> permissions require integration with the BlueZ agent, which is not implemented
> yet.
>
> There are some pending issues necessary for a minimum complete attribute
> permission support (all of them are being worked on):
>
> * The attribute client, upon receiving the "Insufficient Encryption" error,
> shall increase the security level and resend the failed request.
> * The attribute server shall verify the connection permissions on each ATT
> request, and not just once on connection callback.
> * On kernel side, increasing the security level (using setsockopt()) shall
> trigger SMP negotiation for a LE connection, blocking next socket I/O until
> negotiation is finished.
> * On BR/EDR, link encryption is mandatory for GATT (see Vol 3, Part G, 2.4
> "Profile Fundamentals").
>
> Albeit the above issues, we believe these patches are ready for commit.
All three patches have been pushed upstream. Thanks.
Johan
^ permalink raw reply
* RE: [RFC v2 5/9] Bluetooth: Add support for using the crypto subsystem
From: Brian Gix @ 2010-12-07 19:34 UTC (permalink / raw)
To: 'Vinicius Costa Gomes'; +Cc: linux-bluetooth
In-Reply-To: <20101207192317.GC4797@eris>
Hi Vinicius,
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-
> owner@vger.kernel.org] On Behalf Of Vinicius Costa Gomes
> Sent: 07 December, 2010 11:23 AM
> To: Brian Gix
> Cc: linux-bluetooth@vger.kernel.org
> Subject: Re: [RFC v2 5/9] Bluetooth: Add support for using the crypto
> subsystem
>
> Hi Brian,
>
> On 10:35 Tue 07 Dec, Brian Gix wrote:
> >
> > Hi Vinicius,
> >
> > > -----Original Message-----
> > > From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-
> bluetooth-
> > > owner@vger.kernel.org] On Behalf Of Vinicius Costa Gomes
> > > Sent: 06 December, 2010 1:44 PM
> > > To: linux-bluetooth@vger.kernel.org
> > > Cc: Vinicius Costa Gomes
> > > Subject: [RFC v2 5/9] Bluetooth: Add support for using the crypto
> > > subsystem
> > >
> > > This will allow using the crypto subsystem for encrypting data. As
> SMP
> > > (Security Manager Protocol) is implemented almost entirely on the
> host
> > > side and the crypto module already implements the needed methods
> > > (AES-128), it makes sense to use it.
> >
> > I do understand the desire to reuse the crypto module, but I would
> like
> > to point out that every baseband that supports any level of LE-SM, is
> > required to have implemented the HCI commands for LE-SM centric
> encryption
> > and random number generation.
>
> Yes, we are aware of that.
>
> >
> > Also, since these are processor intensive calculations, which must
> take
> > place in real-time on the baseband for encrypted links, I would argue
> > that it makes more sense to use the likely optimized functionality
> > present in the basebands.
>
> I am sure that the baseband is optimized for those operations, but one
> thing that needs to be considered is the time that the information
> takes to get
> to and from the baseband. For example, in the case of a USB controller,
> we need
> to build an HCI command, insert the command in the queue, and wait for
> it to be
> delivered (and received) via the USB bus to the baseband. Using the
> crypto
> subsystem we may even be able to use functionality built inside the
> processor.
>
> >
> > That is not to say that it cannot be done on the host, just that it
> > is likely less efficient, for no gain in portability or
> functionality.
>
> There is a gain in simplicity ;-)
Well that's fine. Again, I have no objection.
>
> >
> >
> > > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > > ---
> > > include/net/bluetooth/hci_core.h | 2 ++
> > > net/bluetooth/hci_core.c | 10 ++++++++++
> > > 2 files changed, 12 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/include/net/bluetooth/hci_core.h
> > > b/include/net/bluetooth/hci_core.h
> > > index 0687e2f..d0a9f5d 100644
> > > --- a/include/net/bluetooth/hci_core.h
> > > +++ b/include/net/bluetooth/hci_core.h
> > > @@ -135,6 +135,8 @@ struct hci_dev {
> > > __u32 req_status;
> > > __u32 req_result;
> > >
> > > + struct crypto_blkcipher *tfm;
> > > +
> > > struct inquiry_cache inq_cache;
> > > struct hci_conn_hash conn_hash;
> > > struct list_head blacklist;
> > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > > index 12c6735..b96c3dd 100644
> > > --- a/net/bluetooth/hci_core.c
> > > +++ b/net/bluetooth/hci_core.c
> > > @@ -41,6 +41,7 @@
> > > #include <linux/interrupt.h>
> > > #include <linux/notifier.h>
> > > #include <linux/rfkill.h>
> > > +#include <linux/crypto.h>
> > > #include <net/sock.h>
> > >
> > > #include <asm/system.h>
> > > @@ -961,6 +962,13 @@ int hci_register_dev(struct hci_dev *hdev)
> > > if (!hdev->workqueue)
> > > goto nomem;
> > >
> > > + hdev->tfm = crypto_alloc_blkcipher("ecb(aes)", 0,
> > > CRYPTO_ALG_ASYNC);
> > > + if (IS_ERR(hdev->tfm)) {
> > > + BT_ERR("Failed to load transform for ecb(aes): %ld",
> > > + PTR_ERR(hdev->tfm));
> > > + goto nomem;
> > > + }
> > > +
> > > hci_register_sysfs(hdev);
> > >
> > > hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
> > > @@ -1001,6 +1009,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
> > > for (i = 0; i < NUM_REASSEMBLY; i++)
> > > kfree_skb(hdev->reassembly[i]);
> > >
> > > + crypto_free_blkcipher(hdev->tfm);
> > > +
> > > hci_notify(hdev, HCI_DEV_UNREG);
> > >
> > > if (hdev->rfkill) {
> > > --
> > > 1.7.3.2
> > >
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe linux-
> > > bluetooth" in
> > > the body of a message to majordomo@vger.kernel.org
> > > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
>
> Cheers,
> --
> Vinicius
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC v2 5/9] Bluetooth: Add support for using the crypto subsystem
From: Vinicius Costa Gomes @ 2010-12-07 19:23 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth
In-Reply-To: <003101cb963d$8dcd6210$a9682630$@org>
Hi Brian,
On 10:35 Tue 07 Dec, Brian Gix wrote:
>
> Hi Vinicius,
>
> > -----Original Message-----
> > From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-
> > owner@vger.kernel.org] On Behalf Of Vinicius Costa Gomes
> > Sent: 06 December, 2010 1:44 PM
> > To: linux-bluetooth@vger.kernel.org
> > Cc: Vinicius Costa Gomes
> > Subject: [RFC v2 5/9] Bluetooth: Add support for using the crypto
> > subsystem
> >
> > This will allow using the crypto subsystem for encrypting data. As SMP
> > (Security Manager Protocol) is implemented almost entirely on the host
> > side and the crypto module already implements the needed methods
> > (AES-128), it makes sense to use it.
>
> I do understand the desire to reuse the crypto module, but I would like
> to point out that every baseband that supports any level of LE-SM, is
> required to have implemented the HCI commands for LE-SM centric encryption
> and random number generation.
Yes, we are aware of that.
>
> Also, since these are processor intensive calculations, which must take
> place in real-time on the baseband for encrypted links, I would argue
> that it makes more sense to use the likely optimized functionality
> present in the basebands.
I am sure that the baseband is optimized for those operations, but one
thing that needs to be considered is the time that the information takes to get
to and from the baseband. For example, in the case of a USB controller, we need
to build an HCI command, insert the command in the queue, and wait for it to be
delivered (and received) via the USB bus to the baseband. Using the crypto
subsystem we may even be able to use functionality built inside the processor.
>
> That is not to say that it cannot be done on the host, just that it
> is likely less efficient, for no gain in portability or functionality.
There is a gain in simplicity ;-)
>
>
> > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > ---
> > include/net/bluetooth/hci_core.h | 2 ++
> > net/bluetooth/hci_core.c | 10 ++++++++++
> > 2 files changed, 12 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/net/bluetooth/hci_core.h
> > b/include/net/bluetooth/hci_core.h
> > index 0687e2f..d0a9f5d 100644
> > --- a/include/net/bluetooth/hci_core.h
> > +++ b/include/net/bluetooth/hci_core.h
> > @@ -135,6 +135,8 @@ struct hci_dev {
> > __u32 req_status;
> > __u32 req_result;
> >
> > + struct crypto_blkcipher *tfm;
> > +
> > struct inquiry_cache inq_cache;
> > struct hci_conn_hash conn_hash;
> > struct list_head blacklist;
> > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > index 12c6735..b96c3dd 100644
> > --- a/net/bluetooth/hci_core.c
> > +++ b/net/bluetooth/hci_core.c
> > @@ -41,6 +41,7 @@
> > #include <linux/interrupt.h>
> > #include <linux/notifier.h>
> > #include <linux/rfkill.h>
> > +#include <linux/crypto.h>
> > #include <net/sock.h>
> >
> > #include <asm/system.h>
> > @@ -961,6 +962,13 @@ int hci_register_dev(struct hci_dev *hdev)
> > if (!hdev->workqueue)
> > goto nomem;
> >
> > + hdev->tfm = crypto_alloc_blkcipher("ecb(aes)", 0,
> > CRYPTO_ALG_ASYNC);
> > + if (IS_ERR(hdev->tfm)) {
> > + BT_ERR("Failed to load transform for ecb(aes): %ld",
> > + PTR_ERR(hdev->tfm));
> > + goto nomem;
> > + }
> > +
> > hci_register_sysfs(hdev);
> >
> > hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
> > @@ -1001,6 +1009,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
> > for (i = 0; i < NUM_REASSEMBLY; i++)
> > kfree_skb(hdev->reassembly[i]);
> >
> > + crypto_free_blkcipher(hdev->tfm);
> > +
> > hci_notify(hdev, HCI_DEV_UNREG);
> >
> > if (hdev->rfkill) {
> > --
> > 1.7.3.2
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-
> > bluetooth" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Cheers,
--
Vinicius
^ permalink raw reply
* RE: [RFC v2 5/9] Bluetooth: Add support for using the crypto subsystem
From: Brian Gix @ 2010-12-07 19:21 UTC (permalink / raw)
To: 'Anderson Lizardo'
Cc: 'Vinicius Costa Gomes', linux-bluetooth
In-Reply-To: <AANLkTin5TYwx8fU6B3B0hSofqNBj6R8ZgOELf4DcJ_cm@mail.gmail.com>
Hi,
> -----Original Message-----
> From: Anderson Lizardo [mailto:anderson.lizardo@openbossa.org]
> Sent: 07 December, 2010 11:07 AM
> To: Brian Gix
> Cc: Vinicius Costa Gomes; linux-bluetooth@vger.kernel.org
> Subject: Re: [RFC v2 5/9] Bluetooth: Add support for using the crypto
> subsystem
>
> Hi,
>
> On Tue, Dec 7, 2010 at 2:35 PM, Brian Gix <bgix@codeaurora.org> wrote:
> >> This will allow using the crypto subsystem for encrypting data. As
> SMP
> >> (Security Manager Protocol) is implemented almost entirely on the
> host
> >> side and the crypto module already implements the needed methods
> >> (AES-128), it makes sense to use it.
> >
> > I do understand the desire to reuse the crypto module, but I would
> like
> > to point out that every baseband that supports any level of LE-SM, is
> > required to have implemented the HCI commands for LE-SM centric
> encryption
> > and random number generation.
>
> Correct.
>
> > Also, since these are processor intensive calculations, which must
> take
> > place in real-time on the baseband for encrypted links, I would argue
> > that it makes more sense to use the likely optimized functionality
> > present in the basebands.
>
> Note that only the LTK negotiation is done on the host/kernel. The
> payload PDU encryption itself still happens on the controller.
>
> Is it expected that LTK generation happens so often? If so, I suspect
> the request/response "overhead" would be bigger than the AES
> implemented in kernel.
>
> Also note that the Linux kernel API uses HW engine where
> available/supported, and at least for x86 it has many optimizations.
>
> Dunno which has better performance in the end though (we haven't
> measured it).
>
> > That is not to say that it cannot be done on the host, just that it
> > is likely less efficient, for no gain in portability or
> functionality.
>
> For LTK calculation I *think* Linux kernel crypto API is fast enough
> (the payloads are small, 16 bytes). Using the "built-in" AES engine on
> LE controllers would be actually a lot more efficient for low-end
> hosts though...
Yeah, but if using crypto.c is what everyone wants, I have no hard
objections,
I guess. I do also see that Gustavo also notes a CRYPTO_BLKCIPHER dependence
that wasn't there before, suggesting that this will require pulling in code
that may not otherwise be needed. The HCI commands to do that work are
pretty straight forward.
>
> My two cents,
> --
> Anderson Lizardo
> OpenBossa Labs - INdT
> Manaus - Brazil
^ permalink raw reply
* Re: [RFC v2 5/9] Bluetooth: Add support for using the crypto subsystem
From: Anderson Lizardo @ 2010-12-07 19:06 UTC (permalink / raw)
To: Brian Gix; +Cc: Vinicius Costa Gomes, linux-bluetooth
In-Reply-To: <003101cb963d$8dcd6210$a9682630$@org>
Hi,
On Tue, Dec 7, 2010 at 2:35 PM, Brian Gix <bgix@codeaurora.org> wrote:
>> This will allow using the crypto subsystem for encrypting data. As SMP
>> (Security Manager Protocol) is implemented almost entirely on the host
>> side and the crypto module already implements the needed methods
>> (AES-128), it makes sense to use it.
>
> I do understand the desire to reuse the crypto module, but I would like
> to point out that every baseband that supports any level of LE-SM, is
> required to have implemented the HCI commands for LE-SM centric encryption
> and random number generation.
Correct.
> Also, since these are processor intensive calculations, which must take
> place in real-time on the baseband for encrypted links, I would argue
> that it makes more sense to use the likely optimized functionality
> present in the basebands.
Note that only the LTK negotiation is done on the host/kernel. The
payload PDU encryption itself still happens on the controller.
Is it expected that LTK generation happens so often? If so, I suspect
the request/response "overhead" would be bigger than the AES
implemented in kernel.
Also note that the Linux kernel API uses HW engine where
available/supported, and at least for x86 it has many optimizations.
Dunno which has better performance in the end though (we haven't measured it).
> That is not to say that it cannot be done on the host, just that it
> is likely less efficient, for no gain in portability or functionality.
For LTK calculation I *think* Linux kernel crypto API is fast enough
(the payloads are small, 16 bytes). Using the "built-in" AES engine on
LE controllers would be actually a lot more efficient for low-end
hosts though...
My two cents,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* RE: [RFC v2 8/9] Bluetooth: Add support for LE Start Encryption
From: Brian Gix @ 2010-12-07 18:58 UTC (permalink / raw)
To: 'Vinicius Costa Gomes', linux-bluetooth
In-Reply-To: <1291671832-13435-9-git-send-email-vinicius.gomes@openbossa.org>
Hi Vinicius,
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-
> owner@vger.kernel.org] On Behalf Of Vinicius Costa Gomes
> Sent: 06 December, 2010 1:44 PM
> To: linux-bluetooth@vger.kernel.org
> Cc: Vinicius Costa Gomes
> Subject: [RFC v2 8/9] Bluetooth: Add support for LE Start Encryption
>
> This adds support for starting SMP Phase 2 Encryption, when the initial
> SMP negotiation is successful. This adds the LE Start Encryption and LE
> Long Term Key Request commands and related events.
>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
> include/net/bluetooth/hci.h | 34 +++++++++++++++++++
> include/net/bluetooth/hci_core.h | 5 +++
> net/bluetooth/hci_conn.c | 47 ++++++++++++++++++++++++++
> net/bluetooth/hci_event.c | 67
> ++++++++++++++++++++++++++++++++++++++
> net/bluetooth/smp.c | 8 ++++-
> 5 files changed, 160 insertions(+), 1 deletions(-)
>
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index dff6ded..e6bed3f 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -626,6 +626,33 @@ struct hci_cp_le_create_conn {
>
> #define HCI_OP_LE_CREATE_CONN_CANCEL 0x200e
>
> +#define HCI_OP_LE_START_ENC 0x2019
> +struct hci_cp_le_start_enc {
> + __le16 handle;
> + __u8 rand[8];
> + __le16 ediv;
> + __u8 ltk[16];
> +} __packed;
> +
> +#define HCI_OP_LE_LTK_REPLY 0x201a
> +struct hci_cp_le_ltk_reply {
> + __le16 handle;
> + __u8 ltk[16];
> +} __packed;
> +struct hci_rp_le_ltk_reply {
> + __u8 status;
> + __le16 handle;
> +} __packed;
> +
> +#define HCI_OP_LE_LTK_NEG_REPLY 0x201b
> +struct hci_cp_le_ltk_neg_reply {
> + __le16 handle;
> +} __packed;
> +struct hci_rp_le_ltk_neg_reply {
> + __u8 status;
> + __le16 handle;
> +} __packed;
> +
> /* ---- HCI Events ---- */
> #define HCI_EV_INQUIRY_COMPLETE 0x01
>
> @@ -897,6 +924,13 @@ struct hci_ev_le_conn_complete {
> __u8 clk_accurancy;
> } __packed;
>
> +#define HCI_EV_LE_LTK_REQ 0x05
> +struct hci_ev_le_ltk_req {
> + __le16 handle;
> + __u8 random[8];
> + __le16 ediv;
> +} __packed;
> +
> /* Internal events generated by Bluetooth stack */
> #define HCI_EV_STACK_INTERNAL 0xfd
> struct hci_ev_stack_internal {
> diff --git a/include/net/bluetooth/hci_core.h
> b/include/net/bluetooth/hci_core.h
> index d0a9f5d..c6c44eb 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -192,6 +192,7 @@ struct hci_conn {
> __u8 sec_level;
> __u8 power_save;
> __u16 disc_timeout;
> + __u8 ltk[16];
> unsigned long pend;
>
> unsigned int sent;
> @@ -713,4 +714,8 @@ struct hci_sec_filter {
>
> void hci_req_complete(struct hci_dev *hdev, int result);
>
> +void hci_le_start_enc(struct hci_conn *conn, u8 ltk[16]);
> +void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]);
> +void hci_le_ltk_neg_reply(struct hci_conn *conn);
> +
> #endif /* __HCI_CORE_H */
> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> index edfb48b..f919ddb 100644
> --- a/net/bluetooth/hci_conn.c
> +++ b/net/bluetooth/hci_conn.c
> @@ -183,6 +183,53 @@ void hci_setup_sync(struct hci_conn *conn, __u16
> handle)
> hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
> }
>
> +void hci_le_start_enc(struct hci_conn *conn, u8 ltk[16])
> +{
> + struct hci_dev *hdev = conn->hdev;
> + struct hci_cp_le_start_enc cp;
> +
> + BT_DBG("%p", conn);
> +
> + memset(&cp, 0, sizeof(cp));
> +
> + cp.handle = cpu_to_le16(conn->handle);
> + memcpy(cp.ltk, ltk, 16);
> +
> + hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
> +}
> +EXPORT_SYMBOL(hci_le_start_enc);
This appears only useful for link encryption with the STK, as both the ediv
random values are Zero. If this is how it was intended, the OK, however
it may be more appropriate in smp.c
> +
> +void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16])
> +{
> + struct hci_dev *hdev = conn->hdev;
> + struct hci_cp_le_ltk_reply cp;
> +
> + BT_DBG("%p", conn);
> +
> + memset(&cp, 0, sizeof(cp));
> +
> + cp.handle = cpu_to_le16(conn->handle);
> + memcpy(&cp.ltk, ltk, sizeof(ltk));
> +
> + hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
> +}
> +EXPORT_SYMBOL(hci_le_ltk_reply);
> +
> +void hci_le_ltk_neg_reply(struct hci_conn *conn)
> +{
> + struct hci_dev *hdev = conn->hdev;
> + struct hci_cp_le_ltk_neg_reply cp;
> +
> + BT_DBG("%p", conn);
> +
> + memset(&cp, 0, sizeof(cp));
> +
> + cp.handle = cpu_to_le16(conn->handle);
> +
> + hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(cp), &cp);
> +}
> +EXPORT_SYMBOL(hci_le_ltk_neg_reply);
> +
> /* Device _must_ be locked */
> void hci_sco_setup(struct hci_conn *conn, __u8 status)
> {
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 55cdd6a..c90696f 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -559,6 +559,30 @@ static void hci_cc_le_read_buffer_size(struct
> hci_dev *hdev,
> hci_req_complete(hdev, rp->status);
> }
>
> +static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff
> *skb)
> +{
> + struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
> +
> + BT_DBG("%s status 0x%x", hdev->name, rp->status);
> +
> + if (rp->status)
> + return;
> +
> + hci_req_complete(hdev, rp->status);
> +}
> +
> +static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct
> sk_buff *skb)
> +{
> + struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
> +
> + BT_DBG("%s status 0x%x", hdev->name, rp->status);
> +
> + if (rp->status)
> + return;
> +
> + hci_req_complete(hdev, rp->status);
> +}
> +
> static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
> {
> BT_DBG("%s status 0x%x", hdev->name, status);
> @@ -920,6 +944,11 @@ static void hci_cs_le_create_conn(struct hci_dev
> *hdev, __u8 status)
> hci_dev_unlock(hdev);
> }
>
> +static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
> +{
> + BT_DBG("%s status 0x%x", hdev->name, status);
> +}
> +
> static inline void hci_inquiry_complete_evt(struct hci_dev *hdev,
> struct sk_buff *skb)
> {
> __u8 status = *((__u8 *) skb->data);
> @@ -1440,6 +1469,14 @@ static inline void hci_cmd_complete_evt(struct
> hci_dev *hdev, struct sk_buff *sk
> hci_cc_le_read_buffer_size(hdev, skb);
> break;
>
> + case HCI_OP_LE_LTK_REPLY:
> + hci_cc_le_ltk_reply(hdev, skb);
> + break;
> +
> + case HCI_OP_LE_LTK_NEG_REPLY:
> + hci_cc_le_ltk_neg_reply(hdev, skb);
> + break;
> +
> default:
> BT_DBG("%s opcode 0x%x", hdev->name, opcode);
> break;
> @@ -1510,6 +1547,10 @@ static inline void hci_cmd_status_evt(struct
> hci_dev *hdev, struct sk_buff *skb)
> hci_cs_le_create_conn(hdev, ev->status);
> break;
>
> + case HCI_OP_LE_START_ENC:
> + hci_cs_le_start_enc(hdev, ev->status);
> + break;
> +
> default:
> BT_DBG("%s opcode 0x%x", hdev->name, opcode);
> break;
> @@ -2013,6 +2054,28 @@ unlock:
> hci_dev_unlock(hdev);
> }
>
> +static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
> + struct sk_buff *skb)
> +{
> + struct hci_ev_le_ltk_req *ev = (void *) skb->data;
> + struct hci_cp_le_ltk_reply cp;
> + struct hci_conn *conn;
> +
> + BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
> +
> + hci_dev_lock(hdev);
> +
> + conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev-
> >handle));
> +
> + memset(&cp, 0, sizeof(cp));
> + cp.handle = cpu_to_le16(conn->handle);
> + memcpy(cp.ltk, conn->ltk, sizeof(conn->ltk));
> +
> + hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
> +
> + hci_dev_unlock(hdev);
> +}
Same basic problem here, except ediv and random should be checked
for all Zeros, in which case it should be considered an STK request
and rejected unless part of an intended SM Pairing procedure. If
they are not zero, then they are the values that should be used to
look up the LTK for the LTK_REPLY, because the BD ADDR of the remote
device may have changed since the last time it was connected.
> +
> static inline void hci_le_meta_evt(struct hci_dev *hdev, struct
> sk_buff *skb)
> {
> struct hci_ev_le_meta *le_ev = (void *) skb->data;
> @@ -2024,6 +2087,10 @@ static inline void hci_le_meta_evt(struct
> hci_dev *hdev, struct sk_buff *skb)
> hci_le_conn_complete_evt(hdev, skb);
> break;
>
> + case HCI_EV_LE_LTK_REQ:
> + hci_le_ltk_request_evt(hdev, skb);
> + break;
> +
> default:
> break;
> }
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index 7d7e8ad..d19b8a2 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -289,7 +289,8 @@ static void smp_cmd_pairing_confirm(struct
> l2cap_conn *conn, struct sk_buff *skb
>
> static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct
> sk_buff *skb)
> {
> - struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
> + struct hci_conn *hcon = conn->hcon;
> + struct crypto_blkcipher *tfm = hcon->hdev->tfm;
> int ret;
> u8 k[16], key[16], res[16], random[16], confirm[16], buf[128];
>
> @@ -297,6 +298,7 @@ static void smp_cmd_pairing_random(struct
> l2cap_conn *conn, struct sk_buff *skb)
> skb_pull(skb, 16);
>
> memset(k, 0, sizeof(k));
> + memset(hcon->ltk, 0, sizeof(hcon->ltk));
>
> if (conn->hcon->out)
> ret = smp_c1(tfm, k, random, conn->preq, conn->pres, 0,
> @@ -320,6 +322,9 @@ static void smp_cmd_pairing_random(struct
> l2cap_conn *conn, struct sk_buff *skb)
>
> if (conn->hcon->out) {
> smp_s1(tfm, k, random, conn->prnd, key);
> + swap128(key, hcon->ltk);
> +
> + hci_le_start_enc(conn->hcon, hcon->ltk);
>
> hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
> sizeof(buf), 0);
> BT_DBG("key %s", buf);
> @@ -330,6 +335,7 @@ static void smp_cmd_pairing_random(struct
> l2cap_conn *conn, struct sk_buff *skb)
> smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 16, r);
>
> smp_s1(tfm, k, conn->prnd, random, key);
> + swap128(key, hcon->ltk);
>
> hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
> sizeof(buf), 0);
> BT_DBG("key %s", buf);
> --
> 1.7.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [RFC v2 5/9] Bluetooth: Add support for using the crypto subsystem
From: Brian Gix @ 2010-12-07 18:35 UTC (permalink / raw)
To: 'Vinicius Costa Gomes', linux-bluetooth
In-Reply-To: <1291671832-13435-6-git-send-email-vinicius.gomes@openbossa.org>
Hi Vinicius,
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-
> owner@vger.kernel.org] On Behalf Of Vinicius Costa Gomes
> Sent: 06 December, 2010 1:44 PM
> To: linux-bluetooth@vger.kernel.org
> Cc: Vinicius Costa Gomes
> Subject: [RFC v2 5/9] Bluetooth: Add support for using the crypto
> subsystem
>
> This will allow using the crypto subsystem for encrypting data. As SMP
> (Security Manager Protocol) is implemented almost entirely on the host
> side and the crypto module already implements the needed methods
> (AES-128), it makes sense to use it.
I do understand the desire to reuse the crypto module, but I would like
to point out that every baseband that supports any level of LE-SM, is
required to have implemented the HCI commands for LE-SM centric encryption
and random number generation.
Also, since these are processor intensive calculations, which must take
place in real-time on the baseband for encrypted links, I would argue
that it makes more sense to use the likely optimized functionality
present in the basebands.
That is not to say that it cannot be done on the host, just that it
is likely less efficient, for no gain in portability or functionality.
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
> include/net/bluetooth/hci_core.h | 2 ++
> net/bluetooth/hci_core.c | 10 ++++++++++
> 2 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/bluetooth/hci_core.h
> b/include/net/bluetooth/hci_core.h
> index 0687e2f..d0a9f5d 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -135,6 +135,8 @@ struct hci_dev {
> __u32 req_status;
> __u32 req_result;
>
> + struct crypto_blkcipher *tfm;
> +
> struct inquiry_cache inq_cache;
> struct hci_conn_hash conn_hash;
> struct list_head blacklist;
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 12c6735..b96c3dd 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -41,6 +41,7 @@
> #include <linux/interrupt.h>
> #include <linux/notifier.h>
> #include <linux/rfkill.h>
> +#include <linux/crypto.h>
> #include <net/sock.h>
>
> #include <asm/system.h>
> @@ -961,6 +962,13 @@ int hci_register_dev(struct hci_dev *hdev)
> if (!hdev->workqueue)
> goto nomem;
>
> + hdev->tfm = crypto_alloc_blkcipher("ecb(aes)", 0,
> CRYPTO_ALG_ASYNC);
> + if (IS_ERR(hdev->tfm)) {
> + BT_ERR("Failed to load transform for ecb(aes): %ld",
> + PTR_ERR(hdev->tfm));
> + goto nomem;
> + }
> +
> hci_register_sysfs(hdev);
>
> hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
> @@ -1001,6 +1009,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
> for (i = 0; i < NUM_REASSEMBLY; i++)
> kfree_skb(hdev->reassembly[i]);
>
> + crypto_free_blkcipher(hdev->tfm);
> +
> hci_notify(hdev, HCI_DEV_UNREG);
>
> if (hdev->rfkill) {
> --
> 1.7.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [RFC v2 4/9] Bluetooth: simple SMP pairing negotiation
From: Brian Gix @ 2010-12-07 18:26 UTC (permalink / raw)
To: 'Vinicius Costa Gomes', linux-bluetooth
Cc: 'Anderson Briglia'
In-Reply-To: <1291671832-13435-5-git-send-email-vinicius.gomes@openbossa.org>
Hi Vinicius,
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-
> owner@vger.kernel.org] On Behalf Of Vinicius Costa Gomes
> Sent: 06 December, 2010 1:44 PM
> To: linux-bluetooth@vger.kernel.org
> Cc: Anderson Briglia; Vinicius Costa Gomes
> Subject: [RFC v2 4/9] Bluetooth: simple SMP pairing negotiation
>
> From: Anderson Briglia <anderson.briglia@openbossa.org>
>
> This implementation only exchanges SMP messages between the Host and
> the
> Remote. No keys are being generated. TK and STK generation will be
> provided in further patches.
>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
> net/bluetooth/l2cap_core.c | 3 +-
> net/bluetooth/smp.c | 114
> ++++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 112 insertions(+), 5 deletions(-)
>
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 674799c..da4f13d 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -4630,7 +4630,8 @@ static void l2cap_recv_frame(struct l2cap_conn
> *conn, struct sk_buff *skb)
> break;
>
> case L2CAP_CID_SMP:
> - smp_sig_channel(conn, skb);
> + if (smp_sig_channel(conn, skb))
> + l2cap_conn_del(conn->hcon, 0x05);
> break;
>
> default:
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index e9dde5f..b25010f 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -64,6 +64,102 @@ static void smp_send_cmd(struct l2cap_conn *conn,
> u8 code, u16 len, void *data)
> hci_send_acl(conn->hcon, skb, 0);
> }
>
> +static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct
> sk_buff *skb)
> +{
> + struct smp_cmd_pairing *rp = (void *) skb->data;
> +
> + BT_DBG("");
> +
> + skb_pull(skb, sizeof(struct smp_cmd_pairing));
> +
> + rp->io_capability = 0x00;
> + rp->oob_flag = 0x00;
> + rp->max_key_size = 16;
> + rp->init_key_dist = 0x00;
> + rp->resp_key_dist = 0x00;
> + rp->auth_req &= 0x05;
> +
> + smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
> +}
As a "placeholder" I understand that there is a fair amount of fleshing
out that these changes need. However, as you have an conn->hcon->out
flag that indicates direction (which hopefully is based on Link Master),
I would like to see checking in this function and next, that the
correct role has received these SMP packets, with a rejection if they
were received by the incorrect role. Also, although the placeholder is
requesting no key distribution, in the fleshed out version, the responder
should be returning the subset (logical AND) of the requesters and the
responders key_dist masks, which in this case is still of course Zero.
I'm sorry if this is to many comments for this starting point.
> +
> +static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct
> sk_buff *skb)
> +{
> + struct smp_cmd_pairing_confirm cp;
> +
> + BT_DBG("");
> +
> + memset(&cp, 0, sizeof(struct smp_cmd_pairing_confirm));
> +
> + smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
> +}
> +
> +static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct
> sk_buff *skb)
> +{
> + BT_DBG("");
> +
> + if (conn->hcon->out) {
> + struct smp_cmd_pairing_random random;
> +
> + BT_DBG("master");
> +
> + memset(&random, 0, sizeof(struct smp_cmd_pairing_random));
> +
> + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
> + &random);
> + } else {
> + struct smp_cmd_pairing_confirm confirm;
> +
> + BT_DBG("slave");
> +
> + memset(&confirm, 0, sizeof(struct
> smp_cmd_pairing_confirm));
> +
> + smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM,
> sizeof(confirm),
> + &confirm);
> + }
> +}
> +
> +static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct
> sk_buff *skb)
> +{
> + struct smp_cmd_pairing_random cp;
> +
> + BT_DBG("");
> +
> + skb_pull(skb, sizeof(struct smp_cmd_pairing_random));
> +
> + /* FIXME: check if random matches */
The random numbers will not match. The correct check will be that
when the encryption with p1, p2, k, and the remote's random number,
is performed, that it matches the confirm previously received
via smp_cmd_pairing_confirm.
> +
> + if (conn->hcon->out) {
> + BT_DBG("master");
> + /* FIXME: start encryption */
> + } else {
> + BT_DBG("slave");
> +
> + memset(&cp, 0, sizeof(struct smp_cmd_pairing_random));
> +
> + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(cp),
> &cp);
> + }
> +}
> +
> +static void smp_cmd_security_req(struct l2cap_conn *conn, struct
> sk_buff *skb)
> +{
> + struct smp_cmd_security_req *rp = (void *) skb->data;
> + struct smp_cmd_pairing cp;
> +
> + BT_DBG("");
> +
> + skb_pull(skb, sizeof(struct smp_cmd_security_req));
> + memset(&cp, 0, sizeof(struct smp_cmd_pairing));
> +
> + cp.io_capability = 0x00;
> + cp.oob_flag = 0x00;
> + cp.max_key_size = 16;
> + cp.init_key_dist = 0x00;
> + cp.resp_key_dist = 0x00;
> + cp.auth_req = rp->auth_req & 0x05;
> +
> + smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
> +}
> +
This function may need to be overloaded, such that if an existing
set of keys already exist (from an earlier pairing) that they are
used by simply encrypting the link, or signing the WRITE_CMD pkt
as needed. Should the link encryption fail due to remote rejection,
we might then request security, subject to the same limitations
used by BR/EDR's SSP.
But I do not know where the division lies between the key storage dB,
the kernel mode code and the user mode code.
> int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
> {
> __u8 authreq;
> @@ -114,23 +210,33 @@ int smp_sig_channel(struct l2cap_conn *conn,
> struct sk_buff *skb)
>
> switch (code) {
> case SMP_CMD_PAIRING_REQ:
> - reason = SMP_PAIRING_NOTSUPP;
> - smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, 1, &reason);
> - err = -1;
> + smp_cmd_pairing_req(conn, skb);
> break;
>
> case SMP_CMD_PAIRING_FAIL:
> break;
>
> case SMP_CMD_PAIRING_RSP:
> + smp_cmd_pairing_rsp(conn, skb);
> + break;
> +
> + case SMP_CMD_SECURITY_REQ:
> + smp_cmd_security_req(conn, skb);
> + break;
> +
> case SMP_CMD_PAIRING_CONFIRM:
> + smp_cmd_pairing_confirm(conn, skb);
> + break;
> +
> case SMP_CMD_PAIRING_RANDOM:
> + smp_cmd_pairing_random(conn, skb);
> + break;
> +
> case SMP_CMD_ENCRYPT_INFO:
> case SMP_CMD_MASTER_IDENT:
> case SMP_CMD_IDENT_INFO:
> case SMP_CMD_IDENT_ADDR_INFO:
> case SMP_CMD_SIGN_INFO:
> - case SMP_CMD_SECURITY_REQ:
> default:
> BT_DBG("Unknown command code 0x%2.2x", code);
>
> --
> 1.7.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC v2 5/9] Bluetooth: Add support for using the crypto subsystem
From: Gustavo F. Padovan @ 2010-12-07 18:05 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <20101207175117.GA4797@eris>
Hi Vinicius,
* Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2010-12-07 14:51:17 -0300]:
> Hi Gustavo,
>
> On 15:27 Tue 07 Dec, Gustavo F. Padovan wrote:
> > Hi Vinicius,
> >
> > * Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2010-12-06 18:43:48 -0300]:
> >
> > > This will allow using the crypto subsystem for encrypting data. As SMP
> > > (Security Manager Protocol) is implemented almost entirely on the host
> > > side and the crypto module already implements the needed methods
> > > (AES-128), it makes sense to use it.
> > >
> > > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > > ---
> > > include/net/bluetooth/hci_core.h | 2 ++
> > > net/bluetooth/hci_core.c | 10 ++++++++++
> > > 2 files changed, 12 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> > > index 0687e2f..d0a9f5d 100644
> > > --- a/include/net/bluetooth/hci_core.h
> > > +++ b/include/net/bluetooth/hci_core.h
> > > @@ -135,6 +135,8 @@ struct hci_dev {
> > > __u32 req_status;
> > > __u32 req_result;
> > >
> > > + struct crypto_blkcipher *tfm;
> > > +
> > > struct inquiry_cache inq_cache;
> > > struct hci_conn_hash conn_hash;
> > > struct list_head blacklist;
> > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > > index 12c6735..b96c3dd 100644
> > > --- a/net/bluetooth/hci_core.c
> > > +++ b/net/bluetooth/hci_core.c
> > > @@ -41,6 +41,7 @@
> > > #include <linux/interrupt.h>
> > > #include <linux/notifier.h>
> > > #include <linux/rfkill.h>
> > > +#include <linux/crypto.h>
> > > #include <net/sock.h>
> > >
> > > #include <asm/system.h>
> > > @@ -961,6 +962,13 @@ int hci_register_dev(struct hci_dev *hdev)
> > > if (!hdev->workqueue)
> > > goto nomem;
> > >
> > > + hdev->tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
> > > + if (IS_ERR(hdev->tfm)) {
> > > + BT_ERR("Failed to load transform for ecb(aes): %ld",
> > > + PTR_ERR(hdev->tfm));
> > > + goto nomem;
> >
> > You are leaking hdev->workqueue here.
>
> Thanks, see below.
>
> >
> > Also you will need to add CRYPTO_BLKCIPHER dependence in the Kconfig.
> > Maybe we should add a CONFIG_BLUETOOTH_SMP, and just build with blkcipher
> > in the case SMP was selected to be built.
>
> Sounds fair. Another alternative is: instead of not being able to register the
> HCI device if the blockcypher allocation fails, we could reply "Pairing Not
> Supported" at the SMP level. We would just need to document somewhere that the
> crypto subsystem and support for AES are needed for SMP to work.
>
> What do you think?
No, because the build will fail if we don't select CRYPTO_BLKCIPHER and
CRYPTO_AES. It that case you can add a #ifdef CONFIG_CRYTO... to avoid the
build failure and comment that you need to enable such features. But I think
that would be better to add an Kconfig option for SMP in this case instead of
document somewhere that we need to enable some other options in the kernel to
have SMP working.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: EVT_NUM_COMP_PKTS and LE, GATT and SM
From: Vinicius Costa Gomes @ 2010-12-07 18:01 UTC (permalink / raw)
To: Brian Gix; +Cc: 'Ville Tervo', linux-bluetooth
In-Reply-To: <002b01cb9632$ca3a9840$5eafc8c0$@org>
Hi Brian,
On 09:18 Tue 07 Dec, Brian Gix wrote:
> Hi Ville, Vinicius,
>
> On Tue, Dec 07, 2010 at 12:47 AM -0800, Ville Tervo wrote:
> > Hi Brian,
> >
> > On Mon, Dec 06, 2010 at 04:35:51PM -0800, ext Brian Gix wrote:
> > > Hi All,
> > >
> > > I've have encountered a problem while using the gatttool, where my
> > write
> > > commands get clobbered by the LE ACL being disconnected prior to the
> > ATT
> > > (fixed channel 4) WRITE_CMD being sent over the LE based ACL link.
> > >
> > > I believe this is fundamentally due to there being no dependency on
> > the
> > > EVT_NUM_COMP_PKTS event when gatttool decides that the WRITE_CMD has
> > been
> > > successfully sent. There is multiple parts to this.
> > >
> > > 1. In User space, the WRITE_CMD pkt is written to the socket.
> > Gatttool
> > > erroneously considers a successful socket write as completion,
> > disconnects
> > > the socket and exits.
>
> I would like to try Vinicius' patch that (may) address this, but again
> I do not have access to infradead, although I think gitorious, which
> you used before, was not a problem.
>
Sorry, I forgot about this problem, please take a look here:
http://gitorious.org/~vcgomes/bluez/vcgomes-bluez
> > >
> > > 2. In Kernel space, the ACL packet is added to an ACL queue, which is
> > > separate from the CMD queue, which can allow either the Disconnect
> > request,
> > > or the ACL packet to be sent over the H4 link to the baseband.
> > >
> >
> > And in usb case CMD and ACL are even using different endpoints.
> >
> > > 3. In the baseband, due to LE clocking (and possible other baseband
> > > activity) the ACL packet could be received first, and the Disconnect
> > CMD
> > > second, and still result in the connection being detached prior to Tx
> > of the
> > > ACL packet containing the ATT WRITE_CMD.
> > >
> > > This is not an issue with any of the ATT READ/FIND/MTU or WRITE_REQ
> > > transactions, because they require a response from the server. I
> > believe
> > > for ATT, this problem is restricted to the WRITE_CMD only, due to
> > it's
> > > unacknowledged nature.
> >
> > True.
> >
> > > However, this will also be an issue with the LE Security Manager,
> > because as
> > > stated in the Core Spec v4.0, Vol 3, in the last paragraph of 3.6.1
> > Key
> > > Distribution on page 630 (of 656):
> > >
> > > > Key distribution is complete in the device sending the final
> > key
> > > when it receives
> > > > the baseband acknowledgement for that key and is complete in
> > the
> > > receiving
> > > > device when it receives the final key being distributed.
> > >
> > > This is intended to prevent exactly the kind of problem I am
> > experiencing
> > > with the ATT WRITE_CMD, and the acknowledgement from the baseband can
> > only
> > > be the EVT_NUM_COMP_PKTS event.
> > >
> > > While talking to my colleagues here, we were thinking that the
> > cleanest
> > > method to get this accomplished would be by using the "select" method
> > with
> > > the ATT socket, where the socket could be marked as non-writable by
> > the
> > > kernel driver until the EVT_NUM_COMP_PKTS is received. The User space
> > code
> > > could then wait for the socket to become writeable before issuing the
> > socket
> > > disconnect.
> > >
> >
> > How about implement waiting on l2cap_sock_shutdown() like for ERTM.
> > User space
> > could then call shutdown() before closing the socket so make sure the
> > data is
> > sent or timeout occurred.
>
> If I understand l2cap_sock_shutdown() correctly, then I think this
> is the correct solution. The socket mode would be BASIC, and the
> channel (dcid) would be fixed-4 (or perhaps fixed-5 or fixed-6 as well),
> but instead of waiting for an ack, it would be waiting on the
> EVT_NUM_COMP_PKTS, that indicates the number of outstanding ACL packets
> on the connection is Zero, with the rest of the logic unchanged.
>
>
> >
> > Would this be enough to solve the problem?
> >
> > > If the Security manager is totally within the kernel, it probably
> > does not
> > > have to do as much work, however it does still need to wait on the
> > > EVT_NUM_COMP_PKTS before disconnecting the remote device.
> > >
> > > Has anybody else observed this issue with ATT WRITE_CMD? It could be
> > getting
> > > exacerbated by slow (115Kbps) H4 links that I am using, however the
> > hcidump
> > > tool confirms that the disconnect happens prior to the
> > EVT_NUM_COMP_PKTS.
> >
> > I have seen this problem but didn't dig it deeper.
> >
> > --
> > Ville
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers,
--
Vinicius
^ permalink raw reply
* Re: [RFC v2 5/9] Bluetooth: Add support for using the crypto subsystem
From: Vinicius Costa Gomes @ 2010-12-07 17:51 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <20101207172713.GF2944@vigoh>
Hi Gustavo,
On 15:27 Tue 07 Dec, Gustavo F. Padovan wrote:
> Hi Vinicius,
>
> * Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2010-12-06 18:43:48 -0300]:
>
> > This will allow using the crypto subsystem for encrypting data. As SMP
> > (Security Manager Protocol) is implemented almost entirely on the host
> > side and the crypto module already implements the needed methods
> > (AES-128), it makes sense to use it.
> >
> > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > ---
> > include/net/bluetooth/hci_core.h | 2 ++
> > net/bluetooth/hci_core.c | 10 ++++++++++
> > 2 files changed, 12 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> > index 0687e2f..d0a9f5d 100644
> > --- a/include/net/bluetooth/hci_core.h
> > +++ b/include/net/bluetooth/hci_core.h
> > @@ -135,6 +135,8 @@ struct hci_dev {
> > __u32 req_status;
> > __u32 req_result;
> >
> > + struct crypto_blkcipher *tfm;
> > +
> > struct inquiry_cache inq_cache;
> > struct hci_conn_hash conn_hash;
> > struct list_head blacklist;
> > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > index 12c6735..b96c3dd 100644
> > --- a/net/bluetooth/hci_core.c
> > +++ b/net/bluetooth/hci_core.c
> > @@ -41,6 +41,7 @@
> > #include <linux/interrupt.h>
> > #include <linux/notifier.h>
> > #include <linux/rfkill.h>
> > +#include <linux/crypto.h>
> > #include <net/sock.h>
> >
> > #include <asm/system.h>
> > @@ -961,6 +962,13 @@ int hci_register_dev(struct hci_dev *hdev)
> > if (!hdev->workqueue)
> > goto nomem;
> >
> > + hdev->tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
> > + if (IS_ERR(hdev->tfm)) {
> > + BT_ERR("Failed to load transform for ecb(aes): %ld",
> > + PTR_ERR(hdev->tfm));
> > + goto nomem;
>
> You are leaking hdev->workqueue here.
Thanks, see below.
>
> Also you will need to add CRYPTO_BLKCIPHER dependence in the Kconfig.
> Maybe we should add a CONFIG_BLUETOOTH_SMP, and just build with blkcipher
> in the case SMP was selected to be built.
Sounds fair. Another alternative is: instead of not being able to register the
HCI device if the blockcypher allocation fails, we could reply "Pairing Not
Supported" at the SMP level. We would just need to document somewhere that the
crypto subsystem and support for AES are needed for SMP to work.
What do you think?
>
> --
> Gustavo F. Padovan
> http://profusion.mobi
Cheers,
--
Vinicius
^ permalink raw reply
* Re: [RFC v2 7/9] Bluetooth: Add support for SMP confirmation checks
From: Gustavo F. Padovan @ 2010-12-07 17:41 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1291671832-13435-8-git-send-email-vinicius.gomes@openbossa.org>
Hi Vinicius,
* Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2010-12-06 18:43:50 -0300]:
> This adds supports for verifying the confirmation value that the
> remote side has sent. This includes support for generating and sending
> the random value used to produce the confirmation value.
>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Can this be split in more than one patch? I'm getting lost.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox