2 * Routines for zrtp packet dissection
3 * IETF draft draft-zimmermann-avt-zrtp-22
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/packet.h>
34 #include <epan/strutil.h>
35 #include <epan/wmem/wmem.h>
36 #include <wsutil/crc32.h>
37 #include "packet-rtp.h"
38 #include "packet-rtcp.h"
43 static int proto_zrtp
= -1;
44 static int hf_zrtp_rtpversion
= -1;
45 static int hf_zrtp_rtppadding
= -1;
46 static int hf_zrtp_rtpextension
= -1;
47 /* static int hf_zrtp_id = -1; */
48 static int hf_zrtp_sequence
= -1;
49 static int hf_zrtp_cookie
= -1;
50 static int hf_zrtp_source_id
= -1;
55 static int hf_zrtp_signature
= -1;
56 static int hf_zrtp_msg_length
= -1;
57 static int hf_zrtp_msg_type
= -1;
58 static int hf_zrtp_msg_version
= -1;
63 static int hf_zrtp_msg_client_id
= -1;
64 static int hf_zrtp_msg_zid
= -1;
65 static int hf_zrtp_msg_sigcap
= -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_hc
= -1;
129 static gint ett_zrtp_msg_kc
= -1;
130 static gint ett_zrtp_msg_ac
= -1;
131 static gint ett_zrtp_msg_cc
= -1;
132 static gint ett_zrtp_msg_sc
= -1;
134 static gint ett_zrtp_checksum
= -1;
139 #define ZRTP_ERR_10 0x10
140 #define ZRTP_ERR_20 0x20
141 #define ZRTP_ERR_30 0x30
142 #define ZRTP_ERR_40 0x40
143 #define ZRTP_ERR_51 0x51
144 #define ZRTP_ERR_52 0x52
145 #define ZRTP_ERR_53 0x53
146 #define ZRTP_ERR_54 0x54
147 #define ZRTP_ERR_55 0x55
148 #define ZRTP_ERR_56 0x56
149 #define ZRTP_ERR_61 0x61
150 #define ZRTP_ERR_62 0x62
151 #define ZRTP_ERR_63 0x63
152 #define ZRTP_ERR_70 0x70
153 #define ZRTP_ERR_80 0x80
154 #define ZRTP_ERR_90 0x90
155 #define ZRTP_ERR_91 0x91
156 #define ZRTP_ERR_A0 0xA0
157 #define ZRTP_ERR_B0 0xB0
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"},
187 { "S384", "SHA-384 Hash"},
188 { "N256", "SHA-3 256-bit hash"},
189 { "N384", "SHA-3 384 bit hash"},
193 const value_string_keyval zrtp_cipher_type_vals
[] =
195 { "AES1", "AES-CM with 128 bit keys"},
196 { "AES2", "AES-CM with 192 bit keys"},
197 { "AES3", "AES-CM with 256 bit keys"},
198 { "2FS1", "TwoFish with 128 bit keys"},
199 { "2FS2", "TwoFish with 192 bit keys"},
200 { "2FS3", "TwoFish with 256 bit keys"},
201 { "CAM1", "Camellia with 128 bit keys"},
202 { "CAM2", "Camellia with 192 bit keys"},
203 { "CAM3", "Camellia with 256 bit keys"},
207 const value_string_keyval zrtp_auth_tag_vals
[] =
209 { "HS32", "HMAC-SHA1 32 bit authentication tag"},
210 { "HS80", "HMAC-SHA1 80 bit authentication tag"},
211 { "SK32", "Skein-512-MAC 32 bit authentication tag"},
212 { "SK64", "Skein-512-MAC 64 bit authentication tag"},
216 const value_string_keyval zrtp_sas_type_vals
[] =
218 { "B32 ", "Short authentication string using base 32"},
219 { "B256", "Short authentication string using base 256"},
223 const value_string_keyval zrtp_key_agreement_vals
[] =
225 { "DH2k", "DH mode with p=2048 bit prime"},
226 { "DH3k", "DH mode with p=3072 bit prime"},
227 { "DH4k", "DH mode with p=4096 bit prime"},
228 { "Prsh", "Preshared non-DH mode using shared secret"},
229 { "EC25", "Elliptic Curve DH-256"},
230 { "EC38", "Elliptic Curve DH-384"},
231 { "EC52", "Elliptic Curve DH-521"},
232 { "Mult", "Multistream mode"},
236 const value_string zrtp_error_vals
[] =
238 { ZRTP_ERR_10
, "Malformed Packet (CRC OK but wrong structure)"},
239 { ZRTP_ERR_20
, "Critical Software Error"},
240 { ZRTP_ERR_30
, "Unsupported ZRTP version"},
241 { ZRTP_ERR_40
, "Hello Components mismatch"},
242 { ZRTP_ERR_51
, "Hash type unsupported"},
243 { ZRTP_ERR_52
, "Cipher type not supported"},
244 { ZRTP_ERR_53
, "Public key exchange not supported"},
245 { ZRTP_ERR_54
, "SRTP auth. tag not supported"},
246 { ZRTP_ERR_55
, "SAS scheme not supported"},
247 { ZRTP_ERR_56
, "No shared secret available, DH mode required"},
248 { ZRTP_ERR_61
, "DH Error: bad pv for initiator/responder value is (1,0,p-1)"},
249 { ZRTP_ERR_62
, "DH Error: bad hash commitment (hvi != hashed data)"},
250 { ZRTP_ERR_63
, "Received relayed SAS from untrusted MiTM"},
251 { ZRTP_ERR_70
, "Auth. Error Bad Confirm Packet HMAC"},
252 { ZRTP_ERR_80
, "Nonce is reused"},
253 { ZRTP_ERR_90
, "Equal ZID's in Hello"},
254 { ZRTP_ERR_91
, "SSRC collision"},
255 { ZRTP_ERR_A0
, "Service unavailable"},
256 { ZRTP_ERR_B0
, "Protocol timeout error"},
257 { ZRTP_ERR_100
, "GoClear packet received, but not allowed"},
262 dissect_Hello(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
264 dissect_ErrorACK(packet_info
*pinfo
);
266 dissect_Commit(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
268 dissect_ClearACK( packet_info
*pinfo
);
270 dissect_Conf2ACK(packet_info
*pinfo
);
272 dissect_HelloACK( packet_info
*pinfo
);
274 dissect_GoClear(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
276 dissect_Error(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
278 dissect_Confirm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
, int part
);
280 dissect_DHPart(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
, int part
);
282 dissect_SASrelay(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
284 dissect_RelayACK(packet_info
*pinfo
);
286 dissect_Ping(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
288 dissect_PingACK(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
292 key_to_val(const gchar
*key
, int keylen
, const value_string_keyval
*kv
, const gchar
*fmt
) {
295 if (!strncmp(kv
[i
].key
, key
, keylen
)) {
300 return wmem_strdup_printf(wmem_packet_scope(), fmt
, key
);
304 check_valid_version(const gchar
*version
) {
306 int match_size
= (version
[0] == '0') ? 4 : 3;
307 while (valid_zrtp_versions
[i
].version
) {
308 if (!strncmp(valid_zrtp_versions
[i
].version
, version
, match_size
)) {
309 return(valid_zrtp_versions
[i
].version
);
318 dissect_zrtp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
320 proto_tree
*zrtp_tree
;
321 proto_tree
*zrtp_msg_tree
;
322 proto_tree
*zrtp_msg_data_tree
;
323 proto_tree
*checksum_tree
;
327 unsigned char message_type
[9];
328 unsigned int prime_offset
= 0;
329 unsigned int msg_offset
= 12;
330 guint32 sent_crc
, calc_crc
;
332 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ZRTP");
334 col_set_str(pinfo
->cinfo
, COL_INFO
, "Unknown ZRTP Packet");
336 ti
= proto_tree_add_protocol_format(tree
, proto_zrtp
, tvb
, 0, -1, "ZRTP protocol");
337 zrtp_tree
= proto_item_add_subtree(ti
, ett_zrtp
);
339 proto_tree_add_item(zrtp_tree
, hf_zrtp_rtpversion
, tvb
, prime_offset
+0, 1, ENC_BIG_ENDIAN
);
340 proto_tree_add_item(zrtp_tree
, hf_zrtp_rtppadding
, tvb
, prime_offset
+0, 1, ENC_BIG_ENDIAN
);
341 proto_tree_add_item(zrtp_tree
, hf_zrtp_rtpextension
, tvb
, prime_offset
+0, 1, ENC_BIG_ENDIAN
);
343 proto_tree_add_item(zrtp_tree
, hf_zrtp_sequence
, tvb
, prime_offset
+2, 2, ENC_BIG_ENDIAN
);
345 proto_tree_add_item(zrtp_tree
, hf_zrtp_cookie
, tvb
, prime_offset
+4, 4, ENC_ASCII
|ENC_NA
);
347 proto_tree_add_item(zrtp_tree
, hf_zrtp_source_id
, tvb
, prime_offset
+8, 4, ENC_BIG_ENDIAN
);
349 linelen
= tvb_reported_length_remaining(tvb
, msg_offset
);
350 checksum_offset
= linelen
-4;
352 ti
= proto_tree_add_protocol_format(zrtp_tree
, proto_zrtp
, tvb
, msg_offset
, linelen
-4, "Message");
353 zrtp_msg_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg
);
355 proto_tree_add_item(zrtp_msg_tree
, hf_zrtp_signature
, tvb
, msg_offset
+0, 2, ENC_BIG_ENDIAN
);
357 proto_tree_add_item(zrtp_msg_tree
, hf_zrtp_msg_length
, tvb
, msg_offset
+2, 2, ENC_BIG_ENDIAN
);
359 tvb_memcpy(tvb
, (void *)message_type
, msg_offset
+4, 8);
360 message_type
[8] = '\0';
361 proto_tree_add_item(zrtp_msg_tree
, hf_zrtp_msg_type
, tvb
, msg_offset
+4, 8, ENC_ASCII
|ENC_NA
);
363 linelen
= tvb_reported_length_remaining(tvb
, msg_offset
+12);
365 if (!strncmp(message_type
, "Hello ", 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_Hello(tvb
, pinfo
, zrtp_msg_data_tree
);
369 } else if (!strncmp(message_type
, "HelloACK", 8)) {
370 dissect_HelloACK(pinfo
);
371 } else if (!strncmp(message_type
, "Commit ", 8)) {
372 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
373 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
374 dissect_Commit(tvb
, pinfo
, zrtp_msg_data_tree
);
375 } else if (!strncmp(message_type
, "DHPart1 ", 8)) {
376 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
377 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
378 dissect_DHPart(tvb
, pinfo
, zrtp_msg_data_tree
, 1);
379 } else if (!strncmp(message_type
, "DHPart2 ", 8)) {
380 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
381 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
382 dissect_DHPart(tvb
, pinfo
, zrtp_msg_data_tree
, 2);
383 } else if (!strncmp(message_type
, "Confirm1", 8)) {
384 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
385 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
386 dissect_Confirm(tvb
, pinfo
, zrtp_msg_data_tree
, 1);
387 } else if (!strncmp(message_type
, "Confirm2", 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_Confirm(tvb
, pinfo
, zrtp_msg_data_tree
, 2);
391 } else if (!strncmp(message_type
, "Conf2ACK", 8)) {
392 dissect_Conf2ACK(pinfo
);
393 } else if (!strncmp(message_type
, "Error ", 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_Error(tvb
, pinfo
, zrtp_msg_data_tree
);
397 } else if (!strncmp(message_type
, "ErrorACK", 8)) {
398 dissect_ErrorACK(pinfo
);
399 } else if (!strncmp(message_type
, "GoClear ", 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_GoClear(tvb
, pinfo
, zrtp_msg_data_tree
);
403 } else if (!strncmp(message_type
, "ClearACK", 8)) {
404 dissect_ClearACK(pinfo
);
405 } else if (!strncmp(message_type
, "SASrelay", 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_SASrelay(tvb
, pinfo
, zrtp_msg_data_tree
);
409 } else if (!strncmp(message_type
, "RelayACK", 8)) {
410 dissect_RelayACK(pinfo
);
411 } else if (!strncmp(message_type
, "Ping ", 8)) {
412 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
413 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
414 dissect_Ping(tvb
, pinfo
, zrtp_msg_data_tree
);
415 } else if (!strncmp(message_type
, "PingACK ", 8)) {
416 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
417 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
418 dissect_PingACK(tvb
, pinfo
, zrtp_msg_data_tree
);
421 sent_crc
= tvb_get_ntohl(tvb
, msg_offset
+checksum_offset
);
422 calc_crc
= ~crc32c_calculate(tvb_get_ptr(tvb
, 0, msg_offset
+checksum_offset
), msg_offset
+checksum_offset
, CRC32C_PRELOAD
);
424 if (sent_crc
== calc_crc
) {
425 ti
= proto_tree_add_uint_format_value(zrtp_tree
, hf_zrtp_checksum
, tvb
, msg_offset
+checksum_offset
, 4, sent_crc
,
426 "0x%04x [correct]", sent_crc
);
427 checksum_tree
= proto_item_add_subtree(ti
, ett_zrtp_checksum
);
428 ti
= proto_tree_add_boolean(checksum_tree
, hf_zrtp_checksum_good
, tvb
, msg_offset
+checksum_offset
, 4, TRUE
);
429 PROTO_ITEM_SET_GENERATED(ti
);
430 ti
= proto_tree_add_boolean(checksum_tree
, hf_zrtp_checksum_bad
, tvb
, msg_offset
+checksum_offset
, 4, FALSE
);
431 PROTO_ITEM_SET_GENERATED(ti
);
433 ti
= proto_tree_add_uint_format_value(zrtp_tree
, hf_zrtp_checksum
, tvb
, msg_offset
+checksum_offset
, 4, sent_crc
,
434 "0x%04x [incorrect, should be 0x%04x]", sent_crc
, calc_crc
);
435 checksum_tree
= proto_item_add_subtree(ti
, ett_zrtp_checksum
);
436 ti
= proto_tree_add_boolean(checksum_tree
, hf_zrtp_checksum_good
, tvb
, msg_offset
+checksum_offset
, 4, FALSE
);
437 PROTO_ITEM_SET_GENERATED(ti
);
438 ti
= proto_tree_add_boolean(checksum_tree
, hf_zrtp_checksum_bad
, tvb
, msg_offset
+checksum_offset
, 4, TRUE
);
439 PROTO_ITEM_SET_GENERATED(ti
);
445 dissect_ErrorACK(packet_info
*pinfo
) {
446 col_set_str(pinfo
->cinfo
, COL_INFO
, "ErrorACK Packet");
450 dissect_ClearACK(packet_info
*pinfo
) {
451 col_set_str(pinfo
->cinfo
, COL_INFO
, "ClearACK Packet");
455 dissect_RelayACK(packet_info
*pinfo
) {
456 col_set_str(pinfo
->cinfo
, COL_INFO
, "RelayACK Packet");
460 dissect_Conf2ACK(packet_info
*pinfo
) {
462 /* Signals start of SRT(C)P streams */
463 struct srtp_info
*dummy_srtp_info
= wmem_new0(wmem_file_scope(), struct srtp_info
);
465 dummy_srtp_info
->encryption_algorithm
= SRTP_ENC_ALG_AES_CM
;
466 dummy_srtp_info
->auth_algorithm
= SRTP_AUTH_ALG_HMAC_SHA1
;
467 dummy_srtp_info
->mki_len
= 0;
468 dummy_srtp_info
->auth_tag_len
= 4;
470 srtp_add_address(pinfo
, &pinfo
->net_src
, pinfo
->srcport
, pinfo
->destport
,
471 "ZRTP", PINFO_FD_NUM(pinfo
), FALSE
, NULL
, dummy_srtp_info
);
473 srtp_add_address(pinfo
, &pinfo
->net_dst
, pinfo
->destport
, pinfo
->srcport
,
474 "ZRTP", PINFO_FD_NUM(pinfo
), FALSE
, NULL
, dummy_srtp_info
);
476 srtcp_add_address(pinfo
, &pinfo
->net_src
, pinfo
->srcport
+1, pinfo
->destport
+1,
477 "ZRTP", PINFO_FD_NUM(pinfo
), dummy_srtp_info
);
479 srtcp_add_address(pinfo
, &pinfo
->net_dst
, pinfo
->destport
+1, pinfo
->srcport
+1,
480 "ZRTP", PINFO_FD_NUM(pinfo
), dummy_srtp_info
);
482 col_set_str(pinfo
->cinfo
, COL_INFO
, "Conf2ACK Packet");
486 dissect_HelloACK(packet_info
*pinfo
) {
487 col_set_str(pinfo
->cinfo
, COL_INFO
, "HelloACK Packet");
491 dissect_Ping(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
492 unsigned int data_offset
= 24;
494 col_set_str(pinfo
->cinfo
, COL_INFO
, "Ping Packet");
496 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_version
, tvb
, data_offset
, 4, ENC_ASCII
|ENC_NA
);
497 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_endpointhash
, tvb
, data_offset
+4, 8, ENC_BIG_ENDIAN
);
501 dissect_PingACK(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
502 unsigned int data_offset
= 24;
504 col_set_str(pinfo
->cinfo
, COL_INFO
, "PingACK Packet");
506 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_version
, tvb
, data_offset
, 4, ENC_ASCII
|ENC_NA
);
507 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_pingack_endpointhash
, tvb
, data_offset
+4, 8, ENC_BIG_ENDIAN
);
508 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_endpointhash
, tvb
, data_offset
+12, 8, ENC_BIG_ENDIAN
);
509 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_ssrc
, tvb
, data_offset
+20, 4, ENC_BIG_ENDIAN
);
513 dissect_GoClear(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
514 unsigned int data_offset
= 24;
516 col_set_str(pinfo
->cinfo
, COL_INFO
, "GoClear Packet");
518 /* Now we should clear the SRT(C)P session... */
520 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+0, 8, ENC_NA
);
524 dissect_Error(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
525 unsigned int data_offset
= 24;
527 col_set_str(pinfo
->cinfo
, COL_INFO
, "Error Packet");
529 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_error
, tvb
, data_offset
, 4, ENC_BIG_ENDIAN
);
533 dissect_Confirm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
, int part
) {
534 unsigned int data_offset
= 24;
537 col_add_fstr(pinfo
->cinfo
, COL_INFO
, (part
== 1) ? "Confirm1 Packet" : "Confirm2 Packet");
539 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+0, 8, ENC_NA
);
540 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_cfb
, tvb
, data_offset
+8, 16, ENC_NA
);
541 linelen
= tvb_reported_length_remaining(tvb
, data_offset
+24);
542 proto_tree_add_protocol_format(zrtp_tree
, proto_zrtp
, tvb
, data_offset
+24, linelen
-4, "Encrypted Data");
546 dissect_SASrelay(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
547 unsigned int data_offset
= 24;
550 col_set_str(pinfo
->cinfo
, COL_INFO
, "SASrelay Packet");
552 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+0, 8, ENC_NA
);
553 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_cfb
, tvb
, data_offset
+8, 16, ENC_NA
);
554 linelen
= tvb_reported_length_remaining(tvb
, data_offset
+24);
555 proto_tree_add_protocol_format(zrtp_tree
, proto_zrtp
, tvb
, data_offset
+24, linelen
-4, "Encrypted Data");
559 dissect_DHPart(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
, int part
) {
560 unsigned int msg_offset
= 12;
561 unsigned int data_offset
= 56;
562 int linelen
, pvr_len
;
564 col_add_fstr(pinfo
->cinfo
, COL_INFO
, (part
== 1) ? "DHPart1 Packet" : "DHPart2 Packet");
566 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hash_image
, tvb
, msg_offset
+12, 32, ENC_NA
);
567 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_rs1ID
, tvb
, data_offset
+0, 8, ENC_NA
);
568 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_rs2ID
, tvb
, data_offset
+8, 8, ENC_NA
);
569 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_auxs
, tvb
, data_offset
+16, 8, ENC_NA
);
570 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_pbxs
, tvb
, data_offset
+24, 8, ENC_NA
);
571 linelen
= tvb_reported_length_remaining(tvb
, data_offset
+32);
572 pvr_len
= linelen
-8-4;
573 proto_tree_add_protocol_format(zrtp_tree
, proto_zrtp
, tvb
, data_offset
+32, pvr_len
, (part
==1) ? "pvr Data" : "pvi Data");
574 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+32+pvr_len
, 8, ENC_NA
);
578 dissect_Commit(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
579 unsigned int msg_offset
= 12;
580 unsigned int data_offset
= 56;
581 unsigned char value
[5];
590 col_set_str(pinfo
->cinfo
, COL_INFO
, "Commit Packet");
592 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hash_image
, tvb
, msg_offset
+12, 32, ENC_NA
);
594 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_zid
, tvb
, data_offset
+0, 12, ENC_NA
);
595 tvb_memcpy(tvb
, (void *)value
, data_offset
+12, 4);
597 proto_tree_add_string_format_value(zrtp_tree
, hf_zrtp_msg_hash
, tvb
, data_offset
+12, 4, value
,
598 "%s", key_to_val(value
, 4, zrtp_hash_type_vals
, "Unknown hash type %s"));
599 tvb_memcpy(tvb
, (void *)value
, data_offset
+16, 4);
601 proto_tree_add_string_format_value(zrtp_tree
, hf_zrtp_msg_cipher
, tvb
, data_offset
+16, 4, value
, "%s",
602 key_to_val(value
, 4, zrtp_cipher_type_vals
, "Unknown cipher type %s"));
603 tvb_memcpy(tvb
, (void *)value
, data_offset
+20, 4);
605 proto_tree_add_string_format(zrtp_tree
, hf_zrtp_msg_at
, tvb
, data_offset
+20, 4, value
,
606 "Auth tag: %s", key_to_val(value
, 4, zrtp_auth_tag_vals
, "Unknown auth tag %s"));
607 tvb_memcpy(tvb
, (void *)value
, data_offset
+24, 4);
609 proto_tree_add_string_format_value(zrtp_tree
, hf_zrtp_msg_keya
, tvb
, data_offset
+24, 4, value
,
610 "%s", key_to_val(value
, 4, zrtp_key_agreement_vals
, "Unknown key agreement %s"));
612 if(!strncmp(value
, "Mult", 4)) {
614 } else if (!strncmp(value
, "Prsh", 4)) {
617 tvb_memcpy(tvb
, (void *)value
, data_offset
+28, 4);
619 proto_tree_add_string_format(zrtp_tree
, hf_zrtp_msg_sas
, tvb
, data_offset
+28, 4, value
,
620 "SAS type: %s", key_to_val(value
, 4, zrtp_sas_type_vals
, "Unknown SAS type %s"));
626 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_nonce
, tvb
, data_offset
+32, 16, ENC_NA
);
632 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_nonce
, tvb
, data_offset
+32, 16, ENC_NA
);
633 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_key_id
, tvb
, data_offset
+48, 8, ENC_NA
);
639 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hvi
, tvb
, data_offset
+32, 32, ENC_NA
);
644 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+offset
, 8, ENC_NA
);
648 dissect_Hello(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
650 unsigned int msg_offset
= 12;
651 unsigned int data_offset
= 88;
654 unsigned int run_offset
;
655 unsigned int hc
, cc
, ac
, kc
, sc
;
656 unsigned int vhc
, vcc
, vac
, vkc
, vsc
;
657 unsigned char value
[5];
658 unsigned char version_str
[5];
659 proto_tree
*tmp_tree
;
661 col_set_str(pinfo
->cinfo
, COL_INFO
, "Hello Packet");
663 tvb_memcpy(tvb
, version_str
, msg_offset
+12, 4);
664 version_str
[4] = '\0';
665 if (check_valid_version(version_str
) == NULL
) {
666 col_set_str(pinfo
->cinfo
, COL_INFO
, "Unsupported version of ZRTP protocol");
668 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_version
, tvb
, msg_offset
+12, 4, ENC_ASCII
|ENC_NA
);
669 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_client_id
, tvb
, msg_offset
+16, 16, ENC_ASCII
|ENC_NA
);
670 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hash_image
, tvb
, msg_offset
+32, 32, ENC_NA
);
671 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_zid
, tvb
, msg_offset
+64, 12, ENC_NA
);
672 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_sigcap
, tvb
, data_offset
+0, 1, ENC_BIG_ENDIAN
);
673 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_mitm
, tvb
, data_offset
+0, 1, ENC_BIG_ENDIAN
);
674 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_passive
, tvb
, data_offset
+0, 1, ENC_BIG_ENDIAN
);
676 val_b
= tvb_get_guint8(tvb
, data_offset
+1);
680 val_b
= tvb_get_guint8(tvb
, data_offset
+2);
686 val_b
= tvb_get_guint8(tvb
, data_offset
+3);
692 ti
= proto_tree_add_uint_format(zrtp_tree
, hf_zrtp_msg_hash_count
, tvb
, data_offset
+1, 1, hc
, "Hash type count = %d", vhc
);
693 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_hc
);
694 run_offset
= data_offset
+4;
695 for (i
=0; i
<vhc
; i
++) {
696 tvb_memcpy(tvb
, (void *)value
, run_offset
, 4);
698 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_hash
, tvb
, run_offset
, 4, value
,
699 "Hash[%d]: %s", i
, key_to_val(value
, 4, zrtp_hash_type_vals
, "Unknown hash type %s"));
702 ti
= proto_tree_add_uint_format(zrtp_tree
, hf_zrtp_msg_cipher_count
, tvb
, data_offset
+2, 1, cc
, "Cipher type count = %d", vcc
);
703 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_cc
);
704 for (i
=0; i
<vcc
; i
++) {
705 tvb_memcpy(tvb
, (void *)value
, run_offset
, 4);
707 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_cipher
, tvb
, run_offset
, 4, value
, "Cipher[%d]: %s", i
,
708 key_to_val(value
, 4, zrtp_cipher_type_vals
, "Unknown cipher type %s"));
711 ti
= proto_tree_add_uint_format(zrtp_tree
, hf_zrtp_msg_authtag_count
, tvb
, data_offset
+2, 1, ac
, "Auth tag count = %d", vac
);
712 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_ac
);
713 for (i
=0; i
<vac
; i
++) {
714 tvb_memcpy(tvb
, (void *)value
, run_offset
, 4);
716 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_at
, tvb
, run_offset
, 4, value
,
717 "Auth tag[%d]: %s", i
, key_to_val(value
, 4, zrtp_auth_tag_vals
, "Unknown auth tag %s"));
720 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
);
721 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_kc
);
722 for (i
=0; i
<vkc
; i
++) {
723 tvb_memcpy(tvb
, (void *)value
, run_offset
, 4);
725 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_keya
, tvb
, run_offset
, 4, value
,
726 "Key agreement[%d]: %s", i
, key_to_val(value
, 4, zrtp_key_agreement_vals
, "Unknown key agreement %s"));
729 ti
= proto_tree_add_uint_format(zrtp_tree
, hf_zrtp_msg_sas_count
, tvb
, data_offset
+3, 1, sc
, "SAS type count = %d", vsc
);
730 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_sc
);
731 for (i
=0; i
<vsc
; i
++) {
732 tvb_memcpy(tvb
, (void *)value
, run_offset
, 4);
734 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_sas
, tvb
, run_offset
, 4, value
,
735 "SAS type[%d]: %s", i
, key_to_val(value
, 4, zrtp_sas_type_vals
, "Unknown SAS type %s"));
739 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, run_offset
, 8, ENC_NA
);
743 proto_register_zrtp(void)
745 static hf_register_info hf
[] = {
746 {&hf_zrtp_rtpversion
,
748 "RTP Version", "zrtp.rtpversion",
755 {&hf_zrtp_rtppadding
,
757 "RTP padding", "zrtp.rtppadding",
764 {&hf_zrtp_rtpextension
,
766 "RTP Extension", "zrtp.rtpextension",
786 "Sequence", "zrtp.sequence",
795 "Magic Cookie", "zrtp.cookie",
796 FT_STRING
, BASE_NONE
,
804 "Source Identifier", "zrtp.source_id",
816 "Signature", "zrtp.signature",
823 {&hf_zrtp_msg_length
,
825 "Length", "zrtp.length",
835 FT_STRING
, BASE_NONE
,
841 {&hf_zrtp_msg_version
,
843 "ZRTP protocol version", "zrtp.version",
844 FT_STRING
, BASE_NONE
,
850 {&hf_zrtp_msg_client_id
,
852 "Client Identifier", "zrtp.client_source_id",
853 FT_STRING
, BASE_NONE
,
859 {&hf_zrtp_msg_hash_image
,
861 "Hash Image", "zrtp.hash_image",
877 {&hf_zrtp_msg_sigcap
,
879 "Sig.capable", "zrtp.sigcap",
895 {&hf_zrtp_msg_passive
,
897 "Passive", "zrtp.passive",
904 {&hf_zrtp_msg_hash_count
,
906 "Hash Count", "zrtp.hc",
913 {&hf_zrtp_msg_cipher_count
,
915 "Cipher Count", "zrtp.cc",
922 {&hf_zrtp_msg_authtag_count
,
924 "Auth tag Count", "zrtp.ac",
931 {&hf_zrtp_msg_key_count
,
933 "Key Agreement Count", "zrtp.kc",
940 {&hf_zrtp_msg_sas_count
,
942 "SAS Count", "zrtp.sc",
952 FT_STRING
, BASE_NONE
,
958 {&hf_zrtp_msg_cipher
,
960 "Cipher", "zrtp.cipher",
961 FT_STRING
, BASE_NONE
,
970 FT_STRING
, BASE_NONE
,
978 "Key Agreement", "zrtp.keya",
979 FT_STRING
, BASE_NONE
,
988 FT_STRING
, BASE_NONE
,
996 "rs1ID", "zrtp.rs1id",
1003 {&hf_zrtp_msg_rs2ID
,
1005 "rs2ID", "zrtp.rs2id",
1006 FT_BYTES
, BASE_NONE
,
1014 "auxs", "zrtp.auxs",
1015 FT_BYTES
, BASE_NONE
,
1023 "pbxs", "zrtp.pbxs",
1024 FT_BYTES
, BASE_NONE
,
1032 "HMAC", "zrtp.hmac",
1033 FT_BYTES
, BASE_NONE
,
1042 FT_BYTES
, BASE_NONE
,
1048 {&hf_zrtp_msg_error
,
1050 "Error", "zrtp.error",
1051 FT_UINT32
, BASE_DEC
,
1052 VALS(zrtp_error_vals
), 0x0,
1057 {&hf_zrtp_msg_ping_version
,
1059 "Ping Version", "zrtp.ping_version",
1060 FT_STRING
, BASE_NONE
,
1066 {&hf_zrtp_msg_ping_endpointhash
,
1068 "Ping Endpoint Hash", "zrtp.ping_endpointhash",
1069 FT_UINT64
, BASE_HEX
,
1075 {&hf_zrtp_msg_pingack_endpointhash
,
1077 "PingAck Endpoint Hash", "zrtp.pingack_endpointhash",
1078 FT_UINT64
, BASE_HEX
,
1084 {&hf_zrtp_msg_ping_ssrc
,
1086 "Ping SSRC", "zrtp.ping_ssrc",
1087 FT_UINT32
, BASE_HEX
,
1095 "Checksum", "zrtp.checksum",
1096 FT_UINT32
, BASE_HEX
,
1102 {&hf_zrtp_checksum_good
,
1104 "Good", "zrtp.checksum_good",
1105 FT_BOOLEAN
, BASE_NONE
,
1107 "True: checksum matches packet content; False: doesn't match content", HFILL
1111 {&hf_zrtp_checksum_bad
,
1113 "Bad", "zrtp.checksum_bad",
1114 FT_BOOLEAN
, BASE_NONE
,
1116 "True: checksum doesn't match packet content; False: matches content", HFILL
1123 FT_BYTES
, BASE_NONE
,
1129 {&hf_zrtp_msg_nonce
,
1131 "nonce", "zrtp.nonce",
1132 FT_BYTES
, BASE_NONE
,
1138 {&hf_zrtp_msg_key_id
,
1140 "key ID", "zrtp.key_id",
1141 FT_BYTES
, BASE_NONE
,
1148 static gint
*ett
[] = {
1160 proto_zrtp
= proto_register_protocol("ZRTP", "ZRTP", "zrtp");
1161 proto_register_field_array(proto_zrtp
, hf
, array_length(hf
));
1162 proto_register_subtree_array(ett
, array_length(ett
));
1163 register_dissector("zrtp", dissect_zrtp
, proto_zrtp
);
1167 proto_reg_handoff_zrtp(void)
1169 dissector_handle_t zrtp_handle
;
1171 zrtp_handle
= find_dissector("zrtp");
1172 dissector_add_handle("udp.port", zrtp_handle
);