aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-06-06 03:50:15 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-12-03 10:51:17 -0500
commit3b19146d23884172fe9d05f90924d4da3cdeb468 (patch)
treeea9dc3f80a0f25290f814218630eae05b650bfd2 /net/bluetooth/smp.c
parent05ddb47a91fa591ed25ad877783a58ae44cc8212 (diff)
Bluetooth: Add basic support for sending our LE SC public key
When the initial pairing request & response PDUs have been exchanged and both have had the LE SC bit set the next step is to generate a ECDH key pair and to send the public key to the remote side. This patch adds basic support for generating the key pair and sending the public key using the new Public Key SMP PDU. It is the initiating device that sends the public key first and the non-initiating device responds by sending its public key respectively (in a subsequent patch). 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.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 4fed367da380..9317583751eb 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -29,10 +29,14 @@
29#include <net/bluetooth/l2cap.h> 29#include <net/bluetooth/l2cap.h>
30#include <net/bluetooth/mgmt.h> 30#include <net/bluetooth/mgmt.h>
31 31
32#include "ecc.h"
32#include "smp.h" 33#include "smp.h"
33 34
34#define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd) 35#define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd)
35 36
37/* Keys which are not distributed with Secure Connections */
38#define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY);
39
36#define SMP_TIMEOUT msecs_to_jiffies(30000) 40#define SMP_TIMEOUT msecs_to_jiffies(30000)
37 41
38#define AUTH_REQ_MASK(dev) (test_bit(HCI_SC_ENABLED, &(dev)->dev_flags) ? \ 42#define AUTH_REQ_MASK(dev) (test_bit(HCI_SC_ENABLED, &(dev)->dev_flags) ? \
@@ -71,6 +75,10 @@ struct smp_chan {
71 struct smp_irk *remote_irk; 75 struct smp_irk *remote_irk;
72 unsigned long flags; 76 unsigned long flags;
73 77
78 /* Secure Connections variables */
79 u8 local_pk[64];
80 u8 local_sk[32];
81
74 struct crypto_blkcipher *tfm_aes; 82 struct crypto_blkcipher *tfm_aes;
75 struct crypto_hash *tfm_cmac; 83 struct crypto_hash *tfm_cmac;
76}; 84};
@@ -1012,7 +1020,18 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
1012 memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 1020 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1013 1021
1014 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 1022 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
1015 SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 1023
1024 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
1025
1026 if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1027 SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
1028 /* Clear bits which are generated but not distributed */
1029 smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1030 /* Wait for Public Key from Initiating Device */
1031 return 0;
1032 } else {
1033 SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
1034 }
1016 1035
1017 /* Request setup of TK */ 1036 /* Request setup of TK */
1018 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); 1037 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
@@ -1022,6 +1041,23 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
1022 return 0; 1041 return 0;
1023} 1042}
1024 1043
1044static u8 sc_send_public_key(struct smp_chan *smp)
1045{
1046 BT_DBG("");
1047
1048 /* Generate local key pair for Secure Connections */
1049 if (!ecc_make_key(smp->local_pk, smp->local_sk))
1050 return SMP_UNSPECIFIED;
1051
1052 BT_DBG("Local Public Key X: %32phN", smp->local_pk);
1053 BT_DBG("Local Public Key Y: %32phN", &smp->local_pk[32]);
1054 BT_DBG("Local Private Key: %32phN", smp->local_sk);
1055
1056 smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
1057
1058 return 0;
1059}
1060
1025static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) 1061static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
1026{ 1062{
1027 struct smp_cmd_pairing *req, *rsp = (void *) skb->data; 1063 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
@@ -1074,6 +1110,13 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
1074 */ 1110 */
1075 smp->remote_key_dist &= rsp->resp_key_dist; 1111 smp->remote_key_dist &= rsp->resp_key_dist;
1076 1112
1113 if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1114 /* Clear bits which are generated but not distributed */
1115 smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1116 SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
1117 return sc_send_public_key(smp);
1118 }
1119
1077 auth |= req->auth_req; 1120 auth |= req->auth_req;
1078 1121
1079 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); 1122 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);