aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorAnderson Briglia <anderson.briglia@openbossa.org>2011-06-09 17:50:42 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-13 14:48:22 -0400
commit88ba43b662b6b944c6278ad81a114fa559807776 (patch)
treeefb2b03056076e797084d6cc54e5e6dd88ae694f /net/bluetooth/smp.c
parentb501d6a1dc21eb61cbbc54e40780084f5d517164 (diff)
Bluetooth: Add simple SMP pairing negotiation
This implementation only exchanges SMP messages between the Host and the Remote. No keys are being generated. TK and STK generation will be provided in further patches. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r--net/bluetooth/smp.c107
1 files changed, 102 insertions, 5 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index aa0434f4aa1a..2240e96552f1 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -64,6 +64,94 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
64 hci_send_acl(conn->hcon, skb, 0); 64 hci_send_acl(conn->hcon, skb, 0);
65} 65}
66 66
67static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
68{
69 struct smp_cmd_pairing *rp = (void *) skb->data;
70
71 BT_DBG("conn %p", conn);
72
73 skb_pull(skb, sizeof(*rp));
74
75 rp->io_capability = 0x00;
76 rp->oob_flag = 0x00;
77 rp->max_key_size = 16;
78 rp->init_key_dist = 0x00;
79 rp->resp_key_dist = 0x00;
80 rp->auth_req &= (SMP_AUTH_BONDING | SMP_AUTH_MITM);
81
82 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
83}
84
85static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
86{
87 struct smp_cmd_pairing_confirm cp;
88
89 BT_DBG("conn %p", conn);
90
91 memset(&cp, 0, sizeof(cp));
92
93 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
94}
95
96static void smp_cmd_pairing_confirm(struct l2cap_conn *conn,
97 struct sk_buff *skb)
98{
99 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
100
101 if (conn->hcon->out) {
102 struct smp_cmd_pairing_random random;
103
104 memset(&random, 0, sizeof(random));
105
106 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
107 &random);
108 } else {
109 struct smp_cmd_pairing_confirm confirm;
110
111 memset(&confirm, 0, sizeof(confirm));
112
113 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(confirm),
114 &confirm);
115 }
116}
117
118static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
119{
120 struct smp_cmd_pairing_random cp;
121
122 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
123
124 skb_pull(skb, sizeof(cp));
125
126 if (conn->hcon->out) {
127 /* FIXME: start encryption */
128 } else {
129 memset(&cp, 0, sizeof(cp));
130
131 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(cp), &cp);
132 }
133}
134
135static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
136{
137 struct smp_cmd_security_req *rp = (void *) skb->data;
138 struct smp_cmd_pairing cp;
139
140 BT_DBG("conn %p", conn);
141
142 skb_pull(skb, sizeof(*rp));
143 memset(&cp, 0, sizeof(cp));
144
145 cp.io_capability = 0x00;
146 cp.oob_flag = 0x00;
147 cp.max_key_size = 16;
148 cp.init_key_dist = 0x00;
149 cp.resp_key_dist = 0x00;
150 cp.auth_req = rp->auth_req & (SMP_AUTH_BONDING | SMP_AUTH_MITM);
151
152 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
153}
154
67int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) 155int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
68{ 156{
69 __u8 authreq; 157 __u8 authreq;
@@ -114,24 +202,33 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
114 202
115 switch (code) { 203 switch (code) {
116 case SMP_CMD_PAIRING_REQ: 204 case SMP_CMD_PAIRING_REQ:
117 reason = SMP_PAIRING_NOTSUPP; 205 smp_cmd_pairing_req(conn, skb);
118 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
119 &reason);
120 err = -EOPNOTSUPP;
121 break; 206 break;
122 207
123 case SMP_CMD_PAIRING_FAIL: 208 case SMP_CMD_PAIRING_FAIL:
124 break; 209 break;
125 210
126 case SMP_CMD_PAIRING_RSP: 211 case SMP_CMD_PAIRING_RSP:
212 smp_cmd_pairing_rsp(conn, skb);
213 break;
214
215 case SMP_CMD_SECURITY_REQ:
216 smp_cmd_security_req(conn, skb);
217 break;
218
127 case SMP_CMD_PAIRING_CONFIRM: 219 case SMP_CMD_PAIRING_CONFIRM:
220 smp_cmd_pairing_confirm(conn, skb);
221 break;
222
128 case SMP_CMD_PAIRING_RANDOM: 223 case SMP_CMD_PAIRING_RANDOM:
224 smp_cmd_pairing_random(conn, skb);
225 break;
226
129 case SMP_CMD_ENCRYPT_INFO: 227 case SMP_CMD_ENCRYPT_INFO:
130 case SMP_CMD_MASTER_IDENT: 228 case SMP_CMD_MASTER_IDENT:
131 case SMP_CMD_IDENT_INFO: 229 case SMP_CMD_IDENT_INFO:
132 case SMP_CMD_IDENT_ADDR_INFO: 230 case SMP_CMD_IDENT_ADDR_INFO:
133 case SMP_CMD_SIGN_INFO: 231 case SMP_CMD_SIGN_INFO:
134 case SMP_CMD_SECURITY_REQ:
135 default: 232 default:
136 BT_DBG("Unknown command code 0x%2.2x", code); 233 BT_DBG("Unknown command code 0x%2.2x", code);
137 234