2 * Routines for HDCP2 dissection
3 * Copyright 2011-2012, Martin Kaiser <martin@kaiser.cx>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * This dissector supports HDCP 2.x over TCP. For now, only the
14 * authentication protocol messages are supported.
16 * The specification of version 2 of the protocol can be found at
17 * http://www.digital-cp.com/files/static_page_files/DABB540C-1A4B-B294-D0008CB2D348FA19/HDCP Interface Independent Adaptation Specification Rev2_1.pdf
22 #include <epan/packet.h>
23 #include <epan/prefs.h>
24 #include <epan/ptvcursor.h>
25 #include <epan/expert.h>
27 void proto_register_hdcp2(void);
28 void proto_reg_handoff_hdcp2(void);
30 static int proto_hdcp2
;
33 static int ett_hdcp2_cert
;
35 static int hf_hdcp2_msg_id
;
36 static int hf_hdcp2_r_tx
;
37 static int hf_hdcp2_repeater
;
38 static int hf_hdcp2_cert_rcv_id
;
39 static int hf_hdcp2_cert_n
;
40 static int hf_hdcp2_cert_e
;
41 static int hf_hdcp2_cert_rcv_sig
;
42 static int hf_hdcp2_e_kpub_km
;
43 static int hf_hdcp2_e_kh_km
;
44 static int hf_hdcp2_m
;
45 static int hf_hdcp2_r_rx
;
46 static int hf_hdcp2_h_prime
;
47 static int hf_hdcp2_r_n
;
48 static int hf_hdcp2_l_prime
;
49 static int hf_hdcp2_e_dkey_ks
;
50 static int hf_hdcp2_r_iv
;
51 static int hf_hdcp2_reserved
;
52 static int hf_hdcp2_tx_length
;
53 static int hf_hdcp2_tx_version
;
54 static int hf_hdcp2_tx_loc_precompute
;
55 static int hf_hdcp2_rx_length
;
56 static int hf_hdcp2_rx_version
;
57 static int hf_hdcp2_rx_loc_precompute
;
59 static expert_field ei_hdcp2_reserved_0
;
60 static expert_field ei_hdcp2_version_not_2
;
61 static expert_field ei_hdcp2_length
;
65 #define ID_AKE_SEND_CERT 3
66 #define ID_AKE_NO_STORED_KM 4
67 #define ID_AKE_STORED_KM 5
68 #define ID_AKE_SEND_RRX 6
69 #define ID_AKE_SEND_H_PRIME 7
70 #define ID_AKE_SEND_PAIRING_INFO 8
72 #define ID_LC_SEND_L_PRIME 10
73 #define ID_SKE_SEND_EKS 11
74 #define ID_AKE_TRANSMITTER_INFO 19
75 #define ID_AKE_RECEIVER_INFO 20
78 #define RCV_ID_LEN 5 /* all lengths are in bytes */
81 #define RCV_SIG_LEN 384
83 #define MSG_FIELD_TRANSMITTER_INFO_LENGTH 6
84 #define MSG_FIELD_RECEIVER_INFO_LENGTH 6
86 #define CERT_RX_LEN (RCV_ID_LEN + N_LEN + E_LEN + 2 + RCV_SIG_LEN)
88 static const value_string hdcp2_msg_id
[] = {
89 { ID_AKE_INIT
, "AKE_Init" },
90 { ID_AKE_TRANSMITTER_INFO
, "AKE_Transmitter_Info" },
91 { ID_AKE_SEND_CERT
, "AKE_Send_Cert" },
92 { ID_AKE_RECEIVER_INFO
, "AKE_Receiver_Info" },
93 { ID_AKE_NO_STORED_KM
, "AKE_No_Stored_km" },
94 { ID_AKE_STORED_KM
, "AKE_Stored_km" },
95 { ID_AKE_SEND_RRX
, "AKE_Send_rrx" },
96 { ID_AKE_SEND_H_PRIME
, "AKE_Send_H_prime" },
97 { ID_AKE_SEND_PAIRING_INFO
, "AKE_Send_Pairing_Info" },
98 { ID_LC_INIT
, "LC_Init" },
99 { ID_LC_SEND_L_PRIME
, "LC_Send_L_prime" },
100 { ID_SKE_SEND_EKS
, "SKE_Send_Eks" },
104 typedef struct _msg_info_t
{
106 uint16_t len
; /* number of bytes following initial msg_id field */
109 static wmem_map_t
*msg_table
;
111 static const msg_info_t msg_info
[] = {
113 { ID_AKE_TRANSMITTER_INFO
, 5 },
114 { ID_AKE_SEND_CERT
, 1+CERT_RX_LEN
},
115 { ID_AKE_RECEIVER_INFO
, 5 },
116 { ID_AKE_NO_STORED_KM
, 128 },
117 { ID_AKE_STORED_KM
, 32 },
118 { ID_AKE_SEND_RRX
, 8 },
119 { ID_AKE_SEND_H_PRIME
, 32 },
120 { ID_AKE_SEND_PAIRING_INFO
, 16 },
122 { ID_LC_SEND_L_PRIME
, 32 },
123 { ID_SKE_SEND_EKS
, 24 }
128 dissect_hdcp2(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
132 proto_tree
*hdcp_tree
, *cert_tree
;
133 uint8_t msg_id
, version
;
134 bool repeater
, loc_precomp
;
135 uint16_t reserved
, length
;
138 /* do the plausibility checks before setting up anything */
140 /* make sure that tvb_get_uint8() won't throw an exception */
141 if (tvb_captured_length(tvb
) < 1)
143 msg_id
= tvb_get_uint8(tvb
, 0);
147 mi
= (msg_info_t
*)wmem_map_lookup(msg_table
,
148 GUINT_TO_POINTER((unsigned)msg_id
));
149 /* 1 -> start after msg_id byte */
150 if (!mi
|| mi
->len
!=tvb_reported_length_remaining(tvb
, 1))
153 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "HDCP2");
154 col_clear(pinfo
->cinfo
, COL_INFO
);
156 pi
= proto_tree_add_protocol_format(tree
, proto_hdcp2
,
157 tvb
, 0, tvb_reported_length(tvb
), "HDCP2");
158 hdcp_tree
= proto_item_add_subtree(pi
, ett_hdcp2
);
159 cursor
= ptvcursor_new(pinfo
->pool
, hdcp_tree
, tvb
, 0);
161 col_append_str(pinfo
->cinfo
, COL_INFO
,
162 val_to_str(msg_id
, hdcp2_msg_id
, "unknown (0x%x)"));
163 ptvcursor_add(cursor
, hf_hdcp2_msg_id
, 1, ENC_BIG_ENDIAN
);
167 ptvcursor_add(cursor
, hf_hdcp2_r_tx
, 8, ENC_BIG_ENDIAN
);
169 case ID_AKE_TRANSMITTER_INFO
:
170 length
= tvb_get_ntohs(tvb
, ptvcursor_current_offset(cursor
));
171 pi
= proto_tree_add_item(ptvcursor_tree(cursor
),
172 hf_hdcp2_tx_length
, tvb
, ptvcursor_current_offset(cursor
),
174 if (length
< MSG_FIELD_TRANSMITTER_INFO_LENGTH
) {
175 expert_add_info_format(pinfo
, pi
, &ei_hdcp2_length
,
176 "Length must be at least %d",
177 MSG_FIELD_TRANSMITTER_INFO_LENGTH
);
179 ptvcursor_advance(cursor
, 2);
180 version
= tvb_get_uint8(tvb
, ptvcursor_current_offset(cursor
));
181 pi
= proto_tree_add_item(ptvcursor_tree(cursor
),
182 hf_hdcp2_tx_version
, tvb
, ptvcursor_current_offset(cursor
),
185 expert_add_info(pinfo
, pi
, &ei_hdcp2_version_not_2
);
187 ptvcursor_advance(cursor
, 1);
188 loc_precomp
= ((tvb_get_ntohs(tvb
, ptvcursor_current_offset(cursor
))
190 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
191 loc_precomp
? "locality precompute" : "no locality precompute");
192 ptvcursor_add(cursor
, hf_hdcp2_tx_loc_precompute
, 2, ENC_BIG_ENDIAN
);
194 case ID_AKE_SEND_CERT
:
195 repeater
= ((tvb_get_uint8(tvb
, ptvcursor_current_offset(cursor
))
197 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
198 repeater
? "repeater" : "no repeater");
199 ptvcursor_add(cursor
, hf_hdcp2_repeater
, 1, ENC_BIG_ENDIAN
);
200 cert_tree
= ptvcursor_add_text_with_subtree(cursor
, CERT_RX_LEN
,
201 ett_hdcp2_cert
, "%s", "HDCP2 Certificate");
202 ptvcursor_add(cursor
, hf_hdcp2_cert_rcv_id
, RCV_ID_LEN
, ENC_NA
);
203 ptvcursor_add(cursor
, hf_hdcp2_cert_n
, N_LEN
, ENC_NA
);
204 ptvcursor_add(cursor
, hf_hdcp2_cert_e
, E_LEN
, ENC_BIG_ENDIAN
);
205 reserved
= tvb_get_ntohs(tvb
, ptvcursor_current_offset(cursor
));
206 pi
= proto_tree_add_item(cert_tree
, hf_hdcp2_reserved
, tvb
,
207 ptvcursor_current_offset(cursor
), 2, ENC_BIG_ENDIAN
);
208 if ((reserved
& 0xEFFF) != 0) {
209 expert_add_info(pinfo
, pi
, &ei_hdcp2_reserved_0
);
211 ptvcursor_advance(cursor
, 2);
212 ptvcursor_add(cursor
, hf_hdcp2_cert_rcv_sig
, RCV_SIG_LEN
, ENC_NA
);
213 ptvcursor_pop_subtree(cursor
);
215 case ID_AKE_RECEIVER_INFO
:
216 length
= tvb_get_ntohs(tvb
, ptvcursor_current_offset(cursor
));
217 pi
= proto_tree_add_item(ptvcursor_tree(cursor
),
218 hf_hdcp2_rx_length
, tvb
, ptvcursor_current_offset(cursor
),
220 if (length
< MSG_FIELD_RECEIVER_INFO_LENGTH
) {
221 expert_add_info_format(pinfo
, pi
, &ei_hdcp2_length
,
222 "Length must be at least %d",
223 MSG_FIELD_RECEIVER_INFO_LENGTH
);
225 ptvcursor_advance(cursor
, 2);
226 version
= tvb_get_uint8(tvb
, ptvcursor_current_offset(cursor
));
227 pi
= proto_tree_add_item(ptvcursor_tree(cursor
),
228 hf_hdcp2_rx_version
, tvb
, ptvcursor_current_offset(cursor
),
231 expert_add_info(pinfo
, pi
, &ei_hdcp2_version_not_2
);
233 ptvcursor_advance(cursor
, 1);
234 loc_precomp
= ((tvb_get_ntohs(tvb
, ptvcursor_current_offset(cursor
))
236 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
237 loc_precomp
? "locality precompute" : "no locality precompute");
238 ptvcursor_add(cursor
, hf_hdcp2_rx_loc_precompute
, 2, ENC_BIG_ENDIAN
);
240 case ID_AKE_NO_STORED_KM
:
241 ptvcursor_add(cursor
, hf_hdcp2_e_kpub_km
, 128, ENC_NA
);
243 case ID_AKE_STORED_KM
:
244 ptvcursor_add(cursor
, hf_hdcp2_e_kh_km
, 16, ENC_NA
);
245 ptvcursor_add(cursor
, hf_hdcp2_m
, 16, ENC_NA
);
247 case ID_AKE_SEND_RRX
:
248 ptvcursor_add(cursor
, hf_hdcp2_r_rx
, 8, ENC_BIG_ENDIAN
);
250 case ID_AKE_SEND_H_PRIME
:
251 ptvcursor_add(cursor
, hf_hdcp2_h_prime
, 32, ENC_NA
);
253 case ID_AKE_SEND_PAIRING_INFO
:
254 ptvcursor_add(cursor
, hf_hdcp2_e_kh_km
, 16, ENC_NA
);
257 ptvcursor_add(cursor
, hf_hdcp2_r_n
, 8, ENC_BIG_ENDIAN
);
259 case ID_LC_SEND_L_PRIME
:
260 ptvcursor_add(cursor
, hf_hdcp2_l_prime
, 32, ENC_NA
);
262 case ID_SKE_SEND_EKS
:
263 ptvcursor_add(cursor
, hf_hdcp2_e_dkey_ks
, 16, ENC_NA
);
264 ptvcursor_add(cursor
, hf_hdcp2_r_iv
, 8, ENC_BIG_ENDIAN
);
270 ptvcursor_free(cursor
);
271 return tvb_reported_length(tvb
);
275 dissect_hdcp2_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
277 return dissect_hdcp2(tvb
, pinfo
, tree
, data
) > 0;
282 proto_register_hdcp2(void)
286 static hf_register_info hf
[] = {
288 { "Message ID", "hdcp2.msg_id", FT_UINT8
, BASE_HEX
,
289 VALS(hdcp2_msg_id
), 0, NULL
, HFILL
} },
291 { "r_tx", "hdcp2.r_tx", FT_UINT64
, BASE_HEX
,
292 NULL
, 0, NULL
, HFILL
} },
293 { &hf_hdcp2_repeater
,
294 { "Repeater", "hdcp2.repeater", FT_BOOLEAN
, 8,
295 NULL
, 0x1, NULL
, HFILL
} },
296 { &hf_hdcp2_cert_rcv_id
,
297 { "Receiver ID", "hdcp2.cert.rcv_id", FT_BYTES
, BASE_NONE
,
298 NULL
, 0, NULL
, HFILL
} },
300 { "Receiver RSA key n", "hdcp2.cert.n", FT_BYTES
, BASE_NONE
,
301 NULL
, 0, NULL
, HFILL
} },
303 { "Receiver RSA key e", "hdcp2.cert.e", FT_UINT24
, BASE_HEX
,
304 NULL
, 0, NULL
, HFILL
} },
305 { &hf_hdcp2_cert_rcv_sig
,
306 { "Receiver signature", "hdcp2.cert.rcv_sig", FT_BYTES
,
307 BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
308 { &hf_hdcp2_e_kpub_km
,
309 { "E_kpub_km", "hdcp2.e_kpub_km", FT_BYTES
, BASE_NONE
,
310 NULL
, 0, NULL
, HFILL
} },
312 { "E_kh_km", "hdcp2.e_kh_km", FT_BYTES
, BASE_NONE
,
313 NULL
, 0, NULL
, HFILL
} },
315 { "m", "hdcp2.m", FT_BYTES
, BASE_NONE
,
316 NULL
, 0, NULL
, HFILL
} },
318 { "r_rx", "hdcp2.r_rx", FT_UINT64
, BASE_HEX
,
319 NULL
, 0, NULL
, HFILL
} },
321 { "H'", "hdcp2.h_prime", FT_BYTES
, BASE_NONE
,
322 NULL
, 0, NULL
, HFILL
} },
324 { "r_n", "hdcp2.r_n", FT_UINT64
, BASE_HEX
,
325 NULL
, 0, NULL
, HFILL
} },
327 { "L'", "hdcp2.l_prime", FT_BYTES
, BASE_NONE
,
328 NULL
, 0, NULL
, HFILL
} },
329 { &hf_hdcp2_e_dkey_ks
,
330 { "E_dkey_ks", "hdcp2.e_dkey_ks", FT_BYTES
, BASE_NONE
,
331 NULL
, 0, NULL
, HFILL
} },
333 { "r_iv", "hdcp2.r_iv", FT_UINT64
, BASE_HEX
,
334 NULL
, 0, NULL
, HFILL
} },
335 { &hf_hdcp2_reserved
,
336 { "Reserved", "hdcp2.reserved", FT_UINT16
, BASE_HEX
,
337 NULL
, 0, NULL
, HFILL
} },
338 { &hf_hdcp2_tx_length
,
339 { "LENGTH", "hdcp2.txinf_len", FT_UINT16
, BASE_DEC
,
340 NULL
, 0, NULL
, HFILL
} },
341 { &hf_hdcp2_tx_version
,
342 { "VERSION", "hdcp2.txinf_ver", FT_UINT8
, BASE_DEC
,
343 NULL
, 0, NULL
, HFILL
} },
344 { &hf_hdcp2_tx_loc_precompute
,
345 { "Locality Precompute", "hdcp2.txinf_cap", FT_BOOLEAN
, 16,
346 NULL
, 0x0001, NULL
, HFILL
} },
347 { &hf_hdcp2_rx_length
,
348 { "LENGTH", "hdcp2.rxinf_len", FT_UINT16
, BASE_DEC
,
349 NULL
, 0, NULL
, HFILL
} },
350 { &hf_hdcp2_rx_version
,
351 { "VERSION", "hdcp2.rxinf_ver", FT_UINT8
, BASE_DEC
,
352 NULL
, 0, NULL
, HFILL
} },
353 { &hf_hdcp2_rx_loc_precompute
,
354 { "Locality Precompute", "hdcp2.rxinf_cap", FT_BOOLEAN
, 16,
355 NULL
, 0x0001, NULL
, HFILL
} },
359 static int *ett
[] = {
364 static ei_register_info ei
[] = {
365 { &ei_hdcp2_reserved_0
, { "hdcp2.reserved.not0", PI_PROTOCOL
, PI_WARN
, "reserved bytes must be set to 0x0", EXPFILL
}},
366 { &ei_hdcp2_version_not_2
, { "hdcp2.version.not2", PI_PROTOCOL
, PI_WARN
, "version must be set to 0x2", EXPFILL
}},
367 { &ei_hdcp2_length
, { "hdcp2.length.invalid", PI_PROTOCOL
, PI_WARN
, "Invalid length", EXPFILL
}},
370 module_t
*hdcp2_module
;
371 expert_module_t
* expert_hdcp2
;
373 msg_table
= wmem_map_new(wmem_epan_scope(), g_direct_hash
, g_direct_equal
);
374 for(i
=0; i
<array_length(msg_info
); i
++) {
375 wmem_map_insert(msg_table
,
376 GUINT_TO_POINTER((unsigned)msg_info
[i
].id
),
377 (void *)(&msg_info
[i
]));
380 proto_hdcp2
= proto_register_protocol("High bandwidth Digital Content Protection version 2", "HDCP2", "hdcp2");
382 hdcp2_module
= prefs_register_protocol_obsolete(proto_hdcp2
);
383 prefs_register_obsolete_preference(hdcp2_module
, "enable");
385 proto_register_field_array(proto_hdcp2
, hf
, array_length(hf
));
386 proto_register_subtree_array(ett
, array_length(ett
));
387 expert_hdcp2
= expert_register_protocol(proto_hdcp2
);
388 expert_register_field_array(expert_hdcp2
, ei
, array_length(ei
));
390 register_dissector("hdcp2", dissect_hdcp2
, proto_hdcp2
);
394 proto_reg_handoff_hdcp2(void)
396 static bool prefs_initialized
= false;
398 if (!prefs_initialized
) {
399 heur_dissector_add ("tcp", dissect_hdcp2_heur
, "HDCP2 over TCP", "hdcp2_tcp", proto_hdcp2
, HEURISTIC_DISABLE
);
401 prefs_initialized
= true;
406 * Editor modelines - https://www.wireshark.org/tools/modelines.html
411 * indent-tabs-mode: nil
414 * vi: set shiftwidth=4 tabstop=8 expandtab:
415 * :indentSize=4:tabSize=8:noTabs=true: