Bluetooth: Add support for SMP timeout
[deliverable/linux.git] / net / bluetooth / smp.c
CommitLineData
eb492e01
AB
1/*
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>
d22ef0bc
AB
27#include <linux/crypto.h>
28#include <crypto/b128ops.h>
29
5d3de7df
VCG
30#define SMP_TIMEOUT 30000 /* 30 seconds */
31
d22ef0bc
AB
32static inline void swap128(u8 src[16], u8 dst[16])
33{
34 int i;
35 for (i = 0; i < 16; i++)
36 dst[15 - i] = src[i];
37}
38
39static inline void swap56(u8 src[7], u8 dst[7])
40{
41 int i;
42 for (i = 0; i < 7; i++)
43 dst[6 - i] = src[i];
44}
45
46static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
47{
48 struct blkcipher_desc desc;
49 struct scatterlist sg;
50 int err, iv_len;
51 unsigned char iv[128];
52
53 if (tfm == NULL) {
54 BT_ERR("tfm %p", tfm);
55 return -EINVAL;
56 }
57
58 desc.tfm = tfm;
59 desc.flags = 0;
60
61 err = crypto_blkcipher_setkey(tfm, k, 16);
62 if (err) {
63 BT_ERR("cipher setkey failed: %d", err);
64 return err;
65 }
66
67 sg_init_one(&sg, r, 16);
68
69 iv_len = crypto_blkcipher_ivsize(tfm);
70 if (iv_len) {
71 memset(&iv, 0xff, iv_len);
72 crypto_blkcipher_set_iv(tfm, iv, iv_len);
73 }
74
75 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
76 if (err)
77 BT_ERR("Encrypt data error %d", err);
78
79 return err;
80}
81
82static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
83 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
84 u8 _rat, bdaddr_t *ra, u8 res[16])
85{
86 u8 p1[16], p2[16];
87 int err;
88
89 memset(p1, 0, 16);
90
91 /* p1 = pres || preq || _rat || _iat */
92 swap56(pres, p1);
93 swap56(preq, p1 + 7);
94 p1[14] = _rat;
95 p1[15] = _iat;
96
97 memset(p2, 0, 16);
98
99 /* p2 = padding || ia || ra */
100 baswap((bdaddr_t *) (p2 + 4), ia);
101 baswap((bdaddr_t *) (p2 + 10), ra);
102
103 /* res = r XOR p1 */
104 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
105
106 /* res = e(k, res) */
107 err = smp_e(tfm, k, res);
108 if (err) {
109 BT_ERR("Encrypt data error");
110 return err;
111 }
112
113 /* res = res XOR p2 */
114 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
115
116 /* res = e(k, res) */
117 err = smp_e(tfm, k, res);
118 if (err)
119 BT_ERR("Encrypt data error");
120
121 return err;
122}
123
124static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16],
125 u8 r1[16], u8 r2[16], u8 _r[16])
126{
127 int err;
128
129 /* Just least significant octets from r1 and r2 are considered */
130 memcpy(_r, r1 + 8, 8);
131 memcpy(_r + 8, r2 + 8, 8);
132
133 err = smp_e(tfm, k, _r);
134 if (err)
135 BT_ERR("Encrypt data error");
136
137 return err;
138}
139
140static int smp_rand(u8 *buf)
141{
142 get_random_bytes(buf, 16);
143
144 return 0;
145}
eb492e01
AB
146
147static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
148 u16 dlen, void *data)
149{
150 struct sk_buff *skb;
151 struct l2cap_hdr *lh;
152 int len;
153
154 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
155
156 if (len > conn->mtu)
157 return NULL;
158
159 skb = bt_skb_alloc(len, GFP_ATOMIC);
160 if (!skb)
161 return NULL;
162
163 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
164 lh->len = cpu_to_le16(sizeof(code) + dlen);
165 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
166
167 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
168
169 memcpy(skb_put(skb, dlen), data, dlen);
170
171 return skb;
172}
173
174static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
175{
176 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
177
178 BT_DBG("code 0x%2.2x", code);
179
180 if (!skb)
181 return;
182
183 hci_send_acl(conn->hcon, skb, 0);
184}
185
da85e5e5
VCG
186static __u8 seclevel_to_authreq(__u8 level)
187{
188 switch (level) {
189 case BT_SECURITY_HIGH:
190 /* Right now we don't support bonding */
191 return SMP_AUTH_MITM;
192
193 default:
194 return SMP_AUTH_NONE;
195 }
196}
197
b8e66eac
VCG
198static void build_pairing_cmd(struct l2cap_conn *conn,
199 struct smp_cmd_pairing *cmd, __u8 authreq)
200{
201 cmd->io_capability = conn->hcon->io_capability;
202 cmd->oob_flag = SMP_OOB_NOT_PRESENT;
203 cmd->max_key_size = 16;
204 cmd->init_key_dist = 0x00;
205 cmd->resp_key_dist = 0x00;
206 cmd->auth_req = authreq;
207}
208
da85e5e5 209static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
88ba43b6
AB
210{
211 struct smp_cmd_pairing *rp = (void *) skb->data;
212
213 BT_DBG("conn %p", conn);
214
f01ead31
AB
215 conn->preq[0] = SMP_CMD_PAIRING_REQ;
216 memcpy(&conn->preq[1], rp, sizeof(*rp));
88ba43b6
AB
217 skb_pull(skb, sizeof(*rp));
218
da85e5e5
VCG
219 if (rp->oob_flag)
220 return SMP_OOB_NOT_AVAIL;
221
222 /* We didn't start the pairing, so no requirements */
223 build_pairing_cmd(conn, rp, SMP_AUTH_NONE);
88ba43b6 224
7d24ddcc
AB
225 /* Just works */
226 memset(conn->tk, 0, sizeof(conn->tk));
227
f01ead31
AB
228 conn->prsp[0] = SMP_CMD_PAIRING_RSP;
229 memcpy(&conn->prsp[1], rp, sizeof(*rp));
230
88ba43b6 231 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
da85e5e5 232
5d3de7df
VCG
233 mod_timer(&conn->security_timer, jiffies +
234 msecs_to_jiffies(SMP_TIMEOUT));
235
da85e5e5 236 return 0;
88ba43b6
AB
237}
238
da85e5e5 239static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
88ba43b6 240{
f01ead31 241 struct smp_cmd_pairing *rp = (void *) skb->data;
88ba43b6 242 struct smp_cmd_pairing_confirm cp;
7d24ddcc
AB
243 struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
244 int ret;
245 u8 res[16];
88ba43b6
AB
246
247 BT_DBG("conn %p", conn);
248
da85e5e5
VCG
249 skb_pull(skb, sizeof(*rp));
250
251 if (rp->oob_flag)
252 return SMP_OOB_NOT_AVAIL;
253
7d24ddcc
AB
254 /* Just works */
255 memset(conn->tk, 0, sizeof(conn->tk));
88ba43b6 256
f01ead31
AB
257 conn->prsp[0] = SMP_CMD_PAIRING_RSP;
258 memcpy(&conn->prsp[1], rp, sizeof(*rp));
f01ead31 259
7d24ddcc
AB
260 ret = smp_rand(conn->prnd);
261 if (ret)
da85e5e5 262 return SMP_UNSPECIFIED;
7d24ddcc
AB
263
264 ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0,
265 conn->src, conn->hcon->dst_type, conn->dst, res);
266 if (ret)
da85e5e5 267 return SMP_UNSPECIFIED;
7d24ddcc
AB
268
269 swap128(res, cp.confirm_val);
270
88ba43b6 271 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
da85e5e5
VCG
272
273 return 0;
88ba43b6
AB
274}
275
da85e5e5 276static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
88ba43b6 277{
7d24ddcc
AB
278 struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
279
88ba43b6
AB
280 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
281
7d24ddcc
AB
282 memcpy(conn->pcnf, skb->data, sizeof(conn->pcnf));
283 skb_pull(skb, sizeof(conn->pcnf));
88ba43b6 284
7d24ddcc
AB
285 if (conn->hcon->out) {
286 u8 random[16];
88ba43b6 287
7d24ddcc 288 swap128(conn->prnd, random);
88ba43b6 289 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
7d24ddcc 290 random);
88ba43b6 291 } else {
7d24ddcc
AB
292 struct smp_cmd_pairing_confirm cp;
293 int ret;
294 u8 res[16];
88ba43b6 295
7d24ddcc
AB
296 ret = smp_rand(conn->prnd);
297 if (ret)
da85e5e5 298 return SMP_UNSPECIFIED;
88ba43b6 299
7d24ddcc
AB
300 ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp,
301 conn->hcon->dst_type, conn->dst,
302 0, conn->src, res);
303 if (ret)
da85e5e5 304 return SMP_CONFIRM_FAILED;
7d24ddcc
AB
305
306 swap128(res, cp.confirm_val);
307
308 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
88ba43b6 309 }
da85e5e5 310
5d3de7df
VCG
311 mod_timer(&conn->security_timer, jiffies +
312 msecs_to_jiffies(SMP_TIMEOUT));
313
da85e5e5 314 return 0;
88ba43b6
AB
315}
316
da85e5e5 317static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
88ba43b6 318{
a7a595f6
VCG
319 struct hci_conn *hcon = conn->hcon;
320 struct crypto_blkcipher *tfm = hcon->hdev->tfm;
7d24ddcc 321 int ret;
9b3d6740 322 u8 key[16], res[16], random[16], confirm[16];
7d24ddcc
AB
323
324 swap128(skb->data, random);
325 skb_pull(skb, sizeof(random));
326
a7a595f6
VCG
327 memset(hcon->ltk, 0, sizeof(hcon->ltk));
328
7d24ddcc
AB
329 if (conn->hcon->out)
330 ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
331 conn->src, conn->hcon->dst_type, conn->dst,
332 res);
333 else
334 ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp,
335 conn->hcon->dst_type, conn->dst, 0, conn->src,
336 res);
337 if (ret)
da85e5e5 338 return SMP_UNSPECIFIED;
88ba43b6
AB
339
340 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
341
7d24ddcc
AB
342 swap128(res, confirm);
343
344 if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf)) != 0) {
7d24ddcc 345 BT_ERR("Pairing failed (confirmation values mismatch)");
da85e5e5 346 return SMP_CONFIRM_FAILED;
7d24ddcc 347 }
88ba43b6
AB
348
349 if (conn->hcon->out) {
a7a595f6
VCG
350 __le16 ediv;
351 u8 rand[8];
352
7d24ddcc 353 smp_s1(tfm, conn->tk, random, conn->prnd, key);
a7a595f6 354 swap128(key, hcon->ltk);
7d24ddcc 355
a7a595f6
VCG
356 memset(rand, 0, sizeof(rand));
357 ediv = 0;
358 hci_le_start_enc(hcon, ediv, rand, hcon->ltk);
88ba43b6 359 } else {
7d24ddcc
AB
360 u8 r[16];
361
362 swap128(conn->prnd, r);
363 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
364
365 smp_s1(tfm, conn->tk, conn->prnd, random, key);
a7a595f6 366 swap128(key, hcon->ltk);
88ba43b6 367 }
da85e5e5
VCG
368
369 return 0;
88ba43b6
AB
370}
371
da85e5e5 372static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
88ba43b6
AB
373{
374 struct smp_cmd_security_req *rp = (void *) skb->data;
375 struct smp_cmd_pairing cp;
f1cb9af5 376 struct hci_conn *hcon = conn->hcon;
88ba43b6
AB
377
378 BT_DBG("conn %p", conn);
379
f1cb9af5 380 if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
da85e5e5 381 return 0;
f1cb9af5 382
88ba43b6 383 skb_pull(skb, sizeof(*rp));
88ba43b6 384
da85e5e5
VCG
385 memset(&cp, 0, sizeof(cp));
386 build_pairing_cmd(conn, &cp, rp->auth_req);
88ba43b6 387
f01ead31
AB
388 conn->preq[0] = SMP_CMD_PAIRING_REQ;
389 memcpy(&conn->preq[1], &cp, sizeof(cp));
390
88ba43b6 391 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
f1cb9af5 392
5d3de7df
VCG
393 mod_timer(&conn->security_timer, jiffies +
394 msecs_to_jiffies(SMP_TIMEOUT));
395
f1cb9af5 396 set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
f1cb9af5 397
da85e5e5 398 return 0;
88ba43b6
AB
399}
400
eb492e01
AB
401int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
402{
3a0259bb 403 struct hci_conn *hcon = conn->hcon;
eb492e01
AB
404 __u8 authreq;
405
3a0259bb
VCG
406 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
407
408 if (IS_ERR(hcon->hdev->tfm))
409 return 1;
eb492e01 410
f1cb9af5
VCG
411 if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
412 return 0;
eb492e01 413
f1cb9af5
VCG
414 if (sec_level == BT_SECURITY_LOW)
415 return 1;
eb492e01 416
f1cb9af5 417 if (hcon->sec_level >= sec_level)
eb492e01 418 return 1;
f1cb9af5
VCG
419
420 authreq = seclevel_to_authreq(sec_level);
eb492e01 421
3a0259bb 422 if (hcon->link_mode & HCI_LM_MASTER) {
eb492e01 423 struct smp_cmd_pairing cp;
f01ead31 424
da85e5e5 425 build_pairing_cmd(conn, &cp, authreq);
f01ead31
AB
426 conn->preq[0] = SMP_CMD_PAIRING_REQ;
427 memcpy(&conn->preq[1], &cp, sizeof(cp));
428
5d3de7df
VCG
429 mod_timer(&conn->security_timer, jiffies +
430 msecs_to_jiffies(SMP_TIMEOUT));
431
eb492e01
AB
432 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
433 } else {
434 struct smp_cmd_security_req cp;
435 cp.auth_req = authreq;
436 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
437 }
438
f1cb9af5
VCG
439 hcon->pending_sec_level = sec_level;
440 set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
441
eb492e01
AB
442 return 0;
443}
444
445int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
446{
447 __u8 code = skb->data[0];
448 __u8 reason;
449 int err = 0;
450
3a0259bb
VCG
451 if (IS_ERR(conn->hcon->hdev->tfm)) {
452 err = PTR_ERR(conn->hcon->hdev->tfm);
453 reason = SMP_PAIRING_NOTSUPP;
454 goto done;
455 }
456
eb492e01
AB
457 skb_pull(skb, sizeof(code));
458
459 switch (code) {
460 case SMP_CMD_PAIRING_REQ:
da85e5e5 461 reason = smp_cmd_pairing_req(conn, skb);
eb492e01
AB
462 break;
463
464 case SMP_CMD_PAIRING_FAIL:
da85e5e5
VCG
465 reason = 0;
466 err = -EPERM;
eb492e01
AB
467 break;
468
469 case SMP_CMD_PAIRING_RSP:
da85e5e5 470 reason = smp_cmd_pairing_rsp(conn, skb);
88ba43b6
AB
471 break;
472
473 case SMP_CMD_SECURITY_REQ:
da85e5e5 474 reason = smp_cmd_security_req(conn, skb);
88ba43b6
AB
475 break;
476
eb492e01 477 case SMP_CMD_PAIRING_CONFIRM:
da85e5e5 478 reason = smp_cmd_pairing_confirm(conn, skb);
88ba43b6
AB
479 break;
480
eb492e01 481 case SMP_CMD_PAIRING_RANDOM:
da85e5e5 482 reason = smp_cmd_pairing_random(conn, skb);
88ba43b6
AB
483 break;
484
eb492e01
AB
485 case SMP_CMD_ENCRYPT_INFO:
486 case SMP_CMD_MASTER_IDENT:
487 case SMP_CMD_IDENT_INFO:
488 case SMP_CMD_IDENT_ADDR_INFO:
489 case SMP_CMD_SIGN_INFO:
eb492e01
AB
490 default:
491 BT_DBG("Unknown command code 0x%2.2x", code);
492
493 reason = SMP_CMD_NOTSUPP;
eb492e01 494 err = -EOPNOTSUPP;
3a0259bb 495 goto done;
eb492e01
AB
496 }
497
3a0259bb
VCG
498done:
499 if (reason)
500 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
501 &reason);
502
eb492e01
AB
503 kfree_skb(skb);
504 return err;
505}
This page took 0.060529 seconds and 5 git commands to generate.