2 * Routines for Multimedia Internet KEYing dissection
3 * Copyright 2007, Mikael Magnusson <mikma@users.sourceforge.net>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 * https://tools.ietf.org/html/rfc3830 MIKEY
14 * https://tools.ietf.org/html/rfc6043 MIKEY-TICKET (ID role required for SAKKE)
15 * https://tools.ietf.org/html/rfc6509 MIKEY-SAKKE
20 * tvbuff offset in 32-bit variable.
22 * Decode Mikey-PK and Mikey-RSA-R with NULL encryption
28 #include <epan/packet.h>
29 #include <epan/asn1.h>
30 #include <epan/proto_data.h>
32 #include <wsutil/array.h>
33 #include "packet-x509af.h"
35 void proto_register_mikey(void);
36 void proto_reg_handoff_mikey(void);
38 #define PORT_MIKEY 2269
40 static const value_string on_off_vals
[] = {
47 MIKEY_TYPE_PSK_INIT
= 0,
54 MIKEY_TYPE_DHHMAC_INIT
,
55 MIKEY_TYPE_DHHMAC_RESP
,
56 MIKEY_TYPE_RSA_R_INIT
,
57 MIKEY_TYPE_RSA_R_RESP
,
58 MIKEY_TYPE_SAKKE_INIT
= 26,
62 static const value_string data_type_vals
[] = {
63 { MIKEY_TYPE_PSK_INIT
, "Pre-shared" },
64 { MIKEY_TYPE_PSK_RESP
, "PSK ver msg" },
65 { MIKEY_TYPE_PK_INIT
, "Public key" },
66 { MIKEY_TYPE_PK_RESP
, "PK ver msg" },
67 { MIKEY_TYPE_DH_INIT
, "D-H init" },
68 { MIKEY_TYPE_DH_RESP
, "D-H resp" },
69 { MIKEY_TYPE_ERROR
, "Error" },
70 { MIKEY_TYPE_DHHMAC_INIT
, "DHHMAC init" },
71 { MIKEY_TYPE_DHHMAC_RESP
, "DHHMAC resp" },
72 { MIKEY_TYPE_RSA_R_INIT
, "RSA-R I_MSG" },
73 { MIKEY_TYPE_RSA_R_RESP
, "RSA-R R_MSG" },
74 { MIKEY_TYPE_SAKKE_INIT
, "SAKKE" },
75 { MIKEY_TYPE_SAKKE_RESP
, "CS Id map Update" },
78 static value_string_ext data_type_vals_ext
= VALUE_STRING_EXT_INIT(data_type_vals
);
84 static const value_string cs_id_map_vals
[] = {
85 { CS_ID_SRTP
, "SRTP-ID" },
104 PL_TR
= 13, /* MIKEY-TICKET (6043) */
115 #define PL_HDR_TEXT "Common Header (HDR)"
116 #define PL_LAST_TEXT "Last payload"
117 #define PL_KEMAC_TEXT "Key Data Transport (KEMAC)"
118 #define PL_PKE_TEXT "Envelope Data (PKE)"
119 #define PL_DH_TEXT "DH Data (DH)"
120 #define PL_SIGN_TEXT "Signature (SIGN)"
121 #define PL_T_TEXT "Timestamp (T)"
122 #define PL_ID_TEXT "ID"
123 #define PL_CERT_TEXT "Certificate (CERT)"
124 #define PL_CHASH_TEXT "CHASH"
125 #define PL_V_TEXT "Ver msg (V)"
126 #define PL_SP_TEXT "Security Policy (SP)"
127 #define PL_RAND_TEXT "RAND"
128 #define PL_ERR_TEXT "Error (ERR)"
129 #define PL_KEY_DATA_TEXT "Key data (KEY)"
130 #define PL_IDR_TEXT "IDR"
131 #define PL_GENERAL_EXT_TEXT "General Extension (EXT)"
132 #define PL_SAKKE_TEXT "SAKKE Encapsulated Data (SAKKE)"
134 static const value_string payload_vals
[] = {
135 { PL_HDR
, PL_HDR_TEXT
},
136 { PL_LAST
, PL_LAST_TEXT
},
137 { PL_KEMAC
, PL_KEMAC_TEXT
},
138 { PL_PKE
, PL_PKE_TEXT
},
139 { PL_DH
, PL_DH_TEXT
},
140 { PL_SIGN
, PL_SIGN_TEXT
},
142 { PL_ID
, PL_ID_TEXT
},
143 { PL_CERT
, PL_CERT_TEXT
},
144 { PL_CHASH
, PL_CHASH_TEXT
},
146 { PL_SP
, PL_SP_TEXT
},
147 { PL_RAND
, PL_RAND_TEXT
},
148 { PL_ERR
, PL_ERR_TEXT
},
149 { PL_IDR
, PL_IDR_TEXT
},
150 { PL_KEY_DATA
, PL_KEY_DATA_TEXT
},
151 { PL_GENERAL_EXT
, PL_GENERAL_EXT_TEXT
},
152 { PL_SAKKE
, PL_SAKKE_TEXT
},
155 #if 0 /* First entry (PL_HDR) is -1 and there are gaps so this doesn't work */
156 static value_string_ext payload_vals_ext
= VALUE_STRING_EXT_INIT(payload_vals
);
165 static const value_string ts_type_vals
[] = {
166 { T_NTP_UTC
, "NTP-UTC" },
168 { T_COUNTER
, "COUNTER" },
178 static const value_string encr_alg_vals
[] = {
179 { ENCR_NULL
, "NULL" },
180 { ENCR_AES_CM_128
, "AES-CM-128" },
181 { ENCR_AES_KW_128
, "AES-KW-128" },
191 static const value_string oakley_vals
[] = {
192 { DH_OAKLEY_5
, "OAKLEY 5" },
193 { DH_OAKLEY_1
, "OAKLEY 1" },
194 { DH_OAKLEY_2
, "OAKLEY 2" },
203 static const value_string mac_alg_vals
[] = {
204 { MAC_NULL
, "NULL" },
205 { MAC_HMAC_SHA_1_160
, "HMAC-SHA-1-160" },
215 static const value_string pke_c_vals
[] = {
216 { PKE_C_NO_CACHE
, "No cache" },
217 { PKE_C_CACHE
, "Cache" },
218 { PKE_C_CACHE_CSB
, "Cache for CSB" },
228 static const value_string sign_s_vals
[] = {
229 { SIGN_S_PKCS1
, "RSA/PKCS#1/1.5" },
230 { SIGN_S_PSS
, "RSA/PSS" },
231 { SIGN_S_ECCSI
, "ECCSI" },
241 static const value_string id_type_vals
[] = {
242 { ID_TYPE_NAI
, "NAI" },
243 { ID_TYPE_URI
, "URI" },
244 { ID_TYPE_BYTE_STRING
, "Byte string" },
249 ID_ROLE_RESERVED
= 0,
259 static const value_string id_role_vals
[] = {
260 { ID_ROLE_RESERVED
, "Reserved" },
261 { ID_ROLE_INIT
, "Initiator (IDRi)" },
262 { ID_ROLE_RESP
, "Responder (IDRr)" },
263 { ID_ROLE_KMS
, "KMS (IDRkms)" },
264 { ID_ROLE_PSK
, "Pre-Shared Key (IDRpsk)" },
265 { ID_ROLE_APP
, "Application (IDRapp)" },
266 { ID_ROLE_INIT_KMS
, "Initiator's KMS (IDRkmsi)" },
267 { ID_ROLE_RESP_KMS
, "Responder's KMS (IDRkmsr)" },
272 CERT_TYPE_X509V3
= 0,
273 CERT_TYPE_X509V3_URL
,
274 CERT_TYPE_X509V3_SIGN
,
275 CERT_TYPE_X509V3_ENCR
278 static const value_string cert_type_vals
[] = {
279 { CERT_TYPE_X509V3
, "X.509v3" },
280 { CERT_TYPE_X509V3_URL
, "X.509v3 URL" },
281 { CERT_TYPE_X509V3_SIGN
, "X.509v3 Sign" },
282 { CERT_TYPE_X509V3_ENCR
, "X.509v3 Encr" },
286 enum srtp_policy_type_t
{
303 #define SP_TEXT_ENCR_ALG "Encryption algorithm"
304 #define SP_TEXT_ENCR_LEN "Session Encr. key length"
305 #define SP_TEXT_AUTH_ALG "Authentication algorithm"
306 #define SP_TEXT_AUTH_KEY_LEN "Session Auth. key length"
307 #define SP_TEXT_SALT_LEN "Session Salt key length"
308 #define SP_TEXT_PRF "SRTP Pseudo Random Function"
309 #define SP_TEXT_KD_RATE "Key derivation rate"
310 #define SP_TEXT_SRTP_ENCR "SRTP encryption"
311 #define SP_TEXT_SRTCP_ENCR "SRTCP encryption"
312 #define SP_TEXT_FEC "Sender's FEC order"
313 #define SP_TEXT_SRTP_AUTH "SRTP authentication"
314 #define SP_TEXT_AUTH_TAG_LEN "Authentication tag length"
315 #define SP_TEXT_SRTP_PREFIX "SRTP prefix length"
318 static const value_string srtp_policy_type_vals
[] = {
319 { SP_ENCR_ALG
, SP_TEXT_ENCR_ALG
},
320 { SP_ENCR_LEN
, SP_TEXT_ENCR_LEN
},
321 { SP_AUTH_ALG
, SP_TEXT_AUTH_ALG
},
322 { SP_AUTH_KEY_LEN
, SP_TEXT_AUTH_KEY_LEN
},
323 { SP_SALT_LEN
, SP_TEXT_SALT_LEN
},
324 { SP_PRF
, SP_TEXT_PRF
},
325 { SP_KD_RATE
, SP_TEXT_KD_RATE
},
326 { SP_SRTP_ENCR
, SP_TEXT_SRTP_ENCR
},
327 { SP_SRTCP_ENCR
, SP_TEXT_SRTCP_ENCR
},
328 { SP_FEC
, SP_TEXT_FEC
},
329 { SP_SRTP_AUTH
, SP_TEXT_SRTP_AUTH
},
330 { SP_AUTH_TAG_LEN
, SP_TEXT_AUTH_TAG_LEN
},
331 { SP_SRTP_PREFIX
, SP_TEXT_SRTP_PREFIX
},
342 static const value_string sp_encr_alg_vals
[] = {
343 { SP_ENCR_NULL
, "NULL" },
344 { SP_ENCR_AES_CM
, "AES-CM" },
345 { SP_ENCR_AES_F8
, "AES-F8" },
354 static const value_string sp_auth_alg_vals
[] = {
355 { SP_AUTH_NULL
, "NULL" },
356 { SP_AUTH_HMAC_SHA_1
, "HMAC-SHA-1" },
364 static const value_string sp_prf_vals
[] = {
365 { SP_PRF_AES_CM
, "AES-CM" },
373 static const value_string sp_fec_vals
[] = {
374 { SP_FEC_SRTP
, "FEC-SRTP" },
379 SP_PROT_TYPE_SRTP
= 0
382 static const value_string sp_prot_type_vals
[] = {
383 { SP_PROT_TYPE_SRTP
, "SRTP" },
391 static const value_string prf_func_vals
[] = {
392 { PRF_FUNC_MIKEY_1
, "MIKEY-1" },
402 static const value_string kv_vals
[] = {
404 { KV_SPI
, "SPI/MKI" },
405 { KV_INTERVAL
, "Interval" },
416 static const value_string kd_vals
[] = {
418 { KD_TGK_SALT
, "TGK+SALT" },
420 { KD_TEK_SALT
, "TEK+SALT" },
425 ERR_AUTH_FAILURE
= 0,
440 static const value_string err_vals
[] = {
441 { ERR_AUTH_FAILURE
, "Authentication failure" },
442 { ERR_INVALID_TS
, "Invalid timestamp" },
443 { ERR_INVALID_PRF
, "PRF function not supported" },
444 { ERR_INVALID_MAC
, "MAC algorithm not supported" },
445 { ERR_INVALID_EA
, "Encryption algorithm not supported" },
446 { ERR_INVALID_HA
, "Hash function not supported" },
447 { ERR_INVALID_DH
, "DH group not supported" },
448 { ERR_INVALID_ID
, "ID not supported" },
449 { ERR_INVALID_CERT
, "Certificate not supported" },
450 { ERR_INVALID_SP
, "SP type not supported" },
451 { ERR_INVALID_SPPAR
, "SP parameters not supported" },
452 { ERR_INVALID_DT
, "Data type not supported" },
453 { ERR_UNKNOWN
, "Unspecified error" },
456 static value_string_ext err_vals_ext
= VALUE_STRING_EXT_INIT(err_vals
);
459 GEN_EXT_VENDOR_ID
= 0,
463 static const value_string genext_type_vals
[] = {
464 { GEN_EXT_VENDOR_ID
, "Vendor-ID" },
465 { GEN_EXT_SDP_ID
, "SDP-IDs" },
477 POS_HDR_CS_ID_MAP_TYPE
,
485 POS_KEMAC_ENCR_DATA_LEN
,
535 POS_SP_PARAM_F_VALUE
,
560 POS_GENERAL_EXT_TYPE
,
562 POS_GENERAL_EXT_DATA
,
563 POS_GENERAL_EXT_VALUE
,
581 typedef struct tag_mikey_t
{
585 typedef int (*mikey_dissector_t
)(mikey_t
*, tvbuff_t
*, packet_info
*, proto_tree
*);
586 struct mikey_dissector_entry
{
588 mikey_dissector_t dissector
;
591 /* Forward declaration we need below */
592 static int dissect_payload(int payload
, mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
595 /* Initialize the protocol and registered fields */
596 static int proto_mikey
;
597 static int hf_mikey
[MAX_POS
+1];
598 static int hf_mikey_sp_param
[SP_MAX
+1];
599 static int hf_mikey_pl
[PL_MAX
];
601 /* Initialize the subtree pointers */
602 static int ett_mikey
;
603 static int ett_mikey_payload
;
604 static int ett_mikey_sp_param
;
605 static int ett_mikey_hdr_id
;
606 static int ett_mikey_enc_data
;
608 static dissector_handle_t mikey_handle
;
610 static const struct mikey_dissector_entry
*
611 mikey_dissector_lookup(const struct mikey_dissector_entry
*map
, int type
)
614 for (i
= 0; map
[i
].dissector
!= NULL
; i
++) {
615 if (map
[i
].type
== type
) {
624 add_next_payload(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
626 proto_tree_add_item(tree
, hf_mikey
[POS_NEXT_PAYLOAD
], tvb
, offset
, 1, ENC_BIG_ENDIAN
);
631 dissect_payload_cs_id_srtp(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
640 no
= tvb_get_uint8(tvb
, 0);
641 ssrc
= tvb_get_ntohl(tvb
, 1);
642 roc
= tvb_get_ntohl(tvb
, 5);
644 id_ti
= proto_tree_add_none_format(tree
, hf_mikey
[POS_ID_SRTP
], tvb
, 0, 9,
645 "SRTP ID: Policy: %d, SSRC: 0x%x, ROC: 0x%x", no
, ssrc
, roc
);
646 id_tree
= proto_item_add_subtree(id_ti
, ett_mikey_hdr_id
);
648 proto_tree_add_item(id_tree
, hf_mikey
[POS_ID_SRTP_NO
], tvb
, 0, 1, ENC_BIG_ENDIAN
);
649 proto_tree_add_item(id_tree
, hf_mikey
[POS_ID_SRTP_SSRC
], tvb
, 1, 4, ENC_BIG_ENDIAN
);
650 proto_tree_add_item(id_tree
, hf_mikey
[POS_ID_SRTP_ROC
], tvb
, 5, 4, ENC_BIG_ENDIAN
);
655 static const struct mikey_dissector_entry cs_id_map
[] = {
656 { CS_ID_SRTP
, dissect_payload_cs_id_srtp
},
661 dissect_payload_cs_id(int type
, mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
663 const struct mikey_dissector_entry
*entry
;
665 entry
= mikey_dissector_lookup(cs_id_map
, type
);
667 if (!entry
|| !entry
->dissector
) {
671 return entry
->dissector(mikey
, tvb
, pinfo
, tree
);
676 dissect_payload_hdr(mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
679 uint8_t cs_id_map_type
;
683 tvb_ensure_bytes_exist(tvb
, offset
, 10);
684 mikey
->type
= tvb_get_uint8(tvb
, offset
+1);
685 ncs
= tvb_get_uint8(tvb
, offset
+8);
686 cs_id_map_type
= tvb_get_uint8(tvb
, offset
+9);
690 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_VERSION
],
691 tvb
, offset
+0, 1, ENC_BIG_ENDIAN
);
693 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_DATA_TYPE
], tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
694 parent
= proto_tree_get_parent(tree
);
695 proto_item_append_text(parent
, " Type: %s",
696 val_to_str_ext_const(mikey
->type
, &data_type_vals_ext
, "Unknown"));
698 add_next_payload(tvb
, tree
, offset
+2);
700 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_V
], tvb
, offset
+3, 1, ENC_BIG_ENDIAN
);
701 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_PRF_FUNC
], tvb
, offset
+3, 1, ENC_BIG_ENDIAN
);
703 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_CSB_ID
], tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
705 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_CS_COUNT
], tvb
, offset
+8, 1, ENC_BIG_ENDIAN
);
706 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_CS_ID_MAP_TYPE
], tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
710 for (i
=0; i
< ncs
; i
++) {
714 sub_tvb
= tvb_new_subset_remaining(tvb
, offset
);
715 len
= dissect_payload_cs_id(cs_id_map_type
, mikey
, sub_tvb
, pinfo
, tree
);
727 dissect_payload_kemac(mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
731 uint16_t encr_length
;
735 encr_alg
= tvb_get_uint8(tvb
, offset
+1);
736 encr_length
= tvb_get_ntohs(tvb
, offset
+2);
737 tvb_ensure_bytes_exist(tvb
, offset
+4, encr_length
+1);
738 mac_alg
= tvb_get_uint8(tvb
, offset
+4+encr_length
);
742 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_ENCR_ALG
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
743 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_ENCR_DATA_LEN
], tvb
, 2, 2, ENC_BIG_ENDIAN
);
744 /* TODO: Add key decode for MIKEY_TYPE_PK_INIT and MIKEY_TYPE_RSA_R_RESP with NULL encryption */
745 if ((encr_alg
== ENCR_NULL
) && (mikey
->type
== MIKEY_TYPE_PSK_INIT
) && (encr_length
> 0)) {
746 proto_item
*key_data_item
;
747 proto_tree
*key_data_tree
;
748 /* We can decode easily the Key Data if NULL encryption is used */
749 key_data_item
= proto_tree_add_item(tree
, hf_mikey_pl
[PL_KEY_DATA
], tvb
, 4, encr_length
, ENC_NA
);
750 key_data_tree
= proto_item_add_subtree(key_data_item
, ett_mikey_enc_data
);
752 sub_tvb
= tvb_new_subset_length(tvb
, offset
+4, encr_length
);
753 dissect_payload(PL_KEY_DATA
, mikey
, sub_tvb
, pinfo
, key_data_tree
);
755 /* If Key Data is encrypted, show only the encr_data */
756 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_ENCR_DATA
], tvb
, 4, encr_length
, ENC_NA
);
758 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_MAC_ALG
], tvb
, 4+encr_length
, 1, ENC_BIG_ENDIAN
);
765 case MAC_HMAC_SHA_1_160
:
772 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_MAC
], tvb
, 4+encr_length
+1, mac_length
, ENC_NA
);
774 return 4+encr_length
+1+mac_length
;
778 dissect_payload_pke(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
783 length
= tvb_get_ntohs(tvb
, offset
+1) &0x3ff;
786 proto_tree_add_item(tree
, hf_mikey
[POS_PKE_C
], tvb
, 1, 2, ENC_BIG_ENDIAN
);
788 proto_tree_add_item(tree
, hf_mikey
[POS_PKE_DATA_LEN
], tvb
, 1, 2, ENC_BIG_ENDIAN
);
791 proto_tree_add_item(tree
, hf_mikey
[POS_PKE_DATA
], tvb
, 3, length
, ENC_NA
);
796 dissect_payload_dh(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
803 dh_group
= tvb_get_uint8(tvb
, offset
+1);
819 kv
= tvb_get_uint8(tvb
, offset
+2+dh_length
) & 0x0f;
822 proto_tree_add_item(tree
, hf_mikey
[POS_DH_GROUP
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
823 proto_tree_add_item(tree
, hf_mikey
[POS_DH_VALUE
], tvb
, 2, dh_length
, ENC_NA
);
824 proto_tree_add_item(tree
, hf_mikey
[POS_DH_RESERV
], tvb
, 2+dh_length
, 1, ENC_BIG_ENDIAN
);
825 proto_tree_add_item(tree
, hf_mikey
[POS_DH_KV
], tvb
, 2+dh_length
, 1, ENC_BIG_ENDIAN
);
832 return 2 + dh_length
+ 1;
836 dissect_payload_sign(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
841 length
= ((tvb_get_uint8(tvb
, offset
+0) & 0x0f) << 8) + tvb_get_uint8(tvb
, offset
+1);
844 proto_tree_add_item(tree
, hf_mikey
[POS_SIGN_S_TYPE
], tvb
, 0, 2, ENC_BIG_ENDIAN
);
845 proto_tree_add_uint(tree
, hf_mikey
[POS_SIGNATURE_LEN
], tvb
, 0, 2, length
);
848 proto_tree_add_item(tree
, hf_mikey
[POS_SIGNATURE
], tvb
, 2, length
, ENC_NA
);
853 dissect_payload_t(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
859 ts_type
= tvb_get_uint8(tvb
, offset
+1);
863 parent
= proto_tree_get_parent(tree
);
864 proto_item_append_text(parent
, " Type: %s", val_to_str_const(ts_type
, ts_type_vals
, "Unknown"));
865 proto_tree_add_item(tree
, hf_mikey
[POS_TS_TYPE
], tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
871 proto_tree_add_item(tree
, hf_mikey
[POS_TS_NTP
], tvb
, offset
+2, 8, ENC_TIME_NTP
|ENC_BIG_ENDIAN
);
886 dissect_payload_id(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
892 type
= tvb_get_uint8(tvb
, offset
+1);
893 length
= tvb_get_ntohs(tvb
, offset
+2);
895 proto_tree_add_item(tree
, hf_mikey
[POS_ID_TYPE
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
896 proto_tree_add_item(tree
, hf_mikey
[POS_ID_LEN
], tvb
, 2, 2, ENC_BIG_ENDIAN
);
901 const uint8_t* pos_id
;
902 proto_tree_add_item_ret_string(tree
, hf_mikey
[POS_ID
], tvb
, 4, length
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &pos_id
);
904 parent
= proto_tree_get_parent(tree
);
905 proto_item_append_text(parent
, " %s: %s", val_to_str_const(type
, id_type_vals
, "Unknown"), pos_id
);
912 dissect_payload_idr(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
918 type
= tvb_get_uint8(tvb
, offset
+2);
919 length
= tvb_get_ntohs(tvb
, offset
+3);
921 proto_tree_add_item(tree
, hf_mikey
[POS_ID_ROLE
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
922 proto_tree_add_item(tree
, hf_mikey
[POS_ID_TYPE
], tvb
, 2, 1, ENC_BIG_ENDIAN
);
923 proto_tree_add_item(tree
, hf_mikey
[POS_ID_LEN
], tvb
, 3, 2, ENC_BIG_ENDIAN
);
928 const uint8_t* pos_id
;
929 proto_tree_add_item_ret_string(tree
, hf_mikey
[POS_ID
], tvb
, 5, length
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &pos_id
);
931 parent
= proto_tree_get_parent(tree
);
932 proto_item_append_text(parent
, " %s: %s", val_to_str_const(type
, id_type_vals
, "Unknown"), pos_id
);
939 dissect_payload_cert(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
947 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
949 type
= tvb_get_uint8(tvb
, offset
+1);
950 length
= tvb_get_ntohs(tvb
, offset
+2);
952 tvb_ensure_bytes_exist(tvb
, offset
+4, length
);
956 parent
= proto_tree_get_parent(tree
);
957 proto_tree_add_item(tree
, hf_mikey
[POS_CERT_TYPE
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
958 proto_tree_add_item(tree
, hf_mikey
[POS_CERT_LEN
], tvb
, 1, 2, ENC_BIG_ENDIAN
);
960 proto_item_append_text(parent
, " Type: %s", val_to_str_const(type
, cert_type_vals
, "Unknown"));
963 subtvb
= tvb_new_subset_length(tvb
, offset
+4, length
);
964 dissect_x509af_Certificate(false, subtvb
, 0, &asn1_ctx
, tree
, hf_mikey
[POS_CERTIFICATE
]);
970 dissect_payload_v(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
976 alg
= tvb_get_uint8(tvb
, offset
+1);
978 proto_tree_add_item(tree
, hf_mikey
[POS_V_AUTH_ALG
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
984 case MAC_HMAC_SHA_1_160
:
991 proto_tree_add_item(tree
, hf_mikey
[POS_V_DATA
], tvb
, 2, length
, ENC_NA
);
997 dissect_payload_sp_param(enum sp_prot_t proto
, tvbuff_t
*tvb
, proto_tree
*tree
)
1004 type
= tvb_get_uint8(tvb
, offset
+0);
1005 length
= tvb_get_uint8(tvb
, offset
+1);
1008 hfindex
= hf_mikey
[POS_SP_PARAM_F
];
1011 case SP_PROT_TYPE_SRTP
:
1012 if (type
< array_length(hf_mikey_sp_param
))
1013 hfindex
= hf_mikey_sp_param
[type
];
1018 proto_item
*param_ti
;
1019 proto_tree
*param_tree
;
1021 * All the parameters in question are either FT_BYTES,
1022 * in which case the byte order is inapplicable, or
1023 * FT_UINT8, in which case it could be given as
1024 * FT_BIG_ENDIAN as per bigger FT_UINT values, but
1025 * ENC_NA also works, as there's only one byte.
1027 param_ti
= proto_tree_add_item(tree
, hfindex
, tvb
, 2, length
, ENC_NA
);
1028 param_tree
= proto_item_add_subtree(param_ti
, ett_mikey_sp_param
);
1030 proto_tree_add_item(param_tree
, hf_mikey
[POS_SP_PARAM_F_TYPE
], tvb
, 0, 1, ENC_BIG_ENDIAN
);
1031 proto_tree_add_item(param_tree
, hf_mikey
[POS_SP_PARAM_F_LEN
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1032 proto_tree_add_item(param_tree
, hf_mikey
[POS_SP_PARAM_F_VALUE
], tvb
, 2, length
, ENC_NA
);
1039 dissect_payload_sp(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1045 enum sp_prot_t type
;
1047 length
= tvb_get_ntohs(tvb
, offset
+3);
1048 no
= tvb_get_uint8(tvb
, offset
+1);
1049 type
= (enum sp_prot_t
)tvb_get_uint8(tvb
, offset
+2);
1053 parent
= proto_tree_get_parent(tree
);
1054 proto_tree_add_item(tree
, hf_mikey
[POS_SP_NO
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1055 proto_tree_add_item(tree
, hf_mikey
[POS_SP_TYPE
], tvb
, 2, 1, ENC_BIG_ENDIAN
);
1056 proto_tree_add_item(tree
, hf_mikey
[POS_SP_PARAM_LEN
], tvb
, 3, 2, ENC_BIG_ENDIAN
);
1058 proto_item_append_text(parent
, " No: %d, Type: %s", no
,
1059 val_to_str_const(type
, sp_prot_type_vals
, "Unknown"));
1062 tvb_ensure_bytes_exist(tvb
, offset
+5, length
);
1063 /* proto_tree_add_item(tree, hf_mikey[POS_SP_PARAM], tvb, 5, length, ENC_NA); */
1068 while (sub_pos
< length
) {
1072 subtvb
= tvb_new_subset_length(tvb
, offset
+sub_pos
, length
-sub_pos
);
1073 param_len
= dissect_payload_sp_param(type
, subtvb
, tree
);
1078 sub_pos
+= param_len
;
1085 dissect_payload_rand(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1090 length
= tvb_get_uint8(tvb
, offset
+1);
1092 proto_tree_add_item(tree
, hf_mikey
[POS_RAND_LEN
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1093 proto_tree_add_item(tree
, hf_mikey
[POS_RAND
], tvb
, 2, length
, ENC_NA
);
1099 dissect_payload_err(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1104 err_no
= tvb_get_uint8(tvb
, 1);
1105 proto_tree_add_item(tree
, hf_mikey
[POS_ERR_NO
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1106 proto_tree_add_item(tree
, hf_mikey
[POS_ERR_RESERVED
], tvb
, 2, 2, ENC_NA
);
1107 parent
= proto_tree_get_parent(tree
);
1108 proto_item_append_text(parent
, ": %s", val_to_str_ext_const(err_no
, &err_vals_ext
, "Unknown"));
1115 dissect_payload_keydata(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1123 key_type
= tvb_get_uint8(tvb
, 1) >> 4;
1124 kv_type
= tvb_get_uint8(tvb
, 1) & 0x0f;
1125 data_len
= tvb_get_ntohs(tvb
, 2);
1131 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_DATA_TYPE
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1132 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_DATA_KV
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1133 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_DATA_LEN
], tvb
, 2, 2, ENC_BIG_ENDIAN
);
1134 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_DATA
], tvb
, 4, data_len
, ENC_NA
);
1136 parent
= proto_tree_get_parent(tree
);
1137 proto_item_append_text(parent
, " Type: %s", val_to_str_const(key_type
, kd_vals
, "Unknown"));
1142 /* Dissect SALT key */
1143 if ((key_type
== KD_TGK_SALT
) || (key_type
== KD_TEK_SALT
)) {
1145 salt_len
= tvb_get_ntohs(tvb
, offset
);
1147 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_SALT_LEN
], tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1148 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_SALT
], tvb
, offset
+2, salt_len
, ENC_NA
);
1150 offset
+= 2+salt_len
;
1153 /* Dissect Key Validity */
1154 if (kv_type
== KV_INTERVAL
) {
1155 uint16_t kv_from_len
;
1158 kv_from_len
= tvb_get_uint8(tvb
, offset
);
1159 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_FROM_LEN
], tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1160 if (kv_from_len
> 0) {
1161 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_FROM
], tvb
, offset
+1, kv_from_len
, ENC_NA
);
1163 offset
+= 1+kv_from_len
;
1165 kv_to_len
= tvb_get_uint8(tvb
, offset
);
1166 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_TO_LEN
], tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1167 if (kv_to_len
> 0) {
1168 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_TO
], tvb
, offset
+1, kv_to_len
, ENC_NA
);
1170 offset
+= 1+kv_to_len
;
1171 } else if (kv_type
== KV_SPI
) {
1172 uint16_t kv_spi_len
;
1174 kv_spi_len
= tvb_get_uint8(tvb
, offset
);
1175 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_SPI_LEN
], tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1176 if (kv_spi_len
> 0) {
1177 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_SPI
], tvb
, offset
+1, kv_spi_len
, ENC_NA
);
1179 offset
+= 1+kv_spi_len
;
1186 dissect_payload_general_ext(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1192 type
= tvb_get_uint8(tvb
, offset
+1);
1193 data_len
= tvb_get_ntohs(tvb
, offset
+2);
1196 proto_tree_add_item(tree
, hf_mikey
[POS_GENERAL_EXT_TYPE
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1197 proto_tree_add_item(tree
, hf_mikey
[POS_GENERAL_EXT_LEN
], tvb
, 2, 2, ENC_BIG_ENDIAN
);
1203 parent
= proto_tree_get_parent(tree
);
1205 /* For SDP-IDs, show a string instead of raw bytes */
1206 proto_tree_add_item(tree
, hf_mikey
[POS_GENERAL_EXT_VALUE
], tvb
, 4, data_len
, ENC_ASCII
);
1208 proto_tree_add_item(tree
, hf_mikey
[POS_GENERAL_EXT_DATA
], tvb
, 4, data_len
, ENC_NA
);
1210 proto_item_append_text(parent
, " Type: %s", val_to_str_const(type
, genext_type_vals
, "Unknown"));
1212 return 4 + data_len
;
1216 dissect_payload_sakke(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1221 data_len
= tvb_get_ntohs(tvb
, offset
+3);
1224 proto_tree_add_item(tree
, hf_mikey
[POS_SAKKE_PARAMS
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1225 proto_tree_add_item(tree
, hf_mikey
[POS_SAKKE_ID_SCHEME
], tvb
, 2, 1, ENC_BIG_ENDIAN
);
1226 proto_tree_add_item(tree
, hf_mikey
[POS_SAKKE_LEN
], tvb
, 3, 2, ENC_BIG_ENDIAN
);
1229 proto_tree_add_item(tree
, hf_mikey
[POS_SAKKE_DATA
], tvb
, 5, data_len
, ENC_NA
);
1230 return 5 + data_len
;
1233 static const struct mikey_dissector_entry payload_map
[] = {
1234 { PL_HDR
, dissect_payload_hdr
},
1235 { PL_KEMAC
, dissect_payload_kemac
},
1236 { PL_PKE
, dissect_payload_pke
},
1237 { PL_DH
, dissect_payload_dh
},
1238 { PL_SIGN
, dissect_payload_sign
},
1239 { PL_T
, dissect_payload_t
},
1240 { PL_ID
, dissect_payload_id
},
1241 { PL_CERT
, dissect_payload_cert
},
1242 { PL_V
, dissect_payload_v
},
1243 { PL_SP
, dissect_payload_sp
},
1244 { PL_RAND
, dissect_payload_rand
},
1245 { PL_ERR
, dissect_payload_err
},
1246 { PL_IDR
, dissect_payload_idr
},
1247 { PL_KEY_DATA
, dissect_payload_keydata
},
1248 { PL_GENERAL_EXT
, dissect_payload_general_ext
},
1249 { PL_SAKKE
, dissect_payload_sakke
},
1254 dissect_payload(int payload
, mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1256 const struct mikey_dissector_entry
*entry
;
1258 entry
= mikey_dissector_lookup(payload_map
, payload
);
1260 if (!entry
|| !entry
->dissector
) {
1264 return entry
->dissector(mikey
, tvb
, pinfo
, tree
);
1267 /* MIKEY dissector */
1269 dissect_mikey(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1271 proto_item
*ti
= NULL
;
1272 proto_tree
*mikey_tree
= NULL
;
1274 int next_payload_offset
;
1278 mikey
= (mikey_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_mikey
, 0);
1281 mikey
= wmem_new0(wmem_file_scope(), mikey_t
);
1283 p_add_proto_data(wmem_file_scope(), pinfo
, proto_mikey
, 0, mikey
);
1287 tvb_ensure_bytes_exist(tvb
, offset
, 3);
1288 next_payload_offset
= offset
+ 2;
1292 ti
= proto_tree_add_item(tree
, proto_mikey
, tvb
, 0, -1, ENC_NA
);
1293 mikey_tree
= proto_item_add_subtree(ti
, ett_mikey
);
1296 while (payload
!= 0) {
1298 proto_item
*sub_ti
= NULL
;
1299 proto_tree
*mikey_payload_tree
= NULL
;
1303 next_payload
= tvb_get_uint8(tvb
, next_payload_offset
);
1304 subtvb
= tvb_new_subset_remaining(tvb
, offset
);
1315 if (hf_mikey_pl
[hf
] == 0)
1318 sub_ti
= proto_tree_add_item(mikey_tree
, hf_mikey_pl
[hf
], subtvb
, 0, -1, ENC_NA
);
1320 mikey_payload_tree
= proto_item_add_subtree(sub_ti
, ett_mikey_payload
);
1321 if ((payload
!= PL_HDR
) && (payload
!= PL_SIGN
))
1322 add_next_payload(tvb
, mikey_payload_tree
, next_payload_offset
);
1325 len
= dissect_payload(payload
, mikey
, subtvb
, pinfo
, mikey_payload_tree
);
1327 /* protocol violation or invalid data, stop dissecting
1328 * but accept the data retrieved so far */
1329 return tvb_captured_length(tvb
);
1333 proto_item_set_len(sub_ti
, len
);
1335 if (payload
== PL_SIGN
)
1338 payload
= next_payload
;
1340 next_payload_offset
= offset
;
1344 proto_item_append_text(ti
, ": %s",
1345 val_to_str_ext_const(mikey
->type
, &data_type_vals_ext
, "Unknown"));
1348 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, "/MIKEY");
1350 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Mikey: %s",
1351 val_to_str_ext_const(mikey
->type
, &data_type_vals_ext
, "Unknown"));
1353 /* Return the amount of data this dissector was able to dissect */
1354 return tvb_captured_length(tvb
);
1358 /* Register the protocol with Wireshark */
1361 proto_register_mikey(void)
1364 /* Setup list of header fields */
1365 static hf_register_info hf
[] = {
1367 { &hf_mikey_pl
[PL_HDR
+1],
1368 { PL_HDR_TEXT
, "mikey.hdr",
1369 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1371 { &hf_mikey_pl
[PL_KEMAC
],
1372 { PL_KEMAC_TEXT
, "mikey.kemac",
1373 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1375 { &hf_mikey_pl
[PL_PKE
],
1376 { PL_PKE_TEXT
, "mikey.pke",
1377 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1379 { &hf_mikey_pl
[PL_DH
],
1380 { PL_DH_TEXT
, "mikey.dh",
1381 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1383 { &hf_mikey_pl
[PL_SIGN
],
1384 { PL_SIGN_TEXT
, "mikey.sign",
1385 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1387 { &hf_mikey_pl
[PL_T
],
1388 { PL_T_TEXT
, "mikey.t",
1389 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1391 { &hf_mikey_pl
[PL_ID
],
1392 { PL_ID_TEXT
, "mikey.id",
1393 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1395 { &hf_mikey_pl
[PL_CERT
],
1396 { PL_CERT_TEXT
, "mikey.cert",
1397 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1399 { &hf_mikey_pl
[PL_CHASH
],
1400 { PL_CHASH_TEXT
, "mikey.chash",
1401 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1403 { &hf_mikey_pl
[PL_V
],
1404 { PL_V_TEXT
, "mikey.v",
1405 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1407 { &hf_mikey_pl
[PL_SP
],
1408 { PL_SP_TEXT
, "mikey.sp",
1409 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1411 { &hf_mikey_pl
[PL_RAND
],
1412 { PL_RAND_TEXT
, "mikey.rand",
1413 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1415 { &hf_mikey_pl
[PL_ERR
],
1416 { PL_ERR_TEXT
, "mikey.err",
1417 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1419 { &hf_mikey_pl
[PL_IDR
],
1420 { PL_IDR_TEXT
, "mikey.idr",
1421 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1423 { &hf_mikey_pl
[PL_KEY_DATA
],
1424 { PL_KEY_DATA_TEXT
, "mikey.key",
1425 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1427 { &hf_mikey_pl
[PL_GENERAL_EXT
],
1428 { PL_GENERAL_EXT_TEXT
, "mikey.ext",
1429 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1431 { &hf_mikey_pl
[PL_SAKKE
],
1432 { PL_SAKKE_TEXT
, "mikey.sakke",
1433 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1436 /* Common Header payload (HDR) */
1437 { &hf_mikey
[POS_HDR_VERSION
],
1438 { "Version", "mikey.version",
1439 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1441 { &hf_mikey
[POS_HDR_DATA_TYPE
],
1442 { "Data Type", "mikey.type",
1443 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &data_type_vals_ext
, 0x0,
1445 { &hf_mikey
[POS_NEXT_PAYLOAD
],
1446 { "Next Payload", "mikey.next_payload",
1447 FT_UINT8
, BASE_DEC
, VALS(payload_vals
), 0x0,
1449 { &hf_mikey
[POS_HDR_V
],
1450 { "V", "mikey.v.set",
1451 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x80,
1453 { &hf_mikey
[POS_HDR_PRF_FUNC
],
1454 { "PRF func", "mikey.prf_func",
1455 FT_UINT8
, BASE_DEC
, VALS(prf_func_vals
), 0x7f,
1457 { &hf_mikey
[POS_HDR_CSB_ID
],
1458 { "CSB ID", "mikey.csb_id",
1459 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1461 { &hf_mikey
[POS_HDR_CS_COUNT
],
1462 { "#CS", "mikey.cs_count",
1463 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1465 { &hf_mikey
[POS_HDR_CS_ID_MAP_TYPE
],
1466 { "CS ID map type", "mikey.cs_id_map_type",
1467 FT_UINT8
, BASE_DEC
, VALS(cs_id_map_vals
), 0x0,
1471 { &hf_mikey
[POS_ID_SRTP
],
1472 { "SRTP ID", "mikey.srtp_id",
1473 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1475 { &hf_mikey
[POS_ID_SRTP_NO
],
1476 { "Policy No", "mikey.srtp_id.policy_no",
1477 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1479 { &hf_mikey
[POS_ID_SRTP_SSRC
],
1480 { "SSRC", "mikey.srtp_id.ssrc",
1481 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1483 { &hf_mikey
[POS_ID_SRTP_ROC
],
1484 { "ROC", "mikey.srtp_id.roc",
1485 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1488 /* Key Data Transport payload (KEMAC) */
1489 { &hf_mikey
[POS_KEMAC_ENCR_ALG
],
1490 { "Encr alg", "mikey.kemac.encr_alg",
1491 FT_UINT8
, BASE_DEC
, VALS(encr_alg_vals
), 0x0,
1493 { &hf_mikey
[POS_KEMAC_ENCR_DATA_LEN
],
1494 { "Key data len", "mikey.kemac.key_data_len",
1495 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1497 { &hf_mikey
[POS_KEMAC_ENCR_DATA
],
1498 { "Key data", "mikey.kemac.key_data",
1499 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1501 { &hf_mikey
[POS_KEMAC_MAC_ALG
],
1502 { "Mac alg", "mikey.kemac.mac_alg",
1503 FT_UINT8
, BASE_DEC
, VALS(mac_alg_vals
), 0x0,
1505 { &hf_mikey
[POS_KEMAC_MAC
],
1506 { "MAC", "mikey.kemac.mac",
1507 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1510 /* Envelope Data payload (PKE) */
1511 { &hf_mikey
[POS_PKE_C
],
1512 { "C", "mikey.pke.c",
1513 FT_UINT16
, BASE_DEC
, VALS(pke_c_vals
), 0xc000,
1515 { &hf_mikey
[POS_PKE_DATA_LEN
],
1516 { "Data len", "mikey.pke.len",
1517 FT_UINT16
, BASE_DEC
, NULL
, 0x3fff,
1519 { &hf_mikey
[POS_PKE_DATA
],
1520 { "Data", "mikey.pke.data",
1521 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1524 /* DH data payload (DH) */
1525 { &hf_mikey
[POS_DH_GROUP
],
1526 { "DH-Group", "mikey.dh.group",
1527 FT_UINT8
, BASE_DEC
, VALS(oakley_vals
), 0x0,
1529 { &hf_mikey
[POS_DH_VALUE
],
1530 { "DH-Value", "mikey.dh.value",
1531 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1533 { &hf_mikey
[POS_DH_RESERV
],
1534 { "Reserv", "mikey.dh.reserv",
1535 FT_UINT8
, BASE_HEX
, NULL
, 0xf0,
1537 { &hf_mikey
[POS_DH_KV
],
1538 { "KV", "mikey.dh.kv",
1539 FT_UINT8
, BASE_DEC
, VALS(kv_vals
), 0x0f,
1542 /* Signature payload (SIGN) */
1543 { &hf_mikey
[POS_SIGN_S_TYPE
],
1544 { "Signature type", "mikey.sign.type",
1545 FT_UINT16
, BASE_DEC
, VALS(sign_s_vals
), 0xf000,
1547 { &hf_mikey
[POS_SIGNATURE_LEN
],
1548 { "Signature len", "mikey.sign.len",
1549 FT_UINT16
, BASE_DEC
, NULL
, 0x0fff,
1551 { &hf_mikey
[POS_SIGNATURE
],
1552 { "Signature", "mikey.sign.data",
1553 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1556 /* Timestamp payload (T) */
1557 { &hf_mikey
[POS_TS_TYPE
],
1558 { "TS type", "mikey.t.ts_type",
1559 FT_UINT8
, BASE_DEC
, VALS(ts_type_vals
), 0x0,
1561 { &hf_mikey
[POS_TS_NTP
],
1562 { "NTP timestamp", "mikey.t.ntp",
1563 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0x0,
1566 { &hf_mikey
[POS_PAYLOAD_STR
],
1567 { "Payload", "mikey.payload",
1568 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1571 /* ID payload (ID) */
1572 { &hf_mikey
[POS_ID_TYPE
],
1573 { "ID type", "mikey.id.type",
1574 FT_UINT8
, BASE_DEC
, VALS(id_type_vals
), 0x0,
1576 { &hf_mikey
[POS_ID_LEN
],
1577 { "ID len", "mikey.id.len",
1578 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1580 { &hf_mikey
[POS_ID
],
1581 { "ID", "mikey.id.data",
1582 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1585 /* Certificate payload (CERT) */
1586 { &hf_mikey
[POS_CERT_LEN
],
1587 { "Certificate len", "mikey.cert.len",
1588 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1590 { &hf_mikey
[POS_CERT_TYPE
],
1591 { "Certificate type", "mikey.cert.type",
1592 FT_UINT8
, BASE_DEC
, VALS(cert_type_vals
), 0x0,
1594 { &hf_mikey
[POS_CERTIFICATE
],
1595 { "Certificate", "mikey.cert.data",
1596 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1599 /* Ver msg payload (V) */
1600 { &hf_mikey
[POS_V_AUTH_ALG
],
1601 { "Auth alg", "mikey.v.auth_alg",
1602 FT_UINT8
, BASE_DEC
, VALS(mac_alg_vals
), 0x0,
1604 { &hf_mikey
[POS_V_DATA
],
1605 { "Ver data", "mikey.v.ver_data",
1606 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1609 /* Security Policy payload (SP) */
1610 { &hf_mikey
[POS_SP_NO
],
1611 { "Policy No", "mikey.sp.no",
1612 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1614 { &hf_mikey
[POS_SP_TYPE
],
1615 { "Protocol type", "mikey.sp.proto_type",
1616 FT_UINT8
, BASE_DEC
, VALS(sp_prot_type_vals
), 0x0,
1618 { &hf_mikey
[POS_SP_PARAM_LEN
],
1619 { "Policy param length", "mikey.sp.param_len",
1620 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1623 /* Security Policy param */
1624 { &hf_mikey
[POS_SP_PARAM_F
],
1625 { "Policy param", "mikey.sp.param",
1626 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1628 { &hf_mikey
[POS_SP_PARAM_F_TYPE
],
1629 { "Type", "mikey.sp.param.type",
1630 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1632 { &hf_mikey
[POS_SP_PARAM_F_LEN
],
1633 { "Length", "mikey.sp.param.len",
1634 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1636 { &hf_mikey
[POS_SP_PARAM_F_VALUE
],
1637 { "Value", "mikey.sp.patam.value",
1638 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1641 /* SRTP policy param */
1642 { &hf_mikey_sp_param
[SP_ENCR_ALG
],
1643 { SP_TEXT_ENCR_ALG
, "mikey.sp.encr_alg",
1644 FT_UINT8
, BASE_DEC
, VALS(sp_encr_alg_vals
), 0x0,
1646 { &hf_mikey_sp_param
[SP_ENCR_LEN
],
1647 { SP_TEXT_ENCR_LEN
, "mikey.sp.encr_len",
1648 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1650 { &hf_mikey_sp_param
[SP_AUTH_ALG
],
1651 { SP_TEXT_AUTH_ALG
, "mikey.sp.auth_alg",
1652 FT_UINT8
, BASE_DEC
, VALS(sp_auth_alg_vals
), 0x0,
1654 { &hf_mikey_sp_param
[SP_AUTH_KEY_LEN
],
1655 { SP_TEXT_AUTH_KEY_LEN
, "mikey.sp.auth_key_len",
1656 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1658 { &hf_mikey_sp_param
[SP_SALT_LEN
],
1659 { SP_TEXT_SALT_LEN
, "mikey.sp.salt_len",
1660 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1662 { &hf_mikey_sp_param
[SP_PRF
],
1663 { SP_TEXT_PRF
, "mikey.sp.prf",
1664 FT_UINT8
, BASE_DEC
, VALS(sp_prf_vals
), 0x0,
1666 { &hf_mikey_sp_param
[SP_KD_RATE
],
1667 { SP_TEXT_KD_RATE
, "mikey.sp.kd_rate",
1668 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1670 { &hf_mikey_sp_param
[SP_SRTP_ENCR
],
1671 { SP_TEXT_SRTP_ENCR
, "mikey.sp.srtp_encr",
1672 FT_UINT8
, BASE_DEC
, VALS(on_off_vals
), 0x0,
1674 { &hf_mikey_sp_param
[SP_SRTCP_ENCR
],
1675 { SP_TEXT_SRTCP_ENCR
, "mikey.sp.srtcp_encr",
1676 FT_UINT8
, BASE_DEC
, VALS(on_off_vals
), 0x0,
1678 { &hf_mikey_sp_param
[SP_FEC
],
1679 { SP_TEXT_FEC
, "mikey.sp.fec",
1680 FT_UINT8
, BASE_DEC
, VALS(sp_fec_vals
), 0x0,
1682 { &hf_mikey_sp_param
[SP_SRTP_AUTH
],
1683 { SP_TEXT_SRTP_AUTH
, "mikey.sp.srtp_auth",
1684 FT_UINT8
, BASE_DEC
, VALS(on_off_vals
), 0x0,
1686 { &hf_mikey_sp_param
[SP_AUTH_TAG_LEN
],
1687 { SP_TEXT_AUTH_TAG_LEN
, "mikey.sp.auth_tag_len",
1688 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1690 { &hf_mikey_sp_param
[SP_SRTP_PREFIX
],
1691 { SP_TEXT_SRTP_PREFIX
, "mikey.sp.srtp_prefix",
1692 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1695 /* RAND payload (RAND) */
1696 { &hf_mikey
[POS_RAND_LEN
],
1697 { "RAND len", "mikey.rand.len",
1698 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1700 { &hf_mikey
[POS_RAND
],
1701 { "RAND", "mikey.rand.data",
1702 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1705 /* Error payload (ERR) */
1706 { &hf_mikey
[POS_ERR_NO
],
1707 { "Error no.", "mikey.err.no",
1708 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &err_vals_ext
, 0x0,
1710 { &hf_mikey
[POS_ERR_RESERVED
],
1711 { "Reserved", "mikey.err.reserved",
1712 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1716 { &hf_mikey
[POS_ID_ROLE
],
1717 { "ID role", "mikey.id.role",
1718 FT_UINT8
, BASE_DEC
, VALS(id_role_vals
), 0x0,
1721 /* Key data sub-payload */
1722 { &hf_mikey
[POS_KEY_DATA_TYPE
],
1723 { "Type", "mikey.key.type",
1724 FT_UINT8
, BASE_DEC
, VALS(kd_vals
), 0xf0,
1726 { &hf_mikey
[POS_KEY_DATA_KV
],
1727 { "KV", "mikey.key.kv",
1728 FT_UINT8
, BASE_DEC
, VALS(kv_vals
), 0x0f,
1730 { &hf_mikey
[POS_KEY_DATA_LEN
],
1731 { "Key len", "mikey.key.data.len",
1732 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1734 { &hf_mikey
[POS_KEY_DATA
],
1735 { "Key", "mikey.key.data",
1736 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1738 { &hf_mikey
[POS_KEY_SALT_LEN
],
1739 { "Salt key len", "mikey.key.salt.len",
1740 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1742 { &hf_mikey
[POS_KEY_SALT
],
1743 { "Salt key", "mikey.key.salt",
1744 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1746 { &hf_mikey
[POS_KEY_KV_FROM_LEN
],
1747 { "Valid from len", "mikey.key.kv.from.len",
1748 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1750 { &hf_mikey
[POS_KEY_KV_FROM
],
1751 { "Valid from", "mikey.key.kv.from",
1752 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1754 { &hf_mikey
[POS_KEY_KV_TO_LEN
],
1755 { "Valid to len", "mikey.key.kv.to.len",
1756 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1758 { &hf_mikey
[POS_KEY_KV_TO
],
1759 { "Valid to", "mikey.key.kv.to",
1760 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1762 { &hf_mikey
[POS_KEY_KV_SPI_LEN
],
1763 { "Valid SPI len", "mikey.key.kv.spi.len",
1764 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1766 { &hf_mikey
[POS_KEY_KV_SPI
],
1767 { "Valid SPI", "mikey.key.kv.spi",
1768 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1771 /* General Extension payload (GENERAL_EXT) */
1772 { &hf_mikey
[POS_GENERAL_EXT_TYPE
],
1773 { "Extension type", "mikey.ext.type",
1774 FT_UINT8
, BASE_DEC
, VALS(genext_type_vals
), 0x0,
1776 { &hf_mikey
[POS_GENERAL_EXT_LEN
],
1777 { "Length", "mikey.ext.len",
1778 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1780 { &hf_mikey
[POS_GENERAL_EXT_DATA
],
1781 { "Data", "mikey.ext.data",
1782 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1784 { &hf_mikey
[POS_GENERAL_EXT_VALUE
],
1785 { "Value", "mikey.ext.value",
1786 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1790 { &hf_mikey
[POS_SAKKE_PARAMS
],
1791 { "SAKKE params", "mikey.sakke.params",
1792 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1794 { &hf_mikey
[POS_SAKKE_ID_SCHEME
],
1795 { "ID scheme", "mikey.sakke.idscheme",
1796 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1798 { &hf_mikey
[POS_SAKKE_LEN
],
1799 { "SAKKE data length", "mikey.sakke.len",
1800 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1802 { &hf_mikey
[POS_SAKKE_DATA
],
1803 { "SAKKE data", "mikey.sakke.data",
1804 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1808 { &hf_mikey[POS_SP_PARAM],
1809 { "Policy param", "mikey.policy_param",
1810 FT_BYTES, BASE_NONE, NULL, 0x0,
1813 { &hf_mikey[POS_PAYLOAD],
1814 { "Payload", "mikey.payload",
1815 FT_BYTES, BASE_HEX, NULL, 0x0,
1820 /* Setup protocol subtree array */
1821 static int *ett
[] = {
1824 &ett_mikey_sp_param
,
1829 /* Register the protocol name and description */
1830 proto_mikey
= proto_register_protocol("Multimedia Internet KEYing", "MIKEY", "mikey");
1832 mikey_handle
= register_dissector("mikey", dissect_mikey
, proto_mikey
);
1834 /* Required function calls to register the header fields and subtrees used */
1835 proto_register_field_array(proto_mikey
, hf
, array_length(hf
));
1836 proto_register_subtree_array(ett
, array_length(ett
));
1841 proto_reg_handoff_mikey(void)
1843 dissector_add_string("key_mgmt", "mikey", mikey_handle
);
1844 dissector_add_uint_with_preference("tcp.port", PORT_MIKEY
, mikey_handle
);
1845 dissector_add_uint_with_preference("udp.port", PORT_MIKEY
, mikey_handle
);
1846 dissector_add_string("media_type", "application/mikey", mikey_handle
);
1849 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1854 * indent-tabs-mode: t
1857 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1858 * :indentSize=8:tabSize=8:noTabs=false: