2 * Routines for Bluetooth Security Manager Protocol dissection
4 * Copyright 2012, Allan M. Madsen <allan.m@madsen.dk>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/packet.h>
34 #include "packet-btl2cap.h"
36 /* Initialize the protocol and registered fields */
37 static int proto_btsmp
= -1;
39 static int hf_btsmp_opcode
= -1;
40 static int hf_btsmp_io_capabilities
= -1;
41 static int hf_btsmp_oob_data_flags
= -1;
42 static int hf_btsmp_reason
= -1;
43 static int hf_btsmp_cfm_value
= -1;
44 static int hf_btsmp_random
= -1;
45 static int hf_btsmp_long_term_key
= -1;
46 static int hf_btsmp_id_resolving_key
= -1;
47 static int hf_btsmp_signature_key
= -1;
48 static int hf_btsmp_bonding_flags
= -1;
49 static int hf_btsmp_mitm_flag
= -1;
50 static int hf_btsmp_max_enc_key_size
= -1;
51 static int hf_btsmp_key_dist_enc
= -1;
52 static int hf_btsmp_key_dist_id
= -1;
53 static int hf_btsmp_key_dist_sign
= -1;
54 static int hf_btsmp_ediv
= -1;
55 static int hf_btsmp_authreq
= -1;
56 static int hf_btsmp_initiator_key_distribution
= -1;
57 static int hf_btsmp_responder_key_distribution
= -1;
59 /* Initialize the subtree pointers */
60 static gint ett_btsmp
= -1;
61 static gint ett_btsmp_auth_req
= -1;
62 static gint ett_btsmp_key_dist
= -1;
65 static const value_string opcode_vals
[] = {
66 {0x01, "Pairing Request"},
67 {0x02, "Pairing Response"},
68 {0x03, "Pairing Confirm"},
69 {0x04, "Pairing Random"},
70 {0x05, "Pairing Failed"},
71 {0x06, "Encryption Information"},
72 {0x07, "Master Identification"},
73 {0x08, "Identity Information"},
74 {0x09, "Identity Address Information"},
75 {0x0a, "Signing Information"},
76 {0x0b, "Security Request"},
81 static const value_string io_capability_vals
[] = {
82 {0x00, "Display Only"},
83 {0x01, "Display Yes/No"},
84 {0x02, "Keyboard Only"},
85 {0x03, "No Input, No Output"},
86 {0x04, "Keyboard, Display"},
90 /* OOB Data present Flag */
91 static const value_string oob_data_flag_vals
[] = {
92 {0x00, "OOB Auth. Data Not Present"},
93 {0x01, "OOB Auth. Data From Remote Device Present"},
98 static const value_string bonding_flag_vals
[] = {
105 static const value_string reason_vals
[] = {
106 {0x01, "Passkey Entry Failed"},
107 {0x02, "OOB Not Available"},
108 {0x03, "Authentication Requirements"},
109 {0x04, "Confirm Value Failed"},
110 {0x05, "Pairing Not Supported"},
111 {0x06, "Encryption Key Size"},
112 {0x07, "Command Not Supported"},
113 {0x08, "Unspecified Reason"},
114 {0x09, "Repeated Attempts"},
115 {0x0a, "Invalid Parameters"},
119 void proto_register_btsmp(void);
120 void proto_reg_handoff_btsmp(void);
123 dissect_btsmp_auth_req(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
)
125 proto_item
*ti_param
;
126 proto_tree
*st_param
;
129 param
= tvb_get_guint8(tvb
, offset
);
130 ti_param
= proto_tree_add_item(tree
, hf_btsmp_authreq
, tvb
, offset
, 1, ENC_NA
);
131 st_param
= proto_item_add_subtree(ti_param
, ett_btsmp_auth_req
);
132 proto_tree_add_item(st_param
, hf_btsmp_bonding_flags
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
133 proto_item_append_text(ti_param
, "%s, ", val_to_str_const(param
& 0x03, bonding_flag_vals
, "<unknown>"));
134 proto_tree_add_item(st_param
, hf_btsmp_mitm_flag
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
135 proto_item_append_text(ti_param
, "%s", (param
& 0x04) ? "MITM" : "No MITM");
137 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s, %s", val_to_str_const(param
& 0x03, bonding_flag_vals
, "<unknown>"), (param
& 0x04) ? "MITM" : "No MITM");
143 dissect_btsmp_key_dist(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, gboolean initiator
)
145 proto_item
*ti_param
;
146 proto_tree
*st_param
;
149 param
= tvb_get_guint8(tvb
, offset
);
151 col_append_str(pinfo
->cinfo
, COL_INFO
, ", Initiator Key(s): ");
152 ti_param
= proto_tree_add_item(tree
, hf_btsmp_initiator_key_distribution
, tvb
, offset
, 1, ENC_NA
);
155 col_append_str(pinfo
->cinfo
, COL_INFO
, ", Responder Key(s): ");
156 ti_param
= proto_tree_add_item(tree
, hf_btsmp_responder_key_distribution
, tvb
, offset
, 1, ENC_NA
);
159 st_param
= proto_item_add_subtree(ti_param
, ett_btsmp_key_dist
);
160 proto_tree_add_item(st_param
, hf_btsmp_key_dist_enc
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
161 proto_tree_add_item(st_param
, hf_btsmp_key_dist_id
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
162 proto_tree_add_item(st_param
, hf_btsmp_key_dist_sign
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
164 proto_item_append_text(ti_param
, "LTK ");
165 col_append_str(pinfo
->cinfo
, COL_INFO
, "LTK ");
168 proto_item_append_text(ti_param
, "IRK ");
169 col_append_str(pinfo
->cinfo
, COL_INFO
, "IRK ");
172 proto_item_append_text(ti_param
, "CSRK ");
173 col_append_str(pinfo
->cinfo
, COL_INFO
, "CSRK ");
180 dissect_btsmp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
187 ti
= proto_tree_add_item(tree
, proto_btsmp
, tvb
, 0, -1, ENC_NA
);
188 st
= proto_item_add_subtree(ti
, ett_btsmp
);
190 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SMP");
192 switch (pinfo
->p2p_dir
) {
194 col_set_str(pinfo
->cinfo
, COL_INFO
, "Sent ");
197 col_set_str(pinfo
->cinfo
, COL_INFO
, "Rcvd ");
200 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown direction %d ",
205 if (tvb_length_remaining(tvb
, 0) < 1)
208 proto_tree_add_item(st
, hf_btsmp_opcode
, tvb
, 0, 1, ENC_LITTLE_ENDIAN
);
209 opcode
= tvb_get_guint8(tvb
, 0);
212 col_append_str(pinfo
->cinfo
, COL_INFO
, val_to_str_const(opcode
, opcode_vals
, "<unknown>"));
215 case 0x01: /* Pairing Request */
216 case 0x02: /* Pairing Response */
218 col_append_str(pinfo
->cinfo
, COL_INFO
, ": ");
220 proto_tree_add_item(st
, hf_btsmp_io_capabilities
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
222 proto_tree_add_item(st
, hf_btsmp_oob_data_flags
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
225 offset
= dissect_btsmp_auth_req(tvb
, offset
, pinfo
, st
);
227 proto_tree_add_item(st
, hf_btsmp_max_enc_key_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
230 offset
= dissect_btsmp_key_dist(tvb
, offset
, pinfo
, st
, TRUE
);
231 offset
= dissect_btsmp_key_dist(tvb
, offset
, pinfo
, st
, FALSE
);
235 case 0x03: /* Pairing Confirm */
236 proto_tree_add_item(st
, hf_btsmp_cfm_value
, tvb
, offset
, 16, ENC_NA
);
240 case 0x04: /* Pairing Random */
241 proto_tree_add_item(st
, hf_btsmp_random
, tvb
, offset
, 16, ENC_NA
);
245 case 0x05: /* Pairing Failed */
246 proto_tree_add_item(st
, hf_btsmp_reason
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
247 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ": %s", val_to_str_const(tvb_get_guint8(tvb
, offset
), reason_vals
, "<unknown>"));
251 case 0x06: /* Encryption Information */
252 proto_tree_add_item(st
, hf_btsmp_long_term_key
, tvb
, offset
, 16, ENC_NA
);
256 case 0x07: /* Master Identification */
257 proto_tree_add_item(st
, hf_btsmp_ediv
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
259 proto_tree_add_item(st
, hf_btsmp_random
, tvb
, offset
, 8, ENC_NA
);
263 case 0x08: /* Identity Information */
264 proto_tree_add_item(st
, hf_btsmp_id_resolving_key
, tvb
, offset
, 16, ENC_NA
);
268 case 0x0a: /* Signing Informationn */
269 proto_tree_add_item(st
, hf_btsmp_signature_key
, tvb
, offset
, 16, ENC_NA
);
273 case 0x0b: /* Security Request */
274 col_append_str(pinfo
->cinfo
, COL_INFO
, ": ");
275 offset
= dissect_btsmp_auth_req(tvb
, offset
, pinfo
, st
);
286 proto_register_btsmp(void)
288 static hf_register_info hf
[] = {
290 {"Opcode", "btsmp.opcode",
291 FT_UINT8
, BASE_HEX
, VALS(opcode_vals
), 0x0,
295 {"Reason", "btsmp.reason",
296 FT_UINT8
, BASE_HEX
, VALS(reason_vals
), 0x0,
299 {&hf_btsmp_io_capabilities
,
300 {"IO Capability", "btsmp.io_capability",
301 FT_UINT8
, BASE_HEX
, VALS(io_capability_vals
), 0x0,
304 {&hf_btsmp_oob_data_flags
,
305 {"OOB Data Flags", "btsmp.oob_data_flags",
306 FT_UINT8
, BASE_HEX
, VALS(oob_data_flag_vals
), 0x0,
309 {&hf_btsmp_cfm_value
,
310 {"Confirm Value", "btsmp.cfm_value",
311 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
315 {"Random Value", "btsmp.random_value",
316 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
319 {&hf_btsmp_long_term_key
,
320 {"Long Term Key", "btsmp.long_term_key",
321 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
324 {&hf_btsmp_id_resolving_key
,
325 {"Identity Resolving Key", "btsmp.id_resolving_key",
326 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
329 {&hf_btsmp_signature_key
,
330 {"Signature Key", "btsmp.signature_key",
331 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
334 {&hf_btsmp_bonding_flags
,
335 {"Bonding Flags", "btsmp.bonding_flags",
336 FT_UINT8
, BASE_HEX
, VALS(bonding_flag_vals
), 0x03,
339 {&hf_btsmp_mitm_flag
,
340 {"MITM Flag", "btsmp.mitm_flag",
341 FT_UINT8
, BASE_DEC
, NULL
, 0x04,
344 {&hf_btsmp_max_enc_key_size
,
345 {"Max Encryption Key Size", "btsmp.max_enc_key_size",
346 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
349 {&hf_btsmp_key_dist_enc
,
350 {"Encryption Key (LTK)", "btsmp.key_dist_enc",
351 FT_UINT8
, BASE_DEC
, NULL
, 0x01,
354 {&hf_btsmp_key_dist_id
,
355 {"Id Key (IRK)", "btsmp.key_dist_id",
356 FT_UINT8
, BASE_DEC
, NULL
, 0x02,
359 {&hf_btsmp_key_dist_sign
,
360 {"Signature Key (CSRK)", "btsmp.key_dist_sign",
361 FT_UINT8
, BASE_DEC
, NULL
, 0x04,
365 {"Encrypted Diversifier (EDIV)", "btsmp.ediv",
366 FT_UINT16
, BASE_HEX
, NULL
, 0x00,
370 {"AuthReq", "btsmp.authreq",
371 FT_NONE
, BASE_NONE
, NULL
, 0x00,
374 {&hf_btsmp_initiator_key_distribution
,
375 {"Initiator Key Distribution", "btsmp.initiator_key_distribution",
376 FT_NONE
, BASE_NONE
, NULL
, 0x00,
379 {&hf_btsmp_responder_key_distribution
,
380 {"Responder Key Distribution", "btsmp.responder_key_distribution",
381 FT_NONE
, BASE_NONE
, NULL
, 0x00,
386 /* Setup protocol subtree array */
387 static gint
*ett
[] = {
393 /* Register the protocol name and description */
394 proto_btsmp
= proto_register_protocol("Bluetooth Security Manager Protocol",
397 new_register_dissector("btsmp", dissect_btsmp
, proto_btsmp
);
399 /* Required function calls to register the header fields and subtrees used */
400 proto_register_field_array(proto_btsmp
, hf
, array_length(hf
));
401 proto_register_subtree_array(ett
, array_length(ett
));
405 proto_reg_handoff_btsmp(void)
407 dissector_handle_t btsmp_handle
;
409 btsmp_handle
= find_dissector("btsmp");
410 dissector_add_uint("btl2cap.cid", BTL2CAP_FIXED_CID_SMP
, btsmp_handle
);
414 * Editor modelines - http://www.wireshark.org/tools/modelines.html
419 * indent-tabs-mode: nil
422 * vi: set shiftwidth=4 tabstop=8 expandtab:
423 * :indentSize=4:tabSize=8:noTabs=true: