blob: 69839797b7dcde9ef0efedfea1d17d2f56072ad0 [file] [log] [blame]
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation;
8
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
21*/
22
23#include <net/bluetooth/bluetooth.h>
24#include <net/bluetooth/hci_core.h>
25#include <net/bluetooth/l2cap.h>
26#include <net/bluetooth/smp.h>
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030027#include <linux/crypto.h>
28#include <crypto/b128ops.h>
29
30static inline void swap128(u8 src[16], u8 dst[16])
31{
32 int i;
33 for (i = 0; i < 16; i++)
34 dst[15 - i] = src[i];
35}
36
37static inline void swap56(u8 src[7], u8 dst[7])
38{
39 int i;
40 for (i = 0; i < 7; i++)
41 dst[6 - i] = src[i];
42}
43
44static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
45{
46 struct blkcipher_desc desc;
47 struct scatterlist sg;
48 int err, iv_len;
49 unsigned char iv[128];
50
51 if (tfm == NULL) {
52 BT_ERR("tfm %p", tfm);
53 return -EINVAL;
54 }
55
56 desc.tfm = tfm;
57 desc.flags = 0;
58
59 err = crypto_blkcipher_setkey(tfm, k, 16);
60 if (err) {
61 BT_ERR("cipher setkey failed: %d", err);
62 return err;
63 }
64
65 sg_init_one(&sg, r, 16);
66
67 iv_len = crypto_blkcipher_ivsize(tfm);
68 if (iv_len) {
69 memset(&iv, 0xff, iv_len);
70 crypto_blkcipher_set_iv(tfm, iv, iv_len);
71 }
72
73 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
74 if (err)
75 BT_ERR("Encrypt data error %d", err);
76
77 return err;
78}
79
80static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
81 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
82 u8 _rat, bdaddr_t *ra, u8 res[16])
83{
84 u8 p1[16], p2[16];
85 int err;
86
87 memset(p1, 0, 16);
88
89 /* p1 = pres || preq || _rat || _iat */
90 swap56(pres, p1);
91 swap56(preq, p1 + 7);
92 p1[14] = _rat;
93 p1[15] = _iat;
94
95 memset(p2, 0, 16);
96
97 /* p2 = padding || ia || ra */
98 baswap((bdaddr_t *) (p2 + 4), ia);
99 baswap((bdaddr_t *) (p2 + 10), ra);
100
101 /* res = r XOR p1 */
102 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
103
104 /* res = e(k, res) */
105 err = smp_e(tfm, k, res);
106 if (err) {
107 BT_ERR("Encrypt data error");
108 return err;
109 }
110
111 /* res = res XOR p2 */
112 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
113
114 /* res = e(k, res) */
115 err = smp_e(tfm, k, res);
116 if (err)
117 BT_ERR("Encrypt data error");
118
119 return err;
120}
121
122static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16],
123 u8 r1[16], u8 r2[16], u8 _r[16])
124{
125 int err;
126
127 /* Just least significant octets from r1 and r2 are considered */
128 memcpy(_r, r1 + 8, 8);
129 memcpy(_r + 8, r2 + 8, 8);
130
131 err = smp_e(tfm, k, _r);
132 if (err)
133 BT_ERR("Encrypt data error");
134
135 return err;
136}
137
138static int smp_rand(u8 *buf)
139{
140 get_random_bytes(buf, 16);
141
142 return 0;
143}
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300144
145static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
146 u16 dlen, void *data)
147{
148 struct sk_buff *skb;
149 struct l2cap_hdr *lh;
150 int len;
151
152 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
153
154 if (len > conn->mtu)
155 return NULL;
156
157 skb = bt_skb_alloc(len, GFP_ATOMIC);
158 if (!skb)
159 return NULL;
160
161 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
162 lh->len = cpu_to_le16(sizeof(code) + dlen);
163 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
164
165 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
166
167 memcpy(skb_put(skb, dlen), data, dlen);
168
169 return skb;
170}
171
172static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
173{
174 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
175
176 BT_DBG("code 0x%2.2x", code);
177
178 if (!skb)
179 return;
180
181 hci_send_acl(conn->hcon, skb, 0);
182}
183
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300184static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
185{
186 struct smp_cmd_pairing *rp = (void *) skb->data;
187
188 BT_DBG("conn %p", conn);
189
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300190 conn->preq[0] = SMP_CMD_PAIRING_REQ;
191 memcpy(&conn->preq[1], rp, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300192 skb_pull(skb, sizeof(*rp));
193
194 rp->io_capability = 0x00;
195 rp->oob_flag = 0x00;
196 rp->max_key_size = 16;
197 rp->init_key_dist = 0x00;
198 rp->resp_key_dist = 0x00;
199 rp->auth_req &= (SMP_AUTH_BONDING | SMP_AUTH_MITM);
200
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300201 /* Just works */
202 memset(conn->tk, 0, sizeof(conn->tk));
203
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300204 conn->prsp[0] = SMP_CMD_PAIRING_RSP;
205 memcpy(&conn->prsp[1], rp, sizeof(*rp));
206
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300207 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
208}
209
210static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
211{
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300212 struct smp_cmd_pairing *rp = (void *) skb->data;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300213 struct smp_cmd_pairing_confirm cp;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300214 struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
215 int ret;
216 u8 res[16];
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300217
218 BT_DBG("conn %p", conn);
219
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300220 /* Just works */
221 memset(conn->tk, 0, sizeof(conn->tk));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300222
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300223 conn->prsp[0] = SMP_CMD_PAIRING_RSP;
224 memcpy(&conn->prsp[1], rp, sizeof(*rp));
225 skb_pull(skb, sizeof(*rp));
226
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300227 ret = smp_rand(conn->prnd);
228 if (ret)
229 return;
230
231 ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0,
232 conn->src, conn->hcon->dst_type, conn->dst, res);
233 if (ret)
234 return;
235
236 swap128(res, cp.confirm_val);
237
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300238 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
239}
240
241static void smp_cmd_pairing_confirm(struct l2cap_conn *conn,
242 struct sk_buff *skb)
243{
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300244 struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
245
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300246 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
247
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300248 memcpy(conn->pcnf, skb->data, sizeof(conn->pcnf));
249 skb_pull(skb, sizeof(conn->pcnf));
250
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300251 if (conn->hcon->out) {
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300252 u8 random[16];
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300253
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300254 swap128(conn->prnd, random);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300255 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300256 random);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300257 } else {
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300258 struct smp_cmd_pairing_confirm cp;
259 int ret;
260 u8 res[16];
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300261
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300262 ret = smp_rand(conn->prnd);
263 if (ret)
264 return;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300265
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300266 ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp,
267 conn->hcon->dst_type, conn->dst,
268 0, conn->src, res);
269 if (ret)
270 return;
271
272 swap128(res, cp.confirm_val);
273
274 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300275 }
276}
277
278static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
279{
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300280 struct hci_conn *hcon = conn->hcon;
281 struct crypto_blkcipher *tfm = hcon->hdev->tfm;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300282 int ret;
Vinicius Costa Gomes9b3d6742011-06-09 18:50:48 -0300283 u8 key[16], res[16], random[16], confirm[16];
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300284
285 swap128(skb->data, random);
286 skb_pull(skb, sizeof(random));
287
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300288 memset(hcon->ltk, 0, sizeof(hcon->ltk));
289
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300290 if (conn->hcon->out)
291 ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
292 conn->src, conn->hcon->dst_type, conn->dst,
293 res);
294 else
295 ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp,
296 conn->hcon->dst_type, conn->dst, 0, conn->src,
297 res);
298 if (ret)
299 return;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300300
301 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
302
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300303 swap128(res, confirm);
304
305 if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf)) != 0) {
306 struct smp_cmd_pairing_fail cp;
307
308 BT_ERR("Pairing failed (confirmation values mismatch)");
309 cp.reason = SMP_CONFIRM_FAILED;
310 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(cp), &cp);
311 return;
312 }
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300313
314 if (conn->hcon->out) {
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300315 __le16 ediv;
316 u8 rand[8];
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300317
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300318 smp_s1(tfm, conn->tk, random, conn->prnd, key);
319 swap128(key, hcon->ltk);
320
321 memset(rand, 0, sizeof(rand));
322 ediv = 0;
323 hci_le_start_enc(hcon, ediv, rand, hcon->ltk);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300324 } else {
325 u8 r[16];
326
327 swap128(conn->prnd, r);
328 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
329
330 smp_s1(tfm, conn->tk, conn->prnd, random, key);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300331 swap128(key, hcon->ltk);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300332 }
333}
334
335static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
336{
337 struct smp_cmd_security_req *rp = (void *) skb->data;
338 struct smp_cmd_pairing cp;
339
340 BT_DBG("conn %p", conn);
341
342 skb_pull(skb, sizeof(*rp));
343 memset(&cp, 0, sizeof(cp));
344
345 cp.io_capability = 0x00;
346 cp.oob_flag = 0x00;
347 cp.max_key_size = 16;
348 cp.init_key_dist = 0x00;
349 cp.resp_key_dist = 0x00;
350 cp.auth_req = rp->auth_req & (SMP_AUTH_BONDING | SMP_AUTH_MITM);
351
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300352 conn->preq[0] = SMP_CMD_PAIRING_REQ;
353 memcpy(&conn->preq[1], &cp, sizeof(cp));
354
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300355 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
356}
357
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300358int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
359{
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300360 struct hci_conn *hcon = conn->hcon;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300361 __u8 authreq;
362
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300363 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
364
365 if (IS_ERR(hcon->hdev->tfm))
366 return 1;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300367
368 switch (sec_level) {
369 case BT_SECURITY_MEDIUM:
370 /* Encrypted, no MITM protection */
371 authreq = HCI_AT_NO_BONDING_MITM;
372 break;
373
374 case BT_SECURITY_HIGH:
375 /* Bonding, MITM protection */
376 authreq = HCI_AT_GENERAL_BONDING_MITM;
377 break;
378
379 case BT_SECURITY_LOW:
380 default:
381 return 1;
382 }
383
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300384 if (hcon->link_mode & HCI_LM_MASTER) {
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300385 struct smp_cmd_pairing cp;
386 cp.io_capability = 0x00;
387 cp.oob_flag = 0x00;
388 cp.max_key_size = 16;
389 cp.init_key_dist = 0x00;
390 cp.resp_key_dist = 0x00;
391 cp.auth_req = authreq;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300392
393 conn->preq[0] = SMP_CMD_PAIRING_REQ;
394 memcpy(&conn->preq[1], &cp, sizeof(cp));
395
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300396 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
397 } else {
398 struct smp_cmd_security_req cp;
399 cp.auth_req = authreq;
400 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
401 }
402
403 return 0;
404}
405
406int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
407{
408 __u8 code = skb->data[0];
409 __u8 reason;
410 int err = 0;
411
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300412 if (IS_ERR(conn->hcon->hdev->tfm)) {
413 err = PTR_ERR(conn->hcon->hdev->tfm);
414 reason = SMP_PAIRING_NOTSUPP;
415 goto done;
416 }
417
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300418 skb_pull(skb, sizeof(code));
419
420 switch (code) {
421 case SMP_CMD_PAIRING_REQ:
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300422 smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300423 break;
424
425 case SMP_CMD_PAIRING_FAIL:
426 break;
427
428 case SMP_CMD_PAIRING_RSP:
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300429 smp_cmd_pairing_rsp(conn, skb);
430 break;
431
432 case SMP_CMD_SECURITY_REQ:
433 smp_cmd_security_req(conn, skb);
434 break;
435
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300436 case SMP_CMD_PAIRING_CONFIRM:
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300437 smp_cmd_pairing_confirm(conn, skb);
438 break;
439
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300440 case SMP_CMD_PAIRING_RANDOM:
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300441 smp_cmd_pairing_random(conn, skb);
442 break;
443
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300444 case SMP_CMD_ENCRYPT_INFO:
445 case SMP_CMD_MASTER_IDENT:
446 case SMP_CMD_IDENT_INFO:
447 case SMP_CMD_IDENT_ADDR_INFO:
448 case SMP_CMD_SIGN_INFO:
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300449 default:
450 BT_DBG("Unknown command code 0x%2.2x", code);
451
452 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300453 err = -EOPNOTSUPP;
454 goto done;
455 }
456
457done:
458 if (reason)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300459 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
460 &reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300461
462 kfree_skb(skb);
463 return err;
464}