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