diff options
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r-- | net/bluetooth/smp.c | 101 |
1 files changed, 46 insertions, 55 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 4f3cde9dd1ea..6f29430c29c4 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -53,6 +53,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) | |||
53 | { | 53 | { |
54 | struct blkcipher_desc desc; | 54 | struct blkcipher_desc desc; |
55 | struct scatterlist sg; | 55 | struct scatterlist sg; |
56 | uint8_t tmp[16], data[16]; | ||
56 | int err; | 57 | int err; |
57 | 58 | ||
58 | if (tfm == NULL) { | 59 | if (tfm == NULL) { |
@@ -63,34 +64,40 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) | |||
63 | desc.tfm = tfm; | 64 | desc.tfm = tfm; |
64 | desc.flags = 0; | 65 | desc.flags = 0; |
65 | 66 | ||
66 | err = crypto_blkcipher_setkey(tfm, k, 16); | 67 | /* The most significant octet of key corresponds to k[0] */ |
68 | swap128(k, tmp); | ||
69 | |||
70 | err = crypto_blkcipher_setkey(tfm, tmp, 16); | ||
67 | if (err) { | 71 | if (err) { |
68 | BT_ERR("cipher setkey failed: %d", err); | 72 | BT_ERR("cipher setkey failed: %d", err); |
69 | return err; | 73 | return err; |
70 | } | 74 | } |
71 | 75 | ||
72 | sg_init_one(&sg, r, 16); | 76 | /* Most significant octet of plaintextData corresponds to data[0] */ |
77 | swap128(r, data); | ||
78 | |||
79 | sg_init_one(&sg, data, 16); | ||
73 | 80 | ||
74 | err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16); | 81 | err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16); |
75 | if (err) | 82 | if (err) |
76 | BT_ERR("Encrypt data error %d", err); | 83 | BT_ERR("Encrypt data error %d", err); |
77 | 84 | ||
85 | /* Most significant octet of encryptedData corresponds to data[0] */ | ||
86 | swap128(data, r); | ||
87 | |||
78 | return err; | 88 | return err; |
79 | } | 89 | } |
80 | 90 | ||
81 | static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) | 91 | static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) |
82 | { | 92 | { |
83 | u8 _res[16], k[16]; | 93 | u8 _res[16]; |
84 | int err; | 94 | int err; |
85 | 95 | ||
86 | /* r' = padding || r */ | 96 | /* r' = padding || r */ |
87 | memset(_res, 0, 13); | 97 | memcpy(_res, r, 3); |
88 | _res[13] = r[2]; | 98 | memset(_res + 3, 0, 13); |
89 | _res[14] = r[1]; | ||
90 | _res[15] = r[0]; | ||
91 | 99 | ||
92 | swap128(irk, k); | 100 | err = smp_e(tfm, irk, _res); |
93 | err = smp_e(tfm, k, _res); | ||
94 | if (err) { | 101 | if (err) { |
95 | BT_ERR("Encrypt error"); | 102 | BT_ERR("Encrypt error"); |
96 | return err; | 103 | return err; |
@@ -102,9 +109,7 @@ static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) | |||
102 | * by taking the least significant 24 bits of the output of e as the | 109 | * by taking the least significant 24 bits of the output of e as the |
103 | * result of ah. | 110 | * result of ah. |
104 | */ | 111 | */ |
105 | res[0] = _res[15]; | 112 | memcpy(res, _res, 3); |
106 | res[1] = _res[14]; | ||
107 | res[2] = _res[13]; | ||
108 | 113 | ||
109 | return 0; | 114 | return 0; |
110 | } | 115 | } |
@@ -152,16 +157,15 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16], | |||
152 | memset(p1, 0, 16); | 157 | memset(p1, 0, 16); |
153 | 158 | ||
154 | /* p1 = pres || preq || _rat || _iat */ | 159 | /* p1 = pres || preq || _rat || _iat */ |
155 | swap56(pres, p1); | 160 | p1[0] = _iat; |
156 | swap56(preq, p1 + 7); | 161 | p1[1] = _rat; |
157 | p1[14] = _rat; | 162 | memcpy(p1 + 2, preq, 7); |
158 | p1[15] = _iat; | 163 | memcpy(p1 + 9, pres, 7); |
159 | |||
160 | memset(p2, 0, 16); | ||
161 | 164 | ||
162 | /* p2 = padding || ia || ra */ | 165 | /* p2 = padding || ia || ra */ |
163 | baswap((bdaddr_t *) (p2 + 4), ia); | 166 | memcpy(p2, ra, 6); |
164 | baswap((bdaddr_t *) (p2 + 10), ra); | 167 | memcpy(p2 + 6, ia, 6); |
168 | memset(p2 + 12, 0, 4); | ||
165 | 169 | ||
166 | /* res = r XOR p1 */ | 170 | /* res = r XOR p1 */ |
167 | u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); | 171 | u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); |
@@ -190,8 +194,8 @@ static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16], | |||
190 | int err; | 194 | int err; |
191 | 195 | ||
192 | /* Just least significant octets from r1 and r2 are considered */ | 196 | /* Just least significant octets from r1 and r2 are considered */ |
193 | memcpy(_r, r1 + 8, 8); | 197 | memcpy(_r, r2, 8); |
194 | memcpy(_r + 8, r2 + 8, 8); | 198 | memcpy(_r + 8, r1, 8); |
195 | 199 | ||
196 | err = smp_e(tfm, k, _r); | 200 | err = smp_e(tfm, k, _r); |
197 | if (err) | 201 | if (err) |
@@ -405,13 +409,10 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | |||
405 | 409 | ||
406 | /* Generate random passkey. Not valid until confirmed. */ | 410 | /* Generate random passkey. Not valid until confirmed. */ |
407 | if (method == CFM_PASSKEY) { | 411 | if (method == CFM_PASSKEY) { |
408 | u8 key[16]; | 412 | memset(smp->tk, 0, sizeof(smp->tk)); |
409 | |||
410 | memset(key, 0, sizeof(key)); | ||
411 | get_random_bytes(&passkey, sizeof(passkey)); | 413 | get_random_bytes(&passkey, sizeof(passkey)); |
412 | passkey %= 1000000; | 414 | passkey %= 1000000; |
413 | put_unaligned_le32(passkey, key); | 415 | put_unaligned_le32(passkey, smp->tk); |
414 | swap128(key, smp->tk); | ||
415 | BT_DBG("PassKey: %d", passkey); | 416 | BT_DBG("PassKey: %d", passkey); |
416 | } | 417 | } |
417 | 418 | ||
@@ -438,7 +439,7 @@ static void confirm_work(struct work_struct *work) | |||
438 | struct crypto_blkcipher *tfm = hdev->tfm_aes; | 439 | struct crypto_blkcipher *tfm = hdev->tfm_aes; |
439 | struct smp_cmd_pairing_confirm cp; | 440 | struct smp_cmd_pairing_confirm cp; |
440 | int ret; | 441 | int ret; |
441 | u8 res[16], reason; | 442 | u8 reason; |
442 | 443 | ||
443 | BT_DBG("conn %p", conn); | 444 | BT_DBG("conn %p", conn); |
444 | 445 | ||
@@ -447,7 +448,8 @@ static void confirm_work(struct work_struct *work) | |||
447 | 448 | ||
448 | ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, | 449 | ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, |
449 | conn->hcon->init_addr_type, &conn->hcon->init_addr, | 450 | conn->hcon->init_addr_type, &conn->hcon->init_addr, |
450 | conn->hcon->resp_addr_type, &conn->hcon->resp_addr, res); | 451 | conn->hcon->resp_addr_type, &conn->hcon->resp_addr, |
452 | cp.confirm_val); | ||
451 | 453 | ||
452 | hci_dev_unlock(hdev); | 454 | hci_dev_unlock(hdev); |
453 | 455 | ||
@@ -458,7 +460,6 @@ static void confirm_work(struct work_struct *work) | |||
458 | 460 | ||
459 | clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); | 461 | clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); |
460 | 462 | ||
461 | swap128(res, cp.confirm_val); | ||
462 | smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); | 463 | smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); |
463 | 464 | ||
464 | return; | 465 | return; |
@@ -474,7 +475,7 @@ static void random_work(struct work_struct *work) | |||
474 | struct hci_conn *hcon = conn->hcon; | 475 | struct hci_conn *hcon = conn->hcon; |
475 | struct hci_dev *hdev = hcon->hdev; | 476 | struct hci_dev *hdev = hcon->hdev; |
476 | struct crypto_blkcipher *tfm = hdev->tfm_aes; | 477 | struct crypto_blkcipher *tfm = hdev->tfm_aes; |
477 | u8 reason, confirm[16], res[16], key[16]; | 478 | u8 reason, confirm[16]; |
478 | int ret; | 479 | int ret; |
479 | 480 | ||
480 | if (IS_ERR_OR_NULL(tfm)) { | 481 | if (IS_ERR_OR_NULL(tfm)) { |
@@ -489,7 +490,7 @@ static void random_work(struct work_struct *work) | |||
489 | 490 | ||
490 | ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, | 491 | ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, |
491 | hcon->init_addr_type, &hcon->init_addr, | 492 | hcon->init_addr_type, &hcon->init_addr, |
492 | hcon->resp_addr_type, &hcon->resp_addr, res); | 493 | hcon->resp_addr_type, &hcon->resp_addr, confirm); |
493 | 494 | ||
494 | hci_dev_unlock(hdev); | 495 | hci_dev_unlock(hdev); |
495 | 496 | ||
@@ -498,8 +499,6 @@ static void random_work(struct work_struct *work) | |||
498 | goto error; | 499 | goto error; |
499 | } | 500 | } |
500 | 501 | ||
501 | swap128(res, confirm); | ||
502 | |||
503 | if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) { | 502 | if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) { |
504 | BT_ERR("Pairing failed (confirmation values mismatch)"); | 503 | BT_ERR("Pairing failed (confirmation values mismatch)"); |
505 | reason = SMP_CONFIRM_FAILED; | 504 | reason = SMP_CONFIRM_FAILED; |
@@ -511,8 +510,7 @@ static void random_work(struct work_struct *work) | |||
511 | __le64 rand = 0; | 510 | __le64 rand = 0; |
512 | __le16 ediv = 0; | 511 | __le16 ediv = 0; |
513 | 512 | ||
514 | smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key); | 513 | smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk); |
515 | swap128(key, stk); | ||
516 | 514 | ||
517 | memset(stk + smp->enc_key_size, 0, | 515 | memset(stk + smp->enc_key_size, 0, |
518 | SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); | 516 | SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); |
@@ -525,15 +523,14 @@ static void random_work(struct work_struct *work) | |||
525 | hci_le_start_enc(hcon, ediv, rand, stk); | 523 | hci_le_start_enc(hcon, ediv, rand, stk); |
526 | hcon->enc_key_size = smp->enc_key_size; | 524 | hcon->enc_key_size = smp->enc_key_size; |
527 | } else { | 525 | } else { |
528 | u8 stk[16], r[16]; | 526 | u8 stk[16]; |
529 | __le64 rand = 0; | 527 | __le64 rand = 0; |
530 | __le16 ediv = 0; | 528 | __le16 ediv = 0; |
531 | 529 | ||
532 | swap128(smp->prnd, r); | 530 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), |
533 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r); | 531 | smp->prnd); |
534 | 532 | ||
535 | smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, key); | 533 | smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk); |
536 | swap128(key, stk); | ||
537 | 534 | ||
538 | memset(stk + smp->enc_key_size, 0, | 535 | memset(stk + smp->enc_key_size, 0, |
539 | SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); | 536 | SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); |
@@ -628,7 +625,6 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | |||
628 | struct l2cap_conn *conn = hcon->smp_conn; | 625 | struct l2cap_conn *conn = hcon->smp_conn; |
629 | struct smp_chan *smp; | 626 | struct smp_chan *smp; |
630 | u32 value; | 627 | u32 value; |
631 | u8 key[16]; | ||
632 | 628 | ||
633 | BT_DBG(""); | 629 | BT_DBG(""); |
634 | 630 | ||
@@ -640,10 +636,9 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | |||
640 | switch (mgmt_op) { | 636 | switch (mgmt_op) { |
641 | case MGMT_OP_USER_PASSKEY_REPLY: | 637 | case MGMT_OP_USER_PASSKEY_REPLY: |
642 | value = le32_to_cpu(passkey); | 638 | value = le32_to_cpu(passkey); |
643 | memset(key, 0, sizeof(key)); | 639 | memset(smp->tk, 0, sizeof(smp->tk)); |
644 | BT_DBG("PassKey: %d", value); | 640 | BT_DBG("PassKey: %d", value); |
645 | put_unaligned_le32(value, key); | 641 | put_unaligned_le32(value, smp->tk); |
646 | swap128(key, smp->tk); | ||
647 | /* Fall Through */ | 642 | /* Fall Through */ |
648 | case MGMT_OP_USER_CONFIRM_REPLY: | 643 | case MGMT_OP_USER_CONFIRM_REPLY: |
649 | set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); | 644 | set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); |
@@ -787,17 +782,13 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | |||
787 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); | 782 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); |
788 | skb_pull(skb, sizeof(smp->pcnf)); | 783 | skb_pull(skb, sizeof(smp->pcnf)); |
789 | 784 | ||
790 | if (conn->hcon->out) { | 785 | if (conn->hcon->out) |
791 | u8 random[16]; | 786 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), |
792 | 787 | smp->prnd); | |
793 | swap128(smp->prnd, random); | 788 | else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) |
794 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random), | ||
795 | random); | ||
796 | } else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) { | ||
797 | queue_work(hdev->workqueue, &smp->confirm); | 789 | queue_work(hdev->workqueue, &smp->confirm); |
798 | } else { | 790 | else |
799 | set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); | 791 | set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); |
800 | } | ||
801 | 792 | ||
802 | return 0; | 793 | return 0; |
803 | } | 794 | } |
@@ -812,7 +803,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | |||
812 | if (skb->len < sizeof(smp->rrnd)) | 803 | if (skb->len < sizeof(smp->rrnd)) |
813 | return SMP_UNSPECIFIED; | 804 | return SMP_UNSPECIFIED; |
814 | 805 | ||
815 | swap128(skb->data, smp->rrnd); | 806 | memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); |
816 | skb_pull(skb, sizeof(smp->rrnd)); | 807 | skb_pull(skb, sizeof(smp->rrnd)); |
817 | 808 | ||
818 | queue_work(hdev->workqueue, &smp->random); | 809 | queue_work(hdev->workqueue, &smp->random); |