2 * Routines for zrtp packet dissection
3 * IETF draft draft-zimmermann-avt-zrtp-22
5 * Copyright 2007, Sagar Pai <sagar@gmail.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-pop.c
13 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include <epan/packet.h>
19 #include <epan/expert.h>
20 #include <epan/crc32-tvb.h>
21 #include <wsutil/crc32.h>
22 #include <wsutil/array.h>
23 #include "packet-rtp.h"
24 #include "packet-rtcp.h"
26 void proto_reg_handoff_zrtp(void);
27 void proto_register_zrtp(void);
32 static int proto_zrtp
;
33 static int hf_zrtp_rtpversion
;
34 static int hf_zrtp_rtppadding
;
35 static int hf_zrtp_rtpextension
;
36 /* static int hf_zrtp_id; */
37 static int hf_zrtp_sequence
;
38 static int hf_zrtp_cookie
;
39 static int hf_zrtp_source_id
;
44 static int hf_zrtp_signature
;
45 static int hf_zrtp_msg_length
;
46 static int hf_zrtp_msg_type
;
47 static int hf_zrtp_msg_version
;
52 static int hf_zrtp_msg_client_id
;
53 static int hf_zrtp_msg_zid
;
54 static int hf_zrtp_msg_sigcap
;
55 static int hf_zrtp_msg_mitm
;
56 static int hf_zrtp_msg_passive
;
57 static int hf_zrtp_msg_hash_count
;
58 static int hf_zrtp_msg_cipher_count
;
59 static int hf_zrtp_msg_authtag_count
;
60 static int hf_zrtp_msg_key_count
;
61 static int hf_zrtp_msg_sas_count
;
62 static int hf_zrtp_msg_hash
;
63 static int hf_zrtp_msg_cipher
;
64 static int hf_zrtp_msg_at
;
65 static int hf_zrtp_msg_keya
;
66 static int hf_zrtp_msg_sas
;
67 static int hf_zrtp_msg_hash_image
;
72 static int hf_zrtp_msg_hvi
;
73 static int hf_zrtp_msg_nonce
;
74 static int hf_zrtp_msg_key_id
;
79 static int hf_zrtp_msg_rs1ID
;
80 static int hf_zrtp_msg_rs2ID
;
81 static int hf_zrtp_msg_auxs
;
82 static int hf_zrtp_msg_pbxs
;
87 static int hf_zrtp_msg_hmac
;
88 static int hf_zrtp_msg_cfb
;
93 static int hf_zrtp_msg_error
;
98 static int hf_zrtp_msg_ping_version
;
99 static int hf_zrtp_msg_ping_endpointhash
;
100 static int hf_zrtp_msg_pingack_endpointhash
;
101 static int hf_zrtp_msg_ping_ssrc
;
106 static int hf_zrtp_checksum
;
107 static int hf_zrtp_checksum_status
;
113 static int ett_zrtp_msg
;
114 static int ett_zrtp_msg_data
;
116 static int ett_zrtp_msg_hc
;
117 static int ett_zrtp_msg_kc
;
118 static int ett_zrtp_msg_ac
;
119 static int ett_zrtp_msg_cc
;
120 static int ett_zrtp_msg_sc
;
122 static int ett_zrtp_checksum
;
125 static expert_field ei_zrtp_checksum
;
127 static dissector_handle_t zrtp_handle
;
133 #define ZRTP_ERR_10 0x10
134 #define ZRTP_ERR_20 0x20
135 #define ZRTP_ERR_30 0x30
136 #define ZRTP_ERR_40 0x40
137 #define ZRTP_ERR_51 0x51
138 #define ZRTP_ERR_52 0x52
139 #define ZRTP_ERR_53 0x53
140 #define ZRTP_ERR_54 0x54
141 #define ZRTP_ERR_55 0x55
142 #define ZRTP_ERR_56 0x56
143 #define ZRTP_ERR_61 0x61
144 #define ZRTP_ERR_62 0x62
145 #define ZRTP_ERR_63 0x63
146 #define ZRTP_ERR_70 0x70
147 #define ZRTP_ERR_80 0x80
148 #define ZRTP_ERR_90 0x90
149 #define ZRTP_ERR_91 0x91
150 #define ZRTP_ERR_A0 0xA0
151 #define ZRTP_ERR_B0 0xB0
152 #define ZRTP_ERR_100 0x100
157 typedef struct _value_zrtp_versions
{
159 } value_zrtp_versions
;
162 typedef struct _value_string_keyval
{
165 } value_string_keyval
;
168 static const value_zrtp_versions valid_zrtp_versions
[] =
178 static const value_string_keyval zrtp_hash_type_vals
[] =
180 { "S256", "SHA-256 Hash"},
181 { "S384", "SHA-384 Hash"},
182 { "N256", "SHA-3 256-bit hash"},
183 { "N384", "SHA-3 384 bit hash"},
187 static const value_string_keyval zrtp_cipher_type_vals
[] =
189 { "AES1", "AES-CM with 128 bit keys"},
190 { "AES2", "AES-CM with 192 bit keys"},
191 { "AES3", "AES-CM with 256 bit keys"},
192 { "2FS1", "TwoFish with 128 bit keys"},
193 { "2FS2", "TwoFish with 192 bit keys"},
194 { "2FS3", "TwoFish with 256 bit keys"},
195 { "CAM1", "Camellia with 128 bit keys"},
196 { "CAM2", "Camellia with 192 bit keys"},
197 { "CAM3", "Camellia with 256 bit keys"},
201 static const value_string_keyval zrtp_auth_tag_vals
[] =
203 { "HS32", "HMAC-SHA1 32 bit authentication tag"},
204 { "HS80", "HMAC-SHA1 80 bit authentication tag"},
205 { "SK32", "Skein-512-MAC 32 bit authentication tag"},
206 { "SK64", "Skein-512-MAC 64 bit authentication tag"},
210 static const value_string_keyval zrtp_sas_type_vals
[] =
212 { "B32 ", "Short authentication string using base 32"},
213 { "B256", "Short authentication string using base 256"},
217 static const value_string_keyval zrtp_key_agreement_vals
[] =
219 { "DH2k", "DH mode with p=2048 bit prime"},
220 { "DH3k", "DH mode with p=3072 bit prime"},
221 { "DH4k", "DH mode with p=4096 bit prime"},
222 { "Prsh", "Preshared non-DH mode using shared secret"},
223 { "EC25", "Elliptic Curve DH-256"},
224 { "EC38", "Elliptic Curve DH-384"},
225 { "EC52", "Elliptic Curve DH-521"},
226 { "Mult", "Multistream mode"},
230 static const value_string zrtp_error_vals
[] =
232 { ZRTP_ERR_10
, "Malformed Packet (CRC OK but wrong structure)"},
233 { ZRTP_ERR_20
, "Critical Software Error"},
234 { ZRTP_ERR_30
, "Unsupported ZRTP version"},
235 { ZRTP_ERR_40
, "Hello Components mismatch"},
236 { ZRTP_ERR_51
, "Hash type unsupported"},
237 { ZRTP_ERR_52
, "Cipher type not supported"},
238 { ZRTP_ERR_53
, "Public key exchange not supported"},
239 { ZRTP_ERR_54
, "SRTP auth. tag not supported"},
240 { ZRTP_ERR_55
, "SAS scheme not supported"},
241 { ZRTP_ERR_56
, "No shared secret available, DH mode required"},
242 { ZRTP_ERR_61
, "DH Error: bad pv for initiator/responder value is (1,0,p-1)"},
243 { ZRTP_ERR_62
, "DH Error: bad hash commitment (hvi != hashed data)"},
244 { ZRTP_ERR_63
, "Received relayed SAS from untrusted MiTM"},
245 { ZRTP_ERR_70
, "Auth. Error Bad Confirm Packet HMAC"},
246 { ZRTP_ERR_80
, "Nonce is reused"},
247 { ZRTP_ERR_90
, "Equal ZID's in Hello"},
248 { ZRTP_ERR_91
, "SSRC collision"},
249 { ZRTP_ERR_A0
, "Service unavailable"},
250 { ZRTP_ERR_B0
, "Protocol timeout error"},
251 { ZRTP_ERR_100
, "GoClear packet received, but not allowed"},
256 dissect_Hello(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
258 dissect_ErrorACK(packet_info
*pinfo
);
260 dissect_Commit(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
262 dissect_ClearACK( packet_info
*pinfo
);
264 dissect_Conf2ACK(packet_info
*pinfo
);
266 dissect_HelloACK( packet_info
*pinfo
);
268 dissect_GoClear(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
270 dissect_Error(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
272 dissect_Confirm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
, int part
);
274 dissect_DHPart(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
, int part
);
276 dissect_SASrelay(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
278 dissect_RelayACK(packet_info
*pinfo
);
280 dissect_Ping(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
282 dissect_PingACK(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
);
286 key_to_val(const char *key
, int keylen
, const value_string_keyval
*kv
, const char *fmt
) {
289 if (!strncmp(kv
[i
].key
, key
, keylen
)) {
294 return wmem_strdup_printf(wmem_packet_scope(), fmt
, key
);
298 check_valid_version(const char *version
) {
300 int match_size
= (version
[0] == '0') ? 4 : 3;
301 while (valid_zrtp_versions
[i
].version
) {
302 if (!strncmp(valid_zrtp_versions
[i
].version
, version
, match_size
)) {
303 return valid_zrtp_versions
[i
].version
;
312 dissect_zrtp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
314 proto_tree
*zrtp_tree
;
315 proto_tree
*zrtp_msg_tree
;
316 proto_tree
*zrtp_msg_data_tree
;
320 unsigned char message_type
[9];
321 unsigned int prime_offset
= 0;
322 unsigned int msg_offset
= 12;
325 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ZRTP");
327 col_set_str(pinfo
->cinfo
, COL_INFO
, "Unknown ZRTP Packet");
329 ti
= proto_tree_add_protocol_format(tree
, proto_zrtp
, tvb
, 0, -1, "ZRTP protocol");
330 zrtp_tree
= proto_item_add_subtree(ti
, ett_zrtp
);
332 proto_tree_add_item(zrtp_tree
, hf_zrtp_rtpversion
, tvb
, prime_offset
+0, 1, ENC_BIG_ENDIAN
);
333 proto_tree_add_item(zrtp_tree
, hf_zrtp_rtppadding
, tvb
, prime_offset
+0, 1, ENC_BIG_ENDIAN
);
334 proto_tree_add_item(zrtp_tree
, hf_zrtp_rtpextension
, tvb
, prime_offset
+0, 1, ENC_BIG_ENDIAN
);
336 proto_tree_add_item(zrtp_tree
, hf_zrtp_sequence
, tvb
, prime_offset
+2, 2, ENC_BIG_ENDIAN
);
338 proto_tree_add_item(zrtp_tree
, hf_zrtp_cookie
, tvb
, prime_offset
+4, 4, ENC_ASCII
);
340 proto_tree_add_item(zrtp_tree
, hf_zrtp_source_id
, tvb
, prime_offset
+8, 4, ENC_BIG_ENDIAN
);
342 linelen
= tvb_reported_length_remaining(tvb
, msg_offset
);
343 checksum_offset
= linelen
-4;
345 ti
= proto_tree_add_protocol_format(zrtp_tree
, proto_zrtp
, tvb
, msg_offset
, linelen
-4, "Message");
346 zrtp_msg_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg
);
348 proto_tree_add_item(zrtp_msg_tree
, hf_zrtp_signature
, tvb
, msg_offset
+0, 2, ENC_BIG_ENDIAN
);
350 proto_tree_add_item(zrtp_msg_tree
, hf_zrtp_msg_length
, tvb
, msg_offset
+2, 2, ENC_BIG_ENDIAN
);
352 tvb_memcpy(tvb
, (void *)message_type
, msg_offset
+4, 8);
353 message_type
[8] = '\0';
354 proto_tree_add_item(zrtp_msg_tree
, hf_zrtp_msg_type
, tvb
, msg_offset
+4, 8, ENC_ASCII
);
356 linelen
= tvb_reported_length_remaining(tvb
, msg_offset
+12);
358 if (!strncmp(message_type
, "Hello ", 8)) {
359 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
360 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
361 dissect_Hello(tvb
, pinfo
, zrtp_msg_data_tree
);
362 } else if (!strncmp(message_type
, "HelloACK", 8)) {
363 dissect_HelloACK(pinfo
);
364 } else if (!strncmp(message_type
, "Commit ", 8)) {
365 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
366 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
367 dissect_Commit(tvb
, pinfo
, zrtp_msg_data_tree
);
368 } else if (!strncmp(message_type
, "DHPart1 ", 8)) {
369 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
370 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
371 dissect_DHPart(tvb
, pinfo
, zrtp_msg_data_tree
, 1);
372 } else if (!strncmp(message_type
, "DHPart2 ", 8)) {
373 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
374 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
375 dissect_DHPart(tvb
, pinfo
, zrtp_msg_data_tree
, 2);
376 } else if (!strncmp(message_type
, "Confirm1", 8)) {
377 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
378 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
379 dissect_Confirm(tvb
, pinfo
, zrtp_msg_data_tree
, 1);
380 } else if (!strncmp(message_type
, "Confirm2", 8)) {
381 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
382 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
383 dissect_Confirm(tvb
, pinfo
, zrtp_msg_data_tree
, 2);
384 } else if (!strncmp(message_type
, "Conf2ACK", 8)) {
385 dissect_Conf2ACK(pinfo
);
386 } else if (!strncmp(message_type
, "Error ", 8)) {
387 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
388 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
389 dissect_Error(tvb
, pinfo
, zrtp_msg_data_tree
);
390 } else if (!strncmp(message_type
, "ErrorACK", 8)) {
391 dissect_ErrorACK(pinfo
);
392 } else if (!strncmp(message_type
, "GoClear ", 8)) {
393 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
394 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
395 dissect_GoClear(tvb
, pinfo
, zrtp_msg_data_tree
);
396 } else if (!strncmp(message_type
, "ClearACK", 8)) {
397 dissect_ClearACK(pinfo
);
398 } else if (!strncmp(message_type
, "SASrelay", 8)) {
399 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
400 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
401 dissect_SASrelay(tvb
, pinfo
, zrtp_msg_data_tree
);
402 } else if (!strncmp(message_type
, "RelayACK", 8)) {
403 dissect_RelayACK(pinfo
);
404 } else if (!strncmp(message_type
, "Ping ", 8)) {
405 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
406 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
407 dissect_Ping(tvb
, pinfo
, zrtp_msg_data_tree
);
408 } else if (!strncmp(message_type
, "PingACK ", 8)) {
409 ti
= proto_tree_add_protocol_format(zrtp_msg_tree
, proto_zrtp
, tvb
, msg_offset
+12, linelen
-4, "Data");
410 zrtp_msg_data_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_data
);
411 dissect_PingACK(tvb
, pinfo
, zrtp_msg_data_tree
);
414 calc_crc
= ~crc32c_tvb_offset_calculate(tvb
, 0, msg_offset
+checksum_offset
, CRC32C_PRELOAD
);
416 proto_tree_add_checksum(zrtp_tree
, tvb
, msg_offset
+checksum_offset
, hf_zrtp_checksum
, hf_zrtp_checksum_status
, &ei_zrtp_checksum
, pinfo
, calc_crc
,
417 ENC_BIG_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
418 return tvb_captured_length(tvb
);
422 dissect_ErrorACK(packet_info
*pinfo
) {
423 col_set_str(pinfo
->cinfo
, COL_INFO
, "ErrorACK Packet");
427 dissect_ClearACK(packet_info
*pinfo
) {
428 col_set_str(pinfo
->cinfo
, COL_INFO
, "ClearACK Packet");
432 dissect_RelayACK(packet_info
*pinfo
) {
433 col_set_str(pinfo
->cinfo
, COL_INFO
, "RelayACK Packet");
437 dissect_Conf2ACK(packet_info
*pinfo
) {
439 /* Signals start of SRT(C)P streams */
440 struct srtp_info
*dummy_srtp_info
= wmem_new0(wmem_file_scope(), struct srtp_info
);
442 dummy_srtp_info
->encryption_algorithm
= SRTP_ENC_ALG_AES_CM
;
443 dummy_srtp_info
->auth_algorithm
= SRTP_AUTH_ALG_HMAC_SHA1
;
444 dummy_srtp_info
->mki_len
= 0;
445 dummy_srtp_info
->auth_tag_len
= 4;
447 srtp_add_address(pinfo
, PT_UDP
, &pinfo
->net_src
, pinfo
->srcport
, pinfo
->destport
,
448 "ZRTP", pinfo
->num
, RTP_MEDIA_AUDIO
, NULL
, dummy_srtp_info
, NULL
);
450 srtp_add_address(pinfo
, PT_UDP
, &pinfo
->net_dst
, pinfo
->destport
, pinfo
->srcport
,
451 "ZRTP", pinfo
->num
, RTP_MEDIA_AUDIO
, NULL
, dummy_srtp_info
, NULL
);
453 srtcp_add_address(pinfo
, &pinfo
->net_src
, pinfo
->srcport
+1, pinfo
->destport
+1,
454 "ZRTP", pinfo
->num
, dummy_srtp_info
);
456 srtcp_add_address(pinfo
, &pinfo
->net_dst
, pinfo
->destport
+1, pinfo
->srcport
+1,
457 "ZRTP", pinfo
->num
, dummy_srtp_info
);
459 col_set_str(pinfo
->cinfo
, COL_INFO
, "Conf2ACK Packet");
463 dissect_HelloACK(packet_info
*pinfo
) {
464 col_set_str(pinfo
->cinfo
, COL_INFO
, "HelloACK Packet");
468 dissect_Ping(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
469 unsigned int data_offset
= 24;
471 col_set_str(pinfo
->cinfo
, COL_INFO
, "Ping Packet");
473 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_version
, tvb
, data_offset
, 4, ENC_ASCII
);
474 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_endpointhash
, tvb
, data_offset
+4, 8, ENC_BIG_ENDIAN
);
478 dissect_PingACK(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
479 unsigned int data_offset
= 24;
481 col_set_str(pinfo
->cinfo
, COL_INFO
, "PingACK Packet");
483 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_version
, tvb
, data_offset
, 4, ENC_ASCII
);
484 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_pingack_endpointhash
, tvb
, data_offset
+4, 8, ENC_BIG_ENDIAN
);
485 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_endpointhash
, tvb
, data_offset
+12, 8, ENC_BIG_ENDIAN
);
486 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_ping_ssrc
, tvb
, data_offset
+20, 4, ENC_BIG_ENDIAN
);
490 dissect_GoClear(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
491 unsigned int data_offset
= 24;
493 col_set_str(pinfo
->cinfo
, COL_INFO
, "GoClear Packet");
495 /* Now we should clear the SRT(C)P session... */
497 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+0, 8, ENC_NA
);
501 dissect_Error(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
502 unsigned int data_offset
= 24;
504 col_set_str(pinfo
->cinfo
, COL_INFO
, "Error Packet");
506 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_error
, tvb
, data_offset
, 4, ENC_BIG_ENDIAN
);
510 dissect_Confirm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
, int part
) {
511 unsigned int data_offset
= 24;
514 col_set_str(pinfo
->cinfo
, COL_INFO
, (part
== 1) ? "Confirm1 Packet" : "Confirm2 Packet");
516 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+0, 8, ENC_NA
);
517 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_cfb
, tvb
, data_offset
+8, 16, ENC_NA
);
518 linelen
= tvb_reported_length_remaining(tvb
, data_offset
+24);
519 proto_tree_add_protocol_format(zrtp_tree
, proto_zrtp
, tvb
, data_offset
+24, linelen
-4, "Encrypted Data");
523 dissect_SASrelay(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
524 unsigned int data_offset
= 24;
527 col_set_str(pinfo
->cinfo
, COL_INFO
, "SASrelay Packet");
529 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+0, 8, ENC_NA
);
530 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_cfb
, tvb
, data_offset
+8, 16, ENC_NA
);
531 linelen
= tvb_reported_length_remaining(tvb
, data_offset
+24);
532 proto_tree_add_protocol_format(zrtp_tree
, proto_zrtp
, tvb
, data_offset
+24, linelen
-4, "Encrypted Data");
536 dissect_DHPart(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
, int part
) {
537 unsigned int msg_offset
= 12;
538 unsigned int data_offset
= 56;
539 int linelen
, pvr_len
;
541 col_set_str(pinfo
->cinfo
, COL_INFO
, (part
== 1) ? "DHPart1 Packet" : "DHPart2 Packet");
543 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hash_image
, tvb
, msg_offset
+12, 32, ENC_NA
);
544 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_rs1ID
, tvb
, data_offset
+0, 8, ENC_NA
);
545 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_rs2ID
, tvb
, data_offset
+8, 8, ENC_NA
);
546 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_auxs
, tvb
, data_offset
+16, 8, ENC_NA
);
547 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_pbxs
, tvb
, data_offset
+24, 8, ENC_NA
);
548 linelen
= tvb_reported_length_remaining(tvb
, data_offset
+32);
549 pvr_len
= linelen
-8-4;
550 proto_tree_add_protocol_format(zrtp_tree
, proto_zrtp
, tvb
, data_offset
+32, pvr_len
, (part
==1) ? "pvr Data" : "pvi Data");
551 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+32+pvr_len
, 8, ENC_NA
);
555 dissect_Commit(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
556 unsigned int msg_offset
= 12;
557 unsigned int data_offset
= 56;
567 col_set_str(pinfo
->cinfo
, COL_INFO
, "Commit Packet");
569 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hash_image
, tvb
, msg_offset
+12, 32, ENC_NA
);
571 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_zid
, tvb
, data_offset
+0, 12, ENC_NA
);
572 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, data_offset
+12, 4, ENC_ASCII
|ENC_NA
);
573 proto_tree_add_string_format_value(zrtp_tree
, hf_zrtp_msg_hash
, tvb
, data_offset
+12, 4, value
,
574 "%s", key_to_val(value
, 4, zrtp_hash_type_vals
, "Unknown hash type %s"));
575 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, data_offset
+16, 4, ENC_ASCII
|ENC_NA
);
576 proto_tree_add_string_format_value(zrtp_tree
, hf_zrtp_msg_cipher
, tvb
, data_offset
+16, 4, value
, "%s",
577 key_to_val(value
, 4, zrtp_cipher_type_vals
, "Unknown cipher type %s"));
578 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, data_offset
+20, 4, ENC_ASCII
|ENC_NA
);
579 proto_tree_add_string_format(zrtp_tree
, hf_zrtp_msg_at
, tvb
, data_offset
+20, 4, value
,
580 "Auth tag: %s", key_to_val(value
, 4, zrtp_auth_tag_vals
, "Unknown auth tag %s"));
581 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, data_offset
+24, 4, ENC_ASCII
|ENC_NA
);
582 proto_tree_add_string_format_value(zrtp_tree
, hf_zrtp_msg_keya
, tvb
, data_offset
+24, 4, value
,
583 "%s", key_to_val(value
, 4, zrtp_key_agreement_vals
, "Unknown key agreement %s"));
585 if(!strncmp(value
, "Mult", 4)) {
587 } else if (!strncmp(value
, "Prsh", 4)) {
590 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, data_offset
+28, 4, ENC_ASCII
|ENC_NA
);
591 proto_tree_add_string_format(zrtp_tree
, hf_zrtp_msg_sas
, tvb
, data_offset
+28, 4, value
,
592 "SAS type: %s", key_to_val(value
, 4, zrtp_sas_type_vals
, "Unknown SAS type %s"));
598 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_nonce
, tvb
, data_offset
+32, 16, ENC_NA
);
604 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_nonce
, tvb
, data_offset
+32, 16, ENC_NA
);
605 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_key_id
, tvb
, data_offset
+48, 8, ENC_NA
);
611 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hvi
, tvb
, data_offset
+32, 32, ENC_NA
);
616 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, data_offset
+offset
, 8, ENC_NA
);
620 dissect_Hello(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*zrtp_tree
) {
622 unsigned int msg_offset
= 12;
623 unsigned int data_offset
= 88;
626 unsigned int run_offset
;
627 unsigned int hc
, cc
, ac
, kc
, sc
;
628 unsigned int vhc
, vcc
, vac
, vkc
, vsc
;
631 proto_tree
*tmp_tree
;
633 col_set_str(pinfo
->cinfo
, COL_INFO
, "Hello Packet");
635 version_str
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, msg_offset
+12, 4, ENC_ASCII
|ENC_NA
);
636 if (check_valid_version(version_str
) == NULL
) {
637 col_set_str(pinfo
->cinfo
, COL_INFO
, "Unsupported version of ZRTP protocol");
639 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_version
, tvb
, msg_offset
+12, 4, ENC_ASCII
);
640 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_client_id
, tvb
, msg_offset
+16, 16, ENC_ASCII
);
641 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hash_image
, tvb
, msg_offset
+32, 32, ENC_NA
);
642 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_zid
, tvb
, msg_offset
+64, 12, ENC_NA
);
643 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_sigcap
, tvb
, data_offset
+0, 1, ENC_BIG_ENDIAN
);
644 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_mitm
, tvb
, data_offset
+0, 1, ENC_BIG_ENDIAN
);
645 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_passive
, tvb
, data_offset
+0, 1, ENC_BIG_ENDIAN
);
647 val_b
= tvb_get_uint8(tvb
, data_offset
+1);
651 val_b
= tvb_get_uint8(tvb
, data_offset
+2);
657 val_b
= tvb_get_uint8(tvb
, data_offset
+3);
663 ti
= proto_tree_add_uint_format(zrtp_tree
, hf_zrtp_msg_hash_count
, tvb
, data_offset
+1, 1, hc
, "Hash type count = %d", vhc
);
664 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_hc
);
665 run_offset
= data_offset
+4;
666 for (i
=0; i
<vhc
; i
++) {
667 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, run_offset
, 4, ENC_ASCII
|ENC_NA
);
668 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_hash
, tvb
, run_offset
, 4, value
,
669 "Hash[%d]: %s", i
, key_to_val(value
, 4, zrtp_hash_type_vals
, "Unknown hash type %s"));
672 ti
= proto_tree_add_uint_format(zrtp_tree
, hf_zrtp_msg_cipher_count
, tvb
, data_offset
+2, 1, cc
, "Cipher type count = %d", vcc
);
673 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_cc
);
674 for (i
=0; i
<vcc
; i
++) {
675 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, run_offset
, 4, ENC_ASCII
|ENC_NA
);
676 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_cipher
, tvb
, run_offset
, 4, value
, "Cipher[%d]: %s", i
,
677 key_to_val(value
, 4, zrtp_cipher_type_vals
, "Unknown cipher type %s"));
680 ti
= proto_tree_add_uint_format(zrtp_tree
, hf_zrtp_msg_authtag_count
, tvb
, data_offset
+2, 1, ac
, "Auth tag count = %d", vac
);
681 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_ac
);
682 for (i
=0; i
<vac
; i
++) {
683 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, run_offset
, 4, ENC_ASCII
|ENC_NA
);
684 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_at
, tvb
, run_offset
, 4, value
,
685 "Auth tag[%d]: %s", i
, key_to_val(value
, 4, zrtp_auth_tag_vals
, "Unknown auth tag %s"));
688 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
);
689 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_kc
);
690 for (i
=0; i
<vkc
; i
++) {
691 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, run_offset
, 4, ENC_ASCII
|ENC_NA
);
692 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_keya
, tvb
, run_offset
, 4, value
,
693 "Key agreement[%d]: %s", i
, key_to_val(value
, 4, zrtp_key_agreement_vals
, "Unknown key agreement %s"));
696 ti
= proto_tree_add_uint_format(zrtp_tree
, hf_zrtp_msg_sas_count
, tvb
, data_offset
+3, 1, sc
, "SAS type count = %d", vsc
);
697 tmp_tree
= proto_item_add_subtree(ti
, ett_zrtp_msg_sc
);
698 for (i
=0; i
<vsc
; i
++) {
699 value
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, run_offset
, 4, ENC_ASCII
|ENC_NA
);
700 proto_tree_add_string_format(tmp_tree
, hf_zrtp_msg_sas
, tvb
, run_offset
, 4, value
,
701 "SAS type[%d]: %s", i
, key_to_val(value
, 4, zrtp_sas_type_vals
, "Unknown SAS type %s"));
705 proto_tree_add_item(zrtp_tree
, hf_zrtp_msg_hmac
, tvb
, run_offset
, 8, ENC_NA
);
709 proto_register_zrtp(void)
711 static hf_register_info hf
[] = {
712 {&hf_zrtp_rtpversion
,
714 "RTP Version", "zrtp.rtpversion",
721 {&hf_zrtp_rtppadding
,
723 "RTP padding", "zrtp.rtppadding",
730 {&hf_zrtp_rtpextension
,
732 "RTP Extension", "zrtp.rtpextension",
752 "Sequence", "zrtp.sequence",
761 "Magic Cookie", "zrtp.cookie",
762 FT_STRING
, BASE_NONE
,
770 "Source Identifier", "zrtp.source_id",
782 "Signature", "zrtp.signature",
789 {&hf_zrtp_msg_length
,
791 "Length", "zrtp.length",
801 FT_STRING
, BASE_NONE
,
807 {&hf_zrtp_msg_version
,
809 "ZRTP protocol version", "zrtp.version",
810 FT_STRING
, BASE_NONE
,
816 {&hf_zrtp_msg_client_id
,
818 "Client Identifier", "zrtp.client_source_id",
819 FT_STRING
, BASE_NONE
,
825 {&hf_zrtp_msg_hash_image
,
827 "Hash Image", "zrtp.hash_image",
843 {&hf_zrtp_msg_sigcap
,
845 "Sig.capable", "zrtp.sigcap",
861 {&hf_zrtp_msg_passive
,
863 "Passive", "zrtp.passive",
870 {&hf_zrtp_msg_hash_count
,
872 "Hash Count", "zrtp.hc",
879 {&hf_zrtp_msg_cipher_count
,
881 "Cipher Count", "zrtp.cc",
888 {&hf_zrtp_msg_authtag_count
,
890 "Auth tag Count", "zrtp.ac",
897 {&hf_zrtp_msg_key_count
,
899 "Key Agreement Count", "zrtp.kc",
906 {&hf_zrtp_msg_sas_count
,
908 "SAS Count", "zrtp.sc",
918 FT_STRING
, BASE_NONE
,
924 {&hf_zrtp_msg_cipher
,
926 "Cipher", "zrtp.cipher",
927 FT_STRING
, BASE_NONE
,
936 FT_STRING
, BASE_NONE
,
944 "Key Agreement", "zrtp.keya",
945 FT_STRING
, BASE_NONE
,
954 FT_STRING
, BASE_NONE
,
962 "rs1ID", "zrtp.rs1id",
971 "rs2ID", "zrtp.rs2id",
1008 FT_BYTES
, BASE_NONE
,
1014 {&hf_zrtp_msg_error
,
1016 "Error", "zrtp.error",
1017 FT_UINT32
, BASE_DEC
,
1018 VALS(zrtp_error_vals
), 0x0,
1023 {&hf_zrtp_msg_ping_version
,
1025 "Ping Version", "zrtp.ping_version",
1026 FT_STRING
, BASE_NONE
,
1032 {&hf_zrtp_msg_ping_endpointhash
,
1034 "Ping Endpoint Hash", "zrtp.ping_endpointhash",
1035 FT_UINT64
, BASE_HEX
,
1041 {&hf_zrtp_msg_pingack_endpointhash
,
1043 "PingAck Endpoint Hash", "zrtp.pingack_endpointhash",
1044 FT_UINT64
, BASE_HEX
,
1050 {&hf_zrtp_msg_ping_ssrc
,
1052 "Ping SSRC", "zrtp.ping_ssrc",
1053 FT_UINT32
, BASE_HEX
,
1061 "Checksum", "zrtp.checksum",
1062 FT_UINT32
, BASE_HEX
,
1068 {&hf_zrtp_checksum_status
,
1070 "Checksum Status", "zrtp.checksum.status",
1071 FT_UINT8
, BASE_NONE
,
1072 VALS(proto_checksum_vals
), 0x0,
1080 FT_BYTES
, BASE_NONE
,
1086 {&hf_zrtp_msg_nonce
,
1088 "nonce", "zrtp.nonce",
1089 FT_BYTES
, BASE_NONE
,
1095 {&hf_zrtp_msg_key_id
,
1097 "key ID", "zrtp.key_id",
1098 FT_BYTES
, BASE_NONE
,
1105 static int *ett
[] = {
1117 static ei_register_info ei
[] = {
1118 { &ei_zrtp_checksum
, { "zrtp.bad_checksum", PI_CHECKSUM
, PI_ERROR
, "Bad checksum", EXPFILL
}},
1121 expert_module_t
* expert_zrtp
;
1123 proto_zrtp
= proto_register_protocol("ZRTP", "ZRTP", "zrtp");
1124 proto_register_field_array(proto_zrtp
, hf
, array_length(hf
));
1125 proto_register_subtree_array(ett
, array_length(ett
));
1126 zrtp_handle
= register_dissector("zrtp", dissect_zrtp
, proto_zrtp
);
1127 expert_zrtp
= expert_register_protocol(proto_zrtp
);
1128 expert_register_field_array(expert_zrtp
, ei
, array_length(ei
));
1132 proto_reg_handoff_zrtp(void)
1134 dissector_add_for_decode_as_with_preference("udp.port", zrtp_handle
);
1138 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1143 * indent-tabs-mode: nil
1146 * ex: set shiftwidth=2 tabstop=8 expandtab:
1147 * :indentSize=2:tabSize=8:noTabs=true: