aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2011-06-09 17:50:53 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-13 15:05:37 -0400
commitda85e5e5afeb72bb6e6b5192a2d252861fafc3e7 (patch)
tree36fb5b1db3da5984f6ae45ce0b406f41b1a85ed2 /net/bluetooth/smp.c
parentb8e66eacab21870d4f800822111c494f9ef291e3 (diff)
Bluetooth: Add support for Pairing features exchange
This patch implements a simple version of the SMP Pairing Features exchange procedure (Vol. 3 Part H, Section 2.3.5.1). For now, everything that would cause a Pairing Method different of Just Works to be chosen is rejected. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r--net/bluetooth/smp.c106
1 files changed, 53 insertions, 53 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index d29700de5a44..dfd6891b9c86 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -181,6 +181,18 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
181 hci_send_acl(conn->hcon, skb, 0); 181 hci_send_acl(conn->hcon, skb, 0);
182} 182}
183 183
184static __u8 seclevel_to_authreq(__u8 level)
185{
186 switch (level) {
187 case BT_SECURITY_HIGH:
188 /* Right now we don't support bonding */
189 return SMP_AUTH_MITM;
190
191 default:
192 return SMP_AUTH_NONE;
193 }
194}
195
184static void build_pairing_cmd(struct l2cap_conn *conn, 196static void build_pairing_cmd(struct l2cap_conn *conn,
185 struct smp_cmd_pairing *cmd, __u8 authreq) 197 struct smp_cmd_pairing *cmd, __u8 authreq)
186{ 198{
@@ -192,7 +204,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
192 cmd->auth_req = authreq; 204 cmd->auth_req = authreq;
193} 205}
194 206
195static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) 207static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
196{ 208{
197 struct smp_cmd_pairing *rp = (void *) skb->data; 209 struct smp_cmd_pairing *rp = (void *) skb->data;
198 210
@@ -202,12 +214,11 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
202 memcpy(&conn->preq[1], rp, sizeof(*rp)); 214 memcpy(&conn->preq[1], rp, sizeof(*rp));
203 skb_pull(skb, sizeof(*rp)); 215 skb_pull(skb, sizeof(*rp));
204 216
205 rp->io_capability = 0x00; 217 if (rp->oob_flag)
206 rp->oob_flag = 0x00; 218 return SMP_OOB_NOT_AVAIL;
207 rp->max_key_size = 16; 219
208 rp->init_key_dist = 0x00; 220 /* We didn't start the pairing, so no requirements */
209 rp->resp_key_dist = 0x00; 221 build_pairing_cmd(conn, rp, SMP_AUTH_NONE);
210 rp->auth_req &= (SMP_AUTH_BONDING | SMP_AUTH_MITM);
211 222
212 /* Just works */ 223 /* Just works */
213 memset(conn->tk, 0, sizeof(conn->tk)); 224 memset(conn->tk, 0, sizeof(conn->tk));
@@ -216,9 +227,11 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
216 memcpy(&conn->prsp[1], rp, sizeof(*rp)); 227 memcpy(&conn->prsp[1], rp, sizeof(*rp));
217 228
218 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp); 229 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
230
231 return 0;
219} 232}
220 233
221static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) 234static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
222{ 235{
223 struct smp_cmd_pairing *rp = (void *) skb->data; 236 struct smp_cmd_pairing *rp = (void *) skb->data;
224 struct smp_cmd_pairing_confirm cp; 237 struct smp_cmd_pairing_confirm cp;
@@ -228,29 +241,34 @@ static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
228 241
229 BT_DBG("conn %p", conn); 242 BT_DBG("conn %p", conn);
230 243
244 skb_pull(skb, sizeof(*rp));
245
246 if (rp->oob_flag)
247 return SMP_OOB_NOT_AVAIL;
248
231 /* Just works */ 249 /* Just works */
232 memset(conn->tk, 0, sizeof(conn->tk)); 250 memset(conn->tk, 0, sizeof(conn->tk));
233 251
234 conn->prsp[0] = SMP_CMD_PAIRING_RSP; 252 conn->prsp[0] = SMP_CMD_PAIRING_RSP;
235 memcpy(&conn->prsp[1], rp, sizeof(*rp)); 253 memcpy(&conn->prsp[1], rp, sizeof(*rp));
236 skb_pull(skb, sizeof(*rp));
237 254
238 ret = smp_rand(conn->prnd); 255 ret = smp_rand(conn->prnd);
239 if (ret) 256 if (ret)
240 return; 257 return SMP_UNSPECIFIED;
241 258
242 ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0, 259 ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0,
243 conn->src, conn->hcon->dst_type, conn->dst, res); 260 conn->src, conn->hcon->dst_type, conn->dst, res);
244 if (ret) 261 if (ret)
245 return; 262 return SMP_UNSPECIFIED;
246 263
247 swap128(res, cp.confirm_val); 264 swap128(res, cp.confirm_val);
248 265
249 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); 266 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
267
268 return 0;
250} 269}
251 270
252static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, 271static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
253 struct sk_buff *skb)
254{ 272{
255 struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm; 273 struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
256 274
@@ -272,21 +290,23 @@ static void smp_cmd_pairing_confirm(struct l2cap_conn *conn,
272 290
273 ret = smp_rand(conn->prnd); 291 ret = smp_rand(conn->prnd);
274 if (ret) 292 if (ret)
275 return; 293 return SMP_UNSPECIFIED;
276 294
277 ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 295 ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp,
278 conn->hcon->dst_type, conn->dst, 296 conn->hcon->dst_type, conn->dst,
279 0, conn->src, res); 297 0, conn->src, res);
280 if (ret) 298 if (ret)
281 return; 299 return SMP_CONFIRM_FAILED;
282 300
283 swap128(res, cp.confirm_val); 301 swap128(res, cp.confirm_val);
284 302
285 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); 303 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
286 } 304 }
305
306 return 0;
287} 307}
288 308
289static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) 309static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
290{ 310{
291 struct hci_conn *hcon = conn->hcon; 311 struct hci_conn *hcon = conn->hcon;
292 struct crypto_blkcipher *tfm = hcon->hdev->tfm; 312 struct crypto_blkcipher *tfm = hcon->hdev->tfm;
@@ -307,19 +327,15 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
307 conn->hcon->dst_type, conn->dst, 0, conn->src, 327 conn->hcon->dst_type, conn->dst, 0, conn->src,
308 res); 328 res);
309 if (ret) 329 if (ret)
310 return; 330 return SMP_UNSPECIFIED;
311 331
312 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 332 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
313 333
314 swap128(res, confirm); 334 swap128(res, confirm);
315 335
316 if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf)) != 0) { 336 if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf)) != 0) {
317 struct smp_cmd_pairing_fail cp;
318
319 BT_ERR("Pairing failed (confirmation values mismatch)"); 337 BT_ERR("Pairing failed (confirmation values mismatch)");
320 cp.reason = SMP_CONFIRM_FAILED; 338 return SMP_CONFIRM_FAILED;
321 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(cp), &cp);
322 return;
323 } 339 }
324 340
325 if (conn->hcon->out) { 341 if (conn->hcon->out) {
@@ -341,9 +357,11 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
341 smp_s1(tfm, conn->tk, conn->prnd, random, key); 357 smp_s1(tfm, conn->tk, conn->prnd, random, key);
342 swap128(key, hcon->ltk); 358 swap128(key, hcon->ltk);
343 } 359 }
360
361 return 0;
344} 362}
345 363
346static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) 364static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
347{ 365{
348 struct smp_cmd_security_req *rp = (void *) skb->data; 366 struct smp_cmd_security_req *rp = (void *) skb->data;
349 struct smp_cmd_pairing cp; 367 struct smp_cmd_pairing cp;
@@ -352,17 +370,12 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
352 BT_DBG("conn %p", conn); 370 BT_DBG("conn %p", conn);
353 371
354 if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) 372 if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
355 return; 373 return 0;
356 374
357 skb_pull(skb, sizeof(*rp)); 375 skb_pull(skb, sizeof(*rp));
358 memset(&cp, 0, sizeof(cp));
359 376
360 cp.io_capability = 0x00; 377 memset(&cp, 0, sizeof(cp));
361 cp.oob_flag = 0x00; 378 build_pairing_cmd(conn, &cp, rp->auth_req);
362 cp.max_key_size = 16;
363 cp.init_key_dist = 0x00;
364 cp.resp_key_dist = 0x00;
365 cp.auth_req = rp->auth_req & (SMP_AUTH_BONDING | SMP_AUTH_MITM);
366 379
367 conn->preq[0] = SMP_CMD_PAIRING_REQ; 380 conn->preq[0] = SMP_CMD_PAIRING_REQ;
368 memcpy(&conn->preq[1], &cp, sizeof(cp)); 381 memcpy(&conn->preq[1], &cp, sizeof(cp));
@@ -370,18 +383,8 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
370 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 383 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
371 384
372 set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend); 385 set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
373}
374 386
375static __u8 seclevel_to_authreq(__u8 level) 387 return 0;
376{
377 switch (level) {
378 case BT_SECURITY_HIGH:
379 /* For now we don't support bonding */
380 return SMP_AUTH_MITM;
381
382 default:
383 return SMP_AUTH_NONE;
384 }
385} 388}
386 389
387int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) 390int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
@@ -407,13 +410,8 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
407 410
408 if (hcon->link_mode & HCI_LM_MASTER) { 411 if (hcon->link_mode & HCI_LM_MASTER) {
409 struct smp_cmd_pairing cp; 412 struct smp_cmd_pairing cp;
410 cp.io_capability = 0x00;
411 cp.oob_flag = 0x00;
412 cp.max_key_size = 16;
413 cp.init_key_dist = 0x00;
414 cp.resp_key_dist = 0x00;
415 cp.auth_req = authreq;
416 413
414 build_pairing_cmd(conn, &cp, authreq);
417 conn->preq[0] = SMP_CMD_PAIRING_REQ; 415 conn->preq[0] = SMP_CMD_PAIRING_REQ;
418 memcpy(&conn->preq[1], &cp, sizeof(cp)); 416 memcpy(&conn->preq[1], &cp, sizeof(cp));
419 417
@@ -446,26 +444,28 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
446 444
447 switch (code) { 445 switch (code) {
448 case SMP_CMD_PAIRING_REQ: 446 case SMP_CMD_PAIRING_REQ:
449 smp_cmd_pairing_req(conn, skb); 447 reason = smp_cmd_pairing_req(conn, skb);
450 break; 448 break;
451 449
452 case SMP_CMD_PAIRING_FAIL: 450 case SMP_CMD_PAIRING_FAIL:
451 reason = 0;
452 err = -EPERM;
453 break; 453 break;
454 454
455 case SMP_CMD_PAIRING_RSP: 455 case SMP_CMD_PAIRING_RSP:
456 smp_cmd_pairing_rsp(conn, skb); 456 reason = smp_cmd_pairing_rsp(conn, skb);
457 break; 457 break;
458 458
459 case SMP_CMD_SECURITY_REQ: 459 case SMP_CMD_SECURITY_REQ:
460 smp_cmd_security_req(conn, skb); 460 reason = smp_cmd_security_req(conn, skb);
461 break; 461 break;
462 462
463 case SMP_CMD_PAIRING_CONFIRM: 463 case SMP_CMD_PAIRING_CONFIRM:
464 smp_cmd_pairing_confirm(conn, skb); 464 reason = smp_cmd_pairing_confirm(conn, skb);
465 break; 465 break;
466 466
467 case SMP_CMD_PAIRING_RANDOM: 467 case SMP_CMD_PAIRING_RANDOM:
468 smp_cmd_pairing_random(conn, skb); 468 reason = smp_cmd_pairing_random(conn, skb);
469 break; 469 break;
470 470
471 case SMP_CMD_ENCRYPT_INFO: 471 case SMP_CMD_ENCRYPT_INFO: