aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-06-06 04:47:30 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-12-03 10:51:17 -0500
commit6433a9a2c47e5b3ddfdb86ee5b57a6eada1f6da7 (patch)
tree4ec2bbc39d3d19ccae0650438dfa9eeef1e34a2e /net
parent760b018b6cf08ee16fed37249a0a0d52d930c356 (diff)
Bluetooth: Add support for LE SC DHKey check PDU
Once we receive the DHKey check PDU it's time to first verify that the value is correct and then proceed with encrypting the link. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/smp.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b12f076d78b1..f59f0510e0b0 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1894,6 +1894,58 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
1894 return 0; 1894 return 0;
1895} 1895}
1896 1896
1897static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
1898{
1899 struct smp_cmd_dhkey_check *check = (void *) skb->data;
1900 struct l2cap_chan *chan = conn->smp;
1901 struct hci_conn *hcon = conn->hcon;
1902 struct smp_chan *smp = chan->data;
1903 u8 a[7], b[7], *local_addr, *remote_addr;
1904 u8 io_cap[3], r[16], e[16];
1905 int err;
1906
1907 BT_DBG("conn %p", conn);
1908
1909 if (skb->len < sizeof(*check))
1910 return SMP_INVALID_PARAMS;
1911
1912 memcpy(a, &hcon->init_addr, 6);
1913 memcpy(b, &hcon->resp_addr, 6);
1914 a[6] = hcon->init_addr_type;
1915 b[6] = hcon->resp_addr_type;
1916
1917 if (hcon->out) {
1918 local_addr = a;
1919 remote_addr = b;
1920 memcpy(io_cap, &smp->prsp[1], 3);
1921 } else {
1922 local_addr = b;
1923 remote_addr = a;
1924 memcpy(io_cap, &smp->preq[1], 3);
1925 }
1926
1927 memset(r, 0, sizeof(r));
1928
1929 err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r,
1930 io_cap, remote_addr, local_addr, e);
1931 if (err)
1932 return SMP_UNSPECIFIED;
1933
1934 if (memcmp(check->e, e, 16))
1935 return SMP_DHKEY_CHECK_FAILED;
1936
1937 smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
1938 SMP_LTK_P256, 0, smp->tk, smp->enc_key_size,
1939 0, 0);
1940
1941 if (hcon->out) {
1942 hci_le_start_enc(hcon, 0, 0, smp->tk);
1943 hcon->enc_key_size = smp->enc_key_size;
1944 }
1945
1946 return 0;
1947}
1948
1897static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) 1949static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1898{ 1950{
1899 struct l2cap_conn *conn = chan->conn; 1951 struct l2cap_conn *conn = chan->conn;
@@ -1982,6 +2034,10 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1982 reason = smp_cmd_public_key(conn, skb); 2034 reason = smp_cmd_public_key(conn, skb);
1983 break; 2035 break;
1984 2036
2037 case SMP_CMD_DHKEY_CHECK:
2038 reason = smp_cmd_dhkey_check(conn, skb);
2039 break;
2040
1985 default: 2041 default:
1986 BT_DBG("Unknown command code 0x%2.2x", code); 2042 BT_DBG("Unknown command code 0x%2.2x", code);
1987 reason = SMP_CMD_NOTSUPP; 2043 reason = SMP_CMD_NOTSUPP;