xref: /netbsd-src/external/bsd/tcpdump/dist/print-esp.c (revision 7330f729ccf0bd976a06f95fad452fe774fc7fd1)
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.10 2019/10/01 16:06:16 christos 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 #ifdef HAVE_LIBCRYPTO
658 USES_APPLE_DEPRECATED_API
659 #endif
660 int
661 esp_print(netdissect_options *ndo,
662 	  const u_char *bp, const int length, const u_char *bp2
663 #ifndef HAVE_LIBCRYPTO
664 	_U_
665 #endif
666 	,
667 	int *nhdr
668 #ifndef HAVE_LIBCRYPTO
669 	_U_
670 #endif
671 	,
672 	int *padlen
673 #ifndef HAVE_LIBCRYPTO
674 	_U_
675 #endif
676 	)
677 {
678 	register const struct newesp *esp;
679 	register const u_char *ep;
680 #ifdef HAVE_LIBCRYPTO
681 	const struct ip *ip;
682 	struct sa_list *sa = NULL;
683 	const struct ip6_hdr *ip6 = NULL;
684 	int advance;
685 	int len;
686 	u_char *secret;
687 	int ivlen = 0;
688 	const u_char *ivoff;
689 	const u_char *p;
690 	EVP_CIPHER_CTX *ctx;
691 	unsigned int block_size, buffer_size;
692 	u_char *input_buffer, *output_buffer;
693 #endif
694 
695 	esp = (const struct newesp *)bp;
696 
697 #ifdef HAVE_LIBCRYPTO
698 	secret = NULL;
699 	advance = 0;
700 #endif
701 
702 #if 0
703 	/* keep secret out of a register */
704 	p = (u_char *)&secret;
705 #endif
706 
707 	/* 'ep' points to the end of available data. */
708 	ep = ndo->ndo_snapend;
709 
710 	if ((const u_char *)(esp + 1) >= ep) {
711 		ND_PRINT((ndo, "[|ESP]"));
712 		goto fail;
713 	}
714 	ND_PRINT((ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi)));
715 	ND_PRINT((ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq)));
716 	ND_PRINT((ndo, ", length %u", length));
717 
718 #ifndef HAVE_LIBCRYPTO
719 	goto fail;
720 #else
721 	/* initiailize SAs */
722 	if (ndo->ndo_sa_list_head == NULL) {
723 		if (!ndo->ndo_espsecret)
724 			goto fail;
725 
726 		esp_print_decodesecret(ndo);
727 	}
728 
729 	if (ndo->ndo_sa_list_head == NULL)
730 		goto fail;
731 
732 	ip = (const struct ip *)bp2;
733 	switch (IP_V(ip)) {
734 	case 6:
735 		ip6 = (const struct ip6_hdr *)bp2;
736 		/* we do not attempt to decrypt jumbograms */
737 		if (!EXTRACT_16BITS(&ip6->ip6_plen))
738 			goto fail;
739 		/* if we can't get nexthdr, we do not need to decrypt it */
740 		len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen);
741 
742 		/* see if we can find the SA, and if so, decode it */
743 		for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
744 			if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
745 			    sa->daddr_version == 6 &&
746 			    UNALIGNED_MEMCMP(&sa->daddr.in6, &ip6->ip6_dst,
747 				   sizeof(struct in6_addr)) == 0) {
748 				break;
749 			}
750 		}
751 		break;
752 	case 4:
753 		/* nexthdr & padding are in the last fragment */
754 		if (EXTRACT_16BITS(&ip->ip_off) & IP_MF)
755 			goto fail;
756 		len = EXTRACT_16BITS(&ip->ip_len);
757 
758 		/* see if we can find the SA, and if so, decode it */
759 		for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
760 			if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
761 			    sa->daddr_version == 4 &&
762 			    UNALIGNED_MEMCMP(&sa->daddr.in4, &ip->ip_dst,
763 				   sizeof(struct in_addr)) == 0) {
764 				break;
765 			}
766 		}
767 		break;
768 	default:
769 		goto fail;
770 	}
771 
772 	/* if we didn't find the specific one, then look for
773 	 * an unspecified one.
774 	 */
775 	if (sa == NULL)
776 		sa = ndo->ndo_sa_default;
777 
778 	/* if not found fail */
779 	if (sa == NULL)
780 		goto fail;
781 
782 	/* if we can't get nexthdr, we do not need to decrypt it */
783 	if (ep - bp2 < len)
784 		goto fail;
785 	if (ep - bp2 > len) {
786 		/* FCS included at end of frame (NetBSD 1.6 or later) */
787 		ep = bp2 + len;
788 	}
789 
790 	/* pointer to the IV, if there is one */
791 	ivoff = (const u_char *)(esp + 1) + 0;
792 	/* length of the IV, if there is one; 0, if there isn't */
793 	ivlen = sa->ivlen;
794 	secret = sa->secret;
795 	ep = ep - sa->authlen;
796 
797 	if (sa->evp) {
798 		ctx = EVP_CIPHER_CTX_new();
799 		if (ctx != NULL) {
800 			if (set_cipher_parameters(ctx, sa->evp, secret, NULL, 0) < 0)
801 				(*ndo->ndo_warning)(ndo, "espkey init failed");
802 
803 			p = ivoff;
804 			set_cipher_parameters(ctx, NULL, NULL, p, 0);
805 			len = ep - (p + ivlen);
806 
807 			/*
808 			 * Allocate buffers for the encrypted and decrypted
809 			 * data.  Both buffers' sizes must be a multiple of
810 			 * the cipher block size, and the output buffer must
811 			 * be separate from the input buffer.
812 			 */
813 			block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
814 			buffer_size = len + (block_size - len % block_size);
815 
816 			/*
817 			 * Attempt to allocate the input buffer.
818 			 */
819 			input_buffer = (u_char *)malloc(buffer_size);
820 			if (input_buffer == NULL) {
821 				EVP_CIPHER_CTX_free(ctx);
822 				(*ndo->ndo_error)(ndo, "can't allocate memory for encrypted data buffer");
823 			}
824 			/*
825 			 * Copy the input data to the encrypted data buffer,
826 			 * and pad it with zeroes.
827 			 */
828 			memcpy(input_buffer, p + ivlen, len);
829 			memset(input_buffer + len, 0, buffer_size - len);
830 
831 			/*
832 			 * Attempt to allocate the output buffer.
833 			 */
834 			output_buffer = (u_char *)malloc(buffer_size);
835 			if (output_buffer == NULL) {
836 				free(input_buffer);
837 				EVP_CIPHER_CTX_free(ctx);
838 				(*ndo->ndo_error)(ndo, "can't allocate memory for decryption buffer");
839 			}
840 
841 			EVP_Cipher(ctx, output_buffer, input_buffer, len);
842 			free(input_buffer);
843 			EVP_CIPHER_CTX_free(ctx);
844 			/*
845 			 * XXX - of course this is wrong, because buf is a
846 			 * const buffer, but changing this would require a
847 			 * more complicated fix.
848 			 */
849 			memcpy(__UNCONST(p + ivlen), output_buffer, len);
850 			free(output_buffer);
851 			advance = ivoff - (const u_char *)esp + ivlen;
852 		} else
853 			advance = sizeof(struct newesp);
854 	} else
855 		advance = sizeof(struct newesp);
856 
857 	/* sanity check for pad length */
858 	if (ep - bp < *(ep - 2))
859 		goto fail;
860 
861 	if (padlen)
862 		*padlen = *(ep - 2) + 2;
863 
864 	if (nhdr)
865 		*nhdr = *(ep - 1);
866 
867 	ND_PRINT((ndo, ": "));
868 	return advance;
869 #endif
870 
871 fail:
872 	return -1;
873 }
874 #ifdef HAVE_LIBCRYPTO
875 USES_APPLE_RST
876 #endif
877 
878 /*
879  * Local Variables:
880  * c-style: whitesmith
881  * c-basic-offset: 8
882  * End:
883  */
884