]> The Tcpdump Group git mirrors - tcpdump/blob - print-esp.c
always use u_intXX_t for protocol format declaration. char/short/int may not
[tcpdump] / print-esp.c
1 /* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24 #ifndef lint
25 static const char rcsid[] =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.13 2000-10-03 02:54:58 itojun Exp $ (LBL)";
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <string.h>
34 #include <sys/param.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38
39 #include <net/route.h>
40
41 #include <netinet/in.h>
42
43 #ifdef HAVE_LIBCRYPTO
44 #include <des.h>
45 #include <blowfish.h>
46 #ifdef HAVE_RC5_H
47 #include <rc5.h>
48 #endif
49 #ifdef HAVE_CAST_H
50 #include <cast.h>
51 #endif
52 #endif
53
54 #include <stdio.h>
55
56 #ifdef INET6
57 #include <netinet/ip6.h>
58 #endif
59
60 #include "ip.h"
61
62 /* there's no standard definition so we are on our own */
63 struct esp {
64 u_int32_t esp_spi; /* ESP */
65 /*variable size, 32bit bound*/ /* Initialization Vector */
66 /*variable size*/ /* Payload data */
67 /*variable size*/ /* padding */
68 /*8bit*/ /* pad size */
69 /*8bit*/ /* next header */
70 /*8bit*/ /* next header */
71 /*variable size, 32bit bound*/ /* Authentication data (new IPsec) */
72 };
73
74 struct newesp {
75 u_int32_t esp_spi; /* ESP */
76 u_int32_t esp_seq; /* Sequence number */
77 /*variable size*/ /* (IV and) Payload data */
78 /*variable size*/ /* padding */
79 /*8bit*/ /* pad size */
80 /*8bit*/ /* next header */
81 /*8bit*/ /* next header */
82 /*variable size, 32bit bound*/ /* Authentication data */
83 };
84
85 #include "interface.h"
86 #include "addrtoname.h"
87
88 int
89 esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
90 {
91 register const struct esp *esp;
92 register const u_char *ep;
93 u_int32_t spi;
94 enum { NONE, DESCBC, BLOWFISH, RC5, CAST128, DES3CBC } algo = NONE;
95 struct ip *ip = NULL;
96 #ifdef INET6
97 struct ip6_hdr *ip6 = NULL;
98 #endif
99 int advance;
100 int len;
101 char *secret = NULL;
102 int ivlen = 0;
103 u_char *ivoff;
104
105 esp = (struct esp *)bp;
106 spi = (u_int32_t)ntohl(esp->esp_spi);
107
108 /* 'ep' points to the end of available data. */
109 ep = snapend;
110
111 if ((u_char *)(esp + 1) >= ep - sizeof(struct esp)) {
112 fputs("[|ESP]", stdout);
113 goto fail;
114 }
115 printf("ESP(spi=%u", spi);
116 printf(",seq=0x%x", (u_int32_t)ntohl(*(u_int32_t *)(esp + 1)));
117 printf(")");
118
119 /* if we don't have decryption key, we can't decrypt this packet. */
120 if (!espsecret)
121 goto fail;
122
123 if (strncmp(espsecret, "des-cbc:", 8) == 0
124 && strlen(espsecret + 8) == 8) {
125 algo = DESCBC;
126 ivlen = 8;
127 secret = espsecret + 8;
128 } else if (strncmp(espsecret, "blowfish-cbc:", 13) == 0) {
129 algo = BLOWFISH;
130 ivlen = 8;
131 secret = espsecret + 13;
132 } else if (strncmp(espsecret, "rc5-cbc:", 8) == 0) {
133 algo = RC5;
134 ivlen = 8;
135 secret = espsecret + 8;
136 } else if (strncmp(espsecret, "cast128-cbc:", 12) == 0) {
137 algo = CAST128;
138 ivlen = 8;
139 secret = espsecret + 12;
140 } else if (strncmp(espsecret, "3des-cbc:", 9) == 0
141 && strlen(espsecret + 9) == 24) {
142 algo = DES3CBC;
143 ivlen = 8;
144 secret = espsecret + 9;
145 } else if (strncmp(espsecret, "none:", 5) == 0) {
146 algo = NONE;
147 ivlen = 0;
148 secret = espsecret + 5;
149 } else if (strlen(espsecret) == 8) {
150 algo = DESCBC;
151 ivlen = 8;
152 secret = espsecret;
153 } else {
154 algo = NONE;
155 ivlen = 0;
156 secret = espsecret;
157 }
158
159 ip = (struct ip *)bp2;
160 switch (IP_V(ip)) {
161 #ifdef INET6
162 case 6:
163 ip6 = (struct ip6_hdr *)bp2;
164 ip = NULL;
165 /* we do not attempt to decrypt jumbograms */
166 if (!ntohs(ip6->ip6_plen))
167 goto fail;
168 /* if we can't get nexthdr, we do not need to decrypt it */
169 len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
170 break;
171 #endif /*INET6*/
172 case 4:
173 #ifdef INET6
174 ip6 = NULL;
175 #endif
176 len = ntohs(ip->ip_len);
177 break;
178 default:
179 goto fail;
180 }
181
182 /* if we can't get nexthdr, we do not need to decrypt it */
183 if (ep - bp2 < len)
184 goto fail;
185
186 if (Rflag)
187 ivoff = (u_char *)(esp + 1) + sizeof(u_int32_t);
188 else
189 ivoff = (u_char *)(esp + 1);
190
191 switch (algo) {
192 case DESCBC:
193 #ifdef HAVE_LIBCRYPTO
194 {
195 u_char iv[8];
196 des_key_schedule schedule;
197 u_char *p;
198
199 switch (ivlen) {
200 case 4:
201 memcpy(iv, ivoff, 4);
202 memcpy(&iv[4], ivoff, 4);
203 p = &iv[4];
204 *p++ ^= 0xff;
205 *p++ ^= 0xff;
206 *p++ ^= 0xff;
207 *p++ ^= 0xff;
208 break;
209 case 8:
210 memcpy(iv, ivoff, 8);
211 break;
212 default:
213 goto fail;
214 }
215
216 des_check_key = 0;
217 des_set_key((void *)secret, schedule);
218
219 p = ivoff + ivlen;
220 des_cbc_encrypt((void *)p, (void *)p,
221 (long)(ep - p), schedule, (void *)iv,
222 DES_DECRYPT);
223 advance = ivoff - (u_char *)esp + ivlen;
224 break;
225 }
226 #else
227 goto fail;
228 #endif /*HAVE_LIBCRYPTO*/
229
230 case BLOWFISH:
231 #ifdef HAVE_LIBCRYPTO
232 {
233 BF_KEY schedule;
234 u_char *p;
235
236 BF_set_key(&schedule, strlen(secret), secret);
237
238 p = ivoff + ivlen;
239 BF_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
240 BF_DECRYPT);
241 advance = ivoff - (u_char *)esp + ivlen;
242 break;
243 }
244 #else
245 goto fail;
246 #endif /*HAVE_LIBCRYPTO*/
247
248 case RC5:
249 #if defined(HAVE_LIBCRYPTO) && defined(HAVE_RC5_H)
250 {
251 RC5_32_KEY schedule;
252 u_char *p;
253
254 RC5_32_set_key(&schedule, strlen(secret), secret,
255 RC5_16_ROUNDS);
256
257 p = ivoff + ivlen;
258 RC5_32_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
259 RC5_DECRYPT);
260 advance = ivoff - (u_char *)esp + ivlen;
261 break;
262 }
263 #else
264 goto fail;
265 #endif /*HAVE_LIBCRYPTO*/
266
267 case CAST128:
268 #if defined(HAVE_LIBCRYPTO) && defined(HAVE_CAST_H) && !defined(HAVE_BUGGY_CAST128)
269 {
270 CAST_KEY schedule;
271 u_char *p;
272
273 CAST_set_key(&schedule, strlen(secret), secret);
274
275 p = ivoff + ivlen;
276 CAST_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
277 CAST_DECRYPT);
278 advance = ivoff - (u_char *)esp + ivlen;
279 break;
280 }
281 #else
282 goto fail;
283 #endif /*HAVE_LIBCRYPTO*/
284
285 case DES3CBC:
286 #if defined(HAVE_LIBCRYPTO)
287 {
288 des_key_schedule s1, s2, s3;
289 u_char *p;
290
291 des_check_key = 0;
292 des_set_key((void *)secret, s1);
293 des_set_key((void *)(secret + 8), s2);
294 des_set_key((void *)(secret + 16), s3);
295
296 p = ivoff + ivlen;
297 des_ede3_cbc_encrypt((void *)p, (void *)p,
298 (long)(ep - p), s1, s2, s3, (void *)ivoff, DES_DECRYPT);
299 advance = ivoff - (u_char *)esp + ivlen;
300 break;
301 }
302 #else
303 goto fail;
304 #endif /*HAVE_LIBCRYPTO*/
305
306 case NONE:
307 default:
308 if (Rflag)
309 advance = sizeof(struct esp) + sizeof(u_int32_t);
310 else
311 advance = sizeof(struct esp);
312 break;
313 }
314
315 /* sanity check for pad length */
316 if (ep - bp < *(ep - 2))
317 goto fail;
318
319 if (nhdr)
320 *nhdr = *(ep - 1);
321
322 printf(": ");
323 return advance;
324
325 fail:
326 if (nhdr)
327 *nhdr = -1;
328 return 65536;
329 }