diff options
-rw-r--r-- | include/net/bluetooth/smp.h | 17 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 107 |
2 files changed, 119 insertions, 5 deletions
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h index 36bdd6eb6aa7..111853ab239a 100644 --- a/include/net/bluetooth/smp.h +++ b/include/net/bluetooth/smp.h | |||
@@ -38,6 +38,23 @@ struct smp_cmd_pairing { | |||
38 | __u8 resp_key_dist; | 38 | __u8 resp_key_dist; |
39 | } __packed; | 39 | } __packed; |
40 | 40 | ||
41 | #define SMP_IO_DISPLAY_ONLY 0x00 | ||
42 | #define SMP_IO_DISPLAY_YESNO 0x01 | ||
43 | #define SMP_IO_KEYBOARD_ONLY 0x02 | ||
44 | #define SMP_IO_NO_INPUT_OUTPUT 0x03 | ||
45 | #define SMP_IO_KEYBOARD_DISPLAY 0x04 | ||
46 | |||
47 | #define SMP_OOB_NOT_PRESENT 0x00 | ||
48 | #define SMP_OOB_PRESENT 0x01 | ||
49 | |||
50 | #define SMP_DIST_ENC_KEY 0x01 | ||
51 | #define SMP_DIST_ID_KEY 0x02 | ||
52 | #define SMP_DIST_SIGN 0x04 | ||
53 | |||
54 | #define SMP_AUTH_NONE 0x00 | ||
55 | #define SMP_AUTH_BONDING 0x01 | ||
56 | #define SMP_AUTH_MITM 0x04 | ||
57 | |||
41 | #define SMP_CMD_PAIRING_CONFIRM 0x03 | 58 | #define SMP_CMD_PAIRING_CONFIRM 0x03 |
42 | struct smp_cmd_pairing_confirm { | 59 | struct smp_cmd_pairing_confirm { |
43 | __u8 confirm_val[16]; | 60 | __u8 confirm_val[16]; |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index aa0434f4aa1a..2240e96552f1 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -64,6 +64,94 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | |||
64 | hci_send_acl(conn->hcon, skb, 0); | 64 | hci_send_acl(conn->hcon, skb, 0); |
65 | } | 65 | } |
66 | 66 | ||
67 | static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | ||
68 | { | ||
69 | struct smp_cmd_pairing *rp = (void *) skb->data; | ||
70 | |||
71 | BT_DBG("conn %p", conn); | ||
72 | |||
73 | skb_pull(skb, sizeof(*rp)); | ||
74 | |||
75 | rp->io_capability = 0x00; | ||
76 | rp->oob_flag = 0x00; | ||
77 | rp->max_key_size = 16; | ||
78 | rp->init_key_dist = 0x00; | ||
79 | rp->resp_key_dist = 0x00; | ||
80 | rp->auth_req &= (SMP_AUTH_BONDING | SMP_AUTH_MITM); | ||
81 | |||
82 | smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp); | ||
83 | } | ||
84 | |||
85 | static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | ||
86 | { | ||
87 | struct smp_cmd_pairing_confirm cp; | ||
88 | |||
89 | BT_DBG("conn %p", conn); | ||
90 | |||
91 | memset(&cp, 0, sizeof(cp)); | ||
92 | |||
93 | smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); | ||
94 | } | ||
95 | |||
96 | static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, | ||
97 | struct sk_buff *skb) | ||
98 | { | ||
99 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); | ||
100 | |||
101 | if (conn->hcon->out) { | ||
102 | struct smp_cmd_pairing_random random; | ||
103 | |||
104 | memset(&random, 0, sizeof(random)); | ||
105 | |||
106 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random), | ||
107 | &random); | ||
108 | } else { | ||
109 | struct smp_cmd_pairing_confirm confirm; | ||
110 | |||
111 | memset(&confirm, 0, sizeof(confirm)); | ||
112 | |||
113 | smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(confirm), | ||
114 | &confirm); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | ||
119 | { | ||
120 | struct smp_cmd_pairing_random cp; | ||
121 | |||
122 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); | ||
123 | |||
124 | skb_pull(skb, sizeof(cp)); | ||
125 | |||
126 | if (conn->hcon->out) { | ||
127 | /* FIXME: start encryption */ | ||
128 | } else { | ||
129 | memset(&cp, 0, sizeof(cp)); | ||
130 | |||
131 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(cp), &cp); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | ||
136 | { | ||
137 | struct smp_cmd_security_req *rp = (void *) skb->data; | ||
138 | struct smp_cmd_pairing cp; | ||
139 | |||
140 | BT_DBG("conn %p", conn); | ||
141 | |||
142 | skb_pull(skb, sizeof(*rp)); | ||
143 | memset(&cp, 0, sizeof(cp)); | ||
144 | |||
145 | cp.io_capability = 0x00; | ||
146 | cp.oob_flag = 0x00; | ||
147 | cp.max_key_size = 16; | ||
148 | cp.init_key_dist = 0x00; | ||
149 | cp.resp_key_dist = 0x00; | ||
150 | cp.auth_req = rp->auth_req & (SMP_AUTH_BONDING | SMP_AUTH_MITM); | ||
151 | |||
152 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); | ||
153 | } | ||
154 | |||
67 | int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) | 155 | int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) |
68 | { | 156 | { |
69 | __u8 authreq; | 157 | __u8 authreq; |
@@ -114,24 +202,33 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
114 | 202 | ||
115 | switch (code) { | 203 | switch (code) { |
116 | case SMP_CMD_PAIRING_REQ: | 204 | case SMP_CMD_PAIRING_REQ: |
117 | reason = SMP_PAIRING_NOTSUPP; | 205 | smp_cmd_pairing_req(conn, skb); |
118 | smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), | ||
119 | &reason); | ||
120 | err = -EOPNOTSUPP; | ||
121 | break; | 206 | break; |
122 | 207 | ||
123 | case SMP_CMD_PAIRING_FAIL: | 208 | case SMP_CMD_PAIRING_FAIL: |
124 | break; | 209 | break; |
125 | 210 | ||
126 | case SMP_CMD_PAIRING_RSP: | 211 | case SMP_CMD_PAIRING_RSP: |
212 | smp_cmd_pairing_rsp(conn, skb); | ||
213 | break; | ||
214 | |||
215 | case SMP_CMD_SECURITY_REQ: | ||
216 | smp_cmd_security_req(conn, skb); | ||
217 | break; | ||
218 | |||
127 | case SMP_CMD_PAIRING_CONFIRM: | 219 | case SMP_CMD_PAIRING_CONFIRM: |
220 | smp_cmd_pairing_confirm(conn, skb); | ||
221 | break; | ||
222 | |||
128 | case SMP_CMD_PAIRING_RANDOM: | 223 | case SMP_CMD_PAIRING_RANDOM: |
224 | smp_cmd_pairing_random(conn, skb); | ||
225 | break; | ||
226 | |||
129 | case SMP_CMD_ENCRYPT_INFO: | 227 | case SMP_CMD_ENCRYPT_INFO: |
130 | case SMP_CMD_MASTER_IDENT: | 228 | case SMP_CMD_MASTER_IDENT: |
131 | case SMP_CMD_IDENT_INFO: | 229 | case SMP_CMD_IDENT_INFO: |
132 | case SMP_CMD_IDENT_ADDR_INFO: | 230 | case SMP_CMD_IDENT_ADDR_INFO: |
133 | case SMP_CMD_SIGN_INFO: | 231 | case SMP_CMD_SIGN_INFO: |
134 | case SMP_CMD_SECURITY_REQ: | ||
135 | default: | 232 | default: |
136 | BT_DBG("Unknown command code 0x%2.2x", code); | 233 | BT_DBG("Unknown command code 0x%2.2x", code); |
137 | 234 | ||