diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-06-01 08:38:09 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-12-03 10:51:19 -0500 |
commit | dddd3059e3bdd02c4850b14b925b3bb37c23f248 (patch) | |
tree | af4cc385c771cb5eac511180b2dcb97ca8550cf9 /net/bluetooth | |
parent | d378a2d77618464f511d35687bbbc6614b1bacda (diff) |
Bluetooth: Add support for SC just-works pairing
If the just-works method was chosen we shouldn't send anything to user
space but simply proceed with sending the DHKey Check PDU. This patch
adds the necessary code for it.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/smp.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 30439368a55a..b6cdb553ccd3 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -1198,22 +1198,13 @@ static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16]) | |||
1198 | return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk); | 1198 | return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk); |
1199 | } | 1199 | } |
1200 | 1200 | ||
1201 | static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey) | 1201 | static void sc_dhkey_check(struct smp_chan *smp, __le32 passkey) |
1202 | { | 1202 | { |
1203 | struct hci_conn *hcon = smp->conn->hcon; | 1203 | struct hci_conn *hcon = smp->conn->hcon; |
1204 | struct smp_cmd_dhkey_check check; | 1204 | struct smp_cmd_dhkey_check check; |
1205 | u8 a[7], b[7], *local_addr, *remote_addr; | 1205 | u8 a[7], b[7], *local_addr, *remote_addr; |
1206 | u8 io_cap[3], r[16]; | 1206 | u8 io_cap[3], r[16]; |
1207 | 1207 | ||
1208 | switch (mgmt_op) { | ||
1209 | case MGMT_OP_USER_PASSKEY_NEG_REPLY: | ||
1210 | smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED); | ||
1211 | return 0; | ||
1212 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: | ||
1213 | smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED); | ||
1214 | return 0; | ||
1215 | } | ||
1216 | |||
1217 | memcpy(a, &hcon->init_addr, 6); | 1208 | memcpy(a, &hcon->init_addr, 6); |
1218 | memcpy(b, &hcon->resp_addr, 6); | 1209 | memcpy(b, &hcon->resp_addr, 6); |
1219 | a[6] = hcon->init_addr_type; | 1210 | a[6] = hcon->init_addr_type; |
@@ -1229,13 +1220,29 @@ static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey) | |||
1229 | memcpy(io_cap, &smp->prsp[1], 3); | 1220 | memcpy(io_cap, &smp->prsp[1], 3); |
1230 | } | 1221 | } |
1231 | 1222 | ||
1232 | memcpy(r, &passkey, sizeof(passkey)); | 1223 | memset(r, 0, sizeof(r)); |
1233 | memset(r + sizeof(passkey), 0, sizeof(r) - sizeof(passkey)); | 1224 | |
1225 | if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) | ||
1226 | memcpy(r, &passkey, sizeof(passkey)); | ||
1234 | 1227 | ||
1235 | smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap, | 1228 | smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap, |
1236 | local_addr, remote_addr, check.e); | 1229 | local_addr, remote_addr, check.e); |
1237 | 1230 | ||
1238 | smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check); | 1231 | smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check); |
1232 | } | ||
1233 | |||
1234 | static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey) | ||
1235 | { | ||
1236 | switch (mgmt_op) { | ||
1237 | case MGMT_OP_USER_PASSKEY_NEG_REPLY: | ||
1238 | smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED); | ||
1239 | return 0; | ||
1240 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: | ||
1241 | smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED); | ||
1242 | return 0; | ||
1243 | } | ||
1244 | |||
1245 | sc_dhkey_check(smp, passkey); | ||
1239 | 1246 | ||
1240 | return 0; | 1247 | return 0; |
1241 | } | 1248 | } |
@@ -1599,6 +1606,14 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1599 | if (err) | 1606 | if (err) |
1600 | return SMP_UNSPECIFIED; | 1607 | return SMP_UNSPECIFIED; |
1601 | 1608 | ||
1609 | if (smp->method == JUST_WORKS) { | ||
1610 | if (hcon->out) { | ||
1611 | sc_dhkey_check(smp, passkey); | ||
1612 | SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); | ||
1613 | } | ||
1614 | return 0; | ||
1615 | } | ||
1616 | |||
1602 | err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, | 1617 | err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, |
1603 | hcon->type, hcon->dst_type, | 1618 | hcon->type, hcon->dst_type, |
1604 | passkey, 0); | 1619 | passkey, 0); |