2 * Routines for zrtp packet dissection
3 * IETF draft draft-zimmermann-avt-zrtp-15x
4 * Copyright 2007, Sagar Pai <sagar@gmail.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * Copied from packet-pop.c
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 #include <epan/packet.h>
38 #include <epan/strutil.h>
39 #include <epan/crc32.h>
44 static int proto_zrtp = -1;
45 static int hf_zrtp_rtpversion = -1;
46 static int hf_zrtp_rtppadding = -1;
47 static int hf_zrtp_rtpextension = -1;
48 static int hf_zrtp_id = -1;
49 static int hf_zrtp_sequence = -1;
50 static int hf_zrtp_cookie = -1;
51 static int hf_zrtp_source_id = -1;
56 static int hf_zrtp_signature = -1;
57 static int hf_zrtp_msg_length = -1;
58 static int hf_zrtp_msg_type = -1;
59 static int hf_zrtp_msg_version = -1;
64 static int hf_zrtp_msg_client_id = -1;
65 static int hf_zrtp_msg_zid = -1;
66 static int hf_zrtp_msg_mitm = -1;
67 static int hf_zrtp_msg_passive = -1;
68 static int hf_zrtp_msg_hash_count = -1;
69 static int hf_zrtp_msg_cipher_count = -1;
70 static int hf_zrtp_msg_authtag_count = -1;
71 static int hf_zrtp_msg_key_count = -1;
72 static int hf_zrtp_msg_sas_count = -1;
73 static int hf_zrtp_msg_hash = -1;
74 static int hf_zrtp_msg_cipher = -1;
75 static int hf_zrtp_msg_at = -1;
76 static int hf_zrtp_msg_keya = -1;
77 static int hf_zrtp_msg_sas = -1;
78 static int hf_zrtp_msg_hash_image = -1;
83 static int hf_zrtp_msg_hvi = -1;
84 static int hf_zrtp_msg_nonce = -1;
85 static int hf_zrtp_msg_key_id = -1;
90 static int hf_zrtp_msg_rs1ID = -1;
91 static int hf_zrtp_msg_rs2ID = -1;
92 static int hf_zrtp_msg_auxs = -1;
93 static int hf_zrtp_msg_pbxs = -1;
98 static int hf_zrtp_msg_hmac = -1;
99 static int hf_zrtp_msg_cfb = -1;
104 static int hf_zrtp_msg_error = -1;
109 static int hf_zrtp_msg_ping_version = -1;
110 static int hf_zrtp_msg_ping_endpointhash = -1;
111 static int hf_zrtp_msg_pingack_endpointhash = -1;
112 static int hf_zrtp_msg_ping_ssrc = -1;
117 static int hf_zrtp_checksum = -1;
118 static int hf_zrtp_checksum_good = -1;
119 static int hf_zrtp_checksum_bad = -1;
124 static gint ett_zrtp = -1;
125 static gint ett_zrtp_msg = -1;
126 static gint ett_zrtp_msg_data = -1;
128 static gint ett_zrtp_msg_encrypted = -1;
129 static gint ett_zrtp_msg_pvr = -1;
130 static gint ett_zrtp_msg_hc = -1;
131 static gint ett_zrtp_msg_kc = -1;
132 static gint ett_zrtp_msg_ac = -1;
133 static gint ett_zrtp_msg_cc = -1;
134 static gint ett_zrtp_msg_sc = -1;
136 static gint ett_zrtp_checksum = -1;
141 #define ZRTP_ERR_10 0x10
142 #define ZRTP_ERR_20 0x20
143 #define ZRTP_ERR_30 0x30
144 #define ZRTP_ERR_40 0x40
145 #define ZRTP_ERR_51 0x51
146 #define ZRTP_ERR_52 0x52
147 #define ZRTP_ERR_53 0x53
148 #define ZRTP_ERR_54 0x54
149 #define ZRTP_ERR_55 0x55
150 #define ZRTP_ERR_56 0x56
151 #define ZRTP_ERR_61 0x61
152 #define ZRTP_ERR_62 0x62
153 #define ZRTP_ERR_63 0x63
154 #define ZRTP_ERR_70 0x70
155 #define ZRTP_ERR_80 0x80
156 #define ZRTP_ERR_90 0x90
157 #define ZRTP_ERR_A0 0xA0
158 #define ZRTP_ERR_100 0x100
163 typedef struct _value_zrtp_versions {
164 const gchar *version;
165 } value_zrtp_versions;
168 typedef struct _value_string_keyval {
171 } value_string_keyval;
174 const value_zrtp_versions valid_zrtp_versions[]=
184 const value_string_keyval zrtp_hash_type_vals[] =
186 { "S256", "SHA-256 Hash"},
190 const value_string_keyval zrtp_cipher_type_vals[] =
192 { "AES1", "AES-CM with 128 bit keys"},
193 { "AES2", "AES-CM with 192 bit keys"},
194 { "AES3", "AES-CM with 256 bit keys"},
195 { "2FS1", "TwoFish with 128 bit keys"},
196 { "2FS2", "TwoFish with 192 bit keys"},
197 { "2FS3", "TwoFish with 256 bit keys"},
198 { "CAM1", "Camellia with 128 bit keys"},
199 { "CAM2", "Camellia with 192 bit keys"},
200 { "CAM3", "Camellia with 256 bit keys"},
204 const value_string_keyval zrtp_auth_tag_vals[] =
206 { "HS32", "HMAC-SHA1 32 bit authentication tag"},
207 { "HS80", "HMAC-SHA1 80 bit authentication tag"},
211 const value_string_keyval zrtp_sas_type_vals[] =
213 { "B32 ", "Short authentication string using base 32"},
214 { "B256", "Short authentication string using base 256"},
218 const value_string_keyval zrtp_key_agreement_vals[] =
220 { "DH2k", "DH mode with p=2048 bit prime"},
221 { "DH3k", "DH mode with p=3072 bit prime"},
222 { "DH4k", "DH mode with p=4096 bit prime"},
223 { "Prsh", "Preshared non-DH mode using shared secret"},
224 { "EC25", "Elliptic Curve DH-256"},
225 { "EC38", "Elliptic Curve DH-384"},
226 { "EC52", "Elliptic Curve DH-521"},
227 { "Mult", "Multistream mode"},
231 const value_string zrtp_error_vals[] =
233 { ZRTP_ERR_10, "Malformed Packet (CRC OK but wrong structure)"},
234 { ZRTP_ERR_20, "Critical Software Error"},
235 { ZRTP_ERR_30, "Unsupported ZRTP version"},
236 { ZRTP_ERR_40, "Hello Components mismatch"},
237 { ZRTP_ERR_51, "Hash type unsupported"},
238 { ZRTP_ERR_52, "Cipher type not supported"},
239 { ZRTP_ERR_53, "Public key exchange not supported"},
240 { ZRTP_ERR_54, "SRTP auth. tag not supported"},
241 { ZRTP_ERR_55, "SAS scheme not supported"},
242 { ZRTP_ERR_56, "No shared secret available, DH mode required"},
243 { ZRTP_ERR_61, "DH Error: bad pv for initiator/responder value is (1,0,p-1)"},
244 { ZRTP_ERR_62, "DH Error: bad hash commitment (hvi != hashed data)"},
245 { ZRTP_ERR_63, "Received relayed SAS from untrusted MiTM"},
246 { ZRTP_ERR_70, "Auth. Error Bad Confirm Packet HMAC"},
247 { ZRTP_ERR_80, "Nonce is reused"},
248 { ZRTP_ERR_90, "Equal ZID's in Hello"},
249 { ZRTP_ERR_A0, "Service unavailable"},
250 { ZRTP_ERR_100, "GoClear packet received, but not allowed"},
255 dissect_Hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
257 dissect_ErrorACK(packet_info *pinfo);
259 dissect_Commit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
261 dissect_ClearACK( packet_info *pinfo);
263 dissect_Conf2ACK(packet_info *pinfo);
265 dissect_HelloACK( packet_info *pinfo);
267 dissect_GoClear(tvbuff_t *tvb,packet_info *pinfo, proto_tree *zrtp_tree);
269 dissect_Error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
271 dissect_Confirm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree,int part);
273 dissect_DHPart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree,int part);
275 dissect_SASrelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
277 dissect_RelayACK(packet_info *pinfo);
279 dissect_Ping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
281 dissect_PingACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
285 key_to_val(const gchar *key, int keylen, const value_string_keyval *kv, const gchar *fmt){
288 if (!strncmp(kv[i].key, key, keylen)){
293 return ep_strdup_printf(fmt, key);
297 check_valid_version(const gchar *version){
299 int match_size = (version[0] == '0') ? 4 : 3;
300 while (valid_zrtp_versions[i].version) {
301 if (!strncmp(valid_zrtp_versions[i].version, version, match_size)){
302 return(valid_zrtp_versions[i].version);
311 dissect_zrtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
313 proto_tree *zrtp_tree;
314 proto_tree *zrtp_msg_tree;
315 proto_tree *zrtp_msg_data_tree;
316 proto_tree *checksum_tree;
320 unsigned char message_type[9];
321 unsigned int prime_offset = 0;
322 unsigned int msg_offset = 12;
323 guint32 sent_crc, calc_crc;
325 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZRTP");
327 if (check_col(pinfo->cinfo, COL_INFO))
328 col_set_str(pinfo->cinfo, COL_INFO, "Unknown ZRTP Packet");
330 ti = proto_tree_add_protocol_format(tree,proto_zrtp,tvb,0,-1,"ZRTP protocol");
331 zrtp_tree = proto_item_add_subtree(ti,ett_zrtp);
333 proto_tree_add_item(zrtp_tree,hf_zrtp_rtpversion,tvb,prime_offset+0,1,FALSE);
334 proto_tree_add_item(zrtp_tree,hf_zrtp_rtppadding,tvb,prime_offset+0,1,FALSE);
335 proto_tree_add_item(zrtp_tree,hf_zrtp_rtpextension,tvb,prime_offset+0,1,FALSE);
337 proto_tree_add_item(zrtp_tree,hf_zrtp_sequence,tvb,prime_offset+2,2,FALSE);
339 proto_tree_add_item(zrtp_tree,hf_zrtp_cookie,tvb,prime_offset+4,4,FALSE);
341 proto_tree_add_item(zrtp_tree,hf_zrtp_source_id,tvb,prime_offset+8,4,FALSE);
343 linelen = tvb_reported_length_remaining(tvb,msg_offset);
344 checksum_offset = linelen-4;
346 ti = proto_tree_add_protocol_format(zrtp_tree,proto_zrtp,tvb,msg_offset,linelen-4,"Message");
347 zrtp_msg_tree = proto_item_add_subtree(ti,ett_zrtp_msg);
349 proto_tree_add_item(zrtp_msg_tree,hf_zrtp_signature,tvb,msg_offset+0,2,FALSE);
351 proto_tree_add_item(zrtp_msg_tree,hf_zrtp_msg_length,tvb,msg_offset+2,2,FALSE);
353 tvb_memcpy(tvb,(void *)message_type,msg_offset+4,8);
354 message_type[8] = '\0';
355 proto_tree_add_item(zrtp_msg_tree,hf_zrtp_msg_type,tvb,msg_offset+4,8,FALSE);
357 linelen = tvb_reported_length_remaining(tvb,msg_offset+12);
359 if (!strncmp(message_type,"Hello ",8)){
360 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
361 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
362 dissect_Hello(tvb,pinfo,zrtp_msg_data_tree);
363 } else if (!strncmp(message_type,"HelloACK",8)){
364 dissect_HelloACK(pinfo);
365 } else if (!strncmp(message_type,"Commit ",8)){
366 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
367 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
368 dissect_Commit(tvb,pinfo,zrtp_msg_data_tree);
369 } else if (!strncmp(message_type,"DHPart1 ",8)){
370 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
371 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
372 dissect_DHPart(tvb,pinfo,zrtp_msg_data_tree,1);
373 } else if (!strncmp(message_type,"DHPart2 ",8)){
374 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
375 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
376 dissect_DHPart(tvb,pinfo,zrtp_msg_data_tree,2);
377 } else if (!strncmp(message_type,"Confirm1",8)){
378 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
379 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
380 dissect_Confirm(tvb,pinfo,zrtp_msg_data_tree,1);
381 } else if (!strncmp(message_type,"Confirm2",8)){
382 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
383 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
384 dissect_Confirm(tvb,pinfo,zrtp_msg_data_tree,2);
385 } else if (!strncmp(message_type,"Conf2ACK",8)){
386 dissect_Conf2ACK(pinfo);
387 } else if (!strncmp(message_type,"Error ",8)){
388 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
389 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
390 dissect_Error(tvb,pinfo,zrtp_msg_data_tree);
391 } else if (!strncmp(message_type,"ErrorACK",8)){
392 dissect_ErrorACK(pinfo);
393 } else if (!strncmp(message_type,"GoClear ",8)){
394 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
395 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
396 dissect_GoClear(tvb,pinfo,zrtp_msg_data_tree);
397 } else if (!strncmp(message_type,"ClearACK",8)){
398 dissect_ClearACK(pinfo);
399 } else if (!strncmp(message_type,"SASrelay",8)){
400 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
401 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
402 dissect_SASrelay(tvb,pinfo,zrtp_msg_data_tree);
403 } else if (!strncmp(message_type,"RelayACK",8)){
404 dissect_RelayACK(pinfo);
405 } else if (!strncmp(message_type,"Ping ",8)){
406 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
407 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
408 dissect_Ping(tvb,pinfo,zrtp_msg_data_tree);
409 } else if (!strncmp(message_type,"PingACK ",8)){
410 ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data");
411 zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data);
412 dissect_PingACK(tvb,pinfo,zrtp_msg_data_tree);
415 sent_crc = tvb_get_ntohl(tvb,msg_offset+checksum_offset);
416 calc_crc = ~crc32c_calculate(tvb_get_ptr(tvb,0,msg_offset+checksum_offset),msg_offset+checksum_offset,CRC32C_PRELOAD);
418 if (sent_crc == calc_crc) {
419 ti = proto_tree_add_uint_format_value(zrtp_tree, hf_zrtp_checksum, tvb, msg_offset+checksum_offset, 4, sent_crc,
420 "0x%04x [correct]", sent_crc);
421 checksum_tree = proto_item_add_subtree(ti, ett_zrtp_checksum);
422 ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_good, tvb, msg_offset+checksum_offset, 4, TRUE);
423 PROTO_ITEM_SET_GENERATED(ti);
424 ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_bad, tvb, msg_offset+checksum_offset, 4, FALSE);
425 PROTO_ITEM_SET_GENERATED(ti);
427 ti = proto_tree_add_uint_format_value(zrtp_tree, hf_zrtp_checksum, tvb, msg_offset+checksum_offset, 4, sent_crc,
428 "0x%04x [incorrect, should be 0x%04x]", sent_crc, calc_crc);
429 checksum_tree = proto_item_add_subtree(ti, ett_zrtp_checksum);
430 ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_good, tvb, msg_offset+checksum_offset, 4, FALSE);
431 PROTO_ITEM_SET_GENERATED(ti);
432 ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_bad, tvb, msg_offset+checksum_offset, 4, TRUE);
433 PROTO_ITEM_SET_GENERATED(ti);
439 dissect_ErrorACK(packet_info *pinfo) {
440 col_set_str(pinfo->cinfo, COL_INFO, "ErrorACK Packet");
444 dissect_ClearACK(packet_info *pinfo) {
445 col_set_str(pinfo->cinfo, COL_INFO, "ClearACK Packet");
449 dissect_RelayACK(packet_info *pinfo) {
450 col_set_str(pinfo->cinfo, COL_INFO, "RelayACK Packet");
454 dissect_Conf2ACK(packet_info *pinfo) {
455 col_set_str(pinfo->cinfo, COL_INFO, "Conf2ACK Packet");
459 dissect_HelloACK(packet_info *pinfo) {
460 col_set_str(pinfo->cinfo, COL_INFO, "HelloACK Packet");
464 dissect_Ping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
465 unsigned int data_offset=24;
467 col_set_str(pinfo->cinfo, COL_INFO, "Ping Packet");
469 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_ping_version,tvb,data_offset,4,FALSE);
470 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_ping_endpointhash,tvb,data_offset+4,8,FALSE);
474 dissect_PingACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
475 unsigned int data_offset=24;
477 col_set_str(pinfo->cinfo, COL_INFO, "PingACK Packet");
479 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_ping_version,tvb,data_offset,4,FALSE);
480 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_pingack_endpointhash,tvb,data_offset+4,8,FALSE);
481 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_ping_endpointhash,tvb,data_offset+12,8,FALSE);
482 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_ping_ssrc,tvb,data_offset+20,4,FALSE);
486 dissect_GoClear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
487 unsigned int data_offset=24;
489 col_set_str(pinfo->cinfo, COL_INFO, "GoClear Packet");
491 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+0,8,FALSE);
495 dissect_Error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
496 unsigned int data_offset=24;
498 col_set_str(pinfo->cinfo, COL_INFO, "Error Packet");
500 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_error,tvb,data_offset,4,FALSE);
504 dissect_Confirm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree,int part) {
506 unsigned int data_offset=24;
507 proto_tree *zrtp_msg_encrypted_tree;
510 if (check_col(pinfo->cinfo, COL_INFO)) {
511 col_add_fstr(pinfo->cinfo, COL_INFO, (part == 1) ? "Confirm1 Packet" : "Confirm2 Packet");
514 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+0,8,FALSE);
515 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_cfb,tvb,data_offset+8,16,FALSE);
516 linelen = tvb_reported_length_remaining(tvb,data_offset+24);
517 ti = proto_tree_add_protocol_format(zrtp_tree,proto_zrtp,tvb,data_offset+24,linelen-4,"Encrypted Data");
518 zrtp_msg_encrypted_tree = proto_item_add_subtree(ti,ett_zrtp_msg_encrypted);
522 dissect_SASrelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
524 unsigned int data_offset=24;
525 proto_tree *zrtp_msg_encrypted_tree;
528 col_set_str(pinfo->cinfo, COL_INFO, "SASrelay Packet");
530 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+0,8,FALSE);
531 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_cfb,tvb,data_offset+8,16,FALSE);
532 linelen = tvb_reported_length_remaining(tvb,data_offset+24);
533 ti = proto_tree_add_protocol_format(zrtp_tree,proto_zrtp,tvb,data_offset+24,linelen-4,"Encrypted Data");
534 zrtp_msg_encrypted_tree = proto_item_add_subtree(ti,ett_zrtp_msg_encrypted);
538 dissect_DHPart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree,int part) {
540 unsigned int msg_offset=12;
541 unsigned int data_offset=56;
542 proto_tree *zrtp_msg_pvr_tree;
543 int linelen, pvr_len;
545 if (check_col(pinfo->cinfo, COL_INFO)) {
546 col_add_fstr(pinfo->cinfo, COL_INFO, (part == 1) ? "DHPart1 Packet" : "DHPart2 Packet");
549 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hash_image,tvb,msg_offset+12,32,FALSE);
550 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_rs1ID,tvb,data_offset+0,8,FALSE);
551 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_rs2ID,tvb,data_offset+8,8,FALSE);
552 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_auxs,tvb,data_offset+16,8,FALSE);
553 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_pbxs,tvb,data_offset+24,8,FALSE);
554 linelen = tvb_reported_length_remaining(tvb,data_offset+32);
555 pvr_len = linelen-8-4;
556 ti = proto_tree_add_protocol_format(zrtp_tree,proto_zrtp,tvb,data_offset+32,pvr_len,(part==1)?"pvr Data":"pvi Data");
557 zrtp_msg_pvr_tree = proto_item_add_subtree(ti,ett_zrtp_msg_pvr);
558 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+32+pvr_len,8,FALSE);
562 dissect_Commit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
563 unsigned int msg_offset=12;
564 unsigned int data_offset=56;
565 unsigned char value[5];
574 col_set_str(pinfo->cinfo, COL_INFO, "Commit Packet");
576 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hash_image,tvb,msg_offset+12,32,FALSE);
578 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_zid,tvb,data_offset+0,12,FALSE);
579 tvb_memcpy(tvb,(void *)value,data_offset+12,4);
581 proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_hash,tvb,data_offset+12,4,value,
582 "Hash: %s",key_to_val(value,4,zrtp_hash_type_vals,"Unknown hash type %s"));
583 tvb_memcpy(tvb,(void *)value,data_offset+16,4);
585 proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_cipher,tvb,data_offset+16,4,value,"Cipher: %s",
586 key_to_val(value,4,zrtp_cipher_type_vals,"Unknown cipher type %s"));
587 tvb_memcpy(tvb,(void *)value,data_offset+20,4);
589 proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_at,tvb,data_offset+20,4,value,
590 "Auth tag: %s",key_to_val(value,4,zrtp_auth_tag_vals,"Unknown auth tag %s"));
591 tvb_memcpy(tvb,(void *)value,data_offset+24,4);
593 proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_keya,tvb,data_offset+24,4,value,
594 "Key agreement: %s",key_to_val(value,4,zrtp_key_agreement_vals,"Unknown key agreement %s"));
596 if(!strncmp(value, "Mult", 4)){
598 } else if (!strncmp(value, "Prsh", 4)){
601 tvb_memcpy(tvb,(void *)value,data_offset+28,4);
603 proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_sas,tvb,data_offset+28,4,value,
604 "SAS type: %s",key_to_val(value,4,zrtp_sas_type_vals,"Unknown SAS type %s"));
610 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_nonce,tvb,data_offset+32,16,FALSE);
616 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_nonce,tvb,data_offset+32,16,FALSE);
617 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_key_id,tvb,data_offset+48,8,FALSE);
623 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hvi,tvb,data_offset+32, 32, FALSE);
628 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+offset,8,FALSE);
632 dissect_Hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
634 unsigned int msg_offset = 12;
635 unsigned int data_offset = 88;
638 unsigned int run_offset;
639 unsigned int hc,cc,ac,kc,sc;
640 unsigned int vhc,vcc,vac,vkc,vsc;
641 unsigned char value[5];
642 unsigned char version_str[5];
643 proto_tree *tmp_tree;
645 col_set_str(pinfo->cinfo, COL_INFO, "Hello Packet");
647 tvb_memcpy(tvb,version_str,msg_offset+12,4);
649 if (check_valid_version(version_str) == NULL){
650 col_set_str(pinfo->cinfo, COL_INFO, "Unsupported version of ZRTP protocol");
652 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_version,tvb,msg_offset+12,4,FALSE);
653 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_client_id,tvb,msg_offset+16,16,FALSE);
654 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hash_image,tvb,msg_offset+32,32,FALSE);
655 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_zid,tvb,msg_offset+64,12,FALSE);
656 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_mitm,tvb,data_offset+0,1,FALSE);
657 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_passive,tvb,data_offset+0,1,FALSE);
659 val_b = tvb_get_guint8(tvb,data_offset+1);
663 val_b = tvb_get_guint8(tvb,data_offset+2);
669 val_b = tvb_get_guint8(tvb,data_offset+3);
675 ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_hash_count,tvb,data_offset+1,1,hc,"Hash type count = %d",vhc);
676 tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_hc);
677 run_offset = data_offset+4;
679 tvb_memcpy(tvb,(void *)value,run_offset,4);
681 proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_hash,tvb,run_offset,4,value,
682 "Hash[%d]: %s",i,key_to_val(value,4,zrtp_hash_type_vals,"Unknown hash type %s"));
685 ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_cipher_count,tvb,data_offset+2,1,cc,"Cipher type count = %d",vcc);
686 tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_cc);
688 tvb_memcpy(tvb,(void *)value,run_offset,4);
690 proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_cipher,tvb,run_offset,4,value,"Cipher[%d]: %s",i,
691 key_to_val(value,4,zrtp_cipher_type_vals,"Unknown cipher type %s"));
694 ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_authtag_count,tvb,data_offset+2,1,ac,"Auth tag count = %d",vac);
695 tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_ac);
697 tvb_memcpy(tvb,(void *)value,run_offset,4);
699 proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_at,tvb,run_offset,4,value,
700 "Auth tag[%d]: %s",i,key_to_val(value,4,zrtp_auth_tag_vals,"Unknown auth tag %s"));
703 ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_key_count,tvb,data_offset+3,1,kc,"Key agreement type count = %d",vkc);
704 tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_kc);
706 tvb_memcpy(tvb,(void *)value,run_offset,4);
708 proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_keya,tvb,run_offset,4,value,
709 "Key agreement[%d]: %s",i,key_to_val(value,4,zrtp_key_agreement_vals,"Unknown key agreement %s"));
712 ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_sas_count,tvb,data_offset+3,1,sc,"SAS type count = %d",vsc);
713 tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_sc);
715 tvb_memcpy(tvb,(void *)value,run_offset,4);
717 proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_sas,tvb,run_offset,4,value,
718 "SAS type[%d]: %s",i,key_to_val(value,4,zrtp_sas_type_vals,"Unknown SAS type %s"));
722 proto_tree_add_item(zrtp_tree,hf_zrtp_msg_hmac,tvb,run_offset,8,FALSE);
726 proto_register_zrtp(void)
728 static hf_register_info hf[] = {
729 {&hf_zrtp_rtpversion,
731 "RTP Version", "zrtp.rtpversion",
738 {&hf_zrtp_rtppadding,
740 "RTP padding", "zrtp.rtppadding",
747 {&hf_zrtp_rtpextension,
749 "RTP Extension", "zrtp.rtpextension",
767 "Sequence", "zrtp.sequence",
776 "Magic Cookie", "zrtp.cookie",
777 FT_STRING, BASE_NONE,
785 "Source Identifier", "zrtp.source_id",
797 "Signature", "zrtp.signature",
804 {&hf_zrtp_msg_length,
806 "Length", "zrtp.length",
816 FT_STRING, BASE_NONE,
822 {&hf_zrtp_msg_version,
824 "ZRTP protocol version", "zrtp.version",
825 FT_STRING, BASE_NONE,
831 {&hf_zrtp_msg_client_id,
833 "Client Identifier", "zrtp.client_source_id",
834 FT_STRING, BASE_NONE,
840 {&hf_zrtp_msg_hash_image,
842 "Hash Image", "zrtp.hash_image",
867 {&hf_zrtp_msg_passive,
869 "Passive", "zrtp.passive",
876 {&hf_zrtp_msg_hash_count,
878 "Hash Count", "zrtp.hc",
885 {&hf_zrtp_msg_cipher_count,
887 "Cipher Count", "zrtp.cc",
894 {&hf_zrtp_msg_authtag_count,
896 "Auth tag Count", "zrtp.ac",
903 {&hf_zrtp_msg_key_count,
905 "Key Agreement Count", "zrtp.kc",
912 {&hf_zrtp_msg_sas_count,
914 "SAS Count", "zrtp.sc",
924 FT_STRING, BASE_NONE,
930 {&hf_zrtp_msg_cipher,
932 "Cipher", "zrtp.cipher",
933 FT_STRING, BASE_NONE,
942 FT_STRING, BASE_NONE,
950 "Key Agreement", "zrtp.keya",
951 FT_STRING, BASE_NONE,
960 FT_STRING, BASE_NONE,
968 "rs1ID", "zrtp.rs1id",
977 "rs2ID", "zrtp.rs2id",
1004 "HMAC", "zrtp.hmac",
1005 FT_BYTES, BASE_NONE,
1014 FT_BYTES, BASE_NONE,
1020 {&hf_zrtp_msg_error,
1022 "Error", "zrtp.error",
1023 FT_UINT32, BASE_DEC,
1024 VALS(zrtp_error_vals), 0x0,
1029 {&hf_zrtp_msg_ping_version,
1031 "Ping Version", "zrtp.ping_version",
1032 FT_STRING, BASE_NONE,
1038 {&hf_zrtp_msg_ping_endpointhash,
1040 "Ping Endpoint Hash", "zrtp.ping_endpointhash",
1041 FT_UINT64, BASE_HEX,
1047 {&hf_zrtp_msg_pingack_endpointhash,
1049 "PingAck Endpoint Hash", "zrtp.pingack_endpointhash",
1050 FT_UINT64, BASE_HEX,
1056 {&hf_zrtp_msg_ping_ssrc,
1058 "Ping SSRC", "zrtp.ping_ssrc",
1059 FT_UINT32, BASE_HEX,
1067 "Checksum", "zrtp.checksum",
1068 FT_UINT32, BASE_HEX,
1074 {&hf_zrtp_checksum_good,
1076 "Good", "zrtp.checksum_good",
1077 FT_BOOLEAN, BASE_NONE,
1079 "True: checksum matches packet content; False: doesn't match content", HFILL
1083 {&hf_zrtp_checksum_bad,
1085 "Bad", "zrtp.checksum_bad",
1086 FT_BOOLEAN, BASE_NONE,
1088 "True: checksum doesn't match packet content; False: matches content", HFILL
1095 FT_BYTES, BASE_NONE,
1101 {&hf_zrtp_msg_nonce,
1103 "nonce", "zrtp.nonce",
1104 FT_BYTES, BASE_NONE,
1110 {&hf_zrtp_msg_key_id,
1112 "key ID", "zrtp.key_id",
1113 FT_BYTES, BASE_NONE,
1120 static gint *ett[] = {
1124 &ett_zrtp_msg_encrypted,
1134 proto_zrtp = proto_register_protocol("ZRTP", "ZRTP", "zrtp");
1135 proto_register_field_array(proto_zrtp, hf, array_length(hf));
1136 proto_register_subtree_array(ett, array_length(ett));
1137 register_dissector("zrtp", dissect_zrtp, proto_zrtp);
1141 proto_reg_handoff_zrtp(void)
1143 dissector_handle_t zrtp_handle;
1145 zrtp_handle = find_dissector("zrtp");
1146 dissector_add_handle("udp.port", zrtp_handle);