tcpdump(8): Workaround compilation warnings and raise WARNS to 3
[dragonfly.git] / contrib / 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 /* \summary: IPSEC Encapsulating Security Payload (ESP) printer */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <netdissect-stdinc.h>
31
32 #include <string.h>
33 #include <stdlib.h>
34
35 /* Any code in this file that depends on HAVE_LIBCRYPTO depends on
36  * HAVE_OPENSSL_EVP_H too. Undefining the former when the latter isn't defined
37  * is the simplest way of handling the dependency.
38  */
39 #ifdef HAVE_LIBCRYPTO
40 #ifdef HAVE_OPENSSL_EVP_H
41 #include <openssl/evp.h>
42 #else
43 #undef HAVE_LIBCRYPTO
44 #endif
45 #endif
46
47 #include "netdissect.h"
48 #include "strtoaddr.h"
49 #include "extract.h"
50
51 #include "ascii_strcasecmp.h"
52
53 #include "ip.h"
54 #include "ip6.h"
55
56 /*
57  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
58  * All rights reserved.
59  *
60  * Redistribution and use in source and binary forms, with or without
61  * modification, are permitted provided that the following conditions
62  * are met:
63  * 1. Redistributions of source code must retain the above copyright
64  *    notice, this list of conditions and the following disclaimer.
65  * 2. Redistributions in binary form must reproduce the above copyright
66  *    notice, this list of conditions and the following disclaimer in the
67  *    documentation and/or other materials provided with the distribution.
68  * 3. Neither the name of the project nor the names of its contributors
69  *    may be used to endorse or promote products derived from this software
70  *    without specific prior written permission.
71  *
72  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
73  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
74  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
75  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
76  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
77  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
78  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
79  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
80  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
81  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82  * SUCH DAMAGE.
83  */
84
85 /*
86  * RFC1827/2406 Encapsulated Security Payload.
87  */
88
89 struct newesp {
90         uint32_t        esp_spi;        /* ESP */
91         uint32_t        esp_seq;        /* Sequence number */
92         /*variable size*/               /* (IV and) Payload data */
93         /*variable size*/               /* padding */
94         /*8bit*/                        /* pad size */
95         /*8bit*/                        /* next header */
96         /*8bit*/                        /* next header */
97         /*variable size, 32bit bound*/  /* Authentication data */
98 };
99
100 #ifdef HAVE_LIBCRYPTO
101 union inaddr_u {
102         struct in_addr in4;
103         struct in6_addr in6;
104 };
105 struct sa_list {
106         struct sa_list  *next;
107         u_int           daddr_version;
108         union inaddr_u  daddr;
109         uint32_t        spi;          /* if == 0, then IKEv2 */
110         int             initiator;
111         u_char          spii[8];      /* for IKEv2 */
112         u_char          spir[8];
113         const EVP_CIPHER *evp;
114         int             ivlen;
115         int             authlen;
116         u_char          authsecret[256];
117         int             authsecret_len;
118         u_char          secret[256];  /* is that big enough for all secrets? */
119         int             secretlen;
120 };
121
122 #ifndef HAVE_EVP_CIPHER_CTX_NEW
123 /*
124  * Allocate an EVP_CIPHER_CTX.
125  * Used if we have an older version of OpenSSL that doesn't provide
126  * routines to allocate and free them.
127  */
128 static EVP_CIPHER_CTX *
129 EVP_CIPHER_CTX_new(void)
130 {
131         EVP_CIPHER_CTX *ctx;
132
133         ctx = malloc(sizeof(*ctx));
134         if (ctx == NULL)
135                 return (NULL);
136         memset(ctx, 0, sizeof(*ctx));
137         return (ctx);
138 }
139
140 static void
141 EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
142 {
143         EVP_CIPHER_CTX_cleanup(ctx);
144         free(ctx);
145 }
146 #endif
147
148 #ifdef HAVE_EVP_CIPHERINIT_EX
149 /*
150  * Initialize the cipher by calling EVP_CipherInit_ex(), because
151  * calling EVP_CipherInit() will reset the cipher context, clearing
152  * the cipher, so calling it twice, with the second call having a
153  * null cipher, will clear the already-set cipher.  EVP_CipherInit_ex(),
154  * however, won't reset the cipher context, so you can use it to specify
155  * the IV oin a second call after a first call to EVP_CipherInit_ex()
156  * to set the cipher and the key.
157  *
158  * XXX - is there some reason why we need to make two calls?
159  */
160 static int
161 set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
162                       const unsigned char *key,
163                       const unsigned char *iv, int enc)
164 {
165         return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);
166 }
167 #else
168 /*
169  * Initialize the cipher by calling EVP_CipherInit(), because we don't
170  * have EVP_CipherInit_ex(); we rely on it not trashing the context.
171  */
172 static int
173 set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
174                       const unsigned char *key,
175                       const unsigned char *iv, int enc)
176 {
177         return EVP_CipherInit(ctx, cipher, key, iv, enc);
178 }
179 #endif
180
181 /*
182  * this will adjust ndo_packetp and ndo_snapend to new buffer!
183  */
184 USES_APPLE_DEPRECATED_API
185 int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
186                                       int initiator,
187                                       u_char spii[8], u_char spir[8],
188                                       const u_char *buf, const u_char *end)
189 {
190         struct sa_list *sa;
191         const u_char *iv;
192         unsigned int len;
193         EVP_CIPHER_CTX *ctx;
194         unsigned int block_size, buffer_size;
195         u_char *input_buffer, *output_buffer;
196
197         /* initiator arg is any non-zero value */
198         if(initiator) initiator=1;
199
200         /* see if we can find the SA, and if so, decode it */
201         for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
202                 if (sa->spi == 0
203                     && initiator == sa->initiator
204                     && memcmp(spii, sa->spii, 8) == 0
205                     && memcmp(spir, sa->spir, 8) == 0)
206                         break;
207         }
208
209         if(sa == NULL) return 0;
210         if(sa->evp == NULL) return 0;
211
212         /*
213          * remove authenticator, and see if we still have something to
214          * work with
215          */
216         end = end - sa->authlen;
217         iv  = buf;
218         buf = buf + sa->ivlen;
219         len = end-buf;
220
221         if(end <= buf) return 0;
222
223         ctx = EVP_CIPHER_CTX_new();
224         if (ctx == NULL)
225                 return 0;
226         if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL, 0) < 0)
227                 (*ndo->ndo_warning)(ndo, "espkey init failed");
228         set_cipher_parameters(ctx, NULL, NULL, iv, 0);
229         /*
230          * Allocate buffers for the encrypted and decrypted data.
231          * Both buffers' sizes must be a multiple of the cipher block
232          * size, and the output buffer must be separate from the input
233          * buffer.
234          */
235         block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
236         buffer_size = len + (block_size - len % block_size);
237
238         /*
239          * Attempt to allocate the input buffer.
240          */
241         input_buffer = (u_char *)malloc(buffer_size);
242         if (input_buffer == NULL) {
243                 EVP_CIPHER_CTX_free(ctx);
244                 (*ndo->ndo_error)(ndo, "can't allocate memory for encrypted data buffer");
245         }
246         /*
247          * Copy the input data to the encrypted data buffer, and pad it
248          * with zeroes.
249          */
250         memcpy(input_buffer, buf, len);
251         memset(input_buffer + len, 0, buffer_size - len);
252
253         /*
254          * Attempt to allocate the output buffer.
255          */
256         output_buffer = (u_char *)malloc(buffer_size);
257         if (output_buffer == NULL) {
258                 free(input_buffer);
259                 EVP_CIPHER_CTX_free(ctx);
260                 (*ndo->ndo_error)(ndo, "can't allocate memory for decryption buffer");
261         }
262         EVP_Cipher(ctx, output_buffer, input_buffer, len);
263         EVP_CIPHER_CTX_free(ctx);
264
265         /*
266          * XXX - of course this is wrong, because buf is a const buffer,
267          * but changing this would require a more complicated fix.
268          */
269         memcpy(__DECONST(u_char *, buf), output_buffer, len);
270         free(input_buffer);
271         free(output_buffer);
272
273         ndo->ndo_packetp = buf;
274         ndo->ndo_snapend = end;
275
276         return 1;
277 }
278 USES_APPLE_RST
279
280 static void esp_print_addsa(netdissect_options *ndo,
281                             struct sa_list *sa, int sa_def)
282 {
283         /* copy the "sa" */
284
285         struct sa_list *nsa;
286
287         nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
288         if (nsa == NULL)
289                 (*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure");
290
291         *nsa = *sa;
292
293         if (sa_def)
294                 ndo->ndo_sa_default = nsa;
295
296         nsa->next = ndo->ndo_sa_list_head;
297         ndo->ndo_sa_list_head = nsa;
298 }
299
300
301 static u_int hexdigit(netdissect_options *ndo, char hex)
302 {
303         if (hex >= '0' && hex <= '9')
304                 return (hex - '0');
305         else if (hex >= 'A' && hex <= 'F')
306                 return (hex - 'A' + 10);
307         else if (hex >= 'a' && hex <= 'f')
308                 return (hex - 'a' + 10);
309         else {
310                 (*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex);
311         }
312 }
313
314 static u_int hex2byte(netdissect_options *ndo, char *hexstring)
315 {
316         u_int byte;
317
318         byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]);
319         return byte;
320 }
321
322 /*
323  * returns size of binary, 0 on failure.
324  */
325 static
326 int espprint_decode_hex(netdissect_options *ndo,
327                         u_char *binbuf, unsigned int binbuf_len,
328                         char *hex)
329 {
330         unsigned int len;
331         int i;
332
333         len = strlen(hex) / 2;
334
335         if (len > binbuf_len) {
336                 (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len);
337                 return 0;
338         }
339
340         i = 0;
341         while (hex[0] != '\0' && hex[1]!='\0') {
342                 binbuf[i] = hex2byte(ndo, hex);
343                 hex += 2;
344                 i++;
345         }
346
347         return i;
348 }
349
350 /*
351  * decode the form:    SPINUM@IP <tab> ALGONAME:0xsecret
352  */
353
354 USES_APPLE_DEPRECATED_API
355 static int
356 espprint_decode_encalgo(netdissect_options *ndo,
357                         char *decode, struct sa_list *sa)
358 {
359         size_t i;
360         const EVP_CIPHER *evp;
361         int authlen = 0;
362         char *colon, *p;
363
364         colon = strchr(decode, ':');
365         if (colon == NULL) {
366                 (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
367                 return 0;
368         }
369         *colon = '\0';
370
371         if (strlen(decode) > strlen("-hmac96") &&
372             !strcmp(decode + strlen(decode) - strlen("-hmac96"),
373                     "-hmac96")) {
374                 p = strstr(decode, "-hmac96");
375                 *p = '\0';
376                 authlen = 12;
377         }
378         if (strlen(decode) > strlen("-cbc") &&
379             !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) {
380                 p = strstr(decode, "-cbc");
381                 *p = '\0';
382         }
383         evp = EVP_get_cipherbyname(decode);
384
385         if (!evp) {
386                 (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
387                 sa->evp = NULL;
388                 sa->authlen = 0;
389                 sa->ivlen = 0;
390                 return 0;
391         }
392
393         sa->evp = evp;
394         sa->authlen = authlen;
395         sa->ivlen = EVP_CIPHER_iv_length(evp);
396
397         colon++;
398         if (colon[0] == '0' && colon[1] == 'x') {
399                 /* decode some hex! */
400
401                 colon += 2;
402                 sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon);
403                 if(sa->secretlen == 0) return 0;
404         } else {
405                 i = strlen(colon);
406
407                 if (i < sizeof(sa->secret)) {
408                         memcpy(sa->secret, colon, i);
409                         sa->secretlen = i;
410                 } else {
411                         memcpy(sa->secret, colon, sizeof(sa->secret));
412                         sa->secretlen = sizeof(sa->secret);
413                 }
414         }
415
416         return 1;
417 }
418 USES_APPLE_RST
419
420 /*
421  * for the moment, ignore the auth algorithm, just hard code the authenticator
422  * length. Need to research how openssl looks up HMAC stuff.
423  */
424 static int
425 espprint_decode_authalgo(netdissect_options *ndo,
426                          char *decode, struct sa_list *sa)
427 {
428         char *colon;
429
430         colon = strchr(decode, ':');
431         if (colon == NULL) {
432                 (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
433                 return 0;
434         }
435         *colon = '\0';
436
437         if(ascii_strcasecmp(colon,"sha1") == 0 ||
438            ascii_strcasecmp(colon,"md5") == 0) {
439                 sa->authlen = 12;
440         }
441         return 1;
442 }
443
444 static void esp_print_decode_ikeline(netdissect_options *ndo, char *line,
445                                      const char *file, int lineno)
446 {
447         /* it's an IKEv2 secret, store it instead */
448         struct sa_list sa1;
449
450         char *init;
451         char *icookie, *rcookie;
452         int   ilen, rlen;
453         char *authkey;
454         char *enckey;
455
456         init = strsep(&line, " \t");
457         icookie = strsep(&line, " \t");
458         rcookie = strsep(&line, " \t");
459         authkey = strsep(&line, " \t");
460         enckey  = strsep(&line, " \t");
461
462         /* if any fields are missing */
463         if(!init || !icookie || !rcookie || !authkey || !enckey) {
464                 (*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u",
465                                     file, lineno);
466
467                 return;
468         }
469
470         ilen = strlen(icookie);
471         rlen = strlen(rcookie);
472
473         if((init[0]!='I' && init[0]!='R')
474            || icookie[0]!='0' || icookie[1]!='x'
475            || rcookie[0]!='0' || rcookie[1]!='x'
476            || ilen!=18
477            || rlen!=18) {
478                 (*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.",
479                                     file, lineno);
480
481                 (*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)",
482                                     init, icookie, ilen, rcookie, rlen);
483
484                 return;
485         }
486
487         sa1.spi = 0;
488         sa1.initiator = (init[0] == 'I');
489         if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8)
490                 return;
491
492         if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8)
493                 return;
494
495         if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return;
496
497         if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return;
498
499         esp_print_addsa(ndo, &sa1, FALSE);
500 }
501
502 /*
503  *
504  * special form: file /name
505  * causes us to go read from this file instead.
506  *
507  */
508 static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
509                                        const char *file, int lineno)
510 {
511         struct sa_list sa1;
512         int sa_def;
513
514         char *spikey;
515         char *decode;
516
517         spikey = strsep(&line, " \t");
518         sa_def = 0;
519         memset(&sa1, 0, sizeof(struct sa_list));
520
521         /* if there is only one token, then it is an algo:key token */
522         if (line == NULL) {
523                 decode = spikey;
524                 spikey = NULL;
525                 /* sa1.daddr.version = 0; */
526                 /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */
527                 /* sa1.spi = 0; */
528                 sa_def    = 1;
529         } else
530                 decode = line;
531
532         if (spikey && ascii_strcasecmp(spikey, "file") == 0) {
533                 /* open file and read it */
534                 FILE *secretfile;
535                 char  fileline[1024];
536                 int   subfile_lineno=0;
537                 char  *nl;
538                 char *filename = line;
539
540                 secretfile = fopen(filename, FOPEN_READ_TXT);
541                 if (secretfile == NULL) {
542                         (*ndo->ndo_error)(ndo, "print_esp: can't open %s: %s\n",
543                             filename, strerror(errno));
544                 }
545
546                 while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
547                         subfile_lineno++;
548                         /* remove newline from the line */
549                         nl = strchr(fileline, '\n');
550                         if (nl)
551                                 *nl = '\0';
552                         if (fileline[0] == '#') continue;
553                         if (fileline[0] == '\0') continue;
554
555                         esp_print_decode_onesecret(ndo, fileline, filename, subfile_lineno);
556                 }
557                 fclose(secretfile);
558
559                 return;
560         }
561
562         if (spikey && ascii_strcasecmp(spikey, "ikev2") == 0) {
563                 esp_print_decode_ikeline(ndo, line, file, lineno);
564                 return;
565         }
566
567         if (spikey) {
568
569                 char *spistr, *foo;
570                 uint32_t spino;
571
572                 spistr = strsep(&spikey, "@");
573                 if (spistr == NULL) {
574                         (*ndo->ndo_warning)(ndo, "print_esp: failed to find the @ token");
575                         return;
576                 }
577
578                 spino = strtoul(spistr, &foo, 0);
579                 if (spistr == foo || !spikey) {
580                         (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo);
581                         return;
582                 }
583
584                 sa1.spi = spino;
585
586                 if (strtoaddr6(spikey, &sa1.daddr.in6) == 1) {
587                         sa1.daddr_version = 6;
588                 } else if (strtoaddr(spikey, &sa1.daddr.in4) == 1) {
589                         sa1.daddr_version = 4;
590                 } else {
591                         (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey);
592                         return;
593                 }
594         }
595
596         if (decode) {
597                 /* skip any blank spaces */
598                 while (isspace((unsigned char)*decode))
599                         decode++;
600
601                 if(!espprint_decode_encalgo(ndo, decode, &sa1)) {
602                         return;
603                 }
604         }
605
606         esp_print_addsa(ndo, &sa1, sa_def);
607 }
608
609 USES_APPLE_DEPRECATED_API
610 static void esp_init(netdissect_options *ndo _U_)
611 {
612         /*
613          * 0.9.6 doesn't appear to define OPENSSL_API_COMPAT, so
614          * we check whether it's undefined or it's less than the
615          * value for 1.1.0.
616          */
617 #if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < 0x10100000L
618         OpenSSL_add_all_algorithms();
619 #endif
620         EVP_add_cipher_alias(SN_des_ede3_cbc, "3des");
621 }
622 USES_APPLE_RST
623
624 void esp_print_decodesecret(netdissect_options *ndo)
625 {
626         char *line;
627         char *p;
628         static int initialized = 0;
629
630         if (!initialized) {
631                 esp_init(ndo);
632                 initialized = 1;
633         }
634
635         p = ndo->ndo_espsecret;
636
637         while (p && p[0] != '\0') {
638                 /* pick out the first line or first thing until a comma */
639                 if ((line = strsep(&p, "\n,")) == NULL) {
640                         line = p;
641                         p = NULL;
642                 }
643
644                 esp_print_decode_onesecret(ndo, line, "cmdline", 0);
645         }
646
647         ndo->ndo_espsecret = NULL;
648 }
649
650 #endif
651
652 #ifdef HAVE_LIBCRYPTO
653 USES_APPLE_DEPRECATED_API
654 #endif
655 int
656 esp_print(netdissect_options *ndo,
657           const u_char *bp, const int length, const u_char *bp2
658 #ifndef HAVE_LIBCRYPTO
659         _U_
660 #endif
661         ,
662         int *nhdr
663 #ifndef HAVE_LIBCRYPTO
664         _U_
665 #endif
666         ,
667         int *padlen
668 #ifndef HAVE_LIBCRYPTO
669         _U_
670 #endif
671         )
672 {
673         register const struct newesp *esp;
674         register const u_char *ep;
675 #ifdef HAVE_LIBCRYPTO
676         const struct ip *ip;
677         struct sa_list *sa = NULL;
678         const struct ip6_hdr *ip6 = NULL;
679         int advance;
680         int len;
681         u_char *secret;
682         int ivlen = 0;
683         const u_char *ivoff;
684         const u_char *p;
685         EVP_CIPHER_CTX *ctx;
686         unsigned int block_size, buffer_size;
687         u_char *input_buffer, *output_buffer;
688 #endif
689
690         esp = (const struct newesp *)bp;
691
692 #ifdef HAVE_LIBCRYPTO
693         secret = NULL;
694         advance = 0;
695 #endif
696
697 #if 0
698         /* keep secret out of a register */
699         p = (u_char *)&secret;
700 #endif
701
702         /* 'ep' points to the end of available data. */
703         ep = ndo->ndo_snapend;
704
705         if ((const u_char *)(esp + 1) >= ep) {
706                 ND_PRINT((ndo, "[|ESP]"));
707                 goto fail;
708         }
709         ND_PRINT((ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi)));
710         ND_PRINT((ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq)));
711         ND_PRINT((ndo, ", length %u", length));
712
713 #ifndef HAVE_LIBCRYPTO
714         goto fail;
715 #else
716         /* initiailize SAs */
717         if (ndo->ndo_sa_list_head == NULL) {
718                 if (!ndo->ndo_espsecret)
719                         goto fail;
720
721                 esp_print_decodesecret(ndo);
722         }
723
724         if (ndo->ndo_sa_list_head == NULL)
725                 goto fail;
726
727         ip = (const struct ip *)bp2;
728         switch (IP_V(ip)) {
729         case 6:
730                 ip6 = (const struct ip6_hdr *)bp2;
731                 /* we do not attempt to decrypt jumbograms */
732                 if (!EXTRACT_16BITS(&ip6->ip6_plen))
733                         goto fail;
734                 /* if we can't get nexthdr, we do not need to decrypt it */
735                 len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen);
736
737                 /* see if we can find the SA, and if so, decode it */
738                 for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
739                         if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
740                             sa->daddr_version == 6 &&
741                             UNALIGNED_MEMCMP(&sa->daddr.in6, &ip6->ip6_dst,
742                                    sizeof(struct in6_addr)) == 0) {
743                                 break;
744                         }
745                 }
746                 break;
747         case 4:
748                 /* nexthdr & padding are in the last fragment */
749                 if (EXTRACT_16BITS(&ip->ip_off) & IP_MF)
750                         goto fail;
751                 len = EXTRACT_16BITS(&ip->ip_len);
752
753                 /* see if we can find the SA, and if so, decode it */
754                 for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
755                         if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
756                             sa->daddr_version == 4 &&
757                             UNALIGNED_MEMCMP(&sa->daddr.in4, &ip->ip_dst,
758                                    sizeof(struct in_addr)) == 0) {
759                                 break;
760                         }
761                 }
762                 break;
763         default:
764                 goto fail;
765         }
766
767         /* if we didn't find the specific one, then look for
768          * an unspecified one.
769          */
770         if (sa == NULL)
771                 sa = ndo->ndo_sa_default;
772
773         /* if not found fail */
774         if (sa == NULL)
775                 goto fail;
776
777         /* if we can't get nexthdr, we do not need to decrypt it */
778         if (ep - bp2 < len)
779                 goto fail;
780         if (ep - bp2 > len) {
781                 /* FCS included at end of frame (NetBSD 1.6 or later) */
782                 ep = bp2 + len;
783         }
784
785         /* pointer to the IV, if there is one */
786         ivoff = (const u_char *)(esp + 1) + 0;
787         /* length of the IV, if there is one; 0, if there isn't */
788         ivlen = sa->ivlen;
789         secret = sa->secret;
790         ep = ep - sa->authlen;
791
792         if (sa->evp) {
793                 ctx = EVP_CIPHER_CTX_new();
794                 if (ctx != NULL) {
795                         if (set_cipher_parameters(ctx, sa->evp, secret, NULL, 0) < 0)
796                                 (*ndo->ndo_warning)(ndo, "espkey init failed");
797
798                         p = ivoff;
799                         set_cipher_parameters(ctx, NULL, NULL, p, 0);
800                         len = ep - (p + ivlen);
801
802                         /*
803                          * Allocate buffers for the encrypted and decrypted
804                          * data.  Both buffers' sizes must be a multiple of
805                          * the cipher block size, and the output buffer must
806                          * be separate from the input buffer.
807                          */
808                         block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
809                         buffer_size = len + (block_size - len % block_size);
810
811                         /*
812                          * Attempt to allocate the input buffer.
813                          */
814                         input_buffer = (u_char *)malloc(buffer_size);
815                         if (input_buffer == NULL) {
816                                 EVP_CIPHER_CTX_free(ctx);
817                                 (*ndo->ndo_error)(ndo, "can't allocate memory for encrypted data buffer");
818                         }
819                         /*
820                          * Copy the input data to the encrypted data buffer,
821                          * and pad it with zeroes.
822                          */
823                         memcpy(input_buffer, p + ivlen, len);
824                         memset(input_buffer + len, 0, buffer_size - len);
825
826                         /*
827                          * Attempt to allocate the output buffer.
828                          */
829                         output_buffer = (u_char *)malloc(buffer_size);
830                         if (output_buffer == NULL) {
831                                 free(input_buffer);
832                                 EVP_CIPHER_CTX_free(ctx);
833                                 (*ndo->ndo_error)(ndo, "can't allocate memory for decryption buffer");
834                         }
835
836                         EVP_Cipher(ctx, output_buffer, input_buffer, len);
837                         free(input_buffer);
838                         EVP_CIPHER_CTX_free(ctx);
839                         /*
840                          * XXX - of course this is wrong, because buf is a
841                          * const buffer, but changing this would require a
842                          * more complicated fix.
843                          */
844                         memcpy(__DECONST(u_char *, p + ivlen), output_buffer, len);
845                         free(output_buffer);
846                         advance = ivoff - (const u_char *)esp + ivlen;
847                 } else
848                         advance = sizeof(struct newesp);
849         } else
850                 advance = sizeof(struct newesp);
851
852         /* sanity check for pad length */
853         if (ep - bp < *(ep - 2))
854                 goto fail;
855
856         if (padlen)
857                 *padlen = *(ep - 2) + 2;
858
859         if (nhdr)
860                 *nhdr = *(ep - 1);
861
862         ND_PRINT((ndo, ": "));
863         return advance;
864 #endif
865
866 fail:
867         return -1;
868 }
869 #ifdef HAVE_LIBCRYPTO
870 USES_APPLE_RST
871 #endif
872
873 /*
874  * Local Variables:
875  * c-style: whitesmith
876  * c-basic-offset: 8
877  * End:
878  */