11960cf9bb51121620083c4cc4d9b5a1aaaef50c
[metze/wireshark/wip.git] / epan / dissectors / packet-hdcp2.c
1 /* packet-hdcp2.c
2  * Routines for HDCP2 dissection
3  * Copyright 2011-2012, Martin Kaiser <martin@kaiser.cx>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 /*
27  * This dissector supports HDCP 2.x over TCP. For now, only the
28  * authentication protocol messages are supported.
29  *
30  * The specification of version 2 of the protocol can be found at
31  * http://www.digital-cp.com/files/static_page_files/DABB540C-1A4B-B294-D0008CB2D348FA19/HDCP Interface Independent Adaptation Specification Rev2_1.pdf
32  */
33
34 #include "config.h"
35
36 #include <glib.h>
37 #include <epan/packet.h>
38 #include <epan/prefs.h>
39 #include <epan/ptvcursor.h>
40 #include <epan/expert.h>
41
42
43 static int proto_hdcp2 = -1;
44
45 static gboolean  hdcp2_enable_dissector = FALSE;
46
47 void proto_reg_handoff_hdcp2(void);
48
49 static gint ett_hdcp2 = -1;
50 static gint ett_hdcp2_cert = -1;
51
52 static int hf_hdcp2_msg_id = -1;
53 static int hf_hdcp2_r_tx = -1;
54 static int hf_hdcp2_repeater = -1;
55 static int hf_hdcp2_cert_rcv_id = -1;
56 static int hf_hdcp2_cert_n = -1;
57 static int hf_hdcp2_cert_e = -1;
58 static int hf_hdcp2_cert_rcv_sig = -1;
59 static int hf_hdcp2_e_kpub_km = -1;
60 static int hf_hdcp2_e_kh_km = -1;
61 static int hf_hdcp2_m = -1;
62 static int hf_hdcp2_r_rx = -1;
63 static int hf_hdcp2_h_prime = -1;
64 static int hf_hdcp2_r_n = -1;
65 static int hf_hdcp2_l_prime = -1;
66 static int hf_hdcp2_e_dkey_ks = -1;
67 static int hf_hdcp2_r_iv = -1;
68
69 #define ID_AKE_INIT              2
70 #define ID_AKE_SEND_CERT         3
71 #define ID_AKE_NO_STORED_KM      4
72 #define ID_AKE_STORED_KM         5
73 #define ID_AKE_SEND_RRX          6
74 #define ID_AKE_SEND_H_PRIME      7
75 #define ID_AKE_SEND_PAIRING_INFO 8
76 #define ID_LC_INIT               9
77 #define ID_LC_SEND_L_PRIME      10
78 #define ID_SKE_SEND_EKS         11
79 #define ID_MAX                  31
80
81 #define RCV_ID_LEN    5  /* all lengths are in bytes */
82 #define N_LEN       128
83 #define E_LEN         3
84 #define RCV_SIG_LEN 384
85
86 #define CERT_RX_LEN   (RCV_ID_LEN + N_LEN + E_LEN + 2 + RCV_SIG_LEN)
87
88 static const value_string hdcp2_msg_id[] = {
89     { ID_AKE_INIT,              "AKE_Init" },
90     { ID_AKE_SEND_CERT,         "AKE_Send_Cert" },
91     { ID_AKE_NO_STORED_KM,      "AKE_No_Stored_km" },
92     { ID_AKE_STORED_KM,         "AKE_Stored_km" },
93     { ID_AKE_SEND_RRX,          "AKE_Send_rrx" },
94     { ID_AKE_SEND_H_PRIME,      "AKE_Send_H_prime" },
95     { ID_AKE_SEND_PAIRING_INFO, "AKE_Send_Pairing_Info" },
96     { ID_LC_INIT,               "LC_Init" },
97     { ID_LC_SEND_L_PRIME,       "LC_Send_L_prime" },
98     { ID_SKE_SEND_EKS,          "SKE_Send_Eks" },
99     { 0, NULL }
100 };
101
102 typedef struct _msg_info_t {
103     guint8  id;
104     guint16 len;  /* number of bytes following initial msg_id field */
105 } msg_info_t;
106
107 static GHashTable *msg_table = NULL;
108
109 static const msg_info_t msg_info[] = {
110     { ID_AKE_INIT,               8 },
111     { ID_AKE_SEND_CERT,        1+CERT_RX_LEN },
112     { ID_AKE_NO_STORED_KM,     128 },
113     { ID_AKE_STORED_KM,         32 },
114     { ID_AKE_SEND_RRX,           8 },
115     { ID_AKE_SEND_H_PRIME,      32 },
116     { ID_AKE_SEND_PAIRING_INFO, 16 },
117     { ID_LC_INIT,                8 },
118     { ID_LC_SEND_L_PRIME,       32 },
119     { ID_SKE_SEND_EKS,          24 }
120 };
121
122
123 static int
124 dissect_hdcp2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
125 {
126     msg_info_t *mi;
127     proto_item *pi;
128     proto_tree *hdcp_tree = NULL, *cert_tree = NULL;
129     guint8 msg_id;
130     gboolean repeater;
131     guint16 reserved;
132     ptvcursor_t *cursor;
133
134     /* do the plausibility checks before setting up anything */
135     msg_id = tvb_get_guint8(tvb, 0);
136     if (msg_id > ID_MAX)
137         return 0;
138
139     mi = (msg_info_t *)g_hash_table_lookup(msg_table,
140             GUINT_TO_POINTER((guint)msg_id));
141     /* 1 -> start after msg_id byte */
142     if (!mi || mi->len!=tvb_reported_length_remaining(tvb, 1))
143         return 0;
144
145     col_set_str(pinfo->cinfo, COL_PROTOCOL, "HDCP2");
146     col_clear(pinfo->cinfo, COL_INFO);
147
148     if (tree) {
149         pi = proto_tree_add_protocol_format(tree, proto_hdcp2,
150                 tvb, 0, tvb_reported_length(tvb), "HDCP2");
151         hdcp_tree = proto_item_add_subtree(pi, ett_hdcp2);
152     }
153     cursor = ptvcursor_new(hdcp_tree, tvb, 0);
154
155     col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
156                     val_to_str(msg_id, hdcp2_msg_id, "unknown (0x%x)"));
157     ptvcursor_add(cursor, hf_hdcp2_msg_id, 1, ENC_BIG_ENDIAN);
158
159     switch (msg_id) {
160         case ID_AKE_INIT:
161             ptvcursor_add(cursor, hf_hdcp2_r_tx, 8, ENC_BIG_ENDIAN);
162             break;
163         case ID_AKE_SEND_CERT:
164             repeater = ((tvb_get_guint8(tvb, ptvcursor_current_offset(cursor))
165                         & 0x01) == 0x01);
166             col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s",
167                     repeater ? "repeater" : "no repeater");
168             ptvcursor_add(cursor, hf_hdcp2_repeater, 1, ENC_BIG_ENDIAN);
169             if (hdcp_tree) {
170                 cert_tree = ptvcursor_add_text_with_subtree(cursor, CERT_RX_LEN,
171                         ett_hdcp2_cert, "%s", "HDCP2 Certificate");
172             }
173             ptvcursor_add(cursor, hf_hdcp2_cert_rcv_id, RCV_ID_LEN, ENC_NA);
174             ptvcursor_add(cursor, hf_hdcp2_cert_n, N_LEN, ENC_NA);
175             ptvcursor_add(cursor, hf_hdcp2_cert_e, E_LEN, ENC_BIG_ENDIAN);
176             reserved = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
177             proto_tree_add_text(cert_tree, tvb,
178                         ptvcursor_current_offset(cursor), 2, "reserved bytes");
179             if (reserved != 0) {
180                 pi = proto_tree_add_text(cert_tree, tvb,
181                         ptvcursor_current_offset(cursor), 2, "invalid value");
182                 expert_add_info_format(pinfo, pi, PI_PROTOCOL, PI_WARN,
183                         "reserved bytes must be set to 0x0");
184             }
185             ptvcursor_advance(cursor, 2);
186             ptvcursor_add(cursor, hf_hdcp2_cert_rcv_sig, RCV_SIG_LEN, ENC_NA);
187             if (cert_tree)
188                 ptvcursor_pop_subtree(cursor);
189             break;
190         case ID_AKE_NO_STORED_KM:
191             ptvcursor_add(cursor, hf_hdcp2_e_kpub_km, 128, ENC_NA);
192             break;
193         case ID_AKE_STORED_KM:
194             ptvcursor_add(cursor, hf_hdcp2_e_kh_km, 16, ENC_NA);
195             ptvcursor_add(cursor, hf_hdcp2_m, 16, ENC_NA);
196             break;
197         case ID_AKE_SEND_RRX:
198             ptvcursor_add(cursor, hf_hdcp2_r_rx, 8, ENC_BIG_ENDIAN);
199             break;
200         case ID_AKE_SEND_H_PRIME:
201             ptvcursor_add(cursor, hf_hdcp2_h_prime, 32, ENC_NA);
202             break;
203         case ID_AKE_SEND_PAIRING_INFO:
204             ptvcursor_add(cursor, hf_hdcp2_e_kh_km, 16, ENC_NA);
205             break;
206         case ID_LC_INIT:
207             ptvcursor_add(cursor, hf_hdcp2_r_n, 8, ENC_BIG_ENDIAN);
208             break;
209         case ID_LC_SEND_L_PRIME:
210             ptvcursor_add(cursor, hf_hdcp2_l_prime, 32, ENC_NA);
211             break;
212         case ID_SKE_SEND_EKS:
213             ptvcursor_add(cursor, hf_hdcp2_e_dkey_ks, 16, ENC_NA);
214             ptvcursor_add(cursor, hf_hdcp2_r_iv, 8, ENC_BIG_ENDIAN);
215             break;
216         default:
217             break;
218     }
219
220     ptvcursor_free(cursor);
221     return tvb_reported_length(tvb);
222 }
223
224
225
226 void
227 proto_register_hdcp2(void)
228 {
229     guint i;
230
231     static hf_register_info hf[] = {
232         { &hf_hdcp2_msg_id,
233             { "Message ID", "hdcp2.msg_id", FT_UINT8, BASE_HEX,
234                 VALS(hdcp2_msg_id), 0, NULL, HFILL } },
235         { &hf_hdcp2_r_tx,
236             { "r_tx", "hdcp2.r_tx", FT_UINT64, BASE_HEX,
237                 NULL, 0, NULL, HFILL } },
238         { &hf_hdcp2_repeater,
239             { "Repeater", "hdcp2.repeater", FT_BOOLEAN, 8,
240                 NULL, 0x1, NULL, HFILL } },
241         { &hf_hdcp2_cert_rcv_id,
242             { "Receiver ID", "hdcp2.cert.rcv_id", FT_BYTES, BASE_NONE,
243                 NULL, 0, NULL, HFILL } },
244         { &hf_hdcp2_cert_n,
245             { "Receiver RSA key n", "hdcp2.cert.n", FT_BYTES, BASE_NONE,
246                 NULL, 0, NULL, HFILL } },
247         { &hf_hdcp2_cert_e,
248             { "Receiver RSA key e", "hdcp2.cert.e", FT_UINT24, BASE_HEX,
249                 NULL, 0, NULL, HFILL } },
250         { &hf_hdcp2_cert_rcv_sig,
251             { "Receiver signature", "hdcp2.cert.rcv_sig", FT_BYTES,
252                 BASE_NONE, NULL, 0, NULL, HFILL } },
253         { &hf_hdcp2_e_kpub_km,
254             { "E_kpub_km", "hdcp2.e_kpub_km", FT_BYTES, BASE_NONE,
255                 NULL, 0, NULL, HFILL } },
256         { &hf_hdcp2_e_kh_km,
257             { "E_kh_km", "hdcp2.e_kh_km", FT_BYTES, BASE_NONE,
258                 NULL, 0, NULL, HFILL } },
259         { &hf_hdcp2_m,
260             { "m", "hdcp2.m", FT_BYTES, BASE_NONE,
261                 NULL, 0, NULL, HFILL } },
262         { &hf_hdcp2_r_rx,
263             { "r_rx", "hdcp2.r_rx", FT_UINT64, BASE_HEX,
264                 NULL, 0, NULL, HFILL } },
265         { &hf_hdcp2_h_prime,
266             { "H'", "hdcp2.h_prime", FT_BYTES, BASE_NONE,
267                 NULL, 0, NULL, HFILL } },
268         { &hf_hdcp2_r_n,
269             { "r_n", "hdcp2.r_n", FT_UINT64, BASE_HEX,
270                 NULL, 0, NULL, HFILL } },
271         { &hf_hdcp2_l_prime,
272             { "L'", "hdcp2.l_prime", FT_BYTES, BASE_NONE,
273                 NULL, 0, NULL, HFILL } },
274         { &hf_hdcp2_e_dkey_ks,
275             { "E_dkey_ks", "hdcp2.e_dkey_ks", FT_BYTES, BASE_NONE,
276                 NULL, 0, NULL, HFILL } },
277         { &hf_hdcp2_r_iv,
278             { "r_iv", "hdcp2.r_iv", FT_UINT64, BASE_HEX,
279                 NULL, 0, NULL, HFILL } }
280 };
281
282     static gint *ett[] = {
283         &ett_hdcp2,
284         &ett_hdcp2_cert
285     };
286
287     module_t *hdcp2_module;
288
289     msg_table = g_hash_table_new(g_direct_hash, g_direct_equal);
290     for(i=0; i<array_length(msg_info); i++) {
291         g_hash_table_insert(msg_table,
292                 GUINT_TO_POINTER((guint)msg_info[i].id),
293                 (const gpointer)(&msg_info[i]));
294     }
295
296     proto_hdcp2 = proto_register_protocol(
297             "High bandwidth Digital Content Protection version 2",
298             "HDCP2", "hdcp2");
299
300     hdcp2_module = prefs_register_protocol(proto_hdcp2, proto_reg_handoff_hdcp2);
301     prefs_register_bool_preference(hdcp2_module, "enable", "Enable dissector",
302                         "Enable heuristic HDCP2 dissector (default is false)",
303                         &hdcp2_enable_dissector);
304
305     proto_register_field_array(proto_hdcp2, hf, array_length(hf));
306     proto_register_subtree_array(ett, array_length(ett));
307
308     new_register_dissector("hdcp2", dissect_hdcp2, proto_hdcp2);
309 }
310
311 void
312 proto_reg_handoff_hdcp2(void)
313 {
314     static gboolean prefs_initialized = FALSE;
315
316     if (!prefs_initialized) {
317         heur_dissector_add ("tcp", dissect_hdcp2, proto_hdcp2);
318
319         prefs_initialized = TRUE;
320     }
321
322     proto_set_decoding(proto_hdcp2, hdcp2_enable_dissector);
323 }
324
325 /*
326  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
327  *
328  * Local variables:
329  * c-basic-offset: 4
330  * tab-width: 8
331  * indent-tabs-mode: nil
332  * End:
333  *
334  * vi: set shiftwidth=4 tabstop=8 expandtab:
335  * :indentSize=4:tabSize=8:noTabs=true:
336  */