]> The Tcpdump Group git mirrors - tcpdump/blob - print-esp.c
From an anonymous SourceForge user: use "u_int32_t", not "uint32_t", to
[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.36 2003-03-19 05:36:22 guy Exp $ (LBL)";
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <string.h>
34
35 #include <tcpdump-stdinc.h>
36
37 #include <stdlib.h>
38
39 #ifdef HAVE_LIBCRYPTO
40 #include <openssl/des.h>
41 #include <openssl/blowfish.h>
42 #ifdef HAVE_OPENSSL_RC5_H
43 #include <openssl/rc5.h>
44 #endif
45 #ifdef HAVE_OPENSSL_CAST_H
46 #include <openssl/cast.h>
47 #endif
48 #endif
49
50 #include <stdio.h>
51
52 #include "ip.h"
53 #include "esp.h"
54 #ifdef INET6
55 #include "ip6.h"
56 #endif
57
58 #if defined(__MINGW32__) || defined(__WATCOMC__)
59 #include "addrinfo.h"
60 extern char *strsep (char **stringp, const char *delim); /* Missing/strsep.c */
61 #endif
62
63 #define AVOID_CHURN 1
64 #include "interface.h"
65 #include "addrtoname.h"
66 #include "extract.h"
67
68 enum cipher { NONE,
69 DESCBC,
70 BLOWFISH,
71 RC5,
72 CAST128,
73 DES3CBC};
74
75
76
77 struct esp_algorithm {
78 const char *name;
79 enum cipher algo;
80 int ivlen;
81 int authlen;
82 int replaysize; /* number of bytes, in excess of 4,
83 may be negative */
84 };
85
86 struct esp_algorithm esp_xforms[]={
87 {"none", NONE, 0, 0, 0},
88 {"des-cbc", DESCBC, 8, 0, 0},
89 {"des-cbc-hmac96", DESCBC, 8, 12, 0},
90 {"blowfish-cbc", BLOWFISH,8, 0, 0},
91 {"blowfish-cbc-hmac96", BLOWFISH,8, 12, 0},
92 {"rc5-cbc", RC5, 8, 0, 0},
93 {"rc5-cbc-hmac96", RC5, 8, 12, 0},
94 {"cast128-cbc", CAST128, 8, 0, 0},
95 {"cast128-cbc-hmac96", CAST128, 8, 12, 0},
96 {"3des-cbc-hmac96", DES3CBC, 8, 12, 0},
97 {NULL, NONE, 0, 0, 0}
98 };
99
100 struct esp_algorithm *null_xf =
101 &esp_xforms[sizeof(esp_xforms)/sizeof(esp_xforms[0]) - 1];
102
103 #ifndef HAVE_SOCKADDR_STORAGE
104 #ifdef INET6
105 struct sockaddr_storage {
106 union {
107 struct sockaddr_in sin;
108 struct sockaddr_in6 sin6;
109 } un;
110 };
111 #else
112 #define sockaddr_storage sockaddr
113 #endif
114 #endif /* HAVE_SOCKADDR_STORAGE */
115
116 struct sa_list {
117 struct sa_list *next;
118 struct sockaddr_storage daddr;
119 u_int32_t spi;
120 struct esp_algorithm *xform;
121 char secret[256]; /* is that big enough for all secrets? */
122 int secretlen;
123 };
124
125 static struct sa_list *sa_list_head=NULL;
126 static struct sa_list *sa_default=NULL;
127
128 static void esp_print_addsa(struct sa_list *sa, int sa_def)
129 {
130 /* copy the "sa" */
131
132 struct sa_list *nsa;
133
134 nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
135 if(nsa == NULL ) {
136 fprintf(stderr, "%s: ran out of memory (%d) to allocate sa structure\n",
137 program_name, sizeof(struct sa_list));
138 exit(2);
139 }
140
141 *nsa = *sa;
142
143 if(sa_def) {
144 sa_default = nsa;
145 }
146
147 nsa->next = sa_list_head;
148 sa_list_head = nsa;
149 }
150
151
152 static int hexdigit(char hex)
153 {
154 if(hex >= '0' && hex <= '9') {
155 return (hex - '0');
156 } else if(hex >= 'A' && hex <= 'F') {
157 return (hex - 'A' + 10);
158 } else if(hex >= 'a' && hex <= 'f') {
159 return (hex - 'a' + 10);
160 } else {
161 printf("invalid hex digit %c in espsecret\n", hex);
162 return 0;
163 }
164 }
165
166 static int hex2byte(char *hexstring)
167 {
168 int byte;
169
170 byte = (hexdigit(hexstring[0]) << 4) +
171 hexdigit(hexstring[1]);
172 return byte;
173 }
174
175 /*
176 * decode the form: SPINUM@IP <tab> ALGONAME:0xsecret
177 *
178 * special form: file /name
179 * causes us to go read from this file instead.
180 *
181 */
182
183 static void esp_print_decode_onesecret(char *line)
184 {
185 struct esp_algorithm *xf;
186 struct sa_list sa1;
187 int sa_def;
188
189 char *spikey;
190 char *decode;
191
192 spikey = strsep(&line, " \t");
193 sa_def = 0;
194 memset(&sa1, 0, sizeof(struct sa_list));
195
196 /* if there is only one token, then it is an algo:key token */
197 if(line == NULL) {
198 decode = spikey;
199 spikey = NULL;
200 /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */
201 /* sa1.spi = 0; */
202 sa_def = 1;
203 } else {
204 decode = line;
205 }
206
207 if(spikey && strcasecmp(spikey, "file")==0) {
208 /* open file and read it */
209 FILE *secretfile;
210 char fileline[1024];
211 char *nl;
212
213 secretfile = fopen(line, FOPEN_READ_TXT);
214 if(secretfile == NULL) {
215 perror(line);
216 exit(3);
217 }
218
219 while(fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
220
221 /* remove newline from the line */
222 nl = strchr(fileline, '\n');
223 if(nl) {
224 *nl = '\0';
225 }
226 if(fileline[0]=='#') continue;
227 if(fileline[0]=='\0') continue;
228
229 esp_print_decode_onesecret(fileline);
230 }
231 fclose(secretfile);
232
233 return;
234 }
235
236 if(spikey) {
237 char *spistr, *foo;
238 u_int32_t spino;
239 struct sockaddr_in *sin;
240 #ifdef INET6
241 struct sockaddr_in6 *sin6;
242 #endif
243
244 spistr = strsep(&spikey, "@");
245
246 spino = strtoul(spistr, &foo, 0);
247 if(spistr == foo || !spikey) {
248 printf("print_esp: failed to decode spi# %s\n", foo);
249 return;
250 }
251
252 sa1.spi = spino;
253
254 sin = (struct sockaddr_in *)&sa1.daddr;
255 #ifdef INET6
256 sin6 = (struct sockaddr_in6 *)&sa1.daddr;
257 if(inet_pton(AF_INET6, spikey, &sin6->sin6_addr) == 1) {
258 #ifdef HAVE_SOCKADDR_SA_LEN
259 sin6->sin6_len = sizeof(struct sockaddr_in6);
260 #endif
261 sin6->sin6_family = AF_INET6;
262 } else
263 #endif
264 if(inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) {
265 #ifdef HAVE_SOCKADDR_SA_LEN
266 sin->sin_len = sizeof(struct sockaddr_in);
267 #endif
268 sin->sin_family = AF_INET;
269 } else {
270 printf("print_esp: can not decode IP# %s\n", spikey);
271 return;
272 }
273 }
274
275 if(decode) {
276 char *colon;
277 char espsecret_key[256];
278 unsigned int len, i;
279
280 /* skip any blank spaces */
281 while(isspace(*decode)) decode++;
282
283 colon = strchr(decode, ':');
284 if(colon == NULL) {
285 printf("failed to decode espsecret: %s\n", decode);
286 return;
287 }
288
289 len = colon - decode;
290 xf = esp_xforms;
291 while(xf->name && strncasecmp(decode, xf->name, len)!=0) {
292 xf++;
293 }
294 if(xf->name == NULL) {
295 printf("failed to find cipher algo %s\n", decode);
296 /* set to NULL transform */
297 return;
298 }
299 sa1.xform = xf;
300
301 colon++;
302 if(colon[0]=='0' && colon[1]=='x') {
303 /* decode some hex! */
304 colon+=2;
305 len = strlen(colon) / 2;
306
307 if(len > 256) {
308 printf("secret is too big: %d\n", len);
309 return;
310 }
311
312 i = 0;
313 while(colon[0] != '\0' && colon[1]!='\0') {
314 espsecret_key[i]=hex2byte(colon);
315 colon+=2;
316 i++;
317 }
318 memcpy(sa1.secret, espsecret_key, i);
319 sa1.secretlen=i;
320 } else {
321 i = strlen(colon);
322 if(i < sizeof(sa1.secret)) {
323 memcpy(sa1.secret, espsecret_key, i);
324 sa1.secretlen = i;
325 } else {
326 memcpy(sa1.secret, espsecret_key, sizeof(sa1.secret));
327 sa1.secretlen = sizeof(sa1.secret);
328 }
329 }
330
331 }
332
333 esp_print_addsa(&sa1, sa_def);
334 }
335
336
337 static void esp_print_decodesecret(void)
338 {
339 char *line;
340 char *p;
341
342 if(espsecret == NULL) {
343 sa_list_head = NULL;
344 return;
345 }
346
347 if(sa_list_head != NULL) {
348 return;
349 }
350
351 p=espsecret;
352
353 while(espsecret && espsecret[0]!='\0') {
354 /* pick out the first line or first thing until a comma */
355 if((line = strsep(&espsecret, "\n,"))==NULL) {
356 line=espsecret;
357 espsecret=NULL;
358 }
359
360 esp_print_decode_onesecret(line);
361 }
362 }
363
364 int
365 esp_print(register const u_char *bp, register const u_char *bp2,
366 int *nhdr, int *padlen)
367 {
368 register const struct newesp *esp;
369 register const u_char *ep;
370 struct ip *ip;
371 struct sa_list *sa = NULL;
372 int espsecret_keylen;
373 #ifdef INET6
374 struct ip6_hdr *ip6 = NULL;
375 #endif
376 int advance;
377 int len;
378 char *secret;
379 int ivlen = 0;
380 u_char *ivoff;
381 #ifdef HAVE_LIBCRYPTO
382 u_char *p;
383 #endif
384
385 esp = (struct newesp *)bp;
386 secret = NULL;
387 advance = 0;
388
389 #if 0
390 /* keep secret out of a register */
391 p = (u_char *)&secret;
392 #endif
393
394 /* 'ep' points to the end of available data. */
395 ep = snapend;
396
397 if ((u_char *)(esp + 1) >= ep) {
398 fputs("[|ESP]", stdout);
399 goto fail;
400 }
401 printf("ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi));
402 printf(",seq=0x%x", EXTRACT_32BITS(&esp->esp_seq));
403 printf(")");
404
405 /* if we don't have decryption key, we can't decrypt this packet. */
406 if(sa_list_head == NULL) {
407 if (!espsecret) {
408 goto fail;
409 }
410 esp_print_decodesecret();
411 }
412
413 if(sa_list_head == NULL) {
414 goto fail;
415 }
416
417 ip = (struct ip *)bp2;
418 switch (IP_V(ip)) {
419 #ifdef INET6
420 case 6:
421 ip6 = (struct ip6_hdr *)bp2;
422 /* we do not attempt to decrypt jumbograms */
423 if (!EXTRACT_16BITS(&ip6->ip6_plen))
424 goto fail;
425 /* if we can't get nexthdr, we do not need to decrypt it */
426 len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen);
427
428 /* see if we can find the SA, and if so, decode it */
429 for (sa = sa_list_head; sa != NULL; sa = sa->next) {
430 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa->daddr;
431 if (sa->spi == ntohl(esp->esp_spi) &&
432 sin6->sin6_family == AF_INET6 &&
433 memcmp(&sin6->sin6_addr, &ip6->ip6_dst,
434 sizeof(struct in6_addr)) == 0) {
435 break;
436 }
437 }
438 break;
439 #endif /*INET6*/
440 case 4:
441 /* nexthdr & padding are in the last fragment */
442 if (EXTRACT_16BITS(&ip->ip_off) & IP_MF)
443 goto fail;
444 len = EXTRACT_16BITS(&ip->ip_len);
445
446 /* see if we can find the SA, and if so, decode it */
447 for (sa = sa_list_head; sa != NULL; sa = sa->next) {
448 struct sockaddr_in *sin = (struct sockaddr_in *)&sa->daddr;
449 if (sa->spi == ntohl(esp->esp_spi) &&
450 sin->sin_family == AF_INET &&
451 sin->sin_addr.s_addr == ip->ip_dst.s_addr) {
452 break;
453 }
454 }
455 break;
456 default:
457 goto fail;
458 }
459
460 /* if we didn't find the specific one, then look for
461 * an unspecified one.
462 */
463 if(sa == NULL) {
464 sa = sa_default;
465 }
466
467 /* if not found fail */
468 if(sa == NULL)
469 goto fail;
470
471 /* if we can't get nexthdr, we do not need to decrypt it */
472 if (ep - bp2 < len)
473 goto fail;
474 if (ep - bp2 > len) {
475 /* FCS included at end of frame (NetBSD 1.6 or later) */
476 ep = bp2 + len;
477 }
478
479 ivoff = (u_char *)(esp + 1) + sa->xform->replaysize;
480 ivlen = sa->xform->ivlen;
481 secret = sa->secret;
482 espsecret_keylen = sa->secretlen;
483
484 switch (sa->xform->algo) {
485 case DESCBC:
486 #ifdef HAVE_LIBCRYPTO
487 {
488 u_char iv[8];
489 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
490 DES_key_schedule schedule;
491 #else
492 des_key_schedule schedule;
493 #endif
494
495 switch (ivlen) {
496 case 4:
497 memcpy(iv, ivoff, 4);
498 memcpy(&iv[4], ivoff, 4);
499 p = &iv[4];
500 *p++ ^= 0xff;
501 *p++ ^= 0xff;
502 *p++ ^= 0xff;
503 *p++ ^= 0xff;
504 break;
505 case 8:
506 memcpy(iv, ivoff, 8);
507 break;
508 default:
509 goto fail;
510 }
511 p = ivoff + ivlen;
512
513 if (espsecret_keylen != 8)
514 goto fail;
515
516 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
517 DES_set_key_unchecked((const_DES_cblock *)secret, &schedule);
518
519 DES_cbc_encrypt((const unsigned char *)p, p,
520 (long)(ep - p), &schedule, (DES_cblock *)iv,
521 DES_DECRYPT);
522
523 #elif OPENSSL_VERSION_NUMBER >= 0x00907000L
524 DES_set_key_unchecked((DES_cblock *)secret, schedule);
525
526 DES_cbc_encrypt((const unsigned char *)p, p,
527 (long)(ep - p), schedule, (DES_cblock *)iv,
528 DES_DECRYPT);
529 #else
530 des_check_key = 0;
531 des_set_key((void *)secret, schedule);
532
533 des_cbc_encrypt((void *)p, (void *)p,
534 (long)(ep - p), schedule, (void *)iv,
535 DES_DECRYPT);
536 #endif
537 advance = ivoff - (u_char *)esp + ivlen;
538 break;
539 }
540 #else
541 goto fail;
542 #endif /*HAVE_LIBCRYPTO*/
543
544 case BLOWFISH:
545 #ifdef HAVE_LIBCRYPTO
546 {
547 BF_KEY schedule;
548
549 if (espsecret_keylen < 5 || espsecret_keylen > 56)
550 goto fail;
551 BF_set_key(&schedule, espsecret_keylen, secret);
552
553 p = ivoff + ivlen;
554 BF_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
555 BF_DECRYPT);
556 advance = ivoff - (u_char *)esp + ivlen;
557 break;
558 }
559 #else
560 goto fail;
561 #endif /*HAVE_LIBCRYPTO*/
562
563 case RC5:
564 #if defined(HAVE_LIBCRYPTO) && defined(HAVE_RC5_H)
565 {
566 RC5_32_KEY schedule;
567
568 if (espsecret_keylen < 5 || espsecret_keylen > 255)
569 goto fail;
570 RC5_32_set_key(&schedule, espsecret_keylen, secret,
571 RC5_16_ROUNDS);
572
573 p = ivoff + ivlen;
574 RC5_32_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
575 RC5_DECRYPT);
576 advance = ivoff - (u_char *)esp + ivlen;
577 break;
578 }
579 #else
580 goto fail;
581 #endif /*HAVE_LIBCRYPTO*/
582
583 case CAST128:
584 #if defined(HAVE_LIBCRYPTO) && defined(HAVE_CAST_H) && !defined(HAVE_BUGGY_CAST128)
585 {
586 CAST_KEY schedule;
587
588 if (espsecret_keylen < 5 || espsecret_keylen > 16)
589 goto fail;
590 CAST_set_key(&schedule, espsecret_keylen, secret);
591
592 p = ivoff + ivlen;
593 CAST_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
594 CAST_DECRYPT);
595 advance = ivoff - (u_char *)esp + ivlen;
596 break;
597 }
598 #else
599 goto fail;
600 #endif /*HAVE_LIBCRYPTO*/
601
602 case DES3CBC:
603 #if defined(HAVE_LIBCRYPTO)
604 {
605 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
606 DES_key_schedule s1, s2, s3;
607
608 if (espsecret_keylen != 24)
609 goto fail;
610 DES_set_odd_parity((DES_cblock *)secret);
611 DES_set_odd_parity((DES_cblock *)(secret + 8));
612 DES_set_odd_parity((DES_cblock *)(secret + 16));
613 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
614 if(DES_set_key_checked((const_DES_cblock *)secret, &s1) != 0) {
615 printf("failed to schedule key 1\n");
616 }
617 if(DES_set_key_checked((const_DES_cblock *)(secret + 8), &s2)!=0) {
618 printf("failed to schedule key 2\n");
619 }
620 if(DES_set_key_checked((const_DES_cblock *)(secret + 16), &s3)!=0) {
621 printf("failed to schedule key 3\n");
622 }
623 #else
624 if(DES_set_key_checked((DES_cblock *)secret, s1) != 0) {
625 printf("failed to schedule key 1\n");
626 }
627 if(DES_set_key_checked((DES_cblock *)(secret + 8), s2)!=0) {
628 printf("failed to schedule key 2\n");
629 }
630 if(DES_set_key_checked((DES_cblock *)(secret + 16), s3)!=0) {
631 printf("failed to schedule key 3\n");
632 }
633 #endif
634
635 p = ivoff + ivlen;
636 DES_ede3_cbc_encrypt((const unsigned char *)p, p,
637 (long)(ep - p),
638 &s1, &s2, &s3,
639 (DES_cblock *)ivoff, DES_DECRYPT);
640 #else
641 des_key_schedule s1, s2, s3;
642
643 if (espsecret_keylen != 24)
644 goto fail;
645 des_check_key = 1;
646 des_set_odd_parity((void *)secret);
647 des_set_odd_parity((void *)(secret + 8));
648 des_set_odd_parity((void *)(secret + 16));
649 if(des_set_key((void *)secret, s1) != 0) {
650 printf("failed to schedule key 1\n");
651 }
652 if(des_set_key((void *)(secret + 8), s2)!=0) {
653 printf("failed to schedule key 2\n");
654 }
655 if(des_set_key((void *)(secret + 16), s3)!=0) {
656 printf("failed to schedule key 3\n");
657 }
658
659 p = ivoff + ivlen;
660 des_ede3_cbc_encrypt((void *)p, (void *)p,
661 (long)(ep - p),
662 s1, s2, s3,
663 (void *)ivoff, DES_DECRYPT);
664 #endif
665 advance = ivoff - (u_char *)esp + ivlen;
666 break;
667 }
668 #else
669 goto fail;
670 #endif /*HAVE_LIBCRYPTO*/
671
672 case NONE:
673 default:
674 advance = sizeof(struct newesp) + sa->xform->replaysize;
675 break;
676 }
677
678 ep = ep - sa->xform->authlen;
679 /* sanity check for pad length */
680 if (ep - bp < *(ep - 2))
681 goto fail;
682
683 if (padlen)
684 *padlen = *(ep - 2) + 2;
685
686 if (nhdr)
687 *nhdr = *(ep - 1);
688
689 printf(": ");
690 return advance;
691
692 fail:
693 if (nhdr)
694 *nhdr = -1;
695 return 65536;
696 }