Bluetooth: Add LE SecMgr and mgmtops support
Enabled ECB Block encoding for Low Energy pairing
Implemented missing components of MGMTOPS interface
Differentiated as needed between BR/EDR pairing and LE pairing
Signed-off-by: Brian Gix <bgix@codeaurora.org>
Conflicts:
net/bluetooth/mgmt.c
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 3466efa..9fda323 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -897,7 +897,20 @@
__u8 le_max_pkt;
} __packed;
+#define HCI_OP_LE_SET_SCAN_PARAMETERS 0x200b
+struct hci_cp_le_set_scan_parameters {
+ __u8 type;
+ __le16 interval;
+ __le16 window;
+ __u8 own_bdaddr_type;
+ __u8 filter;
+} __packed;
+
#define HCI_OP_LE_SET_SCAN_ENABLE 0x200c
+struct hci_cp_le_set_scan_enable {
+ __u8 enable;
+ __u8 filter_dup;
+} __packed;
#define HCI_OP_LE_CREATE_CONN 0x200d
struct hci_cp_le_create_conn {
@@ -928,6 +941,16 @@
__le16 max_ce_len;
} __packed;
+#define HCI_OP_LE_ENCRYPT 0x2017
+struct hci_cp_le_encrypt {
+ __u8 key[16];
+ __u8 data[16];
+} __packed;
+struct hci_cp_le_encrypt_reply {
+ __u8 status;
+ __u8 encrypted[16];
+} __packed;
+
#define HCI_OP_LE_START_ENC 0x2019
struct hci_cp_le_start_enc {
__le16 handle;
@@ -1209,6 +1232,11 @@
__le32 passkey;
} __packed;
+#define HCI_EV_USER_PASSKEY_REQUEST 0x34
+struct hci_ev_user_passkey_request {
+ bdaddr_t bdaddr;
+} __packed;
+
#define HCI_EV_REMOTE_OOB_DATA_REQUEST 0x35
struct hci_ev_remote_oob_data_request {
bdaddr_t bdaddr;
@@ -1220,6 +1248,12 @@
bdaddr_t bdaddr;
} __packed;
+#define HCI_EV_USER_PASSKEY_NOTIFICATION 0x3b
+struct hci_ev_user_passkey_notification {
+ bdaddr_t bdaddr;
+ __le32 passkey;
+} __packed;
+
#define HCI_EV_REMOTE_HOST_FEATURES 0x3d
struct hci_ev_remote_host_features {
bdaddr_t bdaddr;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7e0e151..41af2dd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -84,15 +84,17 @@
u8 rand[8];
} __packed;
-#define KEY_TYPE_LTK 0x11
-#define KEY_TYPE_IRK 0x12
-#define KEY_TYPE_CSRK 0x13
+#define KEY_TYPE_LE_BASE 0x11
+#define KEY_TYPE_LTK 0x11
+#define KEY_TYPE_IRK 0x12
+#define KEY_TYPE_CSRK 0x13
struct link_key_data {
bdaddr_t bdaddr;
u8 type;
u8 val[16];
u8 pin_len;
+ u8 auth;
u8 dlen;
u8 data[0];
} __packed;
@@ -103,6 +105,7 @@
u8 type;
u8 val[16];
u8 pin_len;
+ u8 auth;
u8 dlen;
u8 data[0];
};
@@ -287,6 +290,7 @@
__u8 pin_length;
__u8 enc_key_size;
__u8 io_capability;
+ __u8 auth_initiator;
__u8 power_save;
__u16 disc_timeout;
unsigned long pend;
@@ -318,6 +322,20 @@
struct hci_conn *link;
+ /* Low Energy SMP pairing data */
+ __u8 oob; /* OOB pairing supported */
+ __u8 tk_valid; /* TK value is valid */
+ __u8 cfm_pending; /* CONFIRM cmd may be sent */
+ __u8 preq[7]; /* Pairing Request */
+ __u8 prsp[7]; /* Pairing Response */
+ __u8 prnd[16]; /* Pairing Random */
+ __u8 pcnf[16]; /* Pairing Confirm */
+ __u8 tk[16]; /* Temporary Key */
+ __u8 smp_key_size;
+ __u8 sec_req;
+ __u8 auth;
+ void *smp_conn;
+
void (*connect_cfm_cb) (struct hci_conn *conn, u8 status);
void (*security_cfm_cb) (struct hci_conn *conn, u8 status);
void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason);
@@ -586,7 +604,7 @@
{
if (atomic_dec_and_test(&conn->refcnt)) {
unsigned long timeo;
- if (conn->type == ACL_LINK) {
+ if (conn->type == ACL_LINK || conn->type == LE_LINK) {
del_timer(&conn->idle_timer);
if (conn->state == BT_CONNECTED) {
timeo = msecs_to_jiffies(conn->disc_timeout);
@@ -667,7 +685,7 @@
struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 type);
int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
+ u8 auth, u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
@@ -986,7 +1004,7 @@
int mgmt_powered(u16 index, u8 powered);
int mgmt_discoverable(u16 index, u8 discoverable);
int mgmt_connectable(u16 index, u8 connectable);
-int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type);
+int mgmt_new_key(u16 index, struct link_key *key, u8 bonded);
int mgmt_connected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnect_failed(u16 index);
@@ -994,7 +1012,9 @@
int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr);
int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value);
+int mgmt_user_confirm_request(u16 index, u8 event, bdaddr_t *bdaddr,
+ __le32 value);
+int mgmt_user_oob_request(u16 index, bdaddr_t *bdaddr);
int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
u8 status);
@@ -1002,9 +1022,14 @@
int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status);
int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
u8 status);
-int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi,
- u8 *eir);
-int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name);
+int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 le,
+ u8 *dev_class, s8 rssi, u8 eir_len, u8 *eir);
+int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 status, u8 *name);
+void mgmt_inquiry_started(u16 index);
+void mgmt_inquiry_complete_evt(u16 index, u8 status);
+
+/* LE SMP Management interface */
+int le_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, void *cp);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index be2147e..64c4f16 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -452,13 +452,6 @@
__u8 disc_reason;
- __u8 preq[7]; /* SMP Pairing Request */
- __u8 prsp[7]; /* SMP Pairing Response */
- __u8 prnd[16]; /* SMP Pairing Random */
- __u8 pcnf[16]; /* SMP Pairing Confirm */
- __u8 tk[16]; /* SMP Temporary Key */
- __u8 smp_key_size;
-
struct timer_list security_timer;
struct l2cap_chan_list chan_list;
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index b266b73..9e279fc 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -101,8 +101,9 @@
u8 type;
u8 val[16];
u8 pin_len;
+ u8 auth;
u8 dlen;
- u8 data[0];
+ u8 data[10];
} __packed;
#define MGMT_OP_LOAD_KEYS 0x000D
@@ -198,6 +199,21 @@
bdaddr_t bdaddr;
} __packed;
+#define MGMT_OP_START_DISCOVERY 0x001B
+
+#define MGMT_OP_STOP_DISCOVERY 0x001C
+
+#define MGMT_OP_USER_PASSKEY_REPLY 0x001D
+struct mgmt_cp_user_passkey_reply {
+ bdaddr_t bdaddr;
+ __le32 passkey;
+} __packed;
+
+#define MGMT_OP_RESOLVE_NAME 0x001E
+struct mgmt_cp_resolve_name {
+ bdaddr_t bdaddr;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
@@ -229,7 +245,7 @@
#define MGMT_EV_NEW_KEY 0x000A
struct mgmt_ev_new_key {
- __u8 old_key_type;
+ __u8 store_hint;
struct mgmt_key_info key;
} __packed;
@@ -252,11 +268,14 @@
#define MGMT_EV_PIN_CODE_REQUEST 0x000E
struct mgmt_ev_pin_code_request {
bdaddr_t bdaddr;
+ __u8 secure;
} __packed;
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
bdaddr_t bdaddr;
+ __u8 auto_confirm;
+ __u8 event;
__le32 value;
} __packed;
@@ -276,11 +295,22 @@
bdaddr_t bdaddr;
__u8 dev_class[3];
__s8 rssi;
+ __u8 le;
+ __u8 type;
__u8 eir[HCI_MAX_EIR_LENGTH];
} __packed;
#define MGMT_EV_REMOTE_NAME 0x0013
struct mgmt_ev_remote_name {
bdaddr_t bdaddr;
+ __u8 status;
__u8 name[MGMT_MAX_NAME_LENGTH];
} __packed;
+
+#define MGMT_EV_DISCOVERING 0x0014
+
+#define MGMT_EV_USER_PASSKEY_REQUEST 0x0015
+struct mgmt_ev_user_passkey_request {
+ bdaddr_t bdaddr;
+} __packed;
+
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 46c4576..15a15a0 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -55,6 +55,13 @@
#define SMP_AUTH_BONDING 0x01
#define SMP_AUTH_MITM 0x04
+#define SMP_JUST_WORKS 0x00
+#define SMP_JUST_CFM 0x01
+#define SMP_REQ_PASSKEY 0x02
+#define SMP_CFM_PASSKEY 0x03
+#define SMP_REQ_OOB 0x04
+#define SMP_OVERLAP 0xFF
+
#define SMP_CMD_PAIRING_CONFIRM 0x03
struct smp_cmd_pairing_confirm {
__u8 confirm_val[16];
@@ -118,6 +125,6 @@
/* 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);
-int smp_distribute_keys(struct l2cap_conn *conn, __u8 force);
+int smp_link_encrypt_cmplt(struct l2cap_conn *conn, __u8 status, __u8 encrypt);
#endif /* __SMP_H */