summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-06-06 04:09:28 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-12-03 10:51:17 -0500
commitd8f8edbe93979bdf1f74cd768e68c7705806f0b9 (patch)
tree993126792ee303e7ec25bb42d4b3e976fbbc1287 /net/bluetooth/smp.c
parent3b19146d23884172fe9d05f90924d4da3cdeb468 (diff)
Bluetooth: Add handler function for receiving LE SC public key
This patch adds a handler function for the LE SC SMP Public Key PDU. When we receive the key we proceed with generating the shared DHKey value from the remote public key and local private key. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r--net/bluetooth/smp.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 9317583751eb..1cc438c9c2cb 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -50,6 +50,7 @@ enum {
50 SMP_FLAG_COMPLETE, 50 SMP_FLAG_COMPLETE,
51 SMP_FLAG_INITIATOR, 51 SMP_FLAG_INITIATOR,
52 SMP_FLAG_SC, 52 SMP_FLAG_SC,
53 SMP_FLAG_REMOTE_PK,
53}; 54};
54 55
55struct smp_chan { 56struct smp_chan {
@@ -78,6 +79,8 @@ struct smp_chan {
78 /* Secure Connections variables */ 79 /* Secure Connections variables */
79 u8 local_pk[64]; 80 u8 local_pk[64];
80 u8 local_sk[32]; 81 u8 local_sk[32];
82 u8 remote_pk[64];
83 u8 dhkey[32];
81 84
82 struct crypto_blkcipher *tfm_aes; 85 struct crypto_blkcipher *tfm_aes;
83 struct crypto_hash *tfm_cmac; 86 struct crypto_hash *tfm_cmac;
@@ -1513,6 +1516,43 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1513 return 0; 1516 return 0;
1514} 1517}
1515 1518
1519static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
1520{
1521 struct smp_cmd_public_key *key = (void *) skb->data;
1522 struct hci_conn *hcon = conn->hcon;
1523 struct l2cap_chan *chan = conn->smp;
1524 struct smp_chan *smp = chan->data;
1525 int err;
1526
1527 BT_DBG("conn %p", conn);
1528
1529 if (skb->len < sizeof(*key))
1530 return SMP_INVALID_PARAMS;
1531
1532 memcpy(smp->remote_pk, key, 64);
1533
1534 /* Non-initiating device sends its public key after receiving
1535 * the key from the initiating device.
1536 */
1537 if (!hcon->out) {
1538 err = sc_send_public_key(smp);
1539 if (err)
1540 return err;
1541 }
1542
1543 BT_DBG("Remote Public Key X: %32phN", smp->remote_pk);
1544 BT_DBG("Remote Public Key Y: %32phN", &smp->remote_pk[32]);
1545
1546 if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey))
1547 return SMP_UNSPECIFIED;
1548
1549 BT_DBG("DHKey %32phN", smp->dhkey);
1550
1551 set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
1552
1553 return 0;
1554}
1555
1516static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) 1556static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1517{ 1557{
1518 struct l2cap_conn *conn = chan->conn; 1558 struct l2cap_conn *conn = chan->conn;
@@ -1597,6 +1637,10 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1597 reason = smp_cmd_sign_info(conn, skb); 1637 reason = smp_cmd_sign_info(conn, skb);
1598 break; 1638 break;
1599 1639
1640 case SMP_CMD_PUBLIC_KEY:
1641 reason = smp_cmd_public_key(conn, skb);
1642 break;
1643
1600 default: 1644 default:
1601 BT_DBG("Unknown command code 0x%2.2x", code); 1645 BT_DBG("Unknown command code 0x%2.2x", code);
1602 reason = SMP_CMD_NOTSUPP; 1646 reason = SMP_CMD_NOTSUPP;