]> The Tcpdump Group git mirrors - tcpdump/blob - print-esp.c
switch to HAVE_LIBCRYPTO
[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.6 2000-01-15 02:33:06 mcr 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 #include <net/if.h>
41
42 #include <netinet/in.h>
43 #include <netinet/if_ether.h>
44 #include <netinet/in_systm.h>
45 #include <netinet/ip.h>
46 #include <netinet/ip_icmp.h>
47 #include <netinet/ip_var.h>
48 #include <netinet/udp.h>
49 #include <netinet/udp_var.h>
50 #include <netinet/tcp.h>
51
52 #ifdef HAVE_LIBCRYPTO
53 #include <des.h>
54 #include <blowfish.h>
55 #ifdef HAVE_RC5_H
56 #include <rc5.h>
57 #endif
58 #ifdef HAVE_CAST_H
59 #include <cast.h>
60 #endif
61 #endif
62
63 #include <stdio.h>
64
65 #ifdef INET6
66 #include <netinet/ip6.h>
67 #endif
68
69 /* there's no standard definition so we are on our own */
70 struct esp {
71 u_int32_t esp_spi; /* ESP */
72 /*variable size, 32bit bound*/ /* Initialization Vector */
73 /*variable size*/ /* Payload data */
74 /*variable size*/ /* padding */
75 /*8bit*/ /* pad size */
76 /*8bit*/ /* next header */
77 /*8bit*/ /* next header */
78 /*variable size, 32bit bound*/ /* Authentication data (new IPsec) */
79 };
80
81 struct newesp {
82 u_int32_t esp_spi; /* ESP */
83 u_int32_t esp_seq; /* Sequence number */
84 /*variable size*/ /* (IV and) Payload data */
85 /*variable size*/ /* padding */
86 /*8bit*/ /* pad size */
87 /*8bit*/ /* next header */
88 /*8bit*/ /* next header */
89 /*variable size, 32bit bound*/ /* Authentication data */
90 };
91
92 #include "interface.h"
93 #include "addrtoname.h"
94
95 int
96 esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
97 {
98 register const struct esp *esp;
99 register const u_char *ep;
100 u_int32_t spi;
101 enum { NONE, DESCBC, BLOWFISH, RC5, CAST128, DES3CBC } algo = NONE;
102 struct ip *ip = NULL;
103 #ifdef INET6
104 struct ip6_hdr *ip6 = NULL;
105 #endif
106 int advance;
107 int len;
108 char *secret = NULL;
109 int ivlen = 0;
110 u_char *ivoff;
111
112 esp = (struct esp *)bp;
113 spi = (u_int32_t)ntohl(esp->esp_spi);
114
115 /* 'ep' points to the end of avaible data. */
116 ep = snapend;
117
118 if ((u_char *)(esp + 1) >= ep - sizeof(struct esp)) {
119 fputs("[|ESP]", stdout);
120 goto fail;
121 }
122 printf("ESP(spi=%u", spi);
123 printf(",seq=0x%x", (u_int32_t)ntohl(*(u_int32_t *)(esp + 1)));
124 printf(")");
125
126 /* if we don't have decryption key, we can't decrypt this packet. */
127 if (!espsecret)
128 goto fail;
129
130 if (strncmp(espsecret, "des-cbc:", 8) == 0
131 && strlen(espsecret + 8) == 8) {
132 algo = DESCBC;
133 ivlen = 8;
134 secret = espsecret + 8;
135 } else if (strncmp(espsecret, "blowfish-cbc:", 13) == 0) {
136 algo = BLOWFISH;
137 ivlen = 8;
138 secret = espsecret + 13;
139 } else if (strncmp(espsecret, "rc5-cbc:", 8) == 0) {
140 algo = RC5;
141 ivlen = 8;
142 secret = espsecret + 8;
143 } else if (strncmp(espsecret, "cast128-cbc:", 12) == 0) {
144 algo = CAST128;
145 ivlen = 8;
146 secret = espsecret + 12;
147 } else if (strncmp(espsecret, "3des-cbc:", 9) == 0
148 && strlen(espsecret + 9) == 24) {
149 algo = DES3CBC;
150 ivlen = 8;
151 secret = espsecret + 9;
152 } else if (strncmp(espsecret, "none:", 5) == 0) {
153 algo = NONE;
154 ivlen = 0;
155 secret = espsecret + 5;
156 } else if (strlen(espsecret) == 8) {
157 algo = DESCBC;
158 ivlen = 8;
159 secret = espsecret;
160 } else {
161 algo = NONE;
162 ivlen = 0;
163 secret = espsecret;
164 }
165
166 ip = (struct ip *)bp2;
167 switch (ip->ip_v) {
168 #ifdef INET6
169 case 6:
170 ip6 = (struct ip6_hdr *)bp2;
171 ip = NULL;
172 /* we do not attempt to decrypt jumbograms */
173 if (!ntohs(ip6->ip6_plen))
174 goto fail;
175 /* if we can't get nexthdr, we do not need to decrypt it */
176 len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
177 break;
178 #endif /*INET6*/
179 case 4:
180 #ifdef INET6
181 ip6 = NULL;
182 #endif
183 len = ntohs(ip->ip_len);
184 break;
185 default:
186 goto fail;
187 }
188
189 /* if we can't get nexthdr, we do not need to decrypt it */
190 if (ep - bp2 < len)
191 goto fail;
192
193 if (Rflag)
194 ivoff = (u_char *)(esp + 1) + sizeof(u_int32_t);
195 else
196 ivoff = (u_char *)(esp + 1);
197
198 switch (algo) {
199 case DESCBC:
200 #ifdef HAVE_LIBCRYPTO
201 {
202 u_char iv[8];
203 des_key_schedule schedule;
204 u_char *p;
205
206 switch (ivlen) {
207 case 4:
208 memcpy(iv, ivoff, 4);
209 memcpy(&iv[4], ivoff, 4);
210 p = &iv[4];
211 *p++ ^= 0xff;
212 *p++ ^= 0xff;
213 *p++ ^= 0xff;
214 *p++ ^= 0xff;
215 break;
216 case 8:
217 memcpy(iv, ivoff, 8);
218 break;
219 default:
220 goto fail;
221 }
222
223 des_check_key = 0;
224 des_set_key((void *)secret, schedule);
225
226 p = ivoff + ivlen;
227 des_cbc_encrypt((void *)p, (void *)p,
228 (long)(ep - p), schedule, (void *)iv,
229 DES_DECRYPT);
230 advance = ivoff - (u_char *)esp + ivlen;
231 break;
232 }
233 #else
234 goto fail;
235 #endif /*HAVE_LIBCRYPTO*/
236
237 case BLOWFISH:
238 #ifdef HAVE_LIBCRYPTO
239 {
240 BF_KEY schedule;
241 u_char *p;
242
243 BF_set_key(&schedule, strlen(secret), secret);
244
245 p = ivoff + ivlen;
246 BF_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
247 BF_DECRYPT);
248 advance = ivoff - (u_char *)esp + ivlen;
249 break;
250 }
251 #else
252 goto fail;
253 #endif /*HAVE_LIBCRYPTO*/
254
255 case RC5:
256 #if defined(HAVE_LIBCRYPTO) && defined(HAVE_RC5_H)
257 {
258 RC5_32_KEY schedule;
259 u_char *p;
260
261 RC5_32_set_key(&schedule, strlen(secret), secret,
262 RC5_16_ROUNDS);
263
264 p = ivoff + ivlen;
265 RC5_32_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
266 RC5_DECRYPT);
267 advance = ivoff - (u_char *)esp + ivlen;
268 break;
269 }
270 #else
271 goto fail;
272 #endif /*HAVE_LIBCRYPTO*/
273
274 case CAST128:
275 #if defined(HAVE_LIBCRYPTO) && defined(HAVE_CAST_H) && !defined(HAVE_BUGGY_CAST128)
276 {
277 CAST_KEY schedule;
278 u_char *p;
279
280 CAST_set_key(&schedule, strlen(secret), secret);
281
282 p = ivoff + ivlen;
283 CAST_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
284 CAST_DECRYPT);
285 advance = ivoff - (u_char *)esp + ivlen;
286 break;
287 }
288 #else
289 goto fail;
290 #endif /*HAVE_LIBCRYPTO*/
291
292 case DES3CBC:
293 #if defined(HAVE_LIBCRYPTO)
294 {
295 des_key_schedule s1, s2, s3;
296 u_char *p;
297
298 des_check_key = 0;
299 des_set_key((void *)secret, s1);
300 des_set_key((void *)(secret + 8), s2);
301 des_set_key((void *)(secret + 16), s3);
302
303 p = ivoff + ivlen;
304 des_ede3_cbc_encrypt((void *)p, (void *)p,
305 (long)(ep - p), s1, s2, s3, (void *)ivoff, DES_DECRYPT);
306 advance = ivoff - (u_char *)esp + ivlen;
307 break;
308 }
309 #else
310 goto fail;
311 #endif /*HAVE_LIBCRYPTO*/
312
313 case NONE:
314 default:
315 if (Rflag)
316 advance = sizeof(struct esp) + sizeof(u_int32_t);
317 else
318 advance = sizeof(struct esp);
319 break;
320 }
321
322 /* sanity check for pad length */
323 if (ep - bp < *(ep - 2))
324 goto fail;
325
326 if (nhdr)
327 *nhdr = *(ep - 1);
328
329 printf(": ");
330 return advance;
331
332 fail:
333 if (nhdr)
334 *nhdr = -1;
335 return 65536;
336 }