]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-esp.c
Upgrade to OpenSSH 7.5p1.
[FreeBSD/FreeBSD.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 /*
149  * this will adjust ndo_packetp and ndo_snapend to new buffer!
150  */
151 USES_APPLE_DEPRECATED_API
152 int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
153                                       int initiator,
154                                       u_char spii[8], u_char spir[8],
155                                       const u_char *buf, const u_char *end)
156 {
157         struct sa_list *sa;
158         const u_char *iv;
159         int len;
160         EVP_CIPHER_CTX *ctx;
161
162         /* initiator arg is any non-zero value */
163         if(initiator) initiator=1;
164
165         /* see if we can find the SA, and if so, decode it */
166         for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
167                 if (sa->spi == 0
168                     && initiator == sa->initiator
169                     && memcmp(spii, sa->spii, 8) == 0
170                     && memcmp(spir, sa->spir, 8) == 0)
171                         break;
172         }
173
174         if(sa == NULL) return 0;
175         if(sa->evp == NULL) return 0;
176
177         /*
178          * remove authenticator, and see if we still have something to
179          * work with
180          */
181         end = end - sa->authlen;
182         iv  = buf;
183         buf = buf + sa->ivlen;
184         len = end-buf;
185
186         if(end <= buf) return 0;
187
188         ctx = EVP_CIPHER_CTX_new();
189         if (ctx == NULL)
190                 return 0;
191         if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0)
192                 (*ndo->ndo_warning)(ndo, "espkey init failed");
193         EVP_CipherInit(ctx, NULL, NULL, iv, 0);
194         EVP_Cipher(ctx, __DECONST(u_char *, buf), buf, len);
195         EVP_CIPHER_CTX_free(ctx);
196
197         ndo->ndo_packetp = buf;
198         ndo->ndo_snapend = end;
199
200         return 1;
201
202 }
203 USES_APPLE_RST
204
205 static void esp_print_addsa(netdissect_options *ndo,
206                             struct sa_list *sa, int sa_def)
207 {
208         /* copy the "sa" */
209
210         struct sa_list *nsa;
211
212         nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
213         if (nsa == NULL)
214                 (*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure");
215
216         *nsa = *sa;
217
218         if (sa_def)
219                 ndo->ndo_sa_default = nsa;
220
221         nsa->next = ndo->ndo_sa_list_head;
222         ndo->ndo_sa_list_head = nsa;
223 }
224
225
226 static u_int hexdigit(netdissect_options *ndo, char hex)
227 {
228         if (hex >= '0' && hex <= '9')
229                 return (hex - '0');
230         else if (hex >= 'A' && hex <= 'F')
231                 return (hex - 'A' + 10);
232         else if (hex >= 'a' && hex <= 'f')
233                 return (hex - 'a' + 10);
234         else {
235                 (*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex);
236                 return 0;
237         }
238 }
239
240 static u_int hex2byte(netdissect_options *ndo, char *hexstring)
241 {
242         u_int byte;
243
244         byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]);
245         return byte;
246 }
247
248 /*
249  * returns size of binary, 0 on failure.
250  */
251 static
252 int espprint_decode_hex(netdissect_options *ndo,
253                         u_char *binbuf, unsigned int binbuf_len,
254                         char *hex)
255 {
256         unsigned int len;
257         int i;
258
259         len = strlen(hex) / 2;
260
261         if (len > binbuf_len) {
262                 (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len);
263                 return 0;
264         }
265
266         i = 0;
267         while (hex[0] != '\0' && hex[1]!='\0') {
268                 binbuf[i] = hex2byte(ndo, hex);
269                 hex += 2;
270                 i++;
271         }
272
273         return i;
274 }
275
276 /*
277  * decode the form:    SPINUM@IP <tab> ALGONAME:0xsecret
278  */
279
280 USES_APPLE_DEPRECATED_API
281 static int
282 espprint_decode_encalgo(netdissect_options *ndo,
283                         char *decode, struct sa_list *sa)
284 {
285         size_t i;
286         const EVP_CIPHER *evp;
287         int authlen = 0;
288         char *colon, *p;
289
290         colon = strchr(decode, ':');
291         if (colon == NULL) {
292                 (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
293                 return 0;
294         }
295         *colon = '\0';
296
297         if (strlen(decode) > strlen("-hmac96") &&
298             !strcmp(decode + strlen(decode) - strlen("-hmac96"),
299                     "-hmac96")) {
300                 p = strstr(decode, "-hmac96");
301                 *p = '\0';
302                 authlen = 12;
303         }
304         if (strlen(decode) > strlen("-cbc") &&
305             !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) {
306                 p = strstr(decode, "-cbc");
307                 *p = '\0';
308         }
309         evp = EVP_get_cipherbyname(decode);
310
311         if (!evp) {
312                 (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
313                 sa->evp = NULL;
314                 sa->authlen = 0;
315                 sa->ivlen = 0;
316                 return 0;
317         }
318
319         sa->evp = evp;
320         sa->authlen = authlen;
321         sa->ivlen = EVP_CIPHER_iv_length(evp);
322
323         colon++;
324         if (colon[0] == '0' && colon[1] == 'x') {
325                 /* decode some hex! */
326
327                 colon += 2;
328                 sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon);
329                 if(sa->secretlen == 0) return 0;
330         } else {
331                 i = strlen(colon);
332
333                 if (i < sizeof(sa->secret)) {
334                         memcpy(sa->secret, colon, i);
335                         sa->secretlen = i;
336                 } else {
337                         memcpy(sa->secret, colon, sizeof(sa->secret));
338                         sa->secretlen = sizeof(sa->secret);
339                 }
340         }
341
342         return 1;
343 }
344 USES_APPLE_RST
345
346 /*
347  * for the moment, ignore the auth algorith, just hard code the authenticator
348  * length. Need to research how openssl looks up HMAC stuff.
349  */
350 static int
351 espprint_decode_authalgo(netdissect_options *ndo,
352                          char *decode, struct sa_list *sa)
353 {
354         char *colon;
355
356         colon = strchr(decode, ':');
357         if (colon == NULL) {
358                 (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
359                 return 0;
360         }
361         *colon = '\0';
362
363         if(ascii_strcasecmp(colon,"sha1") == 0 ||
364            ascii_strcasecmp(colon,"md5") == 0) {
365                 sa->authlen = 12;
366         }
367         return 1;
368 }
369
370 static void esp_print_decode_ikeline(netdissect_options *ndo, char *line,
371                                      const char *file, int lineno)
372 {
373         /* it's an IKEv2 secret, store it instead */
374         struct sa_list sa1;
375
376         char *init;
377         char *icookie, *rcookie;
378         int   ilen, rlen;
379         char *authkey;
380         char *enckey;
381
382         init = strsep(&line, " \t");
383         icookie = strsep(&line, " \t");
384         rcookie = strsep(&line, " \t");
385         authkey = strsep(&line, " \t");
386         enckey  = strsep(&line, " \t");
387
388         /* if any fields are missing */
389         if(!init || !icookie || !rcookie || !authkey || !enckey) {
390                 (*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u",
391                                     file, lineno);
392
393                 return;
394         }
395
396         ilen = strlen(icookie);
397         rlen = strlen(rcookie);
398
399         if((init[0]!='I' && init[0]!='R')
400            || icookie[0]!='0' || icookie[1]!='x'
401            || rcookie[0]!='0' || rcookie[1]!='x'
402            || ilen!=18
403            || rlen!=18) {
404                 (*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.",
405                                     file, lineno);
406
407                 (*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)",
408                                     init, icookie, ilen, rcookie, rlen);
409
410                 return;
411         }
412
413         sa1.spi = 0;
414         sa1.initiator = (init[0] == 'I');
415         if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8)
416                 return;
417
418         if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8)
419                 return;
420
421         if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return;
422
423         if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return;
424
425         esp_print_addsa(ndo, &sa1, FALSE);
426 }
427
428 /*
429  *
430  * special form: file /name
431  * causes us to go read from this file instead.
432  *
433  */
434 static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
435                                        const char *file, int lineno)
436 {
437         struct sa_list sa1;
438         int sa_def;
439
440         char *spikey;
441         char *decode;
442
443         spikey = strsep(&line, " \t");
444         sa_def = 0;
445         memset(&sa1, 0, sizeof(struct sa_list));
446
447         /* if there is only one token, then it is an algo:key token */
448         if (line == NULL) {
449                 decode = spikey;
450                 spikey = NULL;
451                 /* sa1.daddr.version = 0; */
452                 /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */
453                 /* sa1.spi = 0; */
454                 sa_def    = 1;
455         } else
456                 decode = line;
457
458         if (spikey && ascii_strcasecmp(spikey, "file") == 0) {
459                 /* open file and read it */
460                 FILE *secretfile;
461                 char  fileline[1024];
462                 int   subfile_lineno=0;
463                 char  *nl;
464                 char *filename = line;
465
466                 secretfile = fopen(filename, FOPEN_READ_TXT);
467                 if (secretfile == NULL) {
468                         (*ndo->ndo_error)(ndo, "print_esp: can't open %s: %s\n",
469                             filename, strerror(errno));
470                         return;
471                 }
472
473                 while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
474                         subfile_lineno++;
475                         /* remove newline from the line */
476                         nl = strchr(fileline, '\n');
477                         if (nl)
478                                 *nl = '\0';
479                         if (fileline[0] == '#') continue;
480                         if (fileline[0] == '\0') continue;
481
482                         esp_print_decode_onesecret(ndo, fileline, filename, subfile_lineno);
483                 }
484                 fclose(secretfile);
485
486                 return;
487         }
488
489         if (spikey && ascii_strcasecmp(spikey, "ikev2") == 0) {
490                 esp_print_decode_ikeline(ndo, line, file, lineno);
491                 return;
492         }
493
494         if (spikey) {
495
496                 char *spistr, *foo;
497                 uint32_t spino;
498
499                 spistr = strsep(&spikey, "@");
500
501                 spino = strtoul(spistr, &foo, 0);
502                 if (spistr == foo || !spikey) {
503                         (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo);
504                         return;
505                 }
506
507                 sa1.spi = spino;
508
509                 if (strtoaddr6(spikey, &sa1.daddr.in6) == 1) {
510                         sa1.daddr_version = 6;
511                 } else if (strtoaddr(spikey, &sa1.daddr.in4) == 1) {
512                         sa1.daddr_version = 4;
513                 } else {
514                         (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey);
515                         return;
516                 }
517         }
518
519         if (decode) {
520                 /* skip any blank spaces */
521                 while (isspace((unsigned char)*decode))
522                         decode++;
523
524                 if(!espprint_decode_encalgo(ndo, decode, &sa1)) {
525                         return;
526                 }
527         }
528
529         esp_print_addsa(ndo, &sa1, sa_def);
530 }
531
532 USES_APPLE_DEPRECATED_API
533 static void esp_init(netdissect_options *ndo _U_)
534 {
535         /*
536          * 0.9.6 doesn't appear to define OPENSSL_API_COMPAT, so
537          * we check whether it's undefined or it's less than the
538          * value for 1.1.0.
539          */
540 #if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < 0x10100000L
541         OpenSSL_add_all_algorithms();
542 #endif
543         EVP_add_cipher_alias(SN_des_ede3_cbc, "3des");
544 }
545 USES_APPLE_RST
546
547 void esp_print_decodesecret(netdissect_options *ndo)
548 {
549         char *line;
550         char *p;
551         static int initialized = 0;
552
553         if (!initialized) {
554                 esp_init(ndo);
555                 initialized = 1;
556         }
557
558         p = ndo->ndo_espsecret;
559
560         while (p && p[0] != '\0') {
561                 /* pick out the first line or first thing until a comma */
562                 if ((line = strsep(&p, "\n,")) == NULL) {
563                         line = p;
564                         p = NULL;
565                 }
566
567                 esp_print_decode_onesecret(ndo, line, "cmdline", 0);
568         }
569
570         ndo->ndo_espsecret = NULL;
571 }
572
573 #endif
574
575 #ifdef HAVE_LIBCRYPTO
576 USES_APPLE_DEPRECATED_API
577 #endif
578 int
579 esp_print(netdissect_options *ndo,
580           const u_char *bp, const int length, const u_char *bp2
581 #ifndef HAVE_LIBCRYPTO
582         _U_
583 #endif
584         ,
585         int *nhdr
586 #ifndef HAVE_LIBCRYPTO
587         _U_
588 #endif
589         ,
590         int *padlen
591 #ifndef HAVE_LIBCRYPTO
592         _U_
593 #endif
594         )
595 {
596         register const struct newesp *esp;
597         register const u_char *ep;
598 #ifdef HAVE_LIBCRYPTO
599         const struct ip *ip;
600         struct sa_list *sa = NULL;
601         const struct ip6_hdr *ip6 = NULL;
602         int advance;
603         int len;
604         u_char *secret;
605         int ivlen = 0;
606         const u_char *ivoff;
607         const u_char *p;
608         EVP_CIPHER_CTX *ctx;
609 #endif
610
611         esp = (const struct newesp *)bp;
612
613 #ifdef HAVE_LIBCRYPTO
614         secret = NULL;
615         advance = 0;
616 #endif
617
618 #if 0
619         /* keep secret out of a register */
620         p = (u_char *)&secret;
621 #endif
622
623         /* 'ep' points to the end of available data. */
624         ep = ndo->ndo_snapend;
625
626         if ((const u_char *)(esp + 1) >= ep) {
627                 ND_PRINT((ndo, "[|ESP]"));
628                 goto fail;
629         }
630         ND_PRINT((ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi)));
631         ND_PRINT((ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq)));
632         ND_PRINT((ndo, ", length %u", length));
633
634 #ifndef HAVE_LIBCRYPTO
635         goto fail;
636 #else
637         /* initiailize SAs */
638         if (ndo->ndo_sa_list_head == NULL) {
639                 if (!ndo->ndo_espsecret)
640                         goto fail;
641
642                 esp_print_decodesecret(ndo);
643         }
644
645         if (ndo->ndo_sa_list_head == NULL)
646                 goto fail;
647
648         ip = (const struct ip *)bp2;
649         switch (IP_V(ip)) {
650         case 6:
651                 ip6 = (const struct ip6_hdr *)bp2;
652                 /* we do not attempt to decrypt jumbograms */
653                 if (!EXTRACT_16BITS(&ip6->ip6_plen))
654                         goto fail;
655                 /* if we can't get nexthdr, we do not need to decrypt it */
656                 len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen);
657
658                 /* see if we can find the SA, and if so, decode it */
659                 for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
660                         if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
661                             sa->daddr_version == 6 &&
662                             UNALIGNED_MEMCMP(&sa->daddr.in6, &ip6->ip6_dst,
663                                    sizeof(struct in6_addr)) == 0) {
664                                 break;
665                         }
666                 }
667                 break;
668         case 4:
669                 /* nexthdr & padding are in the last fragment */
670                 if (EXTRACT_16BITS(&ip->ip_off) & IP_MF)
671                         goto fail;
672                 len = EXTRACT_16BITS(&ip->ip_len);
673
674                 /* see if we can find the SA, and if so, decode it */
675                 for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
676                         if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
677                             sa->daddr_version == 4 &&
678                             UNALIGNED_MEMCMP(&sa->daddr.in4, &ip->ip_dst,
679                                    sizeof(struct in_addr)) == 0) {
680                                 break;
681                         }
682                 }
683                 break;
684         default:
685                 goto fail;
686         }
687
688         /* if we didn't find the specific one, then look for
689          * an unspecified one.
690          */
691         if (sa == NULL)
692                 sa = ndo->ndo_sa_default;
693
694         /* if not found fail */
695         if (sa == NULL)
696                 goto fail;
697
698         /* if we can't get nexthdr, we do not need to decrypt it */
699         if (ep - bp2 < len)
700                 goto fail;
701         if (ep - bp2 > len) {
702                 /* FCS included at end of frame (NetBSD 1.6 or later) */
703                 ep = bp2 + len;
704         }
705
706         ivoff = (const u_char *)(esp + 1) + 0;
707         ivlen = sa->ivlen;
708         secret = sa->secret;
709         ep = ep - sa->authlen;
710
711         if (sa->evp) {
712                 ctx = EVP_CIPHER_CTX_new();
713                 if (ctx != NULL) {
714                         if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0)
715                                 (*ndo->ndo_warning)(ndo, "espkey init failed");
716
717                         p = ivoff;
718                         EVP_CipherInit(ctx, NULL, NULL, p, 0);
719                         EVP_Cipher(ctx, __DECONST(u_char *, p + ivlen),
720                             p + ivlen, ep - (p + ivlen));
721                         EVP_CIPHER_CTX_free(ctx);
722                         advance = ivoff - (const u_char *)esp + ivlen;
723                 } else
724                         advance = sizeof(struct newesp);
725         } else
726                 advance = sizeof(struct newesp);
727
728         /* sanity check for pad length */
729         if (ep - bp < *(ep - 2))
730                 goto fail;
731
732         if (padlen)
733                 *padlen = *(ep - 2) + 2;
734
735         if (nhdr)
736                 *nhdr = *(ep - 1);
737
738         ND_PRINT((ndo, ": "));
739         return advance;
740 #endif
741
742 fail:
743         return -1;
744 }
745 #ifdef HAVE_LIBCRYPTO
746 USES_APPLE_RST
747 #endif
748
749 /*
750  * Local Variables:
751  * c-style: whitesmith
752  * c-basic-offset: 8
753  * End:
754  */