aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/smp.h17
-rw-r--r--net/bluetooth/smp.c107
2 files changed, 119 insertions, 5 deletions
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 36bdd6eb6aa7..111853ab239a 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -38,6 +38,23 @@ struct smp_cmd_pairing {
38 __u8 resp_key_dist; 38 __u8 resp_key_dist;
39} __packed; 39} __packed;
40 40
41#define SMP_IO_DISPLAY_ONLY 0x00
42#define SMP_IO_DISPLAY_YESNO 0x01
43#define SMP_IO_KEYBOARD_ONLY 0x02
44#define SMP_IO_NO_INPUT_OUTPUT 0x03
45#define SMP_IO_KEYBOARD_DISPLAY 0x04
46
47#define SMP_OOB_NOT_PRESENT 0x00
48#define SMP_OOB_PRESENT 0x01
49
50#define SMP_DIST_ENC_KEY 0x01
51#define SMP_DIST_ID_KEY 0x02
52#define SMP_DIST_SIGN 0x04
53
54#define SMP_AUTH_NONE 0x00
55#define SMP_AUTH_BONDING 0x01
56#define SMP_AUTH_MITM 0x04
57
41#define SMP_CMD_PAIRING_CONFIRM 0x03 58#define SMP_CMD_PAIRING_CONFIRM 0x03
42struct smp_cmd_pairing_confirm { 59struct smp_cmd_pairing_confirm {
43 __u8 confirm_val[16]; 60 __u8 confirm_val[16];
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