/src/wireshark/epan/dissectors/packet-ipsec.c
Line | Count | Source |
1 | | /* packet-ipsec.c |
2 | | * Routines for IPsec/IPComp packet disassembly |
3 | | * |
4 | | * Wireshark - Network traffic analyzer |
5 | | * By Gerald Combs <gerald@wireshark.org> |
6 | | * Copyright 1998 Gerald Combs |
7 | | * |
8 | | * SPDX-License-Identifier: GPL-2.0-or-later |
9 | | */ |
10 | | |
11 | | |
12 | | /* |
13 | | |
14 | | Addon: ESP Decryption and Authentication Checking |
15 | | |
16 | | Frederic ROUDAUT (frederic.roudaut@free.fr) |
17 | | Copyright 2006 Frederic ROUDAUT |
18 | | |
19 | | - Decrypt ESP Payload for the following Algorithms defined in RFC 4305: |
20 | | |
21 | | Encryption Algorithm |
22 | | -------------------- |
23 | | NULL |
24 | | TripleDES-CBC [RFC2451] : keylen 192 bits. |
25 | | AES-CBC with 128-bit keys [RFC3602] : keylen 128 and 192/256 bits. |
26 | | AES-CTR [RFC3686] : keylen 160/224/288 bits. The remaining 32 bits will be used as nonce. |
27 | | DES-CBC [RFC2405] : keylen 64 bits |
28 | | |
29 | | - Add ESP Payload Decryption support for the following Encryption Algorithms : |
30 | | BLOWFISH-CBC : keylen 128 bits. |
31 | | TWOFISH-CBC : keylen 128/256 bits. |
32 | | CAST5-CBC : keylen 128 |
33 | | |
34 | | - Check ESP Authentication for the following Algorithms defined in RFC 4305: |
35 | | |
36 | | Authentication Algorithm |
37 | | ------------------------ |
38 | | NULL |
39 | | HMAC-SHA1-96 [RFC2404] : any keylen |
40 | | HMAC-MD5-96 [RFC2403] : any keylen |
41 | | AES-XCBC-MAC-96 [RFC3566] : Not available because no implementation found. |
42 | | |
43 | | - Add ESP Authentication checking for the following Authentication Algorithm : |
44 | | HMAC-SHA256 : any keylen |
45 | | HMAC-RIPEMD160-96 [RFC2857] : any keylen |
46 | | |
47 | | - Added/Modified Authentication checking (David Dahlberg <dahlberg@fgan.de>): |
48 | | CHG: HMAC-SHA256 is now HMAC-SHA-256-96 [draft-ietf-ipsec-ciph-sha-256-00] |
49 | | -> It is implemented this way in USAGI/KAME (Linux/BSD). |
50 | | ADD: HMAC-SHA-256-128 [RFC4868] |
51 | | ICV length of HMAC-SHA-256 was changed in draft-ietf-ipsec-ciph-sha-256-01 |
52 | | to 128 bit. This is "SHOULD" be the standard now! |
53 | | ADD: Additional generic (non-checked) ICV length of 128, 192 and 256. |
54 | | This follows RFC 4868 for the SHA-256+ family. |
55 | | |
56 | | */ |
57 | | |
58 | | #include "config.h" |
59 | 0 | #define WS_LOG_DOMAIN "packet-ipsec" |
60 | | #include <wireshark.h> |
61 | | |
62 | | #include <epan/packet.h> |
63 | | #include <epan/addr_resolv.h> |
64 | | #include <epan/prefs.h> |
65 | | #include <epan/expert.h> |
66 | | #include <epan/tap.h> |
67 | | #include <epan/exported_pdu.h> |
68 | | #include <epan/proto_data.h> |
69 | | #include <epan/decode_as.h> |
70 | | #include <epan/capture_dissectors.h> |
71 | | #include <epan/secrets.h> |
72 | | #include <wiretap/secrets-types.h> |
73 | | #include <stdio.h> /* for sscanf() */ |
74 | | #include <epan/uat-int.h> |
75 | | #include <epan/iana-info.h> |
76 | | #include <wsutil/str_util.h> |
77 | | #include <wsutil/wsgcrypt.h> |
78 | | #include <wsutil/pint.h> |
79 | | |
80 | | #include "packet-ipsec.h" |
81 | | #include "packet-ip.h" |
82 | | |
83 | | void proto_register_ipsec(void); |
84 | | void proto_reg_handoff_ipsec(void); |
85 | | |
86 | | static int proto_ah; |
87 | | static int hf_ah_next_header; |
88 | | static int hf_ah_length; |
89 | | static int hf_ah_reserved; |
90 | | static int hf_ah_spi; |
91 | | static int hf_ah_iv; |
92 | | static int hf_ah_sequence; |
93 | | static int proto_esp; |
94 | | static int hf_esp_spi; |
95 | | static int hf_esp_iv; |
96 | | static int hf_esp_icv; |
97 | | static int hf_esp_icv_good; |
98 | | static int hf_esp_icv_bad; |
99 | | static int hf_esp_sequence; |
100 | | static int hf_esp_encrypted_data; |
101 | | static int hf_esp_decrypted_data; |
102 | | static int hf_esp_contained_data; |
103 | | static int hf_esp_pad; |
104 | | static int hf_esp_pad_len; |
105 | | static int hf_esp_protocol; |
106 | | static int hf_esp_sequence_analysis_expected_sn; |
107 | | static int hf_esp_sequence_analysis_previous_frame; |
108 | | |
109 | | static int proto_ipcomp; |
110 | | static int hf_ipcomp_next_header; |
111 | | static int hf_ipcomp_flags; |
112 | | static int hf_ipcomp_cpi; |
113 | | |
114 | | static int ett_ah; |
115 | | static int ett_esp; |
116 | | static int ett_esp_icv; |
117 | | static int ett_esp_decrypted_data; |
118 | | static int ett_ipcomp; |
119 | | |
120 | | static expert_field ei_esp_sequence_analysis_wrong_sequence_number; |
121 | | static expert_field ei_esp_pad_bogus; |
122 | | |
123 | | |
124 | | static int exported_pdu_tap = -1; |
125 | | |
126 | | static dissector_handle_t ipcomp_handle; |
127 | | static capture_dissector_handle_t ah_cap_handle; |
128 | | |
129 | | static dissector_handle_t data_handle; |
130 | | |
131 | | static dissector_table_t ip_dissector_table; |
132 | | |
133 | | static wmem_map_t *esp_used_sa_map; |
134 | | |
135 | | /* Encryption algorithms defined in RFC 4305 */ |
136 | 102 | #define IPSEC_ENCRYPT_NULL 0 |
137 | 0 | #define IPSEC_ENCRYPT_3DES_CBC 1 |
138 | 0 | #define IPSEC_ENCRYPT_AES_CBC 2 |
139 | 0 | #define IPSEC_ENCRYPT_AES_CTR 3 |
140 | 0 | #define IPSEC_ENCRYPT_DES_CBC 4 |
141 | 0 | #define IPSEC_ENCRYPT_BLOWFISH_CBC 5 |
142 | 0 | #define IPSEC_ENCRYPT_TWOFISH_CBC 6 |
143 | | |
144 | | /* Encryption algorithm defined in RFC 2144 */ |
145 | 0 | #define IPSEC_ENCRYPT_CAST5_CBC 7 |
146 | | |
147 | | /* Encryption algorithms defined in RFC 4106 */ |
148 | 0 | #define IPSEC_ENCRYPT_AES_GCM 8 |
149 | 0 | #define IPSEC_ENCRYPT_AES_GCM_8 9 |
150 | 0 | #define IPSEC_ENCRYPT_AES_GCM_12 10 |
151 | 0 | #define IPSEC_ENCRYPT_AES_GCM_16 11 |
152 | | |
153 | | /* Encryption algorithm defined in RFC 4106 & RFC 8750 */ |
154 | 0 | #define IPSEC_ENCRYPT_AES_GCM_16_IIV 12 |
155 | | |
156 | | /* Encryption algorithm defined in RFC 7634 */ |
157 | 0 | #define IPSEC_ENCRYPT_CHACHA20_POLY1305 13 |
158 | | |
159 | | /* Encryption algorithm defined in RFC 7634 & RFC 8750 */ |
160 | 0 | #define IPSEC_ENCRYPT_CHACHA20_POLY1305_IIV 14 |
161 | | |
162 | | /* Authentication algorithms defined in RFC 4305 */ |
163 | 102 | #define IPSEC_AUTH_NULL 0 |
164 | 0 | #define IPSEC_AUTH_HMAC_SHA1_96 1 |
165 | 0 | #define IPSEC_AUTH_HMAC_SHA256_96 2 |
166 | 0 | #define IPSEC_AUTH_HMAC_SHA256_128 3 |
167 | 0 | #define IPSEC_AUTH_HMAC_SHA384_192 4 |
168 | 0 | #define IPSEC_AUTH_HMAC_SHA512_256 5 |
169 | 0 | #define IPSEC_AUTH_HMAC_MD5_96 6 |
170 | 0 | #define IPSEC_AUTH_HMAC_RIPEMD160_96 7 |
171 | | /* define IPSEC_AUTH_AES_XCBC_MAC_96 6 */ |
172 | 0 | #define IPSEC_AUTH_ANY_64BIT 8 |
173 | 0 | #define IPSEC_AUTH_ANY_96BIT 9 |
174 | 0 | #define IPSEC_AUTH_ANY_128BIT 10 |
175 | 0 | #define IPSEC_AUTH_ANY_192BIT 11 |
176 | 0 | #define IPSEC_AUTH_ANY_256BIT 12 |
177 | | |
178 | | /* ICV types (not an RFC classification) */ |
179 | 102 | #define ICV_TYPE_UNCHECKED 0 /* ICV is not verified */ |
180 | 0 | #define ICV_TYPE_HMAC 1 /* ICV is verified before decryption using an HMAC */ |
181 | 0 | #define ICV_TYPE_AEAD 2 /* ICV is verified during decryption using an AEAD cipher */ |
182 | | |
183 | 0 | #define IPSEC_IPV6_ADDR_LEN 128 |
184 | 0 | #define IPSEC_IPV4_ADDR_LEN 32 |
185 | 0 | #define IPSEC_STRLEN_IPV6 32 |
186 | 0 | #define IPSEC_STRLEN_IPV4 8 |
187 | 16 | #define IPSEC_SA_IPV4 1 |
188 | 16 | #define IPSEC_SA_IPV6 2 |
189 | 16 | #define IPSEC_SA_ANY 3 |
190 | 102 | #define IPSEC_SA_UNKNOWN -1 |
191 | 0 | #define IPSEC_SA_WILDCARDS_ANY '*' |
192 | | /* the maximum number of bytes (10)(including the terminating nul character(11)) */ |
193 | | #define IPSEC_SPI_LEN_MAX 11 |
194 | 118 | #define IPSEC_SA_SN 32 |
195 | 16 | #define IPSEC_SA_ESN 64 |
196 | | |
197 | | |
198 | | /* well-known algorithm number (in CPI), from RFC2409 */ |
199 | | #define IPCOMP_OUI 1 /* vendor specific */ |
200 | | #define IPCOMP_DEFLATE 2 /* RFC2394 */ |
201 | | #define IPCOMP_LZS 3 /* RFC2395 */ |
202 | | #define IPCOMP_MAX 4 |
203 | | |
204 | | |
205 | | static const value_string cpi2val[] = { |
206 | | { IPCOMP_OUI, "OUI" }, |
207 | | { IPCOMP_DEFLATE, "DEFLATE" }, |
208 | | { IPCOMP_LZS, "LZS" }, |
209 | | { 0, NULL }, |
210 | | }; |
211 | | |
212 | | /* The length of the two fields (SPI and Sequence Number) preceding the Payload Data */ |
213 | 199 | #define ESP_HEADER_LEN 8 |
214 | | |
215 | | |
216 | | static const value_string esp_encryption_type_vals[] = { |
217 | | { IPSEC_ENCRYPT_NULL, "NULL" }, |
218 | | { IPSEC_ENCRYPT_3DES_CBC, "TripleDES-CBC [RFC2451]" }, |
219 | | { IPSEC_ENCRYPT_AES_CBC, "AES-CBC [RFC3602]" }, |
220 | | { IPSEC_ENCRYPT_AES_CTR, "AES-CTR [RFC3686]" }, |
221 | | { IPSEC_ENCRYPT_DES_CBC, "DES-CBC [RFC2405]" }, |
222 | | { IPSEC_ENCRYPT_CAST5_CBC, "CAST5-CBC [RFC2144]" }, |
223 | | { IPSEC_ENCRYPT_BLOWFISH_CBC, "BLOWFISH-CBC [RFC2451]" }, |
224 | | { IPSEC_ENCRYPT_TWOFISH_CBC, "TWOFISH-CBC" }, |
225 | | { IPSEC_ENCRYPT_AES_GCM, "AES-GCM [RFC4106]" }, /* deprecated; (no ICV length specified) */ |
226 | | { IPSEC_ENCRYPT_AES_GCM_8, "AES-GCM with 8 octet ICV [RFC4106]" }, |
227 | | { IPSEC_ENCRYPT_AES_GCM_12, "AES-GCM with 12 octet ICV [RFC4106]" }, |
228 | | { IPSEC_ENCRYPT_AES_GCM_16, "AES-GCM with 16 octet ICV [RFC4106]" }, |
229 | | { IPSEC_ENCRYPT_AES_GCM_16_IIV, "AES-GCM with IIV and 16 octet ICV [RFC4106 & RFC8750]" }, |
230 | | { IPSEC_ENCRYPT_CHACHA20_POLY1305, "ChaCha20 with Poly1305 [RFC7634]" }, |
231 | | { IPSEC_ENCRYPT_CHACHA20_POLY1305_IIV, "ChaCha20 with Poly1305 and IIV [RFC7634 & RFC8750]" }, |
232 | | { 0x00, NULL } |
233 | | }; |
234 | | |
235 | | static const char * |
236 | | esp_get_encr_algo_name(int esp_encr_algo) |
237 | 0 | { |
238 | 0 | return esp_encryption_type_vals[esp_encr_algo].strptr; |
239 | 0 | } |
240 | | |
241 | | |
242 | | static const value_string esp_authentication_type_vals[] = { |
243 | | { IPSEC_AUTH_NULL, "NULL" }, |
244 | | { IPSEC_AUTH_HMAC_SHA1_96, "HMAC-SHA-1-96 [RFC2404]" }, |
245 | | { IPSEC_AUTH_HMAC_SHA256_96, "HMAC-SHA-256-96 [draft-ietf-ipsec-ciph-sha-256-00]" }, |
246 | | { IPSEC_AUTH_HMAC_SHA256_128, "HMAC-SHA-256-128 [RFC4868]" }, |
247 | | { IPSEC_AUTH_HMAC_SHA384_192, "HMAC-SHA-384-192 [RFC4868]" }, |
248 | | { IPSEC_AUTH_HMAC_SHA512_256, "HMAC-SHA-512-256 [RFC4868]" }, |
249 | | { IPSEC_AUTH_HMAC_MD5_96, "HMAC-MD5-96 [RFC2403]" }, |
250 | | { IPSEC_AUTH_HMAC_RIPEMD160_96, "MAC-RIPEMD-160-96 [RFC2857]" }, |
251 | | /* { IPSEC_AUTH_AES_XCBC_MAC_96, "AES-XCBC-MAC-96 [RFC3566]" }, */ |
252 | | { IPSEC_AUTH_ANY_64BIT, "ANY 64 bit authentication [no checking]" }, |
253 | | { IPSEC_AUTH_ANY_96BIT, "ANY 96 bit authentication [no checking]" }, |
254 | | { IPSEC_AUTH_ANY_128BIT, "ANY 128 bit authentication [no checking]" }, |
255 | | { IPSEC_AUTH_ANY_192BIT, "ANY 192 bit authentication [no checking]" }, |
256 | | { IPSEC_AUTH_ANY_256BIT, "ANY 256 bit authentication [no checking]" }, |
257 | | { 0x00, NULL } |
258 | | }; |
259 | | |
260 | | static const char * |
261 | | esp_get_auth_algo_name(int esp_auth_algo) |
262 | 0 | { |
263 | 0 | return esp_authentication_type_vals[esp_auth_algo].strptr; |
264 | 0 | } |
265 | | |
266 | | |
267 | | /*------------------------------------- |
268 | | * UAT for ESP |
269 | | *------------------------------------- |
270 | | */ |
271 | | /* UAT entry structure. */ |
272 | | typedef struct { |
273 | | uint8_t protocol; |
274 | | char *srcIP; |
275 | | char *dstIP; |
276 | | char *spi; |
277 | | |
278 | | uint8_t encryption_algo; /* see values in esp_encryption_type_vals */ |
279 | | char *encryption_key_string; |
280 | | char *encryption_key; |
281 | | int encryption_key_length; |
282 | | bool cipher_hd_created; |
283 | | gcry_cipher_hd_t cipher_hd; /* Key is stored here and closed with the SA */ |
284 | | |
285 | | uint8_t authentication_algo; /* see values in esp_authentication_type_vals */ |
286 | | char *authentication_key_string; |
287 | | char *authentication_key; |
288 | | int authentication_key_length; |
289 | | |
290 | | uint8_t sn_length; |
291 | | uint32_t sn_upper; |
292 | | } uat_esp_sa_record_t; |
293 | | |
294 | | static uat_esp_sa_record_t *uat_esp_sa_records; |
295 | | |
296 | | /* Extra SA records that may be set programmatically */ |
297 | | /* 'records' array is now allocated on the heap */ |
298 | 0 | #define MAX_EXTRA_SA_RECORDS 16 |
299 | | typedef struct extra_esp_sa_records_t { |
300 | | unsigned num_records; |
301 | | uat_esp_sa_record_t *records; |
302 | | } extra_esp_sa_records_t; |
303 | | static extra_esp_sa_records_t extra_esp_sa_records; |
304 | | |
305 | | static uat_t * esp_uat; |
306 | | static unsigned num_sa_uat; |
307 | | |
308 | | /* |
309 | | Name : static int compute_ascii_key(char **ascii_key, char *key) |
310 | | Description : Allocate memory for the key and transform the key if it is hexadecimal |
311 | | Return : Return the key length |
312 | | Params: |
313 | | - char **ascii_key : the resulting ascii key allocated here |
314 | | - char *key : the key to compute |
315 | | - char **err : an error string to report if the input is found to be invalid |
316 | | */ |
317 | | static int |
318 | | compute_ascii_key(char **ascii_key, const char *key, char **err) |
319 | 0 | { |
320 | 0 | unsigned key_len = 0, raw_key_len; |
321 | 0 | int hex_digit; |
322 | 0 | unsigned char key_byte; |
323 | 0 | unsigned i, j; |
324 | |
|
325 | 0 | if(key != NULL) |
326 | 0 | { |
327 | 0 | raw_key_len = (unsigned)strlen(key); |
328 | 0 | if((raw_key_len > 2) && (key[0] == '0') && ((key[1] == 'x') || (key[1] == 'X'))) |
329 | 0 | { |
330 | | /* |
331 | | * Key begins with "0x" or "0X"; skip that and treat the rest |
332 | | * as a sequence of hex digits. |
333 | | */ |
334 | 0 | i = 2; /* first character after "0[Xx]" */ |
335 | 0 | j = 0; |
336 | 0 | if(raw_key_len %2 == 1) |
337 | 0 | { |
338 | | /* |
339 | | * Key has an odd number of characters; we act as if the |
340 | | * first character had a 0 in front of it, making the |
341 | | * number of characters even. |
342 | | */ |
343 | 0 | key_len = (raw_key_len - 2) / 2 + 1; |
344 | 0 | *ascii_key = (char *) g_malloc ((key_len + 1)* sizeof(char)); |
345 | 0 | hex_digit = g_ascii_xdigit_value(key[i]); |
346 | 0 | if (hex_digit == -1) |
347 | 0 | { |
348 | 0 | g_free(*ascii_key); |
349 | 0 | *ascii_key = NULL; |
350 | 0 | *err = ws_strdup_printf("Key %s begins with an invalid hex char (%c)", key, key[i]); |
351 | 0 | return -1; /* not a valid hex digit */ |
352 | 0 | } |
353 | 0 | (*ascii_key)[j] = (unsigned char)hex_digit; |
354 | 0 | j++; |
355 | 0 | i++; |
356 | 0 | } |
357 | 0 | else |
358 | 0 | { |
359 | | /* |
360 | | * Key has an even number of characters, so we treat each |
361 | | * pair of hex digits as a single byte value. |
362 | | */ |
363 | 0 | key_len = (raw_key_len - 2) / 2; |
364 | 0 | *ascii_key = (char *) g_malloc ((key_len + 1)* sizeof(char)); |
365 | 0 | } |
366 | | |
367 | 0 | while(i < (raw_key_len -1)) |
368 | 0 | { |
369 | 0 | hex_digit = g_ascii_xdigit_value(key[i]); |
370 | 0 | i++; |
371 | 0 | if (hex_digit == -1) |
372 | 0 | { |
373 | 0 | g_free(*ascii_key); |
374 | 0 | *ascii_key = NULL; |
375 | 0 | *err = ws_strdup_printf("Key %s has an invalid hex char (%c)", |
376 | 0 | key, key[i-1]); |
377 | 0 | return -1; /* not a valid hex digit */ |
378 | 0 | } |
379 | 0 | key_byte = ((unsigned char)hex_digit) << 4; |
380 | 0 | hex_digit = g_ascii_xdigit_value(key[i]); |
381 | 0 | i++; |
382 | 0 | if (hex_digit == -1) |
383 | 0 | { |
384 | 0 | g_free(*ascii_key); |
385 | 0 | *ascii_key = NULL; |
386 | 0 | *err = ws_strdup_printf("Key %s has an invalid hex char (%c)", key, key[i-1]); |
387 | 0 | return -1; /* not a valid hex digit */ |
388 | 0 | } |
389 | 0 | key_byte |= (unsigned char)hex_digit; |
390 | 0 | (*ascii_key)[j] = key_byte; |
391 | 0 | j++; |
392 | 0 | } |
393 | 0 | (*ascii_key)[j] = '\0'; |
394 | 0 | } |
395 | | |
396 | 0 | else if((raw_key_len == 2) && (key[0] == '0') && ((key[1] == 'x') || (key[1] == 'X'))) |
397 | 0 | { |
398 | | /* A valid null key */ |
399 | 0 | *ascii_key = NULL; |
400 | 0 | return 0; |
401 | 0 | } |
402 | 0 | else |
403 | 0 | { |
404 | | /* Doesn't begin with 0X or 0x... */ |
405 | 0 | key_len = raw_key_len; |
406 | 0 | *ascii_key = g_strdup(key); |
407 | 0 | } |
408 | 0 | } |
409 | | |
410 | 0 | return key_len; |
411 | 0 | } |
412 | | |
413 | | |
414 | 0 | static bool uat_esp_sa_record_update_cb(void* r, char** err) { |
415 | 0 | uat_esp_sa_record_t* rec = (uat_esp_sa_record_t *)r; |
416 | | |
417 | | /* Compute keys & lengths once and for all */ |
418 | 0 | g_free(rec->encryption_key); |
419 | 0 | if (rec->cipher_hd_created) { |
420 | 0 | gcry_cipher_close(rec->cipher_hd); |
421 | 0 | rec->cipher_hd_created = false; |
422 | 0 | } |
423 | 0 | if (rec->encryption_key_string) { |
424 | 0 | rec->encryption_key_length = compute_ascii_key(&rec->encryption_key, rec->encryption_key_string, err); |
425 | 0 | } |
426 | 0 | else { |
427 | 0 | rec->encryption_key_length = 0; |
428 | 0 | rec->encryption_key = NULL; |
429 | 0 | } |
430 | |
|
431 | 0 | g_free(rec->authentication_key); |
432 | 0 | if (rec->authentication_key_string) { |
433 | 0 | rec->authentication_key_length = compute_ascii_key(&rec->authentication_key, rec->authentication_key_string, err); |
434 | 0 | } |
435 | 0 | else { |
436 | 0 | rec->authentication_key_length = 0; |
437 | 0 | rec->authentication_key = NULL; |
438 | 0 | } |
439 | | |
440 | | /* TODO: Make sure IP addresses have a valid conversion */ |
441 | | /* Unfortunately, return value of get_full_ipv4_addr() or get_full_ipv6_addr() (depending upon rec->protocol) |
442 | | is not sufficient */ |
443 | | |
444 | | /* TODO: check format of spi */ |
445 | | |
446 | | /* Return true only if *err has not been set by checking code. */ |
447 | 0 | return *err == NULL; |
448 | 0 | } |
449 | | |
450 | 0 | static void* uat_esp_sa_record_copy_cb(void* n, const void* o, size_t siz _U_) { |
451 | 0 | uat_esp_sa_record_t* new_rec = (uat_esp_sa_record_t *)n; |
452 | 0 | const uat_esp_sa_record_t* old_rec = (const uat_esp_sa_record_t *)o; |
453 | | |
454 | | /* Copy UAT fields */ |
455 | 0 | new_rec->protocol = old_rec->protocol; |
456 | 0 | new_rec->srcIP = g_strdup(old_rec->srcIP); |
457 | 0 | new_rec->dstIP = g_strdup(old_rec->dstIP); |
458 | 0 | new_rec->spi = g_strdup(old_rec->spi); |
459 | 0 | new_rec->encryption_algo = old_rec->encryption_algo; |
460 | 0 | new_rec->encryption_key_string = g_strdup(old_rec->encryption_key_string); |
461 | 0 | new_rec->encryption_key = NULL; |
462 | 0 | new_rec->cipher_hd_created = false; |
463 | 0 | new_rec->authentication_algo = old_rec->authentication_algo; |
464 | 0 | new_rec->authentication_key_string = g_strdup(old_rec->authentication_key_string); |
465 | 0 | new_rec->authentication_key = NULL; |
466 | 0 | new_rec->sn_length = old_rec->sn_length; |
467 | 0 | new_rec->sn_upper = old_rec->sn_upper; |
468 | | |
469 | | /* Parse keys as in an update */ |
470 | 0 | char *err = NULL; |
471 | 0 | uat_esp_sa_record_update_cb(new_rec, &err); |
472 | 0 | if (err) { |
473 | 0 | g_free(err); |
474 | 0 | } |
475 | |
|
476 | 0 | return new_rec; |
477 | 0 | } |
478 | | |
479 | 0 | static void uat_esp_sa_record_free_cb(void*r) { |
480 | 0 | uat_esp_sa_record_t* rec = (uat_esp_sa_record_t*)r; |
481 | |
|
482 | 0 | g_free(rec->srcIP); |
483 | 0 | g_free(rec->dstIP); |
484 | 0 | g_free(rec->spi); |
485 | 0 | g_free(rec->encryption_key_string); |
486 | 0 | g_free(rec->encryption_key); |
487 | 0 | g_free(rec->authentication_key_string); |
488 | 0 | g_free(rec->authentication_key); |
489 | |
|
490 | 0 | if (rec->cipher_hd_created) { |
491 | 0 | gcry_cipher_close(rec->cipher_hd); |
492 | 0 | rec->cipher_hd_created = false; |
493 | 0 | } |
494 | 0 | } |
495 | | |
496 | 0 | UAT_VS_DEF(uat_esp_sa_records, protocol, uat_esp_sa_record_t, uint8_t, IPSEC_SA_IPV4, "IPv4") Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_protocol_set_cb Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_protocol_tostr_cb |
497 | 0 | UAT_CSTRING_CB_DEF(uat_esp_sa_records, srcIP, uat_esp_sa_record_t) |
498 | 0 | UAT_CSTRING_CB_DEF(uat_esp_sa_records, dstIP, uat_esp_sa_record_t) |
499 | 0 | UAT_CSTRING_CB_DEF(uat_esp_sa_records, spi, uat_esp_sa_record_t) |
500 | 0 | UAT_VS_DEF(uat_esp_sa_records, encryption_algo, uat_esp_sa_record_t, uint8_t, 0, "FIXX") Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_encryption_algo_set_cb Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_encryption_algo_tostr_cb |
501 | 0 | UAT_CSTRING_CB_DEF(uat_esp_sa_records, encryption_key_string, uat_esp_sa_record_t) |
502 | 0 | UAT_VS_DEF(uat_esp_sa_records, authentication_algo, uat_esp_sa_record_t, uint8_t, 0, "FIXX") Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_authentication_algo_set_cb Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_authentication_algo_tostr_cb |
503 | 0 | UAT_CSTRING_CB_DEF(uat_esp_sa_records, authentication_key_string, uat_esp_sa_record_t) |
504 | 0 | UAT_VS_DEF(uat_esp_sa_records, sn_length, uat_esp_sa_record_t, uint8_t, IPSEC_SA_SN, "32-bit") Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_sn_length_set_cb Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_sn_length_tostr_cb |
505 | 0 | UAT_HEX_CB_DEF(uat_esp_sa_records, sn_upper, uat_esp_sa_record_t) Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_sn_upper_set_cb Unexecuted instantiation: packet-ipsec.c:uat_esp_sa_records_sn_upper_tostr_cb |
506 | | |
507 | | |
508 | | /* Configure a new SA (programmatically, most likely from a private dissector). |
509 | | The arguments here are deliberately in the same string formats as the UAT fields |
510 | | in order to keep code paths common. |
511 | | Note that an attempt to match with these entries will be made *before* entries |
512 | | added through the UAT entry interface/file. */ |
513 | | void esp_sa_record_add_from_dissector(uint8_t protocol, const char *srcIP, const char *dstIP, |
514 | | char *spi, |
515 | | uint8_t encryption_algo, /* values from esp_encryption_type_vals */ |
516 | | const char *encryption_key, |
517 | | uint8_t authentication_algo, /* values from esp_authentication_type_vals */ |
518 | | const char *authentication_key) |
519 | 0 | { |
520 | 0 | uat_esp_sa_record_t* record = NULL; |
521 | 0 | if (extra_esp_sa_records.num_records == 0) { |
522 | 0 | extra_esp_sa_records.records = g_new(uat_esp_sa_record_t, MAX_EXTRA_SA_RECORDS); |
523 | 0 | } |
524 | | /* Add new entry */ |
525 | 0 | if (extra_esp_sa_records.num_records < MAX_EXTRA_SA_RECORDS) { |
526 | 0 | record = &extra_esp_sa_records.records[extra_esp_sa_records.num_records++]; |
527 | 0 | } |
528 | 0 | else { |
529 | | /* No room left!! */ |
530 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Failed to add UE as already have max (%d) configured\n", |
531 | 0 | MAX_EXTRA_SA_RECORDS); |
532 | 0 | return; |
533 | 0 | } |
534 | | |
535 | | /* Copy key fields */ |
536 | 0 | record->protocol = protocol; |
537 | 0 | record->srcIP = g_strdup(srcIP); |
538 | 0 | record->dstIP = g_strdup(dstIP); |
539 | 0 | record->spi = g_strdup(spi); |
540 | | |
541 | | /* Encryption */ |
542 | 0 | record->encryption_algo = encryption_algo; |
543 | 0 | record->encryption_key_string = g_strdup(encryption_key); |
544 | 0 | record->encryption_key = NULL; |
545 | 0 | record->cipher_hd_created = false; |
546 | | |
547 | | /* Authentication */ |
548 | 0 | record->authentication_algo = authentication_algo; |
549 | 0 | record->authentication_key_string = g_strdup(authentication_key); |
550 | 0 | record->authentication_key = NULL; |
551 | | |
552 | | /* XXX - Should we change the function so private dissectors pass this in? */ |
553 | 0 | record->sn_length = IPSEC_SA_SN; |
554 | 0 | record->sn_upper = 0; |
555 | | |
556 | | /* Parse keys */ |
557 | 0 | char *err = NULL; |
558 | 0 | uat_esp_sa_record_update_cb(record, &err); |
559 | 0 | if (err) { |
560 | | /* Free (but ignore) any error string set */ |
561 | 0 | g_free(err); |
562 | 0 | } |
563 | 0 | } |
564 | | |
565 | | /*************************************/ |
566 | | /* Preference settings */ |
567 | | |
568 | | /* Default ESP payload decode to off */ |
569 | | static bool g_esp_enable_encryption_decode; |
570 | | |
571 | | /* Default ESP payload Authentication Checking to off */ |
572 | | static bool g_esp_enable_authentication_check; |
573 | | |
574 | | /**************************************************/ |
575 | | /* Sequence number analysis */ |
576 | | |
577 | | /* SPI state, key is just 32-bit SPI */ |
578 | | typedef struct |
579 | | { |
580 | | uint32_t firstValidSN; |
581 | | uint32_t previousSequenceNumber; |
582 | | uint32_t previousFrameNum; |
583 | | } spi_status; |
584 | | |
585 | | /* The sequence analysis SPI hash table. |
586 | | Maps SPI -> spi_status */ |
587 | | static wmem_map_t *esp_sequence_analysis_hash; |
588 | | |
589 | | /* Results are stored here: framenum -> spi_status */ |
590 | | /* N.B. only store entries for out-of-order frames, if there is no entry for |
591 | | a given frame, it was found to be in-order */ |
592 | | static wmem_map_t *esp_sequence_analysis_report_hash; |
593 | | |
594 | | /* During the first pass, update the SPI state. If the sequence numbers |
595 | | are out of order, add an entry to the report table */ |
596 | | static void check_esp_sequence_info(uint32_t spi, uint32_t sequence_number, packet_info *pinfo) |
597 | 100 | { |
598 | | /* Do the table lookup */ |
599 | 100 | spi_status *status = (spi_status*)wmem_map_lookup(esp_sequence_analysis_hash, |
600 | 100 | GUINT_TO_POINTER((unsigned)spi)); |
601 | 100 | if (status == NULL) { |
602 | | /* Create an entry for this SPI */ |
603 | 27 | status = wmem_new0(wmem_file_scope(), spi_status); |
604 | 27 | status->previousSequenceNumber = sequence_number; |
605 | 27 | status->previousFrameNum = pinfo->num; |
606 | | |
607 | | /* And add it to the table */ |
608 | 27 | wmem_map_insert(esp_sequence_analysis_hash, GUINT_TO_POINTER((unsigned)spi), status); |
609 | 27 | } |
610 | 73 | else { |
611 | 73 | spi_status *frame_status; |
612 | | |
613 | | /* Entry already existed, so check that we got the sequence number we expected. */ |
614 | 73 | if (sequence_number != status->previousSequenceNumber+1) { |
615 | | /* Create report entry */ |
616 | 71 | frame_status = wmem_new0(wmem_file_scope(), spi_status); |
617 | | /* Copy what was expected */ |
618 | 71 | *frame_status = *status; |
619 | | /* And add it into the report table */ |
620 | 71 | wmem_map_insert(esp_sequence_analysis_report_hash, GUINT_TO_POINTER(pinfo->num), frame_status); |
621 | 71 | } |
622 | | /* Adopt this setting as 'current' regardless of whether expected */ |
623 | 73 | status->previousSequenceNumber = sequence_number; |
624 | 73 | status->previousFrameNum = pinfo->num; |
625 | 73 | } |
626 | 100 | } |
627 | | |
628 | | /* Check to see if there is a report stored for this frame. If there is, |
629 | | add it to the tree and report using expert info */ |
630 | | static void show_esp_sequence_info(uint32_t spi, uint32_t sequence_number, |
631 | | tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo) |
632 | 100 | { |
633 | | /* Look up this frame in the report table. */ |
634 | 100 | spi_status *status = (spi_status*)wmem_map_lookup(esp_sequence_analysis_report_hash, |
635 | 100 | GUINT_TO_POINTER(pinfo->num)); |
636 | 100 | if (status != NULL) { |
637 | 83 | proto_item *sn_ti, *frame_ti; |
638 | | |
639 | | /* Expected sequence number */ |
640 | 83 | sn_ti = proto_tree_add_uint(tree, hf_esp_sequence_analysis_expected_sn, |
641 | 83 | tvb, 0, 0, status->previousSequenceNumber+1); |
642 | 83 | if (sequence_number > (status->previousSequenceNumber+1)) { |
643 | 28 | proto_item_append_text(sn_ti, " (%u SNs missing)", |
644 | 28 | sequence_number - (status->previousSequenceNumber+1)); |
645 | 28 | } |
646 | 83 | proto_item_set_generated(sn_ti); |
647 | | |
648 | | /* Link back to previous frame for SPI */ |
649 | 83 | frame_ti = proto_tree_add_uint(tree, hf_esp_sequence_analysis_previous_frame, |
650 | 83 | tvb, 0, 0, status->previousFrameNum); |
651 | 83 | proto_item_set_generated(frame_ti); |
652 | | |
653 | | /* Expert info */ |
654 | 83 | if (sequence_number == status->previousSequenceNumber) { |
655 | 38 | expert_add_info_format(pinfo, sn_ti, &ei_esp_sequence_analysis_wrong_sequence_number, |
656 | 38 | "Wrong Sequence Number for SPI %08x - %u repeated", |
657 | 38 | spi, sequence_number); |
658 | 38 | } |
659 | 45 | else if (sequence_number > status->previousSequenceNumber+1) { |
660 | 27 | expert_add_info_format(pinfo, sn_ti, &ei_esp_sequence_analysis_wrong_sequence_number, |
661 | 27 | "Wrong Sequence Number for SPI %08x - %u missing", |
662 | 27 | spi, |
663 | 27 | sequence_number - (status->previousSequenceNumber+1)); |
664 | 27 | } |
665 | 18 | else { |
666 | 18 | expert_add_info_format(pinfo, sn_ti, &ei_esp_sequence_analysis_wrong_sequence_number, |
667 | 18 | "Wrong Sequence Number for SPI %08x - %u less than expected", |
668 | 18 | spi, |
669 | 18 | (status->previousSequenceNumber+1) - sequence_number); |
670 | 18 | } |
671 | 83 | } |
672 | 100 | } |
673 | | |
674 | | /* |
675 | | Default ESP payload heuristic decode to off |
676 | | (only works if payload is NULL encrypted and ESP payload decode is off or payload is NULL encrypted |
677 | | and the packet does not match a Security Association). |
678 | | */ |
679 | | static bool g_esp_enable_null_encryption_decode_heuristic; |
680 | | |
681 | 0 | #define PADDING_RFC 0 |
682 | 0 | #define PADDING_ZERO 1 |
683 | 0 | #define PADDING_ANY 2 |
684 | | |
685 | | /* PADDING_RFC is chosen as 0 to be the default */ |
686 | | static int g_esp_padding_type; |
687 | | |
688 | | static const enum_val_t esp_padding_vals[] = { |
689 | | { "rfc", "RFC compliant padding only", PADDING_RFC }, |
690 | | { "zero", "All-zero padding also permitted", PADDING_ZERO }, |
691 | | { "any", "Any padding permitted", PADDING_ANY }, |
692 | | { NULL, NULL, 0 } |
693 | | }; |
694 | | |
695 | | /* Default to doing ESP sequence analysis */ |
696 | | static bool g_esp_do_sequence_analysis = true; |
697 | | |
698 | | |
699 | | |
700 | | /* |
701 | | Name : static int get_ipv6_suffix(char* ipv6_suffix, char *ipv6_address) |
702 | | Description : Get the extended IPv6 Suffix of an IPv6 Address |
703 | | Return : Return the number of char of the IPv6 address suffix parsed |
704 | | Params: |
705 | | - char *ipv6_address : the valid ipv6 address to parse in char * |
706 | | - char *ipv6_suffix : the ipv6 suffix associated in char * |
707 | | |
708 | | ex: if IPv6 address is "3ffe::1" the IPv6 suffix will be "0001" and the function will return 3 |
709 | | */ |
710 | | static int get_ipv6_suffix(char* ipv6_suffix, char *ipv6_address) |
711 | 0 | { |
712 | 0 | char suffix[IPSEC_STRLEN_IPV6 + 1]; |
713 | 0 | int cpt = 0; |
714 | 0 | int cpt_suffix = 0; |
715 | 0 | int cpt_seg = 0; |
716 | 0 | int j =0; |
717 | 0 | int ipv6_len = 0; |
718 | 0 | bool found = false; |
719 | |
|
720 | 0 | ipv6_len = (int) strlen(ipv6_address); |
721 | 0 | if(ipv6_len != 0) |
722 | 0 | { |
723 | 0 | while ( (cpt_suffix < IPSEC_STRLEN_IPV6) && (ipv6_len - cpt -1 >= 0) && (found == false)) |
724 | 0 | { |
725 | 0 | if(ipv6_address[ipv6_len - cpt - 1] == ':') |
726 | 0 | { |
727 | | /* Add some 0 to the prefix; */ |
728 | 0 | for(j = cpt_seg; j < 4; j++) |
729 | 0 | { |
730 | 0 | suffix[IPSEC_STRLEN_IPV6 -1 -cpt_suffix] = '0'; |
731 | 0 | cpt_suffix ++; |
732 | 0 | } |
733 | 0 | cpt_seg = 0; |
734 | |
|
735 | 0 | if(ipv6_len - cpt - 1 == 0) |
736 | 0 | { |
737 | | /* Found a suffix */ |
738 | 0 | found = true; |
739 | 0 | } |
740 | 0 | else |
741 | 0 | if(ipv6_address[ipv6_len - cpt - 2] == ':') |
742 | 0 | { |
743 | | /* found a suffix */ |
744 | 0 | cpt +=2; |
745 | 0 | found = true; |
746 | 0 | } |
747 | | |
748 | 0 | else |
749 | 0 | { |
750 | 0 | cpt++; |
751 | 0 | } |
752 | 0 | } |
753 | 0 | else |
754 | 0 | { |
755 | 0 | suffix[IPSEC_STRLEN_IPV6 -1 -cpt_suffix] = g_ascii_toupper(ipv6_address[ipv6_len - cpt - 1]); |
756 | 0 | cpt_seg ++; |
757 | 0 | cpt_suffix ++; |
758 | 0 | cpt++; |
759 | 0 | } |
760 | 0 | } |
761 | |
|
762 | 0 | if(cpt_suffix % 4 != 0) |
763 | 0 | { |
764 | 0 | for(j = cpt_seg; j < 4; j++) |
765 | 0 | { |
766 | 0 | suffix[IPSEC_STRLEN_IPV6 -1 -cpt_suffix] = '0'; |
767 | 0 | cpt_suffix ++; |
768 | 0 | } |
769 | 0 | } |
770 | |
|
771 | 0 | } |
772 | |
|
773 | 0 | for(j = 0 ; j < cpt_suffix ; j ++) |
774 | 0 | { |
775 | 0 | suffix[j] = suffix[j + IPSEC_STRLEN_IPV6 - cpt_suffix] ; |
776 | 0 | } |
777 | |
|
778 | 0 | suffix[j] = '\0'; |
779 | 0 | memcpy(ipv6_suffix,suffix,j + 1); |
780 | 0 | return cpt; |
781 | 0 | } |
782 | | |
783 | | /* |
784 | | Name : static int get_full_ipv6_addr(char* ipv6_addr_expanded, char *ipv6_addr) |
785 | | Description : Get the extended IPv6 Address of an IPv6 Address |
786 | | Return : Return the remaining number of char of the IPv6 address parsed |
787 | | Params: |
788 | | - char *ipv6_addr : the valid ipv6 address to parse in char * |
789 | | - char *ipv6_addr_expanded : the expanded ipv6 address associated in char * |
790 | | |
791 | | ex: if IPv6 address is "3ffe::1" the IPv6 expanded address |
792 | | will be "3FFE0000000000000000000000000001" and the function will return 0 |
793 | | if IPV6 address is "3ffe::*" the IPv6 expanded address |
794 | | will be "3FFE000000000000000000000000****" and the function will return 0 |
795 | | */ |
796 | | static int |
797 | | get_full_ipv6_addr(wmem_allocator_t* scope, char* ipv6_addr_expanded, char *ipv6_addr) |
798 | 0 | { |
799 | 0 | char suffix[IPSEC_STRLEN_IPV6 + 1]; |
800 | 0 | char prefix[IPSEC_STRLEN_IPV6 + 1]; |
801 | 0 | char *prefix_addr; |
802 | |
|
803 | 0 | int suffix_cpt = 0; |
804 | 0 | int suffix_len = 0; |
805 | 0 | int prefix_remaining = 0; |
806 | 0 | int prefix_len = 0; |
807 | 0 | int j = 0; |
808 | 0 | unsigned i = 0; |
809 | 0 | unsigned addr_byte = 0; |
810 | 0 | unsigned mask = IPSEC_IPV6_ADDR_LEN; |
811 | 0 | char* mask_begin = NULL; |
812 | | |
813 | |
|
814 | 0 | if((ipv6_addr == NULL) || (strcmp(ipv6_addr, "") == 0)) return -1; |
815 | | |
816 | 0 | memset(ipv6_addr_expanded, 0x0, IPSEC_STRLEN_IPV6); |
817 | |
|
818 | 0 | mask_begin = strchr(ipv6_addr, '/'); |
819 | 0 | if(mask_begin) |
820 | 0 | { |
821 | 0 | if(sscanf(mask_begin, "/%u", &mask) == EOF) |
822 | 0 | mask = IPSEC_IPV6_ADDR_LEN; |
823 | 0 | mask_begin[0] = '\0'; |
824 | 0 | } |
825 | |
|
826 | 0 | if((strlen(ipv6_addr) == 1) && (ipv6_addr[0] == IPSEC_SA_WILDCARDS_ANY)) |
827 | 0 | { |
828 | 0 | for(j = 0; j < IPSEC_STRLEN_IPV6; j++) |
829 | 0 | { |
830 | 0 | ipv6_addr_expanded[j] = IPSEC_SA_WILDCARDS_ANY; |
831 | 0 | } |
832 | 0 | ipv6_addr_expanded[IPSEC_STRLEN_IPV6] = '\0'; |
833 | 0 | return 0; |
834 | 0 | } |
835 | | |
836 | 0 | suffix_cpt = get_ipv6_suffix(suffix,ipv6_addr); |
837 | 0 | suffix_len = (int) strlen(suffix); |
838 | |
|
839 | 0 | if(suffix_len < IPSEC_STRLEN_IPV6) |
840 | 0 | { |
841 | 0 | prefix_addr = wmem_strndup(scope, ipv6_addr,strlen(ipv6_addr) - suffix_cpt); |
842 | 0 | prefix_remaining = get_ipv6_suffix(prefix,prefix_addr); |
843 | 0 | prefix_len = (int) strlen(prefix); |
844 | 0 | memcpy(ipv6_addr_expanded,prefix,prefix_len); |
845 | 0 | } |
846 | | |
847 | |
|
848 | 0 | for(j = 0; j <= IPSEC_STRLEN_IPV6 - prefix_len - suffix_len; j++) |
849 | 0 | { |
850 | 0 | ipv6_addr_expanded[j + prefix_len] = '0'; |
851 | 0 | } |
852 | |
|
853 | 0 | memcpy(ipv6_addr_expanded + IPSEC_STRLEN_IPV6 - suffix_len, suffix,suffix_len + 1); |
854 | |
|
855 | 0 | for(i = 0; i < IPSEC_STRLEN_IPV6; i++) |
856 | 0 | { |
857 | 0 | if(4 * (i + 1) > mask) |
858 | 0 | { |
859 | 0 | if(mask <= 4 * i || ipv6_addr_expanded[i] == '*') |
860 | 0 | ipv6_addr_expanded[i] = '*'; |
861 | 0 | else { |
862 | 0 | if(sscanf(ipv6_addr_expanded + i, "%X", &addr_byte) == EOF) |
863 | 0 | break; |
864 | 0 | addr_byte &= (0x0F << (4 * (i + 1) - mask)); |
865 | 0 | addr_byte &= 0x0F; |
866 | 0 | snprintf(ipv6_addr_expanded + i, 4, "%X", addr_byte); |
867 | 0 | } |
868 | 0 | } |
869 | 0 | } |
870 | |
|
871 | 0 | if(suffix_len < IPSEC_STRLEN_IPV6) |
872 | 0 | return (int) strlen(ipv6_addr) - suffix_cpt - prefix_remaining; |
873 | 0 | else |
874 | 0 | return (int) strlen(ipv6_addr) - suffix_cpt; |
875 | 0 | } |
876 | | |
877 | | |
878 | | /* |
879 | | Name : static bool get_full_ipv4_addr(char* ipv4_addr_expanded, char *ipv4_addr) |
880 | | Description : Get the extended IPv4 Address of an IPv4 Address |
881 | | Return : Return true if it can derive an IPv4 address. It does not mean that |
882 | | the previous one was valid. |
883 | | Params: |
884 | | - char *ipv4_addr : the valid ipv4 address to parse in char * |
885 | | - char *ipv4_addr_expanded : the expanded ipv4 address associated in char * |
886 | | |
887 | | ex: if IPv4 address is "190.*.*.1" the IPv4 expanded address will be "BE****01" and |
888 | | the function will return 0 |
889 | | if IPv4 address is "*" the IPv4 expanded address will be "********" and |
890 | | the function will return 0 |
891 | | */ |
892 | | static bool |
893 | | get_full_ipv4_addr(char* ipv4_address_expanded, char *ipv4_address) |
894 | 0 | { |
895 | 0 | char addr_byte_string_tmp[12]; |
896 | 0 | char addr_byte_string[12]; |
897 | |
|
898 | 0 | unsigned addr_byte = 0; |
899 | 0 | unsigned i = 0; |
900 | 0 | unsigned j = 0; |
901 | 0 | unsigned k = 0; |
902 | 0 | unsigned cpt = 0; |
903 | 0 | bool done_flag = false; |
904 | 0 | unsigned mask = IPSEC_IPV4_ADDR_LEN; |
905 | 0 | char* mask_begin = NULL; |
906 | |
|
907 | 0 | if((ipv4_address == NULL) || (strcmp(ipv4_address, "") == 0)) return done_flag; |
908 | | |
909 | 0 | mask_begin = strchr(ipv4_address, '/'); |
910 | 0 | if(mask_begin) |
911 | 0 | { |
912 | 0 | if(sscanf(mask_begin, "/%u", &mask) == EOF) |
913 | 0 | mask = IPSEC_IPV4_ADDR_LEN; |
914 | 0 | mask_begin[0] = '\0'; |
915 | 0 | } |
916 | |
|
917 | 0 | if((strlen(ipv4_address) == 1) && (ipv4_address[0] == IPSEC_SA_WILDCARDS_ANY)) |
918 | 0 | { |
919 | 0 | for(i = 0; i <= IPSEC_STRLEN_IPV4; i++) |
920 | 0 | { |
921 | 0 | ipv4_address_expanded[i] = IPSEC_SA_WILDCARDS_ANY; |
922 | 0 | } |
923 | 0 | ipv4_address_expanded[IPSEC_STRLEN_IPV4] = '\0'; |
924 | 0 | done_flag = true; |
925 | 0 | } |
926 | | |
927 | 0 | else { |
928 | 0 | j = 0; |
929 | 0 | cpt = 0; |
930 | 0 | k = 0; |
931 | 0 | while((done_flag == false) && (j <= strlen(ipv4_address)) && (cpt < IPSEC_STRLEN_IPV4)) |
932 | 0 | { |
933 | 0 | if(j == strlen(ipv4_address)) |
934 | 0 | { |
935 | 0 | addr_byte_string_tmp[k] = '\0'; |
936 | 0 | if((strlen(addr_byte_string_tmp) == 1) && (addr_byte_string_tmp[0] == IPSEC_SA_WILDCARDS_ANY)) |
937 | 0 | { |
938 | 0 | for(i = 0; i < 2; i++) |
939 | 0 | { |
940 | 0 | ipv4_address_expanded[cpt] = IPSEC_SA_WILDCARDS_ANY; |
941 | 0 | cpt ++; |
942 | 0 | } |
943 | 0 | } |
944 | 0 | else |
945 | 0 | { |
946 | 0 | if (sscanf(addr_byte_string_tmp,"%u",&addr_byte) == EOF) |
947 | 0 | return false; |
948 | | |
949 | 0 | if(addr_byte < 16) |
950 | 0 | snprintf(addr_byte_string,11,"0%X",addr_byte); |
951 | 0 | else |
952 | 0 | snprintf(addr_byte_string,11,"%X",addr_byte); |
953 | 0 | for(i = 0; i < strlen(addr_byte_string); i++) |
954 | 0 | { |
955 | 0 | ipv4_address_expanded[cpt] = addr_byte_string[i]; |
956 | 0 | cpt ++; |
957 | 0 | } |
958 | 0 | } |
959 | 0 | done_flag = true; |
960 | 0 | } |
961 | | |
962 | 0 | else if(ipv4_address[j] == '.') |
963 | 0 | { |
964 | 0 | addr_byte_string_tmp[k] = '\0'; |
965 | 0 | if((strlen(addr_byte_string_tmp) == 1) && (addr_byte_string_tmp[0] == IPSEC_SA_WILDCARDS_ANY)) |
966 | 0 | { |
967 | 0 | for(i = 0; i < 2; i++) |
968 | 0 | { |
969 | 0 | ipv4_address_expanded[cpt] = IPSEC_SA_WILDCARDS_ANY; |
970 | 0 | cpt ++; |
971 | 0 | } |
972 | 0 | } |
973 | 0 | else |
974 | 0 | { |
975 | 0 | if (sscanf(addr_byte_string_tmp,"%u",&addr_byte) == EOF) |
976 | 0 | return false; |
977 | | |
978 | 0 | if(addr_byte < 16) |
979 | 0 | snprintf(addr_byte_string,11,"0%X",addr_byte); |
980 | 0 | else |
981 | 0 | snprintf(addr_byte_string,11,"%X",addr_byte); |
982 | 0 | for(i = 0; i < strlen(addr_byte_string); i++) |
983 | 0 | { |
984 | 0 | ipv4_address_expanded[cpt] = addr_byte_string[i]; |
985 | 0 | cpt ++; |
986 | 0 | } |
987 | 0 | } |
988 | 0 | k = 0; |
989 | 0 | j++; |
990 | 0 | } |
991 | 0 | else |
992 | 0 | { |
993 | 0 | if(k >= 3) |
994 | 0 | { |
995 | | /* Incorrect IPv4 Address. Erase previous Values in the Byte. (LRU mechanism) */ |
996 | 0 | addr_byte_string_tmp[0] = ipv4_address[j]; |
997 | 0 | k = 1; |
998 | 0 | j++; |
999 | 0 | } |
1000 | 0 | else |
1001 | 0 | { |
1002 | 0 | addr_byte_string_tmp[k] = ipv4_address[j]; |
1003 | 0 | k++; |
1004 | 0 | j++; |
1005 | 0 | } |
1006 | 0 | } |
1007 | |
|
1008 | 0 | } |
1009 | | |
1010 | 0 | for(i = 0; i < IPSEC_STRLEN_IPV4; i++) |
1011 | 0 | { |
1012 | 0 | if(4 * (i + 1) > mask) |
1013 | 0 | { |
1014 | 0 | if(mask <= 4 * i || ipv4_address_expanded[i] == '*') |
1015 | 0 | ipv4_address_expanded[i] = '*'; |
1016 | 0 | else { |
1017 | 0 | if(sscanf(ipv4_address_expanded + i, "%X", &addr_byte) == EOF) |
1018 | 0 | return false; |
1019 | 0 | addr_byte &= (0x0F << (4 * (i + 1) - mask)); |
1020 | 0 | addr_byte &= 0x0F; |
1021 | 0 | snprintf(ipv4_address_expanded + i, 4, "%X", addr_byte); |
1022 | 0 | } |
1023 | 0 | } |
1024 | 0 | } |
1025 | 0 | ipv4_address_expanded[cpt] = '\0'; |
1026 | 0 | } |
1027 | | |
1028 | 0 | return done_flag; |
1029 | 0 | } |
1030 | | |
1031 | | /* |
1032 | | Name : static goolean filter_address_match(char *addr, char *filter, int len, int typ) |
1033 | | Description : check the matching of an address with a filter |
1034 | | Return : Return true if the filter and the address match |
1035 | | Params: |
1036 | | - char *addr : the address to check |
1037 | | - char *filter : the filter |
1038 | | - int typ : the Address type : either IPv6 or IPv4 (IPSEC_SA_IPV6, IPSEC_SA_IPV4) |
1039 | | */ |
1040 | | static bool |
1041 | | filter_address_match(wmem_allocator_t* scope, char *addr, char *filter, int typ) |
1042 | 0 | { |
1043 | 0 | unsigned i; |
1044 | 0 | char addr_hex[IPSEC_STRLEN_IPV6 + 1]; |
1045 | 0 | char filter_hex[IPSEC_STRLEN_IPV6 + 1]; |
1046 | 0 | unsigned addr_len; |
1047 | 0 | unsigned filter_len; |
1048 | |
|
1049 | 0 | switch(typ) { |
1050 | 0 | case IPSEC_SA_ANY: |
1051 | 0 | return true; |
1052 | 0 | case IPSEC_SA_IPV4: |
1053 | 0 | if (!get_full_ipv4_addr(addr_hex, addr)) |
1054 | 0 | return false; |
1055 | 0 | if (!get_full_ipv4_addr(filter_hex, filter)) |
1056 | 0 | return false; |
1057 | 0 | break; |
1058 | 0 | case IPSEC_SA_IPV6: |
1059 | 0 | if (get_full_ipv6_addr(scope, addr_hex, addr)) |
1060 | 0 | return false; |
1061 | 0 | if (get_full_ipv6_addr(scope, filter_hex, filter)) |
1062 | 0 | return false; |
1063 | 0 | break; |
1064 | 0 | case IPSEC_SA_UNKNOWN: |
1065 | 0 | default: |
1066 | 0 | return false; |
1067 | 0 | } |
1068 | | |
1069 | 0 | addr_len = (unsigned)strlen(addr_hex); |
1070 | 0 | filter_len = (unsigned)strlen(filter_hex); |
1071 | |
|
1072 | 0 | if((filter_len == 1) && (filter[0] == IPSEC_SA_WILDCARDS_ANY)){ |
1073 | 0 | return true; |
1074 | 0 | } |
1075 | | |
1076 | 0 | if(addr_len != filter_len) |
1077 | 0 | return false; |
1078 | | |
1079 | | /* No length specified */ |
1080 | 0 | if( ((typ == IPSEC_SA_IPV6) && (filter_len == IPSEC_STRLEN_IPV6)) || |
1081 | 0 | ((typ == IPSEC_SA_IPV4) && (filter_len == IPSEC_STRLEN_IPV4))) |
1082 | 0 | { |
1083 | | /* Check byte by byte ... */ |
1084 | 0 | for(i = 0; i < addr_len; i++) |
1085 | 0 | { |
1086 | 0 | if((filter_hex[i] != IPSEC_SA_WILDCARDS_ANY) && (filter_hex[i] != addr_hex[i])) |
1087 | 0 | return false; |
1088 | 0 | } |
1089 | 0 | return true; |
1090 | 0 | } |
1091 | 0 | else |
1092 | 0 | return false; |
1093 | 0 | return true; |
1094 | |
|
1095 | 0 | } |
1096 | | |
1097 | | |
1098 | | /* |
1099 | | Name : static goolean filter_spi_match(char *spi, char *filter) |
1100 | | Description : check the matching of a spi with a filter |
1101 | | Return : Return true if the filter matches the spi. |
1102 | | Params: |
1103 | | - unsigned spi : the spi to check |
1104 | | - char *filter : the filter |
1105 | | */ |
1106 | | static bool |
1107 | | filter_spi_match(unsigned spi, char *filter) |
1108 | 0 | { |
1109 | 0 | unsigned i; |
1110 | 0 | unsigned filter_len = (unsigned)strlen(filter); |
1111 | | |
1112 | | /* "*" matches against anything */ |
1113 | 0 | if((filter_len == 1) && (filter[0] == IPSEC_SA_WILDCARDS_ANY)) |
1114 | 0 | return true; |
1115 | | |
1116 | | /* If the filter has a wildcard, treat SPI as a string */ |
1117 | 0 | if (strchr(filter, IPSEC_SA_WILDCARDS_ANY) != NULL) { |
1118 | 0 | char spi_string[IPSEC_SPI_LEN_MAX]; |
1119 | |
|
1120 | 0 | snprintf(spi_string, IPSEC_SPI_LEN_MAX,"0x%08x", spi); |
1121 | | |
1122 | | /* Lengths need to match exactly... */ |
1123 | 0 | if(strlen(spi_string) != filter_len) |
1124 | 0 | return false; |
1125 | | |
1126 | | /* ... which means '*' can only appear in the last position of the filter? */ |
1127 | | /* Start at 2, don't compare "0x" each time */ |
1128 | 0 | for(i = 2; filter[i]; i++) |
1129 | 0 | if((filter[i] != IPSEC_SA_WILDCARDS_ANY) && (filter[i] != spi_string[i])) |
1130 | 0 | return false; |
1131 | 0 | } else if (strtoul(filter, NULL, 0) != spi) { |
1132 | 0 | return false; |
1133 | 0 | } |
1134 | 0 | return true; |
1135 | 0 | } |
1136 | | |
1137 | | |
1138 | | /* |
1139 | | Name : static goolean get_esp_sa(g_esp_sa_database *sad, int protocol_typ, char *src, char *dst, unsigned spi, |
1140 | | int *encryption_algo, |
1141 | | int *authentication_algo, |
1142 | | char **encryption_key, |
1143 | | unsigned *encryption_key_len, |
1144 | | char **authentication_key, |
1145 | | unsigned *authentication_key_len, |
1146 | | gcry_cipher_hd_t **cipher_hd, |
1147 | | bool **cipher_hd_created |
1148 | | |
1149 | | Description : Give Encryption Algo, Key and Authentication Algo for a Packet if a corresponding SA is available in a Security Association database |
1150 | | Return: If the SA is not present, false is then returned. |
1151 | | Params: |
1152 | | - g_esp_sa_database *sad : the Security Association Database |
1153 | | - int *pt_protocol_typ : the protocol type |
1154 | | - char *src : the source address |
1155 | | - char *dst : the destination address |
1156 | | - char *spi : the spi of the SA |
1157 | | - int *encryption_algo : the Encryption Algorithm to apply the packet |
1158 | | - int *authentication_algo : the Authentication Algorithm to apply to the packet |
1159 | | - char **encryption_key : the Encryption Key to apply to the packet |
1160 | | - unsigned *encryption_key_len : the Encryption Key length to apply to the packet |
1161 | | - char **authentication_key : the Authentication Key to apply to the packet |
1162 | | - unsigned *authentication_key_len : the Authentication Key len to apply to the packet |
1163 | | - gcry_cipher_hd_t **cipher_hd : pointer handle to be used for ciphering |
1164 | | - bool **cipher_hd_created: points to boolean indicating that cipher handle has |
1165 | | been created. If false, should assign handle to |
1166 | | *cipher_hd and set this to true. |
1167 | | |
1168 | | */ |
1169 | | static bool |
1170 | | get_esp_sa(wmem_allocator_t* scope, |
1171 | | int protocol_typ, char *src, char *dst, unsigned spi, |
1172 | | int *encryption_algo, |
1173 | | int *authentication_algo, |
1174 | | char **encryption_key, |
1175 | | unsigned *encryption_key_len, |
1176 | | char **authentication_key, |
1177 | | unsigned *authentication_key_len, |
1178 | | gcry_cipher_hd_t **cipher_hd, |
1179 | | bool **cipher_hd_created, |
1180 | | uint8_t *sn_length, |
1181 | | uint32_t *sn_upper |
1182 | | ) |
1183 | 0 | { |
1184 | 0 | bool found = false; |
1185 | 0 | unsigned i, j; |
1186 | |
|
1187 | 0 | *cipher_hd = NULL; |
1188 | 0 | *cipher_hd_created = NULL; |
1189 | | |
1190 | | /* Check each known SA in turn */ |
1191 | 0 | for (i = 0, j=0; (found == false) && ((i < num_sa_uat) || (j < extra_esp_sa_records.num_records)); ) |
1192 | 0 | { |
1193 | | /* Get the next record to try */ |
1194 | 0 | uat_esp_sa_record_t *record; |
1195 | 0 | if (j < extra_esp_sa_records.num_records) { |
1196 | | /* Extra ones checked first */ |
1197 | 0 | record = &extra_esp_sa_records.records[j++]; |
1198 | 0 | } |
1199 | 0 | else { |
1200 | | /* Then UAT ones */ |
1201 | 0 | record = &uat_esp_sa_records[i++]; |
1202 | 0 | } |
1203 | |
|
1204 | 0 | if((protocol_typ == record->protocol || record->protocol == IPSEC_SA_ANY) |
1205 | 0 | && (filter_address_match(scope, src, record->srcIP, protocol_typ) || record->protocol == IPSEC_SA_ANY) |
1206 | 0 | && (filter_address_match(scope, dst, record->dstIP, protocol_typ) || record->protocol == IPSEC_SA_ANY) |
1207 | 0 | && filter_spi_match(spi, record->spi)) |
1208 | 0 | { |
1209 | 0 | found = true; |
1210 | |
|
1211 | 0 | *encryption_algo = record->encryption_algo; |
1212 | 0 | *authentication_algo = record->authentication_algo; |
1213 | 0 | *authentication_key = record->authentication_key; |
1214 | 0 | if (record->authentication_key_length == -1) |
1215 | 0 | { |
1216 | | /* Bad key; XXX - report this */ |
1217 | 0 | *authentication_key_len = 0; |
1218 | 0 | found = false; |
1219 | 0 | } |
1220 | 0 | else { |
1221 | 0 | *authentication_key_len = record->authentication_key_length; |
1222 | 0 | } |
1223 | |
|
1224 | 0 | *encryption_key = record->encryption_key; |
1225 | 0 | if (record->encryption_key_length == -1) |
1226 | 0 | { |
1227 | | /* Bad key; XXX - report this */ |
1228 | 0 | *encryption_key_len = 0; |
1229 | 0 | found = false; |
1230 | 0 | } |
1231 | 0 | else { |
1232 | 0 | *encryption_key_len = record->encryption_key_length; |
1233 | 0 | } |
1234 | | |
1235 | | /* Tell the caller whether cipher_hd has been created yet and a pointer. |
1236 | | Pass pointer to created flag so that caller can set if/when |
1237 | | it opens the cipher_hd. */ |
1238 | 0 | *cipher_hd = &record->cipher_hd; |
1239 | 0 | *cipher_hd_created = &record->cipher_hd_created; |
1240 | |
|
1241 | 0 | *sn_length = record->sn_length; |
1242 | 0 | *sn_upper = record->sn_upper; |
1243 | |
|
1244 | 0 | if (found && !wmem_map_lookup(esp_used_sa_map, record)) |
1245 | 0 | wmem_map_insert(esp_used_sa_map, record, NULL); |
1246 | 0 | } |
1247 | 0 | } |
1248 | |
|
1249 | 0 | return found; |
1250 | 0 | } |
1251 | | |
1252 | | static void ah_prompt(packet_info *pinfo, char *result) |
1253 | 0 | { |
1254 | 0 | snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IP protocol %u as", |
1255 | 0 | GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_ah, pinfo->curr_layer_num))); |
1256 | 0 | } |
1257 | | |
1258 | | static void *ah_value(packet_info *pinfo) |
1259 | 0 | { |
1260 | 0 | return p_get_proto_data(pinfo->pool, pinfo, proto_ah, pinfo->curr_layer_num); |
1261 | 0 | } |
1262 | | |
1263 | | static void |
1264 | | export_ipsec_pdu(dissector_handle_t dissector_handle, packet_info *pinfo, tvbuff_t *tvb) |
1265 | 61 | { |
1266 | 61 | if (have_tap_listener(exported_pdu_tap)) { |
1267 | 0 | exp_pdu_data_t *exp_pdu_data = export_pdu_create_common_tags(pinfo, dissector_handle_get_dissector_name(dissector_handle), EXP_PDU_TAG_DISSECTOR_NAME); |
1268 | |
|
1269 | 0 | exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb); |
1270 | 0 | exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb); |
1271 | 0 | exp_pdu_data->pdu_tvb = tvb; |
1272 | |
|
1273 | 0 | tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data); |
1274 | 0 | } |
1275 | 61 | } |
1276 | | |
1277 | | static bool |
1278 | 0 | esp_padding_override(tvbuff_t *tvb, int offset, int esp_pad_len) { |
1279 | |
|
1280 | 0 | switch (g_esp_padding_type) { |
1281 | 0 | case PADDING_RFC: |
1282 | 0 | return false; |
1283 | 0 | case PADDING_ZERO: |
1284 | 0 | for (int j=0; j < esp_pad_len; j++) { |
1285 | 0 | if (tvb_get_uint8(tvb, offset - (j + 1)) != 0) { |
1286 | 0 | return false; |
1287 | 0 | } |
1288 | 0 | } |
1289 | | /* FALLTHROUGH */ |
1290 | 0 | case PADDING_ANY: |
1291 | 0 | return true; |
1292 | 0 | default: |
1293 | 0 | return false; |
1294 | 0 | } |
1295 | 0 | return false; |
1296 | 0 | } |
1297 | | |
1298 | | /** |
1299 | | * Implements much of RFC 5879, "Heuristics for Detecting ESP-NULL Packets" |
1300 | | * |
1301 | | * Does NOT attempt to properly detect ENCR_NULL_AUTH_AES_GMAC. |
1302 | | */ |
1303 | | static int |
1304 | | esp_null_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *esp_tree) |
1305 | 0 | { |
1306 | 0 | int esp_packet_len, esp_pad_len, esp_icv_len, offset; |
1307 | 0 | unsigned encapsulated_protocol; |
1308 | 0 | uint32_t saved_match_uint; |
1309 | 0 | bool heur_ok; |
1310 | |
|
1311 | 0 | proto_item *ti; |
1312 | 0 | tvbuff_t *next_tvb; |
1313 | 0 | dissector_handle_t dissector_handle; |
1314 | | |
1315 | | /* Possible ICV lengths to try. Per RFC 5879, smallest to largest. |
1316 | | */ |
1317 | 0 | static const int icv_lengths[] = { |
1318 | 0 | 12, |
1319 | 0 | 16, |
1320 | 0 | 24, |
1321 | 0 | 32, |
1322 | 0 | -1 |
1323 | 0 | }; |
1324 | |
|
1325 | 0 | esp_packet_len = tvb_reported_length(tvb); |
1326 | |
|
1327 | 0 | for (int i = 0; (esp_icv_len = icv_lengths[i]) != -1; i++) { |
1328 | | |
1329 | | /* Make sure the packet is not truncated before the fields |
1330 | | * we need to read to determine the encapsulated protocol. |
1331 | | */ |
1332 | 0 | if (esp_packet_len >= (esp_icv_len + 2)) |
1333 | 0 | { |
1334 | 0 | offset = esp_packet_len - (esp_icv_len + 2); |
1335 | 0 | if (!tvb_bytes_exist(tvb, offset, 2)) { |
1336 | 0 | continue; |
1337 | 0 | } |
1338 | 0 | esp_pad_len = tvb_get_uint8(tvb, offset); |
1339 | 0 | encapsulated_protocol = tvb_get_uint8(tvb, offset + 1); |
1340 | 0 | dissector_handle = dissector_get_uint_handle(ip_dissector_table, encapsulated_protocol); |
1341 | 0 | if (dissector_handle == NULL) { |
1342 | 0 | continue; |
1343 | 0 | } |
1344 | 0 | if (ESP_HEADER_LEN + esp_pad_len > offset) { |
1345 | 0 | continue; |
1346 | 0 | } |
1347 | 0 | heur_ok = true; |
1348 | 0 | for (int j=0; j < esp_pad_len; j++) { |
1349 | 0 | if (tvb_get_uint8(tvb, offset - (j + 1)) != (esp_pad_len - j)) { |
1350 | 0 | heur_ok = false; |
1351 | 0 | break; |
1352 | 0 | } |
1353 | 0 | } |
1354 | 0 | if (!heur_ok && !esp_padding_override(tvb, offset, esp_pad_len)) { |
1355 | 0 | continue; |
1356 | 0 | } |
1357 | | |
1358 | 0 | saved_match_uint = pinfo->match_uint; |
1359 | 0 | pinfo->match_uint = encapsulated_protocol; |
1360 | 0 | next_tvb = tvb_new_subset_length(tvb, ESP_HEADER_LEN, offset - ESP_HEADER_LEN - esp_pad_len); |
1361 | | /* If the matching dissector has been disabled or rejects the packet, |
1362 | | * consider the heuristic failed. |
1363 | | * XXX: Should we also catch exceptions and consider those failures too? |
1364 | | * |
1365 | | * Note that the case of ENCR_NULL_AUTH_AES_GMAC will find the correct |
1366 | | * padding and encapsulated protocol using a 16 byte ICV, but needs to |
1367 | | * skip over the 8 bytes of IV. |
1368 | | */ |
1369 | 0 | if (call_dissector_only(dissector_handle, next_tvb, pinfo, proto_tree_get_parent_tree(esp_tree), NULL) == 0) { |
1370 | 0 | pinfo->match_uint = saved_match_uint; |
1371 | 0 | continue; |
1372 | 0 | } |
1373 | 0 | export_ipsec_pdu(dissector_handle, pinfo, next_tvb); |
1374 | 0 | pinfo->match_uint = saved_match_uint; |
1375 | |
|
1376 | 0 | if (esp_tree) { |
1377 | 0 | if (esp_pad_len !=0) { |
1378 | 0 | ti = proto_tree_add_item(esp_tree, hf_esp_pad, |
1379 | 0 | tvb, offset - esp_pad_len, |
1380 | 0 | esp_pad_len, ENC_NA); |
1381 | 0 | if (!heur_ok) { |
1382 | 0 | expert_add_info(pinfo, ti, &ei_esp_pad_bogus); |
1383 | 0 | } |
1384 | 0 | } |
1385 | |
|
1386 | 0 | proto_tree_add_uint(esp_tree, hf_esp_pad_len, tvb, |
1387 | 0 | offset, 1, |
1388 | 0 | esp_pad_len); |
1389 | |
|
1390 | 0 | proto_tree_add_uint_format(esp_tree, hf_esp_protocol, tvb, |
1391 | 0 | offset + 1, 1, |
1392 | 0 | encapsulated_protocol, |
1393 | 0 | "Next header: %s (0x%02x)", |
1394 | 0 | ipprotostr(encapsulated_protocol), encapsulated_protocol); |
1395 | 0 | } |
1396 | |
|
1397 | 0 | return esp_icv_len; |
1398 | 0 | } |
1399 | 0 | } |
1400 | 0 | return esp_icv_len; |
1401 | 0 | } |
1402 | | |
1403 | | static bool |
1404 | | capture_ah(const unsigned char *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header) |
1405 | 0 | { |
1406 | 0 | uint8_t nxt; |
1407 | 0 | int advance; |
1408 | |
|
1409 | 0 | if (!BYTES_ARE_IN_FRAME(offset, len, 2)) |
1410 | 0 | return false; |
1411 | 0 | nxt = pd[offset]; |
1412 | 0 | advance = 8 + ((pd[offset+1] - 1) << 2); |
1413 | 0 | if (!BYTES_ARE_IN_FRAME(offset, len, advance)) |
1414 | 0 | return false; |
1415 | 0 | offset += advance; |
1416 | |
|
1417 | 0 | return try_capture_dissector("ip.proto", nxt, pd, offset, len, cpinfo, pseudo_header); |
1418 | 0 | } |
1419 | | |
1420 | | static int |
1421 | | dissect_ah(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) |
1422 | 62 | { |
1423 | 62 | proto_tree *ah_tree, *root_tree; |
1424 | 62 | proto_item *pi, *ti; |
1425 | 62 | unsigned ah_nxt; /* Next header */ |
1426 | 62 | uint8_t ah_len; /* Length of header in 32bit words minus 2 */ |
1427 | 62 | unsigned ah_hdr_len; /* Length of header in octets */ |
1428 | 62 | unsigned ah_icv_len; /* Length of ICV header field in octets */ |
1429 | 62 | uint32_t ah_spi; /* Security parameter index */ |
1430 | 62 | tvbuff_t *next_tvb; |
1431 | 62 | dissector_handle_t dissector_handle; |
1432 | 62 | uint32_t saved_match_uint; |
1433 | | |
1434 | 62 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "AH"); |
1435 | 62 | col_clear(pinfo->cinfo, COL_INFO); |
1436 | | |
1437 | 62 | ah_nxt = tvb_get_uint8(tvb, 0); |
1438 | 62 | ah_len = tvb_get_uint8(tvb, 1); |
1439 | 62 | ah_hdr_len = (ah_len + 2) * 4; |
1440 | 62 | ah_icv_len = ah_len ? (ah_len - 1) * 4 : 0; |
1441 | | |
1442 | 62 | root_tree = p_ipv6_pinfo_select_root(pinfo, tree); |
1443 | 62 | p_ipv6_pinfo_add_len(pinfo, ah_hdr_len); |
1444 | | |
1445 | 62 | pi = proto_tree_add_item(root_tree, proto_ah, tvb, 0, -1, ENC_NA); |
1446 | 62 | ah_tree = proto_item_add_subtree(pi, ett_ah); |
1447 | | |
1448 | 62 | proto_tree_add_item(ah_tree, hf_ah_next_header, tvb, 0, 1, ENC_BIG_ENDIAN); |
1449 | 62 | ti = proto_tree_add_item(ah_tree, hf_ah_length, tvb, 1, 1, ENC_BIG_ENDIAN); |
1450 | 62 | proto_item_append_text(ti, " (%u bytes)", ah_hdr_len); |
1451 | 62 | proto_tree_add_item(ah_tree, hf_ah_reserved, tvb, 2, 2, ENC_NA); |
1452 | 62 | proto_tree_add_item_ret_uint(ah_tree, hf_ah_spi, tvb, 4, 4, ENC_BIG_ENDIAN, &ah_spi); |
1453 | | |
1454 | 62 | col_add_fstr(pinfo->cinfo, COL_INFO, "AH (SPI=0x%08x)", ah_spi); |
1455 | | |
1456 | 62 | proto_tree_add_item(ah_tree, hf_ah_sequence, tvb, 8, 4, ENC_BIG_ENDIAN); |
1457 | 62 | proto_tree_add_item(ah_tree, hf_ah_iv, tvb, 12, ah_icv_len, ENC_NA); |
1458 | | |
1459 | 62 | proto_item_set_len(pi, ah_hdr_len); |
1460 | | |
1461 | | /* Save next header value for Decode As dialog */ |
1462 | 62 | p_add_proto_data(pinfo->pool, pinfo, proto_ah, |
1463 | 62 | pinfo->curr_layer_num, GUINT_TO_POINTER(ah_nxt)); |
1464 | | |
1465 | 62 | next_tvb = tvb_new_subset_remaining(tvb, ah_hdr_len); |
1466 | | |
1467 | 62 | if (pinfo->dst.type == AT_IPv6) { |
1468 | 33 | ipv6_dissect_next(ah_nxt, next_tvb, pinfo, tree, (ws_ip6 *)data); |
1469 | 33 | } else { |
1470 | | /* do lookup with the subdissector table */ |
1471 | 29 | saved_match_uint = pinfo->match_uint; |
1472 | 29 | dissector_handle = dissector_get_uint_handle(ip_dissector_table, ah_nxt); |
1473 | 29 | if (dissector_handle) { |
1474 | 17 | pinfo->match_uint = ah_nxt; |
1475 | 17 | } else { |
1476 | 12 | dissector_handle = data_handle; |
1477 | 12 | } |
1478 | 29 | export_ipsec_pdu(dissector_handle, pinfo, next_tvb); |
1479 | 29 | call_dissector(dissector_handle, next_tvb, pinfo, tree); |
1480 | 29 | pinfo->match_uint = saved_match_uint; |
1481 | 29 | } |
1482 | 62 | return tvb_captured_length(tvb); |
1483 | 62 | } |
1484 | | |
1485 | | static int |
1486 | | dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
1487 | 102 | { |
1488 | 102 | proto_tree *esp_tree = NULL, *decr_tree = NULL, *icv_tree = NULL; |
1489 | 102 | proto_item *item = NULL; |
1490 | 102 | proto_item *iv_item = NULL, *encr_data_item = NULL, *icv_item = NULL; |
1491 | | |
1492 | | /* Packet Variables related */ |
1493 | 102 | char *ip_src = NULL; |
1494 | 102 | char *ip_dst = NULL; |
1495 | | |
1496 | 102 | uint32_t spi = 0; |
1497 | 102 | unsigned encapsulated_protocol = 0; |
1498 | 102 | bool decrypt_dissect_ok = false; |
1499 | 102 | tvbuff_t *next_tvb; |
1500 | 102 | dissector_handle_t dissector_handle; |
1501 | 102 | uint32_t saved_match_uint; |
1502 | | |
1503 | 102 | bool null_encryption_decode_heuristic = false; |
1504 | 102 | uint8_t *esp_iv = NULL; |
1505 | 102 | uint8_t *esp_encr_data = NULL; |
1506 | 102 | uint8_t *esp_decr_data = NULL; |
1507 | 102 | uint8_t *esp_icv = NULL; |
1508 | 102 | tvbuff_t *tvb_decrypted = NULL; |
1509 | | |
1510 | | /* IPSEC encryption Variables related */ |
1511 | 102 | int protocol_typ = IPSEC_SA_UNKNOWN; |
1512 | 102 | int esp_encr_algo = IPSEC_ENCRYPT_NULL; |
1513 | 102 | int esp_auth_algo = IPSEC_AUTH_NULL; |
1514 | 102 | int icv_type = ICV_TYPE_UNCHECKED; |
1515 | 102 | char *esp_encr_key = NULL; |
1516 | 102 | char *esp_auth_key = NULL; |
1517 | 102 | unsigned esp_encr_key_len = 0; |
1518 | 102 | unsigned esp_auth_key_len = 0; |
1519 | 102 | gcry_cipher_hd_t *cipher_hd; |
1520 | 102 | bool *cipher_hd_created; |
1521 | | |
1522 | 102 | int offset = 0; |
1523 | 102 | int esp_packet_len = 0; |
1524 | 102 | int esp_iv_len = 0; |
1525 | 102 | int esp_block_len = 0; |
1526 | 102 | int esp_encr_data_len = 0; |
1527 | 102 | int esp_decr_data_len = 0; |
1528 | 102 | int esp_icv_len = 0; |
1529 | 102 | int esp_salt_len = 0; |
1530 | 102 | bool decrypt_ok = false; |
1531 | 102 | bool decrypt_using_libgcrypt = false; |
1532 | 102 | bool icv_checked = false; |
1533 | 102 | bool icv_correct = false; |
1534 | 102 | bool sad_is_present = false; |
1535 | 102 | int esp_pad_len = 0; |
1536 | | |
1537 | | |
1538 | | /* Variables for decryption and authentication checking used for libgcrypt */ |
1539 | 102 | gcry_md_hd_t md_hd; |
1540 | 102 | int md_len = 0; |
1541 | 102 | gcry_error_t err = 0; |
1542 | 102 | int crypt_algo_libgcrypt = 0; |
1543 | 102 | int crypt_mode_libgcrypt = 0; |
1544 | 102 | int auth_algo_libgcrypt = 0; |
1545 | 102 | char *esp_icv_expected = NULL; /* as readable hex string, for error messages */ |
1546 | 102 | unsigned char ctr_block[16]; |
1547 | 102 | unsigned char nonce[12]; /* nonce for decrypting ChaCha20-Poly1305 */ |
1548 | | |
1549 | | |
1550 | 102 | uint32_t sequence_number; |
1551 | 102 | uint8_t sn_length = IPSEC_SA_SN; |
1552 | 102 | uint32_t sn_upper = 0; |
1553 | | |
1554 | | /* |
1555 | | * load the top pane info. This should be overwritten by |
1556 | | * the next protocol in the stack |
1557 | | */ |
1558 | | |
1559 | 102 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESP"); |
1560 | 102 | col_clear(pinfo->cinfo, COL_INFO); |
1561 | | |
1562 | | /* |
1563 | | * populate a tree in the second pane with the status of the link layer |
1564 | | * (ie none) |
1565 | | */ |
1566 | 102 | item = proto_tree_add_item(tree, proto_esp, tvb, 0, -1, ENC_NA); |
1567 | 102 | esp_tree = proto_item_add_subtree(item, ett_esp); |
1568 | 102 | proto_tree_add_item_ret_uint(esp_tree, hf_esp_spi, tvb, |
1569 | 102 | 0, 4, ENC_BIG_ENDIAN, &spi); |
1570 | 102 | proto_tree_add_item_ret_uint(esp_tree, hf_esp_sequence, tvb, |
1571 | 102 | 4, 4, ENC_BIG_ENDIAN, &sequence_number); |
1572 | | |
1573 | 102 | col_add_fstr(pinfo->cinfo, COL_INFO, "ESP (SPI=0x%08x)", spi); |
1574 | | |
1575 | | /* Sequence number analysis */ |
1576 | 102 | if (g_esp_do_sequence_analysis) { |
1577 | 100 | if (!pinfo->fd->visited) { |
1578 | 100 | check_esp_sequence_info(spi, sequence_number, pinfo); |
1579 | 100 | } |
1580 | 100 | show_esp_sequence_info(spi, sequence_number, |
1581 | 100 | tvb, esp_tree, pinfo); |
1582 | 100 | } |
1583 | | |
1584 | 102 | esp_packet_len = tvb_reported_length(tvb); |
1585 | | |
1586 | | /* Get length of remaining ESP packet (without the header) */ |
1587 | 102 | esp_encr_data_len = esp_packet_len - ESP_HEADER_LEN; |
1588 | 102 | if (esp_encr_data_len <= 0) |
1589 | 5 | return tvb_captured_length(tvb); |
1590 | | |
1591 | 97 | offset = ESP_HEADER_LEN; |
1592 | | |
1593 | | /* The SAD is not activated */ |
1594 | 97 | if(g_esp_enable_null_encryption_decode_heuristic && |
1595 | 0 | !g_esp_enable_encryption_decode) |
1596 | 0 | null_encryption_decode_heuristic = true; |
1597 | | |
1598 | 97 | if(g_esp_enable_encryption_decode || g_esp_enable_authentication_check) |
1599 | 0 | { |
1600 | | /* Get Source & Destination Addresses in char * with all the bytes available. */ |
1601 | |
|
1602 | 0 | if (pinfo->src.type == AT_IPv4){ |
1603 | 0 | protocol_typ = IPSEC_SA_IPV4; |
1604 | 0 | }else if (pinfo->src.type == AT_IPv6){ |
1605 | 0 | protocol_typ = IPSEC_SA_IPV6; |
1606 | 0 | } |
1607 | | |
1608 | | /* Create strings for src, dst addresses */ |
1609 | 0 | ip_src = address_to_str(pinfo->pool, &pinfo->src); |
1610 | 0 | ip_dst = address_to_str(pinfo->pool, &pinfo->dst); |
1611 | | |
1612 | | /* Get the SPI */ |
1613 | 0 | if (tvb_captured_length(tvb) >= 4) |
1614 | 0 | { |
1615 | 0 | spi = tvb_get_ntohl(tvb, 0); |
1616 | 0 | } |
1617 | | |
1618 | | |
1619 | | /* |
1620 | | PARSE the SAD and fill it. It may take some time since it will |
1621 | | be called every times an ESP Payload is found. |
1622 | | */ |
1623 | |
|
1624 | 0 | if((sad_is_present = get_esp_sa(pinfo->pool, protocol_typ, ip_src, ip_dst, spi, |
1625 | 0 | &esp_encr_algo, &esp_auth_algo, |
1626 | 0 | &esp_encr_key, &esp_encr_key_len, &esp_auth_key, &esp_auth_key_len, |
1627 | 0 | &cipher_hd, &cipher_hd_created, &sn_length, &sn_upper))) |
1628 | 0 | { |
1629 | |
|
1630 | 0 | switch(esp_auth_algo) |
1631 | 0 | { |
1632 | 0 | case IPSEC_AUTH_NULL: |
1633 | 0 | esp_icv_len = 0; |
1634 | 0 | break; |
1635 | | |
1636 | 0 | case IPSEC_AUTH_ANY_64BIT: |
1637 | 0 | esp_icv_len = 8; |
1638 | 0 | break; |
1639 | | |
1640 | 0 | case IPSEC_AUTH_HMAC_SHA256_128: |
1641 | 0 | case IPSEC_AUTH_ANY_128BIT: |
1642 | 0 | esp_icv_len = 16; |
1643 | 0 | break; |
1644 | | |
1645 | 0 | case IPSEC_AUTH_HMAC_SHA512_256: |
1646 | 0 | case IPSEC_AUTH_ANY_256BIT: |
1647 | 0 | esp_icv_len = 32; |
1648 | 0 | break; |
1649 | | |
1650 | 0 | case IPSEC_AUTH_HMAC_SHA384_192: |
1651 | 0 | case IPSEC_AUTH_ANY_192BIT: |
1652 | 0 | esp_icv_len = 24; |
1653 | 0 | break; |
1654 | | |
1655 | 0 | case IPSEC_AUTH_HMAC_SHA1_96: |
1656 | 0 | case IPSEC_AUTH_HMAC_SHA256_96: |
1657 | | /* case IPSEC_AUTH_AES_XCBC_MAC_96: */ |
1658 | 0 | case IPSEC_AUTH_HMAC_MD5_96: |
1659 | 0 | case IPSEC_AUTH_HMAC_RIPEMD160_96: |
1660 | 0 | case IPSEC_AUTH_ANY_96BIT: |
1661 | 0 | default: |
1662 | 0 | esp_icv_len = 12; |
1663 | 0 | break; |
1664 | 0 | } |
1665 | | |
1666 | 0 | switch(esp_encr_algo) |
1667 | 0 | { |
1668 | 0 | case IPSEC_ENCRYPT_AES_GCM_8: |
1669 | 0 | esp_encr_algo = IPSEC_ENCRYPT_AES_GCM; |
1670 | 0 | esp_icv_len = 8; |
1671 | 0 | break; |
1672 | | |
1673 | 0 | case IPSEC_ENCRYPT_AES_GCM_12: |
1674 | 0 | esp_encr_algo = IPSEC_ENCRYPT_AES_GCM; |
1675 | 0 | esp_icv_len = 12; |
1676 | 0 | break; |
1677 | | |
1678 | 0 | case IPSEC_ENCRYPT_AES_GCM_16: |
1679 | 0 | esp_encr_algo = IPSEC_ENCRYPT_AES_GCM; |
1680 | 0 | esp_icv_len = 16; |
1681 | 0 | break; |
1682 | | |
1683 | 0 | case IPSEC_ENCRYPT_AES_GCM: |
1684 | 0 | esp_icv_len = 0; |
1685 | 0 | } |
1686 | | |
1687 | 0 | if(g_esp_enable_authentication_check) |
1688 | 0 | { |
1689 | 0 | if (sn_length == IPSEC_SA_ESN && g_esp_do_sequence_analysis) { |
1690 | 0 | spi_status *status = (spi_status*)wmem_map_lookup(esp_sequence_analysis_hash, |
1691 | 0 | GUINT_TO_POINTER((unsigned)spi)); |
1692 | | /* We only support 2^32 - 1 frames (and only 2^31 - 1 in the Qt packet |
1693 | | * list), so at most we can overflow once. In a normal capture we |
1694 | | * expect half the frames to be from each direction, too. The proper |
1695 | | * method in RFC 4303 Appendix A involves storing valid sequence |
1696 | | * numbers at multiple points for subsequent passes to slide the window, |
1697 | | * but we shouldn't need to. */ |
1698 | 0 | if (status && status->firstValidSN) { |
1699 | 0 | const uint32_t window = 0x8000U; |
1700 | 0 | if (status->firstValidSN >= window) { |
1701 | 0 | if (sequence_number < (status->firstValidSN - window)) { |
1702 | 0 | sn_upper++; |
1703 | 0 | } |
1704 | 0 | } else { |
1705 | 0 | if (sequence_number >= (status->firstValidSN - window)) { |
1706 | 0 | sn_upper--; |
1707 | 0 | } |
1708 | 0 | } |
1709 | 0 | } |
1710 | 0 | } |
1711 | |
|
1712 | 0 | switch(esp_auth_algo) |
1713 | 0 | { |
1714 | 0 | case IPSEC_AUTH_HMAC_SHA1_96: |
1715 | | /* |
1716 | | RFC 2404 : HMAC-SHA-1-96 is a secret key algorithm. |
1717 | | While no fixed key length is specified in [RFC-2104], |
1718 | | for use with either ESP or AH a fixed key length of |
1719 | | 160-bits MUST be supported. Key lengths other than |
1720 | | 160-bits MUST NOT be supported (i.e. only 160-bit keys |
1721 | | are to be used by HMAC-SHA-1-96). A key length of |
1722 | | 160-bits was chosen based on the recommendations in |
1723 | | [RFC-2104] (i.e. key lengths less than the |
1724 | | authentication length decrease security strength and |
1725 | | keys longer than the authentication length do not |
1726 | | significantly increase security strength). |
1727 | | */ |
1728 | 0 | auth_algo_libgcrypt = GCRY_MD_SHA1; |
1729 | 0 | icv_type = ICV_TYPE_HMAC; |
1730 | 0 | break; |
1731 | | |
1732 | 0 | case IPSEC_AUTH_NULL: |
1733 | 0 | break; |
1734 | | |
1735 | | /* |
1736 | | case IPSEC_AUTH_AES_XCBC_MAC_96: |
1737 | | auth_algo_libgcrypt = |
1738 | | authentication_check_using_libgcrypt = true; |
1739 | | break; |
1740 | | */ |
1741 | | |
1742 | 0 | case IPSEC_AUTH_HMAC_SHA256_96: |
1743 | 0 | case IPSEC_AUTH_HMAC_SHA256_128: |
1744 | 0 | auth_algo_libgcrypt = GCRY_MD_SHA256; |
1745 | 0 | icv_type = ICV_TYPE_HMAC; |
1746 | 0 | break; |
1747 | | |
1748 | 0 | case IPSEC_AUTH_HMAC_SHA384_192: |
1749 | 0 | auth_algo_libgcrypt = GCRY_MD_SHA384; |
1750 | 0 | icv_type = ICV_TYPE_HMAC; |
1751 | 0 | break; |
1752 | | |
1753 | 0 | case IPSEC_AUTH_HMAC_SHA512_256: |
1754 | 0 | auth_algo_libgcrypt = GCRY_MD_SHA512; |
1755 | 0 | icv_type = ICV_TYPE_HMAC; |
1756 | 0 | break; |
1757 | | |
1758 | 0 | case IPSEC_AUTH_HMAC_MD5_96: |
1759 | | /* |
1760 | | RFC 2403 : HMAC-MD5-96 is a secret key algorithm. |
1761 | | While no fixed key length is specified in [RFC-2104], |
1762 | | for use with either ESP or AH a fixed key length of |
1763 | | 128-bits MUST be supported. Key lengths other than |
1764 | | 128-bits MUST NOT be supported (i.e. only 128-bit keys |
1765 | | are to be used by HMAC-MD5-96). A key length of |
1766 | | 128-bits was chosen based on the recommendations in |
1767 | | [RFC-2104] (i.e. key lengths less than the |
1768 | | authentication code length decrease security strength and |
1769 | | keys longer than the authentication code length do not |
1770 | | significantly increase security strength). |
1771 | | */ |
1772 | 0 | auth_algo_libgcrypt = GCRY_MD_MD5; |
1773 | 0 | icv_type = ICV_TYPE_HMAC; |
1774 | 0 | break; |
1775 | | |
1776 | 0 | case IPSEC_AUTH_HMAC_RIPEMD160_96: |
1777 | | /* |
1778 | | RFC 2857 : HMAC-RIPEMD-160-96 produces a 160-bit |
1779 | | authentication code. This 160-bit value can be |
1780 | | truncated as described in RFC2104. For use with |
1781 | | either ESP or AH, a truncated value using the first |
1782 | | 96 bits MUST be supported. |
1783 | | */ |
1784 | 0 | auth_algo_libgcrypt = GCRY_MD_RMD160; |
1785 | 0 | icv_type = ICV_TYPE_HMAC; |
1786 | 0 | break; |
1787 | | |
1788 | 0 | case IPSEC_AUTH_ANY_64BIT: |
1789 | 0 | case IPSEC_AUTH_ANY_96BIT: |
1790 | 0 | case IPSEC_AUTH_ANY_128BIT: |
1791 | 0 | case IPSEC_AUTH_ANY_192BIT: |
1792 | 0 | case IPSEC_AUTH_ANY_256BIT: |
1793 | 0 | default: |
1794 | 0 | break; |
1795 | 0 | } |
1796 | | |
1797 | 0 | if(icv_type == ICV_TYPE_HMAC) |
1798 | 0 | { |
1799 | | /* Allocate buffer for ICV */ |
1800 | 0 | esp_icv = (uint8_t *)tvb_memdup(pinfo->pool, tvb, esp_packet_len - esp_icv_len, esp_icv_len); |
1801 | |
|
1802 | 0 | err = gcry_md_open (&md_hd, auth_algo_libgcrypt, GCRY_MD_FLAG_HMAC); |
1803 | 0 | if (err) |
1804 | 0 | { |
1805 | 0 | gcry_md_close(md_hd); |
1806 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Error in Algorithm %s, gcry_md_open failed: %s\n", |
1807 | 0 | gcry_md_algo_name(auth_algo_libgcrypt), gcry_strerror(err)); |
1808 | 0 | } |
1809 | 0 | else |
1810 | 0 | { |
1811 | 0 | md_len = gcry_md_get_algo_dlen (auth_algo_libgcrypt); |
1812 | 0 | if (md_len < 1 || md_len < esp_icv_len) |
1813 | 0 | { |
1814 | 0 | gcry_md_close(md_hd); |
1815 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Error in Algorithm %s, grcy_md_get_algo_dlen failed: %d\n", |
1816 | 0 | gcry_md_algo_name(auth_algo_libgcrypt), md_len); |
1817 | 0 | } |
1818 | 0 | else |
1819 | 0 | { |
1820 | 0 | unsigned char *esp_icv_computed; |
1821 | |
|
1822 | 0 | gcry_md_setkey( md_hd, esp_auth_key, esp_auth_key_len ); |
1823 | |
|
1824 | 0 | gcry_md_write (md_hd, tvb_get_ptr(tvb, 0, esp_packet_len - esp_icv_len), esp_packet_len - esp_icv_len); |
1825 | |
|
1826 | 0 | if (sn_length == IPSEC_SA_ESN) { |
1827 | 0 | uint8_t sn_bytes[4]; |
1828 | 0 | phtonu32(sn_bytes, sn_upper); |
1829 | 0 | for (int i = 0; i < 4; i++) { |
1830 | 0 | gcry_md_putc(md_hd, sn_bytes[i]); |
1831 | 0 | } |
1832 | 0 | } |
1833 | |
|
1834 | 0 | esp_icv_computed = gcry_md_read (md_hd, auth_algo_libgcrypt); |
1835 | 0 | if (esp_icv_computed == 0) |
1836 | 0 | { |
1837 | 0 | gcry_md_close(md_hd); |
1838 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Error in Algorithm %s, gcry_md_read failed\n", |
1839 | 0 | gcry_md_algo_name(auth_algo_libgcrypt)); |
1840 | 0 | } |
1841 | |
|
1842 | 0 | if(memcmp (esp_icv_computed, esp_icv, esp_icv_len) == 0) { |
1843 | 0 | icv_checked = true; |
1844 | 0 | icv_correct = true; |
1845 | 0 | } else { |
1846 | 0 | icv_checked = true; |
1847 | 0 | icv_correct = false; |
1848 | 0 | esp_icv_expected = bytes_to_str(pinfo->pool, esp_icv_computed, esp_icv_len); |
1849 | 0 | } |
1850 | 0 | } |
1851 | |
|
1852 | 0 | gcry_md_close(md_hd); |
1853 | 0 | } |
1854 | 0 | } |
1855 | 0 | } |
1856 | | |
1857 | 0 | if(g_esp_enable_encryption_decode) |
1858 | 0 | { |
1859 | | /* Deactivation of the Heuristic to decrypt using the NULL encryption algorithm since the packet is matching a SA */ |
1860 | 0 | null_encryption_decode_heuristic = false; |
1861 | |
|
1862 | 0 | switch(esp_encr_algo) |
1863 | 0 | { |
1864 | 0 | case IPSEC_ENCRYPT_3DES_CBC : |
1865 | | /* RFC 2451 says : |
1866 | | 3DES CBC uses a key of 192 bits. |
1867 | | The first 3DES key is taken from the first 64 bits, |
1868 | | the second from the next 64 bits, and the third |
1869 | | from the last 64 bits. |
1870 | | Implementations MUST take into consideration the |
1871 | | parity bits when initially accepting a new set of |
1872 | | keys. Each of the three keys is really 56 bits in |
1873 | | length with the extra 8 bits used for parity. */ |
1874 | | |
1875 | | /* Fix parameters for 3DES-CBC */ |
1876 | 0 | esp_iv_len = esp_block_len = 8; |
1877 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_3DES; |
1878 | 0 | crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; |
1879 | |
|
1880 | 0 | if (esp_encr_key_len != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) |
1881 | 0 | { |
1882 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm 3DES-CBC : Bad Keylen (got %u Bits, need %lu)\n", |
1883 | 0 | esp_encr_key_len * 8, |
1884 | 0 | (unsigned long) gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt) * 8); |
1885 | 0 | decrypt_ok = false; |
1886 | 0 | } |
1887 | 0 | else |
1888 | 0 | decrypt_using_libgcrypt = true; |
1889 | |
|
1890 | 0 | break; |
1891 | | |
1892 | 0 | case IPSEC_ENCRYPT_AES_CBC : |
1893 | | /* RFC 3602 says : |
1894 | | AES supports three key sizes: 128 bits, 192 bits, |
1895 | | and 256 bits. The default key size is 128 bits, |
1896 | | and all implementations MUST support this key size. |
1897 | | Implementations MAY also support key sizes of 192 |
1898 | | bits and 256 bits. */ |
1899 | | |
1900 | | /* Fix parameters for AES-CBC */ |
1901 | 0 | esp_iv_len = esp_block_len = 16; |
1902 | 0 | crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; |
1903 | |
|
1904 | 0 | switch(esp_encr_key_len * 8) |
1905 | 0 | { |
1906 | 0 | case 128: |
1907 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_AES128; |
1908 | 0 | decrypt_using_libgcrypt = true; |
1909 | 0 | break; |
1910 | | |
1911 | 0 | case 192: |
1912 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_AES192; |
1913 | 0 | decrypt_using_libgcrypt = true; |
1914 | 0 | break; |
1915 | | |
1916 | 0 | case 256: |
1917 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_AES256; |
1918 | 0 | decrypt_using_libgcrypt = true; |
1919 | 0 | break; |
1920 | | |
1921 | 0 | default: |
1922 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm AES-CBC : Bad Keylen (%u Bits)\n", |
1923 | 0 | esp_encr_key_len * 8); |
1924 | 0 | decrypt_ok = false; |
1925 | 0 | } |
1926 | | |
1927 | 0 | break; |
1928 | | |
1929 | 0 | case IPSEC_ENCRYPT_CAST5_CBC : |
1930 | | /* RFC 2144 says : |
1931 | | The CAST-128 encryption algorithm has been designed to allow a key |
1932 | | size that can vary from 40 bits to 128 bits, in 8-bit increments |
1933 | | (that is, the allowable key sizes are 40, 48, 56, 64, ..., 112, 120, |
1934 | | and 128 bits.) |
1935 | | We support only 128 bits. */ |
1936 | | |
1937 | | /* Fix parameters for CAST5-CBC */ |
1938 | 0 | esp_iv_len = esp_block_len = 8; |
1939 | 0 | crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; |
1940 | |
|
1941 | 0 | switch(esp_encr_key_len * 8) |
1942 | 0 | { |
1943 | 0 | case 128: |
1944 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_CAST5; |
1945 | 0 | decrypt_using_libgcrypt = true; |
1946 | 0 | break; |
1947 | 0 | default: |
1948 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm CAST5-CBC : Bad Keylen (%u Bits)\n", |
1949 | 0 | esp_encr_key_len * 8); |
1950 | 0 | decrypt_ok = false; |
1951 | 0 | } |
1952 | 0 | break; |
1953 | | |
1954 | 0 | case IPSEC_ENCRYPT_DES_CBC : |
1955 | | /* RFC 2405 says : |
1956 | | DES-CBC is a symmetric secret key algorithm. |
1957 | | The key size is 64-bits. |
1958 | | [It is commonly known as a 56-bit key as the key |
1959 | | has 56 significant bits; the least significant |
1960 | | bit in every byte is the parity bit.] */ |
1961 | | |
1962 | | /* Fix parameters for DES-CBC */ |
1963 | 0 | esp_iv_len = esp_block_len = 8; |
1964 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_DES; |
1965 | 0 | crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; |
1966 | |
|
1967 | 0 | if (esp_encr_key_len != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) |
1968 | 0 | { |
1969 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm DES-CBC : Bad Keylen (%u Bits, need %lu)\n", |
1970 | 0 | esp_encr_key_len * 8, (unsigned long) gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt) * 8); |
1971 | 0 | decrypt_ok = false; |
1972 | 0 | } |
1973 | 0 | else |
1974 | 0 | decrypt_using_libgcrypt = true; |
1975 | |
|
1976 | 0 | break; |
1977 | | |
1978 | 0 | case IPSEC_ENCRYPT_AES_CTR : |
1979 | 0 | case IPSEC_ENCRYPT_AES_GCM : |
1980 | | /* RFC 3686 says : |
1981 | | AES supports three key sizes: 128 bits, 192 bits, |
1982 | | and 256 bits. The default key size is 128 bits, |
1983 | | and all implementations MUST support this key |
1984 | | size. Implementations MAY also support key sizes |
1985 | | of 192 bits and 256 bits. The remaining 32 bits |
1986 | | will be used as nonce. */ |
1987 | | |
1988 | | /* Fix parameters for AES-CTR/AES-GCM */ |
1989 | 0 | esp_iv_len = 8; |
1990 | 0 | esp_block_len = 1; |
1991 | | /* The counter mode key includes a 4 byte nonce following the key, which is used as the salt */ |
1992 | 0 | esp_salt_len = 4; |
1993 | 0 | esp_encr_key_len -= esp_salt_len; |
1994 | |
|
1995 | 0 | crypt_mode_libgcrypt = |
1996 | 0 | (esp_encr_algo == IPSEC_ENCRYPT_AES_CTR) ? GCRY_CIPHER_MODE_CTR : GCRY_CIPHER_MODE_GCM; |
1997 | 0 | switch(esp_encr_key_len * 8) |
1998 | 0 | { |
1999 | 0 | case 128: |
2000 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_AES128; |
2001 | 0 | decrypt_using_libgcrypt = true; |
2002 | 0 | break; |
2003 | | |
2004 | 0 | case 192: |
2005 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_AES192; |
2006 | 0 | decrypt_using_libgcrypt = true; |
2007 | 0 | break; |
2008 | | |
2009 | 0 | case 256: |
2010 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_AES256; |
2011 | 0 | decrypt_using_libgcrypt = true; |
2012 | 0 | break; |
2013 | | |
2014 | 0 | default: |
2015 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm %s : Bad Keylen (%u Bits)\n", |
2016 | 0 | (esp_encr_algo == IPSEC_ENCRYPT_AES_CTR) ? "AES-CTR" : "AES-GCM", |
2017 | 0 | esp_encr_key_len * 8); |
2018 | 0 | decrypt_ok = false; |
2019 | 0 | } |
2020 | | |
2021 | 0 | if (esp_encr_algo == IPSEC_ENCRYPT_AES_GCM) { |
2022 | 0 | if (esp_auth_algo != IPSEC_AUTH_NULL) { |
2023 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error: AES-GCM encryption can only be used with NULL authentication\n"); |
2024 | 0 | } |
2025 | 0 | icv_type = ICV_TYPE_AEAD; |
2026 | 0 | } |
2027 | |
|
2028 | 0 | break; |
2029 | | |
2030 | 0 | case IPSEC_ENCRYPT_TWOFISH_CBC : |
2031 | | /* Twofish is a 128-bit block cipher developed by |
2032 | | Counterpane Labs that accepts a variable-length |
2033 | | key up to 256 bits. |
2034 | | We will only accept key sizes of 128 and 256 bits. |
2035 | | */ |
2036 | | |
2037 | | /* Fix parameters for TWOFISH-CBC */ |
2038 | 0 | esp_iv_len = 16; |
2039 | 0 | crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; |
2040 | |
|
2041 | 0 | switch(esp_encr_key_len * 8) |
2042 | 0 | { |
2043 | 0 | case 128: |
2044 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_TWOFISH128; |
2045 | 0 | decrypt_using_libgcrypt = true; |
2046 | 0 | break; |
2047 | | |
2048 | 0 | case 256: |
2049 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_TWOFISH; |
2050 | 0 | decrypt_using_libgcrypt = true; |
2051 | 0 | break; |
2052 | | |
2053 | 0 | default: |
2054 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm TWOFISH-CBC : Bad Keylen (%u Bits)\n", |
2055 | 0 | esp_encr_key_len * 8); |
2056 | 0 | decrypt_ok = false; |
2057 | 0 | } |
2058 | | |
2059 | 0 | break; |
2060 | | |
2061 | 0 | case IPSEC_ENCRYPT_BLOWFISH_CBC : |
2062 | | /* Bruce Schneier of Counterpane Systems developed |
2063 | | the Blowfish block cipher algorithm. |
2064 | | RFC 2451 shows that Blowfish uses key sizes from |
2065 | | 40 to 448 bits. The Default size is 128 bits. |
2066 | | We will only accept key sizes of 128 bits, because |
2067 | | libgrypt only accept this key size. |
2068 | | */ |
2069 | | |
2070 | | /* Fix parameters for BLOWFISH-CBC */ |
2071 | 0 | esp_iv_len = esp_block_len = 8; |
2072 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_BLOWFISH; |
2073 | 0 | crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; |
2074 | |
|
2075 | 0 | if (esp_encr_key_len != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) |
2076 | 0 | { |
2077 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm BLOWFISH-CBC : Bad Keylen (%u Bits, need %lu)\n", |
2078 | 0 | esp_encr_key_len * 8, (unsigned long) gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt) * 8); |
2079 | 0 | decrypt_ok = false; |
2080 | 0 | } |
2081 | 0 | else |
2082 | 0 | decrypt_using_libgcrypt = true; |
2083 | |
|
2084 | 0 | break; |
2085 | | |
2086 | 0 | case IPSEC_ENCRYPT_AES_GCM_16_IIV: |
2087 | 0 | esp_iv_len = 0; // Implicit IV - First Byte after SEQ is Data |
2088 | 0 | esp_icv_len = 16; // ICV is 16 bytes long |
2089 | 0 | crypt_mode_libgcrypt = GCRY_CIPHER_MODE_GCM; |
2090 | | |
2091 | | /* The key includes a 4 byte nonce following the key, which is used as the salt */ |
2092 | 0 | esp_salt_len = 4; |
2093 | 0 | esp_encr_key_len -= esp_salt_len; |
2094 | |
|
2095 | 0 | switch(esp_encr_key_len * 8) |
2096 | 0 | { |
2097 | 0 | case 128: |
2098 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_AES128; |
2099 | 0 | decrypt_using_libgcrypt = true; |
2100 | 0 | break; |
2101 | | |
2102 | 0 | case 192: |
2103 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_AES192; |
2104 | 0 | decrypt_using_libgcrypt = true; |
2105 | 0 | break; |
2106 | | |
2107 | 0 | case 256: |
2108 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_AES256; |
2109 | 0 | decrypt_using_libgcrypt = true; |
2110 | 0 | break; |
2111 | | |
2112 | 0 | default: |
2113 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm AES_GCM16: Bad Keylen (%u Bits)\n", |
2114 | 0 | esp_encr_key_len * 8); |
2115 | 0 | decrypt_ok = false; |
2116 | 0 | } |
2117 | | |
2118 | 0 | break; |
2119 | | |
2120 | 0 | case IPSEC_ENCRYPT_CHACHA20_POLY1305: |
2121 | 0 | esp_iv_len = 8; // IV is 8 byte long |
2122 | 0 | esp_icv_len = 16; // AEAD Mode - ICV is Associated Data |
2123 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_CHACHA20; |
2124 | 0 | crypt_mode_libgcrypt = GCRY_CIPHER_MODE_POLY1305; |
2125 | 0 | icv_type = ICV_TYPE_AEAD; |
2126 | 0 | auth_algo_libgcrypt = GCRY_MAC_POLY1305; |
2127 | | |
2128 | | /* The key includes a 4 byte nonce following the key, which is used as the salt */ |
2129 | 0 | esp_salt_len = 4; |
2130 | 0 | esp_encr_key_len -= esp_salt_len; |
2131 | |
|
2132 | 0 | if (esp_encr_key_len != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) |
2133 | 0 | { |
2134 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm CHACHA20_POLY1305: Bad Keylen (%u Bits, need %lu)\n", |
2135 | 0 | esp_encr_key_len * 8, (unsigned long) gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt) * 8); |
2136 | 0 | decrypt_ok = false; |
2137 | 0 | } |
2138 | 0 | else |
2139 | 0 | decrypt_using_libgcrypt = true; |
2140 | |
|
2141 | 0 | break; |
2142 | | |
2143 | 0 | case IPSEC_ENCRYPT_CHACHA20_POLY1305_IIV: |
2144 | 0 | esp_iv_len = 0; // Implicit IV - First Byte after SEQ is Data |
2145 | 0 | esp_icv_len = 16; // AEAD Mode - ICV is Associated Data |
2146 | 0 | crypt_algo_libgcrypt = GCRY_CIPHER_CHACHA20; |
2147 | 0 | crypt_mode_libgcrypt = GCRY_CIPHER_MODE_POLY1305; |
2148 | 0 | icv_type = ICV_TYPE_AEAD; |
2149 | 0 | auth_algo_libgcrypt = GCRY_MAC_POLY1305; |
2150 | | |
2151 | | /* The counter mode key includes a 4 byte nonce following the key, which is used as the salt */ |
2152 | 0 | esp_salt_len = 4; |
2153 | 0 | esp_encr_key_len -= esp_salt_len; |
2154 | |
|
2155 | 0 | if (esp_encr_key_len != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) |
2156 | 0 | { |
2157 | 0 | REPORT_DISSECTOR_BUG("<ESP Preferences> Error in Encryption Algorithm CHACHA20_POLY1305_IIV: Bad Keylen (%u Bits, need %lu)\n", |
2158 | 0 | esp_encr_key_len * 8, (unsigned long) gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt) * 8); |
2159 | 0 | decrypt_ok = false; |
2160 | 0 | } |
2161 | 0 | else |
2162 | 0 | decrypt_using_libgcrypt = true; |
2163 | |
|
2164 | 0 | break; |
2165 | | |
2166 | 0 | case IPSEC_ENCRYPT_NULL : |
2167 | 0 | default : |
2168 | | /* Fix parameters */ |
2169 | 0 | esp_iv_len = 0; |
2170 | 0 | esp_block_len = 1; |
2171 | | |
2172 | | /* Allocate buffer for decrypted data */ |
2173 | 0 | if (esp_encr_data_len < esp_icv_len) { |
2174 | 0 | return esp_packet_len; |
2175 | 0 | } |
2176 | 0 | esp_decr_data_len = esp_encr_data_len - esp_icv_len; |
2177 | 0 | esp_decr_data = tvb_memdup(pinfo->pool, tvb, ESP_HEADER_LEN, esp_decr_data_len); |
2178 | |
|
2179 | 0 | decrypt_ok = true; |
2180 | |
|
2181 | 0 | break; |
2182 | 0 | } |
2183 | | |
2184 | 0 | esp_encr_data_len -= (esp_iv_len + esp_icv_len); |
2185 | | |
2186 | | /* |
2187 | | * Zero or negative length of encrypted data shows that the user specified |
2188 | | * wrong encryption algorithm and/or authentication algorithm. |
2189 | | */ |
2190 | 0 | if (esp_encr_data_len <= 0) { |
2191 | 0 | return esp_packet_len; |
2192 | 0 | } |
2193 | | |
2194 | | /* |
2195 | | * Add the IV to the tree and store it in a packet scope buffer for later decryption |
2196 | | * if the specified encryption algorithm uses IV. |
2197 | | */ |
2198 | 0 | if (esp_iv_len) { |
2199 | 0 | tvb_ensure_bytes_exist(tvb, offset, esp_iv_len); |
2200 | |
|
2201 | 0 | iv_item = proto_tree_add_item(esp_tree, hf_esp_iv, tvb, offset, esp_iv_len, ENC_NA); |
2202 | 0 | proto_item_append_text(iv_item, " (%d bytes)", esp_iv_len); |
2203 | 0 | esp_iv = (unsigned char *)tvb_memdup(pinfo->pool, tvb, offset, esp_iv_len); |
2204 | |
|
2205 | 0 | offset += esp_iv_len; |
2206 | 0 | } |
2207 | | |
2208 | | /* |
2209 | | * Add the encrypted portion to the tree and store it in a packet scope buffer for later decryption. |
2210 | | */ |
2211 | 0 | if (esp_encr_data_len) { |
2212 | 0 | encr_data_item = proto_tree_add_item(esp_tree, hf_esp_encrypted_data, tvb, offset, esp_encr_data_len, ENC_NA); |
2213 | 0 | proto_item_append_text(encr_data_item, " (%d bytes) <%s>", |
2214 | 0 | esp_encr_data_len, |
2215 | 0 | esp_get_encr_algo_name(esp_encr_algo)); |
2216 | |
|
2217 | 0 | esp_encr_data = (unsigned char *)tvb_memdup(pinfo->pool, tvb, offset, esp_encr_data_len); |
2218 | 0 | offset += esp_encr_data_len; |
2219 | | |
2220 | | /* |
2221 | | * Verify that the encrypted payload data is properly aligned: The ciphertext length |
2222 | | * needs to be a multiple of the of block size (which equals 1 for 'stream ciphers' |
2223 | | * like AES-GCM and AES-CTR) and the ciphertext needs to terminate on a 4-byte boundary, |
2224 | | * according to RFC 2406, section 2.4. Given the fact that all current block sizes are |
2225 | | * powers of 2, only the stricter alignment requirement needs to be checked: |
2226 | | */ |
2227 | 0 | if (esp_block_len > 4 && esp_encr_data_len % esp_block_len != 0) { |
2228 | 0 | proto_item_append_text(encr_data_item, "[Invalid length, ciphertext should be a multiple of block size (%u)]", |
2229 | 0 | esp_block_len); |
2230 | 0 | decrypt_using_libgcrypt = false; |
2231 | 0 | } else if (esp_encr_data_len % 4 != 0) { |
2232 | 0 | proto_item_append_text(encr_data_item, "[Invalid length, ciphertext should terminate at 4-byte boundary]"); |
2233 | 0 | decrypt_using_libgcrypt = false; |
2234 | 0 | } |
2235 | 0 | } |
2236 | | |
2237 | | |
2238 | | /* |
2239 | | * Add the ICV (Integrity Check Value) to the tree before decryption to ensure |
2240 | | * the ICV be displayed even if the decryption fails. |
2241 | | */ |
2242 | |
|
2243 | 0 | if (esp_icv_len) { |
2244 | 0 | icv_item = proto_tree_add_item(esp_tree, hf_esp_icv, tvb, offset, esp_icv_len, ENC_NA); |
2245 | 0 | proto_item_append_text(icv_item, " (%d bytes) <%s>", |
2246 | 0 | esp_icv_len, |
2247 | 0 | icv_type == ICV_TYPE_AEAD ? |
2248 | 0 | esp_get_encr_algo_name(esp_encr_algo) : |
2249 | 0 | esp_get_auth_algo_name(esp_auth_algo)); |
2250 | |
|
2251 | 0 | } |
2252 | |
|
2253 | 0 | if (decrypt_using_libgcrypt) |
2254 | 0 | { |
2255 | | /* |
2256 | | * Allocate buffer for decrypted data. |
2257 | | */ |
2258 | 0 | esp_decr_data_len = esp_encr_data_len; |
2259 | 0 | esp_decr_data = tvb_memdup(pinfo->pool, tvb, ESP_HEADER_LEN, esp_decr_data_len); |
2260 | | |
2261 | | /* (Lazily) create the cipher_hd */ |
2262 | 0 | if (!(*cipher_hd_created)) { |
2263 | 0 | err = gcry_cipher_open(cipher_hd, crypt_algo_libgcrypt, crypt_mode_libgcrypt, 0); |
2264 | 0 | if (err) { |
2265 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, grcy_open_cipher failed: %s\n", |
2266 | 0 | gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, gcry_strerror(err)); |
2267 | 0 | } |
2268 | 0 | else |
2269 | 0 | { |
2270 | | /* OK, set the key */ |
2271 | 0 | if (*cipher_hd_created == false) |
2272 | 0 | { |
2273 | 0 | err = gcry_cipher_setkey(*cipher_hd, esp_encr_key, esp_encr_key_len); |
2274 | |
|
2275 | 0 | if (err) { |
2276 | 0 | gcry_cipher_close(*cipher_hd); |
2277 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, gcry_cipher_setkey(key_len=%u) failed: %s\n", |
2278 | 0 | gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, esp_encr_key_len, gcry_strerror(err)); |
2279 | 0 | } |
2280 | 0 | } |
2281 | | |
2282 | | /* Key is created and has its key set now */ |
2283 | 0 | *cipher_hd_created = true; |
2284 | 0 | } |
2285 | 0 | } |
2286 | | |
2287 | | /* Now try to decrypt */ |
2288 | 0 | if (esp_encr_algo == IPSEC_ENCRYPT_AES_CTR || esp_encr_algo == IPSEC_ENCRYPT_AES_GCM) |
2289 | 0 | { |
2290 | 0 | unsigned int ctr_block_size = sizeof(ctr_block); |
2291 | | |
2292 | | /* Set CTR first */ |
2293 | 0 | memset(ctr_block, 0, ctr_block_size); |
2294 | 0 | memcpy(ctr_block, esp_encr_key + esp_encr_key_len, esp_salt_len); |
2295 | 0 | memcpy(ctr_block + esp_salt_len, esp_iv, esp_iv_len); |
2296 | |
|
2297 | 0 | if (crypt_mode_libgcrypt == GCRY_CIPHER_MODE_CTR) { |
2298 | 0 | ctr_block[ctr_block_size-1] = 1; |
2299 | 0 | if (esp_encr_algo == IPSEC_ENCRYPT_AES_GCM) { |
2300 | | /* AES-CTR is used as fallback for AES-GCM (only) if gcrypt does not have AEAD ciphers. |
2301 | | * The extra increment is necessary because AES-GCM reserves counter 0 for the final |
2302 | | * step to create the authentication tag and starts encryption with counter 1. |
2303 | | */ |
2304 | 0 | ctr_block[ctr_block_size-1]++; |
2305 | 0 | } |
2306 | 0 | err = gcry_cipher_setctr(*cipher_hd, ctr_block, 16); |
2307 | 0 | } else { |
2308 | 0 | err = gcry_cipher_setiv(*cipher_hd, ctr_block, esp_salt_len + esp_iv_len); |
2309 | 0 | } |
2310 | 0 | } |
2311 | 0 | else if (esp_encr_algo == IPSEC_ENCRYPT_CHACHA20_POLY1305_IIV || esp_encr_algo == IPSEC_ENCRYPT_AES_GCM_16_IIV) |
2312 | 0 | { |
2313 | | // Implicit IV, see https://www.rfc-editor.org/rfc/rfc8750.html |
2314 | 0 | unsigned int nonce_size = sizeof(nonce); |
2315 | 0 | memset(nonce, 0, nonce_size); |
2316 | 0 | memcpy(nonce, esp_encr_key + esp_encr_key_len, esp_salt_len); |
2317 | 0 | nonce[8] = (sequence_number >> 24) & 0xff; |
2318 | 0 | nonce[9] = (sequence_number >> 16) & 0xff; |
2319 | 0 | nonce[10] = (sequence_number >> 8) & 0xff; |
2320 | 0 | nonce[11] = sequence_number & 0xff; |
2321 | 0 | err = gcry_cipher_setiv(*cipher_hd, nonce, 12); |
2322 | 0 | } |
2323 | 0 | else if (esp_encr_algo == IPSEC_ENCRYPT_CHACHA20_POLY1305) |
2324 | 0 | { |
2325 | | // see https://www.rfc-editor.org/rfc/rfc7634.html |
2326 | 0 | unsigned int nonce_size = sizeof(nonce); |
2327 | |
|
2328 | 0 | memset(nonce, 0, nonce_size); |
2329 | 0 | memcpy(nonce, esp_encr_key + esp_encr_key_len, esp_salt_len); |
2330 | 0 | memcpy(nonce + esp_salt_len, esp_iv, esp_iv_len); |
2331 | |
|
2332 | 0 | err = gcry_cipher_setiv(*cipher_hd, nonce, esp_salt_len + esp_iv_len); |
2333 | 0 | } |
2334 | 0 | else |
2335 | 0 | { |
2336 | 0 | err = gcry_cipher_setiv(*cipher_hd, esp_iv, esp_iv_len); |
2337 | 0 | } |
2338 | |
|
2339 | 0 | if (err) { |
2340 | 0 | gcry_cipher_close(*cipher_hd); |
2341 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, gcry_cipher_set%s() failed: %s\n", |
2342 | 0 | gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, |
2343 | 0 | (crypt_mode_libgcrypt == GCRY_CIPHER_MODE_CTR) ? "ctr" : "iv", |
2344 | 0 | gcry_strerror(err)); |
2345 | 0 | } |
2346 | | |
2347 | |
|
2348 | 0 | if (g_esp_enable_authentication_check && icv_type == ICV_TYPE_AEAD) { |
2349 | | /* Allocate buffer for ICV */ |
2350 | 0 | esp_icv = (uint8_t *)tvb_memdup(pinfo->pool, tvb, esp_packet_len - esp_icv_len, esp_icv_len); |
2351 | |
|
2352 | 0 | if (sn_length == IPSEC_SA_SN) { |
2353 | 0 | err = gcry_cipher_authenticate(*cipher_hd, tvb_get_ptr(tvb, 0, ESP_HEADER_LEN), ESP_HEADER_LEN); |
2354 | 0 | } else { |
2355 | 0 | uint8_t *aad = wmem_alloc(pinfo->pool, ESP_HEADER_LEN + 4); |
2356 | 0 | tvb_memcpy(tvb, aad, 0, 4); |
2357 | 0 | phtonu32(&aad[4], sn_upper); |
2358 | 0 | tvb_memcpy(tvb, &aad[ESP_HEADER_LEN], 4, ESP_HEADER_LEN); |
2359 | 0 | err = gcry_cipher_authenticate(*cipher_hd, aad, ESP_HEADER_LEN + 4); |
2360 | 0 | } |
2361 | |
|
2362 | 0 | if (err) { |
2363 | 0 | gcry_cipher_close(*cipher_hd); |
2364 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, gcry_cipher_authenticate() failed: %s\n", |
2365 | 0 | gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, gcry_strerror(err)); |
2366 | 0 | } |
2367 | 0 | } |
2368 | |
|
2369 | 0 | if (!err) |
2370 | 0 | { |
2371 | 0 | err = gcry_cipher_decrypt(*cipher_hd, esp_decr_data, esp_decr_data_len, esp_encr_data, esp_encr_data_len); |
2372 | 0 | } |
2373 | |
|
2374 | 0 | if (err) |
2375 | 0 | { |
2376 | 0 | gcry_cipher_close(*cipher_hd); |
2377 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Error in Algorithm %s, Mode %d, gcry_cipher_decrypt failed: %s\n", |
2378 | 0 | gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, gcry_strerror(err)); |
2379 | 0 | } |
2380 | 0 | else |
2381 | 0 | { |
2382 | | /* Decryption has finished */ |
2383 | 0 | decrypt_ok = true; |
2384 | |
|
2385 | 0 | if (g_esp_enable_authentication_check && icv_type == ICV_TYPE_AEAD) { |
2386 | 0 | unsigned char *esp_icv_computed; |
2387 | 0 | int tag_len; |
2388 | |
|
2389 | 0 | tag_len = (auth_algo_libgcrypt == GCRY_MAC_POLY1305) ? 16 : (int)gcry_cipher_get_algo_blklen(crypt_algo_libgcrypt); |
2390 | |
|
2391 | 0 | if (tag_len < esp_icv_len) { |
2392 | 0 | ws_warning("<IPsec/ESP Dissector> Error in Algorithm %s, tag length (%d) is less than icv length (%d)", |
2393 | 0 | gcry_md_algo_name(crypt_algo_libgcrypt), tag_len, esp_icv_len); |
2394 | 0 | } |
2395 | |
|
2396 | 0 | esp_icv_computed = (unsigned char *)wmem_alloc(pinfo->pool, tag_len); |
2397 | 0 | err = gcry_cipher_gettag(*cipher_hd, esp_icv_computed, tag_len); |
2398 | 0 | if (err) { |
2399 | 0 | gcry_cipher_close(*cipher_hd); |
2400 | 0 | REPORT_DISSECTOR_BUG("<IPsec/ESP Dissector> Error in Algorithm %s: gcry_cipher_gettag failed: %s", |
2401 | 0 | gcry_md_algo_name(crypt_algo_libgcrypt), gcry_strerror(err)); |
2402 | 0 | } |
2403 | |
|
2404 | 0 | if (memcmp(esp_icv_computed, esp_icv, esp_icv_len) == 0) { |
2405 | 0 | icv_checked = true; |
2406 | 0 | icv_correct = true; |
2407 | 0 | } else { |
2408 | 0 | icv_checked = true; |
2409 | 0 | icv_correct = false; |
2410 | 0 | esp_icv_expected = bytes_to_str(pinfo->pool, esp_icv_computed, esp_icv_len); |
2411 | 0 | } |
2412 | 0 | } |
2413 | 0 | } |
2414 | 0 | } |
2415 | 0 | } |
2416 | 0 | } |
2417 | 0 | else if(g_esp_enable_null_encryption_decode_heuristic) |
2418 | 0 | { |
2419 | | /* The packet does not belong to a Security Association */ |
2420 | 0 | null_encryption_decode_heuristic = true; |
2421 | 0 | } |
2422 | | |
2423 | 0 | if(decrypt_ok) |
2424 | 0 | { |
2425 | 0 | tvb_decrypted = tvb_new_child_real_data(tvb, (uint8_t *)wmem_memdup(pinfo->pool, esp_decr_data, esp_decr_data_len), |
2426 | 0 | esp_decr_data_len, esp_decr_data_len); |
2427 | |
|
2428 | 0 | add_new_data_source(pinfo, tvb_decrypted, "Decrypted Data"); |
2429 | 0 | item = proto_tree_add_item(esp_tree, hf_esp_decrypted_data, tvb_decrypted, 0, esp_decr_data_len, ENC_NA); |
2430 | 0 | proto_item_append_text(item, " (%d byte%s)", esp_decr_data_len, plurality(esp_decr_data_len, "", "s")); |
2431 | |
|
2432 | 0 | decr_tree = proto_item_add_subtree(item, ett_esp_decrypted_data); |
2433 | | |
2434 | | /* Make sure the packet is not truncated before the fields |
2435 | | * we need to read to determine the encapsulated protocol */ |
2436 | 0 | if(tvb_bytes_exist(tvb_decrypted, esp_decr_data_len - 2, 2)) |
2437 | 0 | { |
2438 | 0 | int esp_contained_data_len; |
2439 | |
|
2440 | 0 | esp_pad_len = tvb_get_uint8(tvb_decrypted, esp_decr_data_len - 2); |
2441 | 0 | esp_contained_data_len = esp_decr_data_len - esp_pad_len - 2; |
2442 | |
|
2443 | 0 | if(esp_contained_data_len > 0) |
2444 | 0 | { |
2445 | 0 | item = proto_tree_add_item(decr_tree, hf_esp_contained_data, tvb_decrypted, 0, esp_contained_data_len, ENC_NA); |
2446 | 0 | proto_item_append_text(item, " (%d byte%s)", esp_contained_data_len, plurality(esp_contained_data_len, "", "s")); |
2447 | | |
2448 | | /* Get the encapsulated protocol */ |
2449 | 0 | encapsulated_protocol = tvb_get_uint8(tvb_decrypted, esp_decr_data_len - 1); |
2450 | |
|
2451 | 0 | dissector_handle = dissector_get_uint_handle(ip_dissector_table, encapsulated_protocol); |
2452 | 0 | if (dissector_handle) { |
2453 | | /* |
2454 | | * Recursively dissect the decrypted frame |
2455 | | * |
2456 | | * Note that the dissection restarts at the top level 'tree' here, not |
2457 | | * at 'decr_tree', which is hidden inside the ESP subtree. This has |
2458 | | * the effect that the protocol layers of the decrypted packet show up |
2459 | | * in the protocol stack of the Packet Details Pane immediately below |
2460 | | * the ESP layer, which is more intuitive and practical for the user. |
2461 | | */ |
2462 | 0 | saved_match_uint = pinfo->match_uint; |
2463 | 0 | pinfo->match_uint = encapsulated_protocol; |
2464 | 0 | next_tvb = tvb_new_subset_length(tvb_decrypted, 0, esp_contained_data_len); |
2465 | 0 | export_ipsec_pdu(dissector_handle, pinfo, next_tvb); |
2466 | 0 | call_dissector(dissector_handle, next_tvb, pinfo, tree); |
2467 | 0 | pinfo->match_uint = saved_match_uint; |
2468 | 0 | decrypt_dissect_ok = true; |
2469 | 0 | } |
2470 | 0 | } |
2471 | 0 | } |
2472 | |
|
2473 | 0 | if(decrypt_dissect_ok) |
2474 | 0 | { |
2475 | 0 | if(decr_tree) |
2476 | 0 | { |
2477 | 0 | if(esp_pad_len !=0) |
2478 | 0 | proto_tree_add_item(decr_tree, hf_esp_pad, |
2479 | 0 | tvb_decrypted, |
2480 | 0 | esp_decr_data_len - esp_pad_len - 2, |
2481 | 0 | esp_pad_len, ENC_NA); |
2482 | |
|
2483 | 0 | proto_tree_add_uint(decr_tree, hf_esp_pad_len, tvb_decrypted, |
2484 | 0 | esp_decr_data_len - 2, 1, |
2485 | 0 | esp_pad_len); |
2486 | |
|
2487 | 0 | proto_tree_add_uint_format(decr_tree, hf_esp_protocol, tvb_decrypted, |
2488 | 0 | esp_decr_data_len - 1, 1, |
2489 | 0 | encapsulated_protocol, |
2490 | 0 | "Next header: %s (0x%02x)", |
2491 | 0 | ipprotostr(encapsulated_protocol), encapsulated_protocol); |
2492 | 0 | } |
2493 | 0 | } |
2494 | 0 | else |
2495 | 0 | { |
2496 | 0 | next_tvb = tvb_new_subset_length(tvb_decrypted, 0, |
2497 | 0 | esp_decr_data_len); |
2498 | 0 | export_ipsec_pdu(data_handle, pinfo, next_tvb); |
2499 | 0 | call_dissector(data_handle, next_tvb, pinfo, decr_tree); |
2500 | 0 | } |
2501 | 0 | } |
2502 | 0 | } |
2503 | | |
2504 | | /* |
2505 | | If the packet is present in the security association database and the field g_esp_enable_authentication_check set. |
2506 | | */ |
2507 | 97 | if(!g_esp_enable_encryption_decode && g_esp_enable_authentication_check && sad_is_present) |
2508 | 0 | { |
2509 | 0 | if ((esp_packet_len - ESP_HEADER_LEN) > esp_icv_len) { |
2510 | 0 | next_tvb = tvb_new_subset_length(tvb, ESP_HEADER_LEN, esp_packet_len - ESP_HEADER_LEN - esp_icv_len); |
2511 | 0 | export_ipsec_pdu(data_handle, pinfo, next_tvb); |
2512 | 0 | call_dissector(data_handle, next_tvb, pinfo, esp_tree); |
2513 | 0 | } |
2514 | 0 | } |
2515 | | /* The packet does not belong to a security association and the field g_esp_enable_null_encryption_decode_heuristic is set */ |
2516 | 97 | else if(null_encryption_decode_heuristic) |
2517 | 0 | { |
2518 | 0 | if(g_esp_enable_null_encryption_decode_heuristic) |
2519 | 0 | { |
2520 | 0 | esp_icv_len = esp_null_heur(tvb, pinfo, esp_tree); |
2521 | 0 | } |
2522 | |
|
2523 | 0 | if(esp_icv_len != -1) |
2524 | 0 | { |
2525 | 0 | offset = esp_packet_len - esp_icv_len; |
2526 | 0 | if(esp_tree) |
2527 | 0 | { |
2528 | | /* Make sure we have the auth trailer data */ |
2529 | 0 | if(tvb_bytes_exist(tvb, offset, esp_icv_len)) |
2530 | 0 | { |
2531 | 0 | icv_item = proto_tree_add_item(esp_tree, hf_esp_icv, tvb, offset, esp_icv_len, ENC_NA); |
2532 | 0 | } |
2533 | 0 | else |
2534 | 0 | { |
2535 | | /* Truncated so just display what we have */ |
2536 | 0 | icv_item = proto_tree_add_bytes_format(esp_tree, hf_esp_icv, tvb, offset, |
2537 | 0 | esp_icv_len - (esp_packet_len - tvb_captured_length(tvb)), |
2538 | 0 | NULL, "Integrity Check Value (truncated)"); |
2539 | 0 | } |
2540 | 0 | } |
2541 | 0 | } |
2542 | 0 | } |
2543 | | |
2544 | 97 | if(icv_item != NULL) { |
2545 | |
|
2546 | 0 | bool good = false, bad = false; |
2547 | |
|
2548 | 0 | icv_tree = proto_item_add_subtree(icv_item, ett_esp_icv); |
2549 | |
|
2550 | 0 | if(icv_checked) { |
2551 | 0 | if (icv_correct) { |
2552 | 0 | proto_item_append_text(icv_item, " [correct]"); |
2553 | 0 | good = true; |
2554 | 0 | if (sn_length == IPSEC_SA_ESN && g_esp_do_sequence_analysis) { |
2555 | 0 | spi_status *status = (spi_status*)wmem_map_lookup(esp_sequence_analysis_hash, |
2556 | 0 | GUINT_TO_POINTER((unsigned)spi)); |
2557 | 0 | if (status && !status->firstValidSN) { |
2558 | 0 | status->firstValidSN = sequence_number; |
2559 | 0 | } |
2560 | 0 | } |
2561 | 0 | } else { |
2562 | 0 | proto_item_append_text(icv_item, " [incorrect, should be %s]", esp_icv_expected); |
2563 | 0 | bad = true; |
2564 | 0 | } |
2565 | 0 | } else { |
2566 | 0 | proto_item_append_text(icv_item, " [unchecked]"); |
2567 | 0 | } |
2568 | |
|
2569 | 0 | item = proto_tree_add_boolean(icv_tree, hf_esp_icv_good, |
2570 | 0 | tvb, offset, esp_icv_len, good); |
2571 | 0 | proto_item_set_generated(item); |
2572 | |
|
2573 | 0 | item = proto_tree_add_boolean(icv_tree, hf_esp_icv_bad, |
2574 | 0 | tvb, offset, esp_icv_len, bad); |
2575 | 0 | proto_item_set_generated(item); |
2576 | 0 | } |
2577 | | |
2578 | 97 | return tvb_captured_length(tvb); |
2579 | 97 | } |
2580 | | |
2581 | | |
2582 | | static int |
2583 | | dissect_ipcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dissector_data _U_) |
2584 | 27 | { |
2585 | 27 | proto_tree *ipcomp_tree; |
2586 | 27 | proto_item *ti; |
2587 | 27 | uint8_t comp_nxt; /* Next Header */ |
2588 | 27 | uint32_t comp_cpi; /* Compression parameter index */ |
2589 | 27 | dissector_handle_t dissector_handle; |
2590 | 27 | uint32_t saved_match_uint; |
2591 | 27 | tvbuff_t *data, *decomp; |
2592 | | |
2593 | | /* |
2594 | | * load the top pane info. This should be overwritten by |
2595 | | * the next protocol in the stack |
2596 | | */ |
2597 | 27 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPComp"); |
2598 | 27 | col_clear(pinfo->cinfo, COL_INFO); |
2599 | | |
2600 | 27 | comp_nxt = tvb_get_uint8(tvb, 0); |
2601 | | |
2602 | | /* |
2603 | | * populate a tree in the second pane with the status of the link layer |
2604 | | * (ie none) |
2605 | | */ |
2606 | 27 | ti = proto_tree_add_item(tree, proto_ipcomp, tvb, 0, -1, ENC_NA); |
2607 | 27 | ipcomp_tree = proto_item_add_subtree(ti, ett_ipcomp); |
2608 | | |
2609 | 27 | proto_tree_add_uint_format_value(ipcomp_tree, hf_ipcomp_next_header, tvb, |
2610 | 27 | 0, 1, comp_nxt, "%s (0x%02x)", ipprotostr(comp_nxt), comp_nxt); |
2611 | 27 | proto_tree_add_item(ipcomp_tree, hf_ipcomp_flags, tvb, 1, 1, ENC_NA); |
2612 | 27 | proto_tree_add_item_ret_uint(ipcomp_tree, hf_ipcomp_cpi, tvb, 2, 2, ENC_BIG_ENDIAN, &comp_cpi); |
2613 | | |
2614 | 27 | col_add_fstr(pinfo->cinfo, COL_INFO, "IPComp (CPI=%s)", val_to_str(pinfo->pool, comp_cpi, cpi2val, "0x%04x")); |
2615 | | |
2616 | 27 | data = tvb_new_subset_remaining(tvb, 4); |
2617 | 27 | export_ipsec_pdu(data_handle, pinfo, data); |
2618 | 27 | call_dissector(data_handle, data, pinfo, ipcomp_tree); |
2619 | | |
2620 | | /* |
2621 | | * try to uncompress as if it were DEFLATEd. With negotiated |
2622 | | * CPIs, we don't know the algorithm beforehand; if we get it |
2623 | | * wrong, tvb_child_uncompress_zlib() returns NULL and nothing is displayed. |
2624 | | */ |
2625 | 27 | decomp = tvb_child_uncompress_zlib(data, data, 0, tvb_captured_length(data)); |
2626 | 27 | if (decomp) { |
2627 | 17 | add_new_data_source(pinfo, decomp, "IPcomp inflated data"); |
2628 | 17 | saved_match_uint = pinfo->match_uint; |
2629 | 17 | dissector_handle = dissector_get_uint_handle(ip_dissector_table, comp_nxt); |
2630 | 17 | if (dissector_handle) { |
2631 | 15 | pinfo->match_uint = comp_nxt; |
2632 | 15 | } else { |
2633 | 2 | dissector_handle = data_handle; |
2634 | 2 | } |
2635 | 17 | export_ipsec_pdu(dissector_handle, pinfo, decomp); |
2636 | 17 | call_dissector(dissector_handle, decomp, pinfo, tree); |
2637 | 17 | pinfo->match_uint = saved_match_uint; |
2638 | 17 | } |
2639 | | |
2640 | 27 | return tvb_captured_length(tvb); |
2641 | 27 | } |
2642 | | |
2643 | | static void ipsec_cleanup_protocol(void) |
2644 | 0 | { |
2645 | | /* Free any SA records added by other dissectors */ |
2646 | 0 | unsigned n; |
2647 | 0 | for (n=0; n < extra_esp_sa_records.num_records; n++) { |
2648 | 0 | uat_esp_sa_record_free_cb(&(extra_esp_sa_records.records[n])); |
2649 | 0 | } |
2650 | | |
2651 | | /* Free overall block of records */ |
2652 | 0 | g_free(extra_esp_sa_records.records); |
2653 | 0 | extra_esp_sa_records.records = NULL; |
2654 | 0 | extra_esp_sa_records.num_records = 0; |
2655 | 0 | } |
2656 | | |
2657 | | static void |
2658 | | esp_secrets_block_callback(const void *secrets, unsigned size _U_) |
2659 | 0 | { |
2660 | 0 | char *err; |
2661 | |
|
2662 | 0 | if (!uat_load_str(esp_uat, (const char *)secrets, &err)) |
2663 | 0 | g_free(err); |
2664 | 0 | } |
2665 | | |
2666 | | static void |
2667 | | esp_print_record(void *key, void *value _U_, void *user_data) |
2668 | 0 | { |
2669 | 0 | char *str = uat_record_tostr(esp_uat, key); |
2670 | |
|
2671 | 0 | wmem_strbuf_append_printf((wmem_strbuf_t *)user_data, "%s\n", str); |
2672 | 0 | g_free(str); |
2673 | 0 | } |
2674 | | |
2675 | | static unsigned |
2676 | | esp_export_secret_count(void) |
2677 | 0 | { |
2678 | 0 | return wmem_map_size(esp_used_sa_map); |
2679 | 0 | } |
2680 | | |
2681 | | static bool |
2682 | | esp_export_dsb(wtap* wth) |
2683 | 0 | { |
2684 | 0 | wtap_block_t block; |
2685 | 0 | wtapng_dsb_mandatory_t *dsb; |
2686 | 0 | wmem_strbuf_t *secrets; |
2687 | |
|
2688 | 0 | if (!wmem_map_size(esp_used_sa_map)) |
2689 | 0 | return false; |
2690 | | |
2691 | 0 | secrets = wmem_strbuf_create(NULL); |
2692 | 0 | wmem_map_foreach(esp_used_sa_map, esp_print_record, secrets); |
2693 | |
|
2694 | 0 | block = wtap_block_create(WTAP_BLOCK_DECRYPTION_SECRETS); |
2695 | 0 | dsb = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(block); |
2696 | |
|
2697 | 0 | dsb->secrets_type = SECRETS_TYPE_ESP; |
2698 | 0 | dsb->secrets_data = (uint8_t*)wmem_strbuf_finalize(secrets); |
2699 | 0 | dsb->secrets_len = (uint32_t)strlen((char*)dsb->secrets_data); |
2700 | |
|
2701 | 0 | wtap_file_add_decryption_secrets(wth, block); |
2702 | 0 | return true; |
2703 | 0 | } |
2704 | | |
2705 | | void |
2706 | | proto_register_ipsec(void) |
2707 | 16 | { |
2708 | 16 | static hf_register_info hf_ah[] = { |
2709 | 16 | { &hf_ah_next_header, |
2710 | 16 | { "Next header", "ah.next_header", FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0x0, |
2711 | 16 | NULL, HFILL }}, |
2712 | 16 | { &hf_ah_length, |
2713 | 16 | { "Length", "ah.length", FT_UINT8, BASE_DEC, NULL, 0x0, |
2714 | 16 | NULL, HFILL }}, |
2715 | 16 | { &hf_ah_reserved, |
2716 | 16 | { "Reserved", "ah.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, |
2717 | 16 | NULL, HFILL }}, |
2718 | 16 | { &hf_ah_spi, |
2719 | 16 | { "AH SPI", "ah.spi", FT_UINT32, BASE_HEX, NULL, 0x0, |
2720 | 16 | "IP Authentication Header Security Parameters Index", HFILL }}, |
2721 | 16 | { &hf_ah_iv, |
2722 | 16 | { "AH ICV", "ah.icv", FT_BYTES, BASE_NONE, NULL, 0x0, |
2723 | 16 | "IP Authentication Header Integrity Check Value", HFILL }}, |
2724 | 16 | { &hf_ah_sequence, |
2725 | 16 | { "AH Sequence", "ah.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, |
2726 | 16 | "IP Authentication Header Sequence Number", HFILL }} |
2727 | 16 | }; |
2728 | | |
2729 | 16 | static hf_register_info hf_esp[] = { |
2730 | 16 | { &hf_esp_spi, |
2731 | 16 | { "ESP SPI", "esp.spi", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, |
2732 | 16 | "IP Encapsulating Security Payload Security Parameters Index", HFILL }}, |
2733 | 16 | { &hf_esp_sequence, |
2734 | 16 | { "ESP Sequence", "esp.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, |
2735 | 16 | "IP Encapsulating Security Payload Sequence Number", HFILL }}, |
2736 | 16 | { &hf_esp_pad, |
2737 | 16 | { "Pad", "esp.pad", FT_BYTES, BASE_NONE, NULL, 0x0, |
2738 | 16 | NULL, HFILL }}, |
2739 | 16 | { &hf_esp_pad_len, |
2740 | 16 | { "ESP Pad Length", "esp.pad_len", FT_UINT8, BASE_DEC, NULL, 0x0, |
2741 | 16 | "IP Encapsulating Security Payload Pad Length", HFILL }}, |
2742 | 16 | { &hf_esp_protocol, |
2743 | 16 | { "ESP Next Header", "esp.protocol", FT_UINT8, BASE_HEX, NULL, 0x0, |
2744 | 16 | "IP Encapsulating Security Payload Next Header", HFILL }}, |
2745 | 16 | { &hf_esp_iv, |
2746 | 16 | { "ESP IV", "esp.iv", FT_BYTES, BASE_NONE, NULL, 0x0, |
2747 | 16 | "IP Encapsulating Security Payload Initialization Vector", HFILL }}, |
2748 | 16 | { &hf_esp_encrypted_data, |
2749 | 16 | { "ESP Encrypted Data", "esp.encrypted_data", FT_BYTES, BASE_NONE, NULL, 0x0, |
2750 | 16 | "IP Encapsulating Security Payload Encrypted Data", HFILL }}, |
2751 | 16 | { &hf_esp_decrypted_data, |
2752 | 16 | { "ESP Decrypted Data", "esp.decrypted_data", FT_BYTES, BASE_NONE, NULL, 0x0, |
2753 | 16 | "IP Encapsulating Security Payload Decrypted Data", HFILL }}, |
2754 | 16 | { &hf_esp_contained_data, |
2755 | 16 | { "ESP Contained Data", "esp.contained_data", FT_BYTES, BASE_NONE, NULL, 0x0, |
2756 | 16 | "IP Encapsulating Security Payload Contained Data", HFILL }}, |
2757 | 16 | { &hf_esp_icv, |
2758 | 16 | { "ESP ICV", "esp.icv", FT_BYTES, BASE_NONE, NULL, 0x0, |
2759 | 16 | "IP Encapsulating Security Payload Integrity Check Value", HFILL }}, |
2760 | 16 | { &hf_esp_icv_good, |
2761 | 16 | { "Good", "esp.icv_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
2762 | 16 | "True: ICV matches packet content; False: doesn't match content or not checked", HFILL }}, |
2763 | 16 | { &hf_esp_icv_bad, |
2764 | 16 | { "Bad", "esp.icv_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
2765 | 16 | "True: ICV doesn't match packet content; False: matches content or not checked", HFILL }}, |
2766 | 16 | { &hf_esp_sequence_analysis_expected_sn, |
2767 | 16 | { "Expected SN", "esp.sequence-analysis.expected-sn", FT_UINT32, BASE_DEC, NULL, 0x0, |
2768 | 16 | NULL, HFILL }}, |
2769 | 16 | { &hf_esp_sequence_analysis_previous_frame, |
2770 | 16 | { "Previous Frame", "esp.sequence-analysis.previous-frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, |
2771 | 16 | NULL, HFILL }}, |
2772 | 16 | }; |
2773 | | |
2774 | 16 | static hf_register_info hf_ipcomp[] = { |
2775 | 16 | { &hf_ipcomp_next_header, |
2776 | 16 | { "Next Header", "ipcomp.next_header", FT_UINT8, BASE_HEX, NULL, 0x0, |
2777 | 16 | NULL, HFILL }}, |
2778 | 16 | { &hf_ipcomp_flags, |
2779 | 16 | { "IPComp Flags", "ipcomp.flags", FT_UINT8, BASE_HEX, NULL, 0x0, |
2780 | 16 | "IP Payload Compression Protocol Flags", HFILL }}, |
2781 | 16 | { &hf_ipcomp_cpi, |
2782 | 16 | { "IPComp CPI", "ipcomp.cpi", FT_UINT16, BASE_HEX, VALS(cpi2val), 0x0, |
2783 | 16 | "IP Payload Compression Protocol Compression Parameter Index", HFILL }}, |
2784 | 16 | }; |
2785 | | |
2786 | 16 | static int *ett[] = { |
2787 | 16 | &ett_ah, |
2788 | 16 | &ett_esp, |
2789 | 16 | &ett_esp_icv, |
2790 | 16 | &ett_esp_decrypted_data, |
2791 | 16 | &ett_ipcomp, |
2792 | 16 | }; |
2793 | | |
2794 | 16 | static ei_register_info ei[] = { |
2795 | 16 | { &ei_esp_sequence_analysis_wrong_sequence_number, { "esp.sequence-analysis.wrong-sequence-number", PI_SEQUENCE, PI_WARN, "Wrong Sequence Number", EXPFILL }}, |
2796 | 16 | { &ei_esp_pad_bogus, { "esp.pad.bogus", PI_PROTOCOL, PI_WARN, "Padding MUST increment starting with 1 [RFC 4303 2.4]", EXPFILL }} |
2797 | 16 | }; |
2798 | | |
2799 | 16 | static const value_string esp_proto_type_vals[] = { |
2800 | 16 | { IPSEC_SA_IPV4, "IPv4" }, |
2801 | 16 | { IPSEC_SA_IPV6, "IPv6" }, |
2802 | 16 | { IPSEC_SA_ANY, "Any" }, |
2803 | 16 | { 0x00, NULL } |
2804 | 16 | }; |
2805 | | |
2806 | 16 | static const value_string esp_sn_length_vals[] = { |
2807 | 16 | { IPSEC_SA_SN, "32-bit" }, |
2808 | 16 | { IPSEC_SA_ESN, "64-bit" }, |
2809 | 16 | { 0x00, NULL } |
2810 | 16 | }; |
2811 | | |
2812 | 16 | static uat_field_t esp_uat_flds[] = { |
2813 | 16 | UAT_FLD_VS(uat_esp_sa_records, protocol, "Protocol", esp_proto_type_vals, "Protocol used"), |
2814 | 16 | UAT_FLD_CSTRING(uat_esp_sa_records, srcIP, "Src IP", "Source Address"), |
2815 | 16 | UAT_FLD_CSTRING(uat_esp_sa_records, dstIP, "Dest IP", "Destination Address"), |
2816 | 16 | UAT_FLD_CSTRING(uat_esp_sa_records, spi, "SPI", "SPI"), |
2817 | 16 | UAT_FLD_VS(uat_esp_sa_records, encryption_algo, "Encryption", esp_encryption_type_vals, "Encryption algorithm"), |
2818 | 16 | UAT_FLD_CSTRING(uat_esp_sa_records, encryption_key_string, "Encryption Key", "Encryption Key"), |
2819 | 16 | UAT_FLD_VS(uat_esp_sa_records, authentication_algo, "Authentication", esp_authentication_type_vals, "Authentication algorithm"), |
2820 | 16 | UAT_FLD_CSTRING(uat_esp_sa_records, authentication_key_string, "Authentication Key", "Authentication Key"), |
2821 | 16 | UAT_FLD_VS(uat_esp_sa_records, sn_length, "SN", esp_sn_length_vals, "Sequence Number length"), |
2822 | 16 | UAT_FLD_HEX(uat_esp_sa_records, sn_upper, "ESN High Bits", "Extended Sequence Number upper 32 bits (hex)"), |
2823 | 16 | UAT_END_FIELDS |
2824 | 16 | }; |
2825 | | |
2826 | 16 | static build_valid_func ah_da_build_value[1] = {ah_value}; |
2827 | 16 | static decode_as_value_t ah_da_values = {ah_prompt, 1, ah_da_build_value}; |
2828 | 16 | static decode_as_t ah_da = {"ah", "ip.proto", 1, 0, &ah_da_values, NULL, NULL, |
2829 | 16 | decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL, NULL, NULL }; |
2830 | | |
2831 | 16 | module_t *ah_module; |
2832 | 16 | module_t *esp_module; |
2833 | | |
2834 | 16 | expert_module_t* expert_esp; |
2835 | | |
2836 | 16 | proto_ah = proto_register_protocol("Authentication Header", "AH", "ah"); |
2837 | 16 | proto_register_field_array(proto_ah, hf_ah, array_length(hf_ah)); |
2838 | | |
2839 | 16 | proto_esp = proto_register_protocol("Encapsulating Security Payload", "ESP", "esp"); |
2840 | 16 | proto_register_field_array(proto_esp, hf_esp, array_length(hf_esp)); |
2841 | | |
2842 | 16 | proto_ipcomp = proto_register_protocol("IP Payload Compression", "IPComp", "ipcomp"); |
2843 | 16 | proto_register_field_array(proto_ipcomp, hf_ipcomp, array_length(hf_ipcomp)); |
2844 | | |
2845 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
2846 | | |
2847 | 16 | expert_esp = expert_register_protocol(proto_esp); |
2848 | 16 | expert_register_field_array(expert_esp, ei, array_length(ei)); |
2849 | | |
2850 | 16 | ah_module = prefs_register_protocol_obsolete(proto_ah); |
2851 | | |
2852 | 16 | prefs_register_obsolete_preference(ah_module, "place_ah_payload_in_subtree"); |
2853 | | |
2854 | 16 | esp_module = prefs_register_protocol(proto_esp, NULL); |
2855 | | |
2856 | 16 | prefs_register_bool_preference(esp_module, "enable_null_encryption_decode_heuristic", |
2857 | 16 | "Attempt to detect/decode NULL encrypted ESP payloads", |
2858 | 16 | "This is done only if the Decoding is not SET or the packet does not belong to a SA. " |
2859 | 16 | "Tries ICV lengths of 12, 16, 24, and 32 bytes, checks for valid padding, " |
2860 | 16 | "and attempts to decode based on the derived Next Header field. " |
2861 | 16 | "Does not detect ENCR_NULL_AUTH_AES_GMAC (i.e. assumes 0 length IV)", |
2862 | 16 | &g_esp_enable_null_encryption_decode_heuristic); |
2863 | | |
2864 | 16 | prefs_register_enum_preference(esp_module, "padding", |
2865 | 16 | "Padding type accepted", |
2866 | 16 | "RFC 4303 2.4 requires that padding bytes, if present, MUST " |
2867 | 16 | "be the monotonically increasing sequence 1, 2, 3, …. " |
2868 | 16 | "Some implementations add non-compliant padding. " |
2869 | 16 | "This option determines what, if any, non-compliant padding " |
2870 | 16 | "the NULL encryption heuristic will allow. " |
2871 | 16 | "WARNING: Allowing non-compliant padding can lead to " |
2872 | 16 | "significant false positives.", |
2873 | 16 | &g_esp_padding_type, esp_padding_vals, false); |
2874 | | |
2875 | 16 | prefs_register_bool_preference(esp_module, "do_esp_sequence_analysis", |
2876 | 16 | "Check sequence numbers of ESP frames", |
2877 | 16 | "Check that successive frames increase sequence number by 1 within an SPI. This should work OK when only one host is sending frames on an SPI", |
2878 | 16 | &g_esp_do_sequence_analysis); |
2879 | | |
2880 | 16 | prefs_register_bool_preference(esp_module, "enable_encryption_decode", |
2881 | 16 | "Attempt to detect/decode encrypted ESP payloads", |
2882 | 16 | "Attempt to decode based on the SAD described hereafter.", |
2883 | 16 | &g_esp_enable_encryption_decode); |
2884 | | |
2885 | 16 | prefs_register_bool_preference(esp_module, "enable_authentication_check", |
2886 | 16 | "Attempt to Check ESP Authentication", |
2887 | 16 | "Attempt to Check ESP Authentication based on the SAD described hereafter.", |
2888 | 16 | &g_esp_enable_authentication_check); |
2889 | | |
2890 | 16 | esp_uat = uat_new("ESP SAs", |
2891 | 16 | sizeof(uat_esp_sa_record_t), /* record size */ |
2892 | 16 | "esp_sa", /* filename */ |
2893 | 16 | true, /* from_profile */ |
2894 | 16 | &uat_esp_sa_records, /* data_ptr */ |
2895 | 16 | &num_sa_uat, /* numitems_ptr */ |
2896 | 16 | UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */ |
2897 | 16 | NULL, /* help */ |
2898 | 16 | uat_esp_sa_record_copy_cb, /* copy callback */ |
2899 | 16 | uat_esp_sa_record_update_cb, /* update callback */ |
2900 | 16 | uat_esp_sa_record_free_cb, /* free callback */ |
2901 | 16 | NULL, /* post update callback */ |
2902 | 16 | NULL, /* reset callback */ |
2903 | 16 | esp_uat_flds); /* UAT field definitions */ |
2904 | | |
2905 | 16 | static const char *esp_uat_defaults_[] = { |
2906 | 16 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "32-bit", "0" }; |
2907 | 16 | uat_set_default_values(esp_uat, esp_uat_defaults_); |
2908 | | |
2909 | 16 | prefs_register_uat_preference(esp_module, |
2910 | 16 | "sa_table", |
2911 | 16 | "ESP SAs", |
2912 | 16 | "Preconfigured ESP Security Associations", |
2913 | 16 | esp_uat); |
2914 | | |
2915 | 16 | esp_sequence_analysis_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal); |
2916 | 16 | esp_sequence_analysis_report_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal); |
2917 | 16 | register_cleanup_routine(&ipsec_cleanup_protocol); |
2918 | | |
2919 | 16 | register_dissector("esp", dissect_esp, proto_esp); |
2920 | 16 | register_dissector("ah", dissect_ah, proto_ah); |
2921 | | |
2922 | 16 | ipcomp_handle = register_dissector("ipcomp", dissect_ipcomp, proto_ipcomp); |
2923 | 16 | ah_cap_handle = register_capture_dissector("ah", capture_ah, proto_ah); |
2924 | | |
2925 | 16 | register_decode_as(&ah_da); |
2926 | | |
2927 | 16 | secrets_register_type(SECRETS_TYPE_ESP, esp_secrets_block_callback); |
2928 | 16 | secrets_register_inject_type("ESP", esp_export_secret_count, esp_export_dsb, NULL); |
2929 | | |
2930 | 16 | esp_used_sa_map = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal); |
2931 | 16 | } |
2932 | | |
2933 | | void |
2934 | | proto_reg_handoff_ipsec(void) |
2935 | 16 | { |
2936 | 16 | dissector_handle_t esp_handle, ah_handle; |
2937 | | |
2938 | 16 | data_handle = find_dissector("data"); |
2939 | 16 | ah_handle = find_dissector("ah"); |
2940 | 16 | dissector_add_uint("ip.proto", IP_PROTO_AH, ah_handle); |
2941 | 16 | esp_handle = find_dissector("esp"); |
2942 | 16 | dissector_add_uint("ip.proto", IP_PROTO_ESP, esp_handle); |
2943 | 16 | dissector_add_uint("ip.proto", IP_PROTO_IPCOMP, ipcomp_handle); |
2944 | | |
2945 | 16 | ip_dissector_table = find_dissector_table("ip.proto"); |
2946 | | |
2947 | 16 | capture_dissector_add_uint("ip.proto", IP_PROTO_AH, ah_cap_handle); |
2948 | | |
2949 | 16 | exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_3); |
2950 | 16 | } |
2951 | | |
2952 | | /* |
2953 | | * Editor modelines |
2954 | | * |
2955 | | * Local Variables: |
2956 | | * c-basic-offset: 2 |
2957 | | * tab-width: 8 |
2958 | | * indent-tabs-mode: nil |
2959 | | * End: |
2960 | | * |
2961 | | * ex: set shiftwidth=2 tabstop=8 expandtab: |
2962 | | * :indentSize=2:tabSize=8:noTabs=true: |
2963 | | */ |