Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-zrtp.c
blob1d5867d50eb7cd2470586a338962f5f01dba5047
1 /* packet-zrtp.c
2 * Routines for zrtp packet dissection
3 * IETF draft draft-zimmermann-avt-zrtp-22
4 * RFC 6189
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
16 #include "config.h"
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);
30 RTP header
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;
42 ZRTP header
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;
50 Hello Data
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;
70 Commit Data
72 static int hf_zrtp_msg_hvi;
73 static int hf_zrtp_msg_nonce;
74 static int hf_zrtp_msg_key_id;
77 DHParts Data
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;
85 Confirm Data
87 static int hf_zrtp_msg_hmac;
88 static int hf_zrtp_msg_cfb;
91 Error Data
93 static int hf_zrtp_msg_error;
96 Ping Data
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;
104 Checksum Data
106 static int hf_zrtp_checksum;
107 static int hf_zrtp_checksum_status;
110 Sub-Tree
112 static int ett_zrtp;
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;
131 Definitions
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
155 Text for Display
157 typedef struct _value_zrtp_versions {
158 const char *version;
159 } value_zrtp_versions;
162 typedef struct _value_string_keyval {
163 const char *key;
164 const char *val;
165 } value_string_keyval;
168 static const value_zrtp_versions valid_zrtp_versions[] =
170 {"1.1x"},
171 {"1.0x"},
172 {"0.95"},
173 {"0.90"},
174 {"0.85"},
175 {NULL}
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"},
184 { NULL, NULL }
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"},
198 { NULL, NULL }
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"},
207 { NULL, NULL }
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"},
214 { NULL, NULL }
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"},
227 { NULL, NULL }
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"},
252 { 0, NULL}
255 static void
256 dissect_Hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
257 static void
258 dissect_ErrorACK(packet_info *pinfo);
259 static void
260 dissect_Commit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
261 static void
262 dissect_ClearACK( packet_info *pinfo);
263 static void
264 dissect_Conf2ACK(packet_info *pinfo);
265 static void
266 dissect_HelloACK( packet_info *pinfo);
267 static void
268 dissect_GoClear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
269 static void
270 dissect_Error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
271 static void
272 dissect_Confirm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree, int part);
273 static void
274 dissect_DHPart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree, int part);
275 static void
276 dissect_SASrelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
277 static void
278 dissect_RelayACK(packet_info *pinfo);
279 static void
280 dissect_Ping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
281 static void
282 dissect_PingACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
285 static const char *
286 key_to_val(const char *key, int keylen, const value_string_keyval *kv, const char *fmt) {
287 int i = 0;
288 while (kv[i].key) {
289 if (!strncmp(kv[i].key, key, keylen)) {
290 return kv[i].val;
292 i++;
294 return wmem_strdup_printf(wmem_packet_scope(), fmt, key);
297 static const char *
298 check_valid_version(const char *version) {
299 int i = 0;
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;
305 i++;
307 return NULL;
311 static int
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;
317 proto_item *ti;
318 int linelen;
319 int checksum_offset;
320 unsigned char message_type[9];
321 unsigned int prime_offset = 0;
322 unsigned int msg_offset = 12;
323 uint32_t calc_crc;
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);
421 static void
422 dissect_ErrorACK(packet_info *pinfo) {
423 col_set_str(pinfo->cinfo, COL_INFO, "ErrorACK Packet");
426 static void
427 dissect_ClearACK(packet_info *pinfo) {
428 col_set_str(pinfo->cinfo, COL_INFO, "ClearACK Packet");
431 static void
432 dissect_RelayACK(packet_info *pinfo) {
433 col_set_str(pinfo->cinfo, COL_INFO, "RelayACK Packet");
436 static void
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");
462 static void
463 dissect_HelloACK(packet_info *pinfo) {
464 col_set_str(pinfo->cinfo, COL_INFO, "HelloACK Packet");
467 static void
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);
477 static void
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);
489 static void
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);
500 static void
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);
509 static void
510 dissect_Confirm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree, int part) {
511 unsigned int data_offset = 24;
512 int linelen;
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");
522 static void
523 dissect_SASrelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
524 unsigned int data_offset = 24;
525 int linelen;
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");
535 static void
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);
554 static void
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;
558 char *value;
559 int key_type = 0;
561 0 - other type
562 1 - "Mult"
563 2 - "Prsh"
565 unsigned int offset;
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);
570 /* ZID */
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)) {
586 key_type = 1;
587 } else if (!strncmp(value, "Prsh", 4)) {
588 key_type = 2;
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"));
594 switch (key_type) {
595 case 1: /*
596 Mult
598 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_nonce, tvb, data_offset+32, 16, ENC_NA);
599 offset = 48;
600 break;
601 case 2: /*
602 Prsh
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);
606 offset = 56;
607 break;
608 default: /*
609 other
611 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hvi, tvb, data_offset+32, 32, ENC_NA);
612 offset = 64;
613 break;
616 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hmac, tvb, data_offset+offset, 8, ENC_NA);
619 static void
620 dissect_Hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
621 proto_item *ti;
622 unsigned int msg_offset = 12;
623 unsigned int data_offset = 88;
624 uint8_t val_b;
625 unsigned int i;
626 unsigned int run_offset;
627 unsigned int hc, cc, ac, kc, sc;
628 unsigned int vhc, vcc, vac, vkc, vsc;
629 char *value;
630 char *version_str;
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);
648 hc = val_b & 0x0F;
649 vhc = hc;
651 val_b = tvb_get_uint8(tvb, data_offset+2);
652 cc = val_b & 0xF0;
653 ac = val_b & 0x0F;
654 vcc = cc >> 4;
655 vac = ac;
657 val_b = tvb_get_uint8(tvb, data_offset+3);
658 kc = val_b & 0xF0;
659 sc = val_b & 0x0F;
660 vkc = kc >> 4;
661 vsc = sc;
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"));
670 run_offset += 4;
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"));
678 run_offset += 4;
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"));
686 run_offset += 4;
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"));
694 run_offset += 4;
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"));
702 run_offset += 4;
705 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hmac, tvb, run_offset, 8, ENC_NA);
708 void
709 proto_register_zrtp(void)
711 static hf_register_info hf[] = {
712 {&hf_zrtp_rtpversion,
714 "RTP Version", "zrtp.rtpversion",
715 FT_UINT8, BASE_DEC,
716 NULL, 0xC0,
717 NULL, HFILL
721 {&hf_zrtp_rtppadding,
723 "RTP padding", "zrtp.rtppadding",
724 FT_BOOLEAN, 8,
725 NULL, 0x20,
726 NULL, HFILL
730 {&hf_zrtp_rtpextension,
732 "RTP Extension", "zrtp.rtpextension",
733 FT_BOOLEAN, 8,
734 NULL, 0x10,
735 NULL, HFILL
739 #if 0
740 {&hf_zrtp_id,
742 "ID", "zrtp.id",
743 FT_UINT8, BASE_HEX,
744 NULL, 0x0,
745 NULL, HFILL
748 #endif
750 {&hf_zrtp_sequence,
752 "Sequence", "zrtp.sequence",
753 FT_UINT16, BASE_DEC,
754 NULL, 0x0,
755 NULL, HFILL
759 {&hf_zrtp_cookie,
761 "Magic Cookie", "zrtp.cookie",
762 FT_STRING, BASE_NONE,
763 NULL, 0x0,
764 NULL, HFILL
768 {&hf_zrtp_source_id,
770 "Source Identifier", "zrtp.source_id",
771 FT_UINT32, BASE_HEX,
772 NULL, 0x0,
773 NULL, HFILL
778 Message Types
780 {&hf_zrtp_signature,
782 "Signature", "zrtp.signature",
783 FT_UINT16, BASE_HEX,
784 NULL, 0x0,
785 NULL, HFILL
789 {&hf_zrtp_msg_length,
791 "Length", "zrtp.length",
792 FT_UINT16, BASE_DEC,
793 NULL, 0x0,
794 NULL, HFILL
798 {&hf_zrtp_msg_type,
800 "Type", "zrtp.type",
801 FT_STRING, BASE_NONE,
802 NULL, 0x0,
803 NULL, HFILL
807 {&hf_zrtp_msg_version,
809 "ZRTP protocol version", "zrtp.version",
810 FT_STRING, BASE_NONE,
811 NULL, 0x0,
812 NULL, HFILL
816 {&hf_zrtp_msg_client_id,
818 "Client Identifier", "zrtp.client_source_id",
819 FT_STRING, BASE_NONE,
820 NULL, 0x0,
821 NULL, HFILL
825 {&hf_zrtp_msg_hash_image,
827 "Hash Image", "zrtp.hash_image",
828 FT_BYTES, BASE_NONE,
829 NULL, 0x0,
830 NULL, HFILL
834 {&hf_zrtp_msg_zid,
836 "ZID", "zrtp.zid",
837 FT_BYTES, BASE_NONE,
838 NULL, 0x0,
839 NULL, HFILL
843 {&hf_zrtp_msg_sigcap,
845 "Sig.capable", "zrtp.sigcap",
846 FT_BOOLEAN, 8,
847 NULL, 0x40,
848 NULL, HFILL
852 {&hf_zrtp_msg_mitm,
854 "MiTM", "zrtp.mitm",
855 FT_BOOLEAN, 8,
856 NULL, 0x20,
857 NULL, HFILL
861 {&hf_zrtp_msg_passive,
863 "Passive", "zrtp.passive",
864 FT_BOOLEAN, 8,
865 NULL, 0x10,
866 NULL, HFILL
870 {&hf_zrtp_msg_hash_count,
872 "Hash Count", "zrtp.hc",
873 FT_UINT8, BASE_DEC,
874 NULL, 0x0F,
875 NULL, HFILL
879 {&hf_zrtp_msg_cipher_count,
881 "Cipher Count", "zrtp.cc",
882 FT_UINT8, BASE_DEC,
883 NULL, 0xF0,
884 NULL, HFILL
888 {&hf_zrtp_msg_authtag_count,
890 "Auth tag Count", "zrtp.ac",
891 FT_UINT8, BASE_DEC,
892 NULL, 0x0F,
893 NULL, HFILL
897 {&hf_zrtp_msg_key_count,
899 "Key Agreement Count", "zrtp.kc",
900 FT_UINT8, BASE_DEC,
901 NULL, 0xF0,
902 NULL, HFILL
906 {&hf_zrtp_msg_sas_count,
908 "SAS Count", "zrtp.sc",
909 FT_UINT8, BASE_DEC,
910 NULL, 0x0F,
911 NULL, HFILL
915 {&hf_zrtp_msg_hash,
917 "Hash", "zrtp.hash",
918 FT_STRING, BASE_NONE,
919 NULL, 0x0,
920 NULL, HFILL
924 {&hf_zrtp_msg_cipher,
926 "Cipher", "zrtp.cipher",
927 FT_STRING, BASE_NONE,
928 NULL, 0x0,
929 NULL, HFILL
933 {&hf_zrtp_msg_at,
935 "AT", "zrtp.at",
936 FT_STRING, BASE_NONE,
937 NULL, 0x0,
938 NULL, HFILL
942 {&hf_zrtp_msg_keya,
944 "Key Agreement", "zrtp.keya",
945 FT_STRING, BASE_NONE,
946 NULL, 0x0,
947 NULL, HFILL
951 {&hf_zrtp_msg_sas,
953 "SAS", "zrtp.sas",
954 FT_STRING, BASE_NONE,
955 NULL, 0x0,
956 NULL, HFILL
960 {&hf_zrtp_msg_rs1ID,
962 "rs1ID", "zrtp.rs1id",
963 FT_BYTES, BASE_NONE,
964 NULL, 0x0,
965 NULL, HFILL
969 {&hf_zrtp_msg_rs2ID,
971 "rs2ID", "zrtp.rs2id",
972 FT_BYTES, BASE_NONE,
973 NULL, 0x0,
974 NULL, HFILL
978 {&hf_zrtp_msg_auxs,
980 "auxs", "zrtp.auxs",
981 FT_BYTES, BASE_NONE,
982 NULL, 0x0,
983 NULL, HFILL
987 {&hf_zrtp_msg_pbxs,
989 "pbxs", "zrtp.pbxs",
990 FT_BYTES, BASE_NONE,
991 NULL, 0x0,
992 NULL, HFILL
996 {&hf_zrtp_msg_hmac,
998 "HMAC", "zrtp.hmac",
999 FT_BYTES, BASE_NONE,
1000 NULL, 0x0,
1001 NULL, HFILL
1005 {&hf_zrtp_msg_cfb,
1007 "CFB", "zrtp.cfb",
1008 FT_BYTES, BASE_NONE,
1009 NULL, 0x0,
1010 NULL, HFILL
1014 {&hf_zrtp_msg_error,
1016 "Error", "zrtp.error",
1017 FT_UINT32, BASE_DEC,
1018 VALS(zrtp_error_vals), 0x0,
1019 NULL, HFILL
1023 {&hf_zrtp_msg_ping_version,
1025 "Ping Version", "zrtp.ping_version",
1026 FT_STRING, BASE_NONE,
1027 NULL, 0x0,
1028 NULL, HFILL
1032 {&hf_zrtp_msg_ping_endpointhash,
1034 "Ping Endpoint Hash", "zrtp.ping_endpointhash",
1035 FT_UINT64, BASE_HEX,
1036 NULL, 0x0,
1037 NULL, HFILL
1041 {&hf_zrtp_msg_pingack_endpointhash,
1043 "PingAck Endpoint Hash", "zrtp.pingack_endpointhash",
1044 FT_UINT64, BASE_HEX,
1045 NULL, 0x0,
1046 NULL, HFILL
1050 {&hf_zrtp_msg_ping_ssrc,
1052 "Ping SSRC", "zrtp.ping_ssrc",
1053 FT_UINT32, BASE_HEX,
1054 NULL, 0x0,
1055 NULL, HFILL
1059 {&hf_zrtp_checksum,
1061 "Checksum", "zrtp.checksum",
1062 FT_UINT32, BASE_HEX,
1063 NULL, 0x0,
1064 NULL, HFILL
1068 {&hf_zrtp_checksum_status,
1070 "Checksum Status", "zrtp.checksum.status",
1071 FT_UINT8, BASE_NONE,
1072 VALS(proto_checksum_vals), 0x0,
1073 NULL, HFILL
1077 {&hf_zrtp_msg_hvi,
1079 "hvi", "zrtp.hvi",
1080 FT_BYTES, BASE_NONE,
1081 NULL, 0x0,
1082 NULL, HFILL
1086 {&hf_zrtp_msg_nonce,
1088 "nonce", "zrtp.nonce",
1089 FT_BYTES, BASE_NONE,
1090 NULL, 0x0,
1091 NULL, HFILL
1095 {&hf_zrtp_msg_key_id,
1097 "key ID", "zrtp.key_id",
1098 FT_BYTES, BASE_NONE,
1099 NULL, 0x0,
1100 NULL, HFILL
1105 static int *ett[] = {
1106 &ett_zrtp,
1107 &ett_zrtp_msg,
1108 &ett_zrtp_msg_data,
1109 &ett_zrtp_msg_hc,
1110 &ett_zrtp_msg_kc,
1111 &ett_zrtp_msg_ac,
1112 &ett_zrtp_msg_cc,
1113 &ett_zrtp_msg_sc,
1114 &ett_zrtp_checksum
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));
1131 void
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
1140 * Local Variables:
1141 * c-basic-offset: 2
1142 * tab-width: 8
1143 * indent-tabs-mode: nil
1144 * End:
1146 * ex: set shiftwidth=2 tabstop=8 expandtab:
1147 * :indentSize=2:tabSize=8:noTabs=true: