1/*	$NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $	*/
2
3/*
4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24#ifndef lint
25static const char rcsid[] _U_ =
26    "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.58 2007-12-07 00:03:07 mcr Exp $ (LBL)";
27#endif
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <string.h>
34
35#include <tcpdump-stdinc.h>
36
37#include <stdlib.h>
38
39#ifdef __APPLE__
40#include <CommonCrypto/CommonCryptor.h>
41#include <CommonCrypto/CommonCryptorSPI.h>
42
43struct CCCryptoCipherData
44{
45	CCAlgorithm	algorithm;
46	CCMode		mode;
47	CCPadding	padding;
48	size_t		keySizeInBytes;
49};
50typedef struct CCCryptoCipherData CCCryptoCipherData;
51
52/*!
53	@function	CCGetCryptoCipherDataFromName
54	@abstract	This function will use the name specified by the name parameter to fill out the outCipherData parameter
55	@param		name The name of the cipher to use.  This supports the OpenSSL naming convention
56	@param		outCipherData An out parameter that will be filled in with the cipher data for the named cipher
57	@result		returns 1 if successful 0 otherwise
58*/
59int CCGetCryptoCipherDataFromName(const char* name, CCCryptoCipherData* outCipherData);
60
61/*!
62	@function	CCCryptorCreateFromCipherData
63	@abstract	This function will create a CCCryptorRef given a valid CCCryptoCipherData , operation and an iv
64	@param		cipherData This is a pointer to a CCCryptoCipherData containing the data describing the cipher
65	@param		op This is the operation encrypt or decrypt that the new CCCryptorRef will perform
66	@param		key The key to use. Must not be NULL
67	@param		iv An optional iv parameter to be set for the cipher
68	@param		cryptorRef This is an out parameter for the CCCryptorRef
69	@result		return the status of the call
70*/
71CCCryptorStatus CCCryptorCreateFromCipherData(CCCryptoCipherData* cipherData,
72                    CCOperation op, const void* key, const void* iv, CCCryptorRef *cryptorRef);
73
74#else /* __APPLE__ */
75
76#ifdef HAVE_LIBCRYPTO
77#ifdef HAVE_OPENSSL_EVP_H
78#include <openssl/evp.h>
79#endif
80#endif
81#endif /* __APPLE__ */
82
83#include <stdio.h>
84
85#include "ip.h"
86#include "esp.h"
87#ifdef INET6
88#include "ip6.h"
89#endif
90
91#include "netdissect.h"
92#include "addrtoname.h"
93#include "extract.h"
94
95#ifdef __APPLE__
96
97// OpenSSL uses a default key size on ciphers that have vaiable key sizes
98#define gDefaultOpenSSLKeySize 16
99
100struct CipherTable
101{
102	const char*		cipherName;
103	CCCryptoCipherData	cipherData;
104};
105typedef struct CipherTable CipherTable;
106
107
108// The default for OpenSSL is that padding will be done.  That is the default
109// here as well
110static CipherTable const gCiphers[] =
111{
112	// Lower case strings
113
114	{"aes-128-ecb", {kCCAlgorithmAES128, kCCModeECB, ccPKCS7Padding, kCCKeySizeAES128}},
115	{"aes-128-cbc", {kCCAlgorithmAES128, kCCModeCBC, ccPKCS7Padding, kCCKeySizeAES128}},
116	{"aes-128-ofb", {kCCAlgorithmAES128, kCCModeOFB, ccPKCS7Padding, kCCKeySizeAES128}},
117	{"aes-128-cfb", {kCCAlgorithmAES128, kCCModeCFB, ccPKCS7Padding, kCCKeySizeAES128}},
118	{"aes-128-cfb8", {kCCAlgorithmAES128, kCCModeCFB8, ccPKCS7Padding, kCCKeySizeAES128}},
119
120	{"aes-192-ecb", {kCCAlgorithmAES128, kCCModeECB, ccPKCS7Padding, kCCKeySizeAES192}},
121	{"aes-192-cbc", {kCCAlgorithmAES128, kCCModeCBC, ccPKCS7Padding, kCCKeySizeAES192}},
122	{"aes-192-ofb", {kCCAlgorithmAES128, kCCModeOFB, ccPKCS7Padding, kCCKeySizeAES192}},
123	{"aes-192-cfb", {kCCAlgorithmAES128, kCCModeCFB, ccPKCS7Padding, kCCKeySizeAES192}},
124	{"aes-192-cfb8", {kCCAlgorithmAES128, kCCModeCFB8, ccPKCS7Padding, kCCKeySizeAES192}},
125
126	{"aes-256-ecb", {kCCAlgorithmAES128, kCCModeECB, ccPKCS7Padding, kCCKeySizeAES256}},
127	{"aes-256-cbc", {kCCAlgorithmAES128, kCCModeCBC, ccPKCS7Padding, kCCKeySizeAES256}},
128	{"aes-256-ofb", {kCCAlgorithmAES128, kCCModeOFB, ccPKCS7Padding, kCCKeySizeAES256}},
129	{"aes-256-cfb", {kCCAlgorithmAES128, kCCModeCFB, ccPKCS7Padding, kCCKeySizeAES256}},
130	{"aes-256-cfb8", {kCCAlgorithmAES128, kCCModeCFB8, ccPKCS7Padding, kCCKeySizeAES256}},
131
132	{"des-ecb", {kCCAlgorithmDES, kCCModeECB, ccPKCS7Padding, kCCKeySizeDES}},
133	{"des-cbc", {kCCAlgorithmDES, kCCModeCBC, ccPKCS7Padding, kCCKeySizeDES}},
134	{"des-ofb", {kCCAlgorithmDES, kCCModeOFB, ccPKCS7Padding, kCCKeySizeDES}},
135	{"des-cfb", {kCCAlgorithmDES, kCCModeCFB, ccPKCS7Padding, kCCKeySizeDES}},
136	{"des-cfb8", {kCCAlgorithmDES, kCCModeCFB8, ccPKCS7Padding, kCCKeySizeDES}},
137
138	{"des-ede3", {kCCAlgorithm3DES, kCCModeECB, ccPKCS7Padding, kCCKeySize3DES}},
139	{"3des", {kCCAlgorithm3DES, kCCModeCBC, ccPKCS7Padding, kCCKeySize3DES}},
140	{"des-ede3-cbc", {kCCAlgorithm3DES, kCCModeCBC, ccPKCS7Padding, kCCKeySize3DES}},
141	{"des-ede-ofb", {kCCAlgorithm3DES, kCCModeOFB, ccPKCS7Padding, kCCKeySize3DES}},
142	{"des-ede3-cfb", {kCCAlgorithm3DES, kCCModeCFB, ccPKCS7Padding, kCCKeySize3DES}},
143	{"des-ede3-cfb8", {kCCAlgorithm3DES, kCCModeCFB8, ccPKCS7Padding, kCCKeySize3DES}},
144
145	{"rc4", {kCCAlgorithmRC4, kCCModeECB, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
146
147	{"rc2-ecb", {kCCAlgorithmRC2, kCCModeECB, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
148	{"rc2-cbc", {kCCAlgorithmRC2, kCCModeCBC, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
149	{"rc2-ofb", {kCCAlgorithmRC2, kCCModeOFB, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
150	{"rc2-cfb", {kCCAlgorithmRC2, kCCModeCFB, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
151
152	{"bf-ecb", {kCCAlgorithmBlowfish, kCCModeECB, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
153	{"bf-cbc", {kCCAlgorithmBlowfish, kCCModeCBC, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
154	{"bf-ofb", {kCCAlgorithmBlowfish, kCCModeOFB, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
155	{"bf-cfb", {kCCAlgorithmBlowfish, kCCModeCFB, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
156
157	{"cast5-ecb", {kCCAlgorithmCAST, kCCModeECB, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
158	{"cast5-cbc", {kCCAlgorithmCAST, kCCModeCBC, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
159	{"cast5-ofb", {kCCAlgorithmCAST, kCCModeOFB, ccPKCS7Padding, gDefaultOpenSSLKeySize}},
160	{"cast5-cfb", {kCCAlgorithmCAST, kCCModeCFB, ccPKCS7Padding, gDefaultOpenSSLKeySize}}
161};
162
163/* ==========================================================================
164	Function:	CCGetCryptoCipherDataFromName
165	Description:	Provide a way to get the information needed for creating
166			a CommonCrypto CCCryptoRef from an OpenSSL style cipher
167			name
168   ========================================================================== */
169int CCGetCryptoCipherDataFromName(const char* name, CCCryptoCipherData* outCipherData)
170{
171	int result = 0;					// guilty until proven
172	int numCiphers = 0;				// Number of cipher records to check
173	int iCnt = 0;					// for loop counter
174	const CipherTable* tablePtr = gCiphers;	// pointer into the static table
175	const char* tableCipherName = NULL;
176
177	// Parameter checking
178	if (NULL == name || NULL == outCipherData) {
179		return result;
180	}
181
182	outCipherData->algorithm = (CCAlgorithm)-1; // guilt until proven
183
184	numCiphers = sizeof(gCiphers) / sizeof(CipherTable);
185	for (iCnt = 0; iCnt < numCiphers; iCnt++, tablePtr++) {
186		tableCipherName = tablePtr->cipherName;
187		if (!strcmp(name, tableCipherName))
188		{
189			// Found one
190			*outCipherData = tablePtr->cipherData;
191			result = 1;
192			break;
193		}
194	}
195
196	return result;
197}
198
199/* ==========================================================================
200	Function:	CCCryptorCreateFromCipherData
201	Description:	Given a CCCryptoCipherData record, create a CCCryptorRef
202   ========================================================================== */
203CCCryptorStatus CCCryptorCreateFromCipherData(CCCryptoCipherData* cipherData,
204                    CCOperation op, const void* key, const void* iv,
205					CCCryptorRef *cryptorRef)
206{
207	// Parameter checking
208	if (NULL == cipherData || NULL == cryptorRef || NULL == key ||
209		cipherData->algorithm == (CCAlgorithm)-1) {
210		return kCCParamError;
211	}
212
213	// Create the CryptoRef
214	return CCCryptorCreateWithMode(op, cipherData->mode, cipherData->algorithm,
215		cipherData->padding, iv, key, cipherData->keySizeInBytes,
216		NULL, 0, 0, 0, cryptorRef);
217}
218
219/* ==========================================================================
220	Function:	IVLengthFromCipherData
221	Description:	Given a CCCryptoCipherData record, return the correct
222			IV length in bytes
223   ========================================================================== */
224int IVLengthFromCipherData(CCCryptoCipherData* cipherData)
225{
226    int result = -1;    // guilt until proven
227    if (NULL == cipherData || cipherData->algorithm == (CCAlgorithm)-1) {
228        return -1;
229    }
230
231    switch(cipherData->algorithm)
232    {
233		case kCCAlgorithmAES128:
234			result = kCCBlockSizeAES128;
235			break;
236
237		case kCCAlgorithmDES:
238			result = kCCBlockSizeDES;
239			break;
240
241		case kCCAlgorithm3DES:
242			result = kCCBlockSize3DES;
243			break;
244
245		case kCCAlgorithmCAST:
246			result = kCCBlockSizeCAST;
247			break;
248
249		case kCCAlgorithmRC2:
250			result = kCCBlockSizeRC2;
251			break;
252
253		case kCCAlgorithmBlowfish:
254			result = kCCBlockSizeBlowfish;
255			break;
256
257   }
258
259    return result;
260}
261
262/* ==========================================================================
263	Function:		BlockSizeFromCipherData
264	Description:	Given a CCCryptoCipherData record, return the correct
265                    block size in bytes
266   ========================================================================== */
267int BlockSizeFromCipherData(CCCryptoCipherData* cipherData)
268{
269	return IVLengthFromCipherData(cipherData);
270}
271
272#endif /* __APPLE__ */
273
274#ifndef HAVE_SOCKADDR_STORAGE
275#ifdef INET6
276struct sockaddr_storage {
277	union {
278		struct sockaddr_in sin;
279		struct sockaddr_in6 sin6;
280	} un;
281};
282#else
283#define sockaddr_storage sockaddr
284#endif
285#endif /* HAVE_SOCKADDR_STORAGE */
286
287#ifdef HAVE_LIBCRYPTO
288struct sa_list {
289	struct sa_list	*next;
290	struct sockaddr_storage daddr;
291	u_int32_t	spi;          /* if == 0, then IKEv2 */
292	int             initiator;
293	u_char          spii[8];      /* for IKEv2 */
294	u_char          spir[8];
295#ifdef __APPLE__
296	CCCryptoCipherData    cipherData;
297#else /* __APPLE__ */
298	const EVP_CIPHER *evp;
299#endif /* __APPLE__ */
300	int		ivlen;
301	int		authlen;
302	u_char          authsecret[256];
303	int             authsecret_len;
304	u_char		secret[256];  /* is that big enough for all secrets? */
305	int		secretlen;
306};
307
308/*
309 * this will adjust ndo_packetp and ndo_snapend to new buffer!
310 */
311int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
312				      int initiator,
313				      u_char spii[8], u_char spir[8],
314				      u_char *buf, u_char *end)
315{
316	struct sa_list *sa;
317	u_char *iv;
318	int len;
319#ifdef __APPLE__
320	CCCryptorRef    ctx;
321	size_t          dataMoved = 0;
322#else /* __APPLE__ */
323	EVP_CIPHER_CTX ctx;
324#endif /* __APPLE__ */
325
326	/* initiator arg is any non-zero value */
327	if(initiator) initiator=1;
328
329	/* see if we can find the SA, and if so, decode it */
330	for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
331		if (sa->spi == 0
332		    && initiator == sa->initiator
333		    && memcmp(spii, sa->spii, 8) == 0
334		    && memcmp(spir, sa->spir, 8) == 0)
335			break;
336	}
337
338	if(sa == NULL) return 0;
339#ifdef __APPLE__
340	if(sa->cipherData.algorithm == (CCAlgorithm)-1) return 0;
341#else /* __APPLE__ */
342	if(sa->evp == NULL) return 0;
343#endif /* __APPLE__ */
344
345	/*
346	 * remove authenticator, and see if we still have something to
347	 * work with
348	 */
349	end = end - sa->authlen;
350	iv  = buf;
351	buf = buf + sa->ivlen;
352	len = end-buf;
353
354	if(end <= buf) return 0;
355
356#ifdef __APPLE__
357	ctx = NULL;
358	if (kCCSuccess != CCCryptorCreateFromCipherData(&sa->cipherData, kCCDecrypt, sa->secret, iv, &ctx))
359		(*ndo->ndo_warning)(ndo, "espkey init failed");
360
361	(void)CCCryptorUpdate(ctx, buf, len, buf, len, &dataMoved);
362	CCCryptorRelease(ctx);
363	ctx = NULL;
364#else /* __APPLE__ */
365	memset(&ctx, 0, sizeof(ctx));
366	if (EVP_CipherInit(&ctx, sa->evp, sa->secret, NULL, 0) < 0)
367		(*ndo->ndo_warning)(ndo, "espkey init failed");
368	EVP_CipherInit(&ctx, NULL, NULL, iv, 0);
369	EVP_Cipher(&ctx, buf, buf, len);
370	EVP_CIPHER_CTX_cleanup(&ctx);
371#endif /* __APPLE__ */
372
373	ndo->ndo_packetp = buf;
374	ndo->ndo_snapend = end;
375
376	return 1;
377
378}
379
380static void esp_print_addsa(netdissect_options *ndo,
381			    struct sa_list *sa, int sa_def)
382{
383	/* copy the "sa" */
384
385	struct sa_list *nsa;
386
387	nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
388	if (nsa == NULL)
389		(*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure");
390
391	*nsa = *sa;
392
393	if (sa_def)
394		ndo->ndo_sa_default = nsa;
395
396	nsa->next = ndo->ndo_sa_list_head;
397	ndo->ndo_sa_list_head = nsa;
398}
399
400
401static u_int hexdigit(netdissect_options *ndo, char hex)
402{
403	if (hex >= '0' && hex <= '9')
404		return (hex - '0');
405	else if (hex >= 'A' && hex <= 'F')
406		return (hex - 'A' + 10);
407	else if (hex >= 'a' && hex <= 'f')
408		return (hex - 'a' + 10);
409	else {
410		(*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex);
411		return 0;
412	}
413}
414
415static u_int hex2byte(netdissect_options *ndo, char *hexstring)
416{
417	u_int byte;
418
419	byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]);
420	return byte;
421}
422
423/*
424 * returns size of binary, 0 on failure.
425 */
426static
427int espprint_decode_hex(netdissect_options *ndo,
428			u_char *binbuf, unsigned int binbuf_len,
429			char *hex)
430{
431	unsigned int len;
432	int i;
433
434	len = strlen(hex) / 2;
435
436	if (len > binbuf_len) {
437		(*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len);
438		return 0;
439	}
440
441	i = 0;
442	while (hex[0] != '\0' && hex[1]!='\0') {
443		binbuf[i] = hex2byte(ndo, hex);
444		hex += 2;
445		i++;
446	}
447
448	return i;
449}
450
451/*
452 * decode the form:    SPINUM@IP <tab> ALGONAME:0xsecret
453 */
454
455static int
456espprint_decode_encalgo(netdissect_options *ndo,
457			char *decode, struct sa_list *sa)
458{
459	int len;
460	size_t i;
461#ifdef __APPLE__
462	CCCryptoCipherData cipherData;
463#else /* __APPLE__ */
464	const EVP_CIPHER *evp;
465#endif /* __APPLE__	*/
466	int authlen = 0;
467	char *colon, *p;
468
469	colon = strchr(decode, ':');
470	if (colon == NULL) {
471		(*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
472		return 0;
473	}
474	*colon = '\0';
475
476	len = colon - decode;
477	if (strlen(decode) > strlen("-hmac96") &&
478	    !strcmp(decode + strlen(decode) - strlen("-hmac96"),
479		    "-hmac96")) {
480		p = strstr(decode, "-hmac96");
481		*p = '\0';
482		authlen = 12;
483	}
484	if (strlen(decode) > strlen("-cbc") &&
485	    !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) {
486		p = strstr(decode, "-cbc");
487		*p = '\0';
488	}
489
490#ifdef __APPLE__
491	if (!CCGetCryptoCipherDataFromName(decode, &cipherData)) {
492		(*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
493		sa->authlen = 0;
494		sa->ivlen = 0;
495		return 0;
496	}
497#else /* __APPLE__ */
498	evp = EVP_get_cipherbyname(decode);
499
500	if (!evp) {
501		(*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
502		sa->evp = NULL;
503		sa->authlen = 0;
504		sa->ivlen = 0;
505		return 0;
506	}
507#endif /* __APPLE__	*/
508
509#ifdef __APPLE__
510	sa->cipherData = cipherData;
511	sa->authlen = authlen;
512	sa->ivlen =IVLengthFromCipherData(&cipherData);
513#else /* __APPLE__ */
514	sa->evp = evp;
515	sa->authlen = authlen;
516	sa->ivlen = EVP_CIPHER_iv_length(evp);
517#endif /* __APPLE__	*/
518
519	colon++;
520	if (colon[0] == '0' && colon[1] == 'x') {
521		/* decode some hex! */
522
523		colon += 2;
524		sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon);
525		if(sa->secretlen == 0) return 0;
526	} else {
527		i = strlen(colon);
528
529		if (i < sizeof(sa->secret)) {
530			memcpy(sa->secret, colon, i);
531			sa->secretlen = i;
532		} else {
533			memcpy(sa->secret, colon, sizeof(sa->secret));
534			sa->secretlen = sizeof(sa->secret);
535		}
536	}
537
538	return 1;
539}
540
541/*
542 * for the moment, ignore the auth algorith, just hard code the authenticator
543 * length. Need to research how openssl looks up HMAC stuff.
544 */
545static int
546espprint_decode_authalgo(netdissect_options *ndo,
547			 char *decode, struct sa_list *sa)
548{
549	char *colon;
550
551	colon = strchr(decode, ':');
552	if (colon == NULL) {
553		(*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
554		return 0;
555	}
556	*colon = '\0';
557
558	if(strcasecmp(colon,"sha1") == 0 ||
559	   strcasecmp(colon,"md5") == 0) {
560		sa->authlen = 12;
561	}
562	return 1;
563}
564
565static void esp_print_decode_ikeline(netdissect_options *ndo, char *line,
566				     const char *file, int lineno)
567{
568	/* it's an IKEv2 secret, store it instead */
569	struct sa_list sa1;
570
571	char *init;
572	char *icookie, *rcookie;
573	int   ilen, rlen;
574	char *authkey;
575	char *enckey;
576
577	init = strsep(&line, " \t");
578	icookie = strsep(&line, " \t");
579	rcookie = strsep(&line, " \t");
580	authkey = strsep(&line, " \t");
581	enckey  = strsep(&line, " \t");
582
583	/* if any fields are missing */
584	if(!init || !icookie || !rcookie || !authkey || !enckey) {
585		(*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u",
586				    file, lineno);
587
588		return;
589	}
590
591	ilen = strlen(icookie);
592	rlen = strlen(rcookie);
593
594	if((init[0]!='I' && init[0]!='R')
595	   || icookie[0]!='0' || icookie[1]!='x'
596	   || rcookie[0]!='0' || rcookie[1]!='x'
597	   || ilen!=18
598	   || rlen!=18) {
599		(*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.",
600				    file, lineno);
601
602		(*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)",
603				    init, icookie, ilen, rcookie, rlen);
604
605		return;
606	}
607
608	sa1.spi = 0;
609	sa1.initiator = (init[0] == 'I');
610	if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8)
611		return;
612
613	if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8)
614		return;
615
616	if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return;
617
618	if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return;
619
620	esp_print_addsa(ndo, &sa1, FALSE);
621}
622
623/*
624 *
625 * special form: file /name
626 * causes us to go read from this file instead.
627 *
628 */
629static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
630				       const char *file, int lineno)
631{
632	struct sa_list sa1;
633	int sa_def;
634
635	char *spikey;
636	char *decode;
637
638	spikey = strsep(&line, " \t");
639	sa_def = 0;
640	memset(&sa1, 0, sizeof(struct sa_list));
641
642	/* if there is only one token, then it is an algo:key token */
643	if (line == NULL) {
644		decode = spikey;
645		spikey = NULL;
646		/* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */
647		/* sa1.spi = 0; */
648		sa_def    = 1;
649	} else
650		decode = line;
651
652	if (spikey && strcasecmp(spikey, "file") == 0) {
653		/* open file and read it */
654		FILE *secretfile;
655		char  fileline[1024];
656		int   lineno=0;
657		char  *nl;
658		char *filename = line;
659
660		secretfile = fopen(filename, FOPEN_READ_TXT);
661		if (secretfile == NULL) {
662			perror(filename);
663			exit(3);
664		}
665
666		while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
667			lineno++;
668			/* remove newline from the line */
669			nl = strchr(fileline, '\n');
670			if (nl)
671				*nl = '\0';
672			if (fileline[0] == '#') continue;
673			if (fileline[0] == '\0') continue;
674
675			esp_print_decode_onesecret(ndo, fileline, filename, lineno);
676		}
677		fclose(secretfile);
678
679		return;
680	}
681
682	if (spikey && strcasecmp(spikey, "ikev2") == 0) {
683		esp_print_decode_ikeline(ndo, line, file, lineno);
684		return;
685	}
686
687	if (spikey) {
688
689		char *spistr, *foo;
690		u_int32_t spino;
691		struct sockaddr_in *sin;
692#ifdef INET6
693		struct sockaddr_in6 *sin6;
694#endif
695
696		spistr = strsep(&spikey, "@");
697
698		spino = strtoul(spistr, &foo, 0);
699		if (spistr == foo || !spikey) {
700			(*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo);
701			return;
702		}
703
704		sa1.spi = spino;
705
706		sin = (struct sockaddr_in *)&sa1.daddr;
707#ifdef INET6
708		sin6 = (struct sockaddr_in6 *)&sa1.daddr;
709		if (inet_pton(AF_INET6, spikey, &sin6->sin6_addr) == 1) {
710#ifdef HAVE_SOCKADDR_SA_LEN
711			sin6->sin6_len = sizeof(struct sockaddr_in6);
712#endif
713			sin6->sin6_family = AF_INET6;
714		} else
715#endif
716			if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) {
717#ifdef HAVE_SOCKADDR_SA_LEN
718				sin->sin_len = sizeof(struct sockaddr_in);
719#endif
720				sin->sin_family = AF_INET;
721			} else {
722				(*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey);
723				return;
724			}
725	}
726
727	if (decode) {
728		/* skip any blank spaces */
729		while (isspace((unsigned char)*decode))
730			decode++;
731
732		if(!espprint_decode_encalgo(ndo, decode, &sa1)) {
733			return;
734		}
735	}
736
737	esp_print_addsa(ndo, &sa1, sa_def);
738}
739
740static void esp_init(netdissect_options *ndo _U_)
741{
742#ifndef __APPLE__
743	OpenSSL_add_all_algorithms();
744	EVP_add_cipher_alias(SN_des_ede3_cbc, "3des");
745#endif /* __APPLE__ */
746}
747
748void esp_print_decodesecret(netdissect_options *ndo)
749{
750	char *line;
751	char *p;
752	static int initialized = 0;
753
754	if (!initialized) {
755		esp_init(ndo);
756		initialized = 1;
757	}
758
759	p = ndo->ndo_espsecret;
760
761	while (p && p[0] != '\0') {
762		/* pick out the first line or first thing until a comma */
763		if ((line = strsep(&p, "\n,")) == NULL) {
764			line = p;
765			p = NULL;
766		}
767
768		esp_print_decode_onesecret(ndo, line, "cmdline", 0);
769	}
770
771	ndo->ndo_espsecret = NULL;
772}
773
774#endif
775
776int
777esp_print(netdissect_options *ndo,
778	  const u_char *bp, const int length, const u_char *bp2
779#ifndef HAVE_LIBCRYPTO
780	_U_
781#endif
782	,
783	int *nhdr
784#ifndef HAVE_LIBCRYPTO
785	_U_
786#endif
787	,
788	int *padlen
789#ifndef HAVE_LIBCRYPTO
790	_U_
791#endif
792	)
793{
794	register const struct newesp *esp;
795	register const u_char *ep;
796#ifdef HAVE_LIBCRYPTO
797	struct ip *ip;
798	struct sa_list *sa = NULL;
799	int espsecret_keylen;
800#ifdef INET6
801	struct ip6_hdr *ip6 = NULL;
802#endif
803	int advance;
804	int len;
805	u_char *secret;
806	int ivlen = 0;
807	u_char *ivoff;
808	u_char *p;
809#ifdef __APPLE__
810	CCCryptorRef    ctx;
811	size_t          dataMoved = 0;
812#else /* __APPLE__ */
813	EVP_CIPHER_CTX ctx;
814	int blocksz;
815#endif /* __APPLE__ */
816#endif
817
818	esp = (struct newesp *)bp;
819
820#ifdef HAVE_LIBCRYPTO
821	secret = NULL;
822	advance = 0;
823#endif
824
825#if 0
826	/* keep secret out of a register */
827	p = (u_char *)&secret;
828#endif
829
830	/* 'ep' points to the end of available data. */
831	ep = ndo->ndo_snapend;
832
833	if ((u_char *)(esp + 1) >= ep) {
834		fputs("[|ESP]", stdout);
835		goto fail;
836	}
837	(*ndo->ndo_printf)(ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi));
838	(*ndo->ndo_printf)(ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq));
839        (*ndo->ndo_printf)(ndo, ", length %u", length);
840
841#ifndef HAVE_LIBCRYPTO
842	goto fail;
843#else
844	/* initiailize SAs */
845	if (ndo->ndo_sa_list_head == NULL) {
846		if (!ndo->ndo_espsecret)
847			goto fail;
848
849		esp_print_decodesecret(ndo);
850	}
851
852	if (ndo->ndo_sa_list_head == NULL)
853		goto fail;
854
855	ip = (struct ip *)bp2;
856	switch (IP_V(ip)) {
857#ifdef INET6
858	case 6:
859		ip6 = (struct ip6_hdr *)bp2;
860		/* we do not attempt to decrypt jumbograms */
861		if (!EXTRACT_16BITS(&ip6->ip6_plen))
862			goto fail;
863		/* if we can't get nexthdr, we do not need to decrypt it */
864		len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen);
865
866		/* see if we can find the SA, and if so, decode it */
867		for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
868			struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa->daddr;
869			if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
870			    sin6->sin6_family == AF_INET6 &&
871			    memcmp(&sin6->sin6_addr, &ip6->ip6_dst,
872				   sizeof(struct in6_addr)) == 0) {
873				break;
874			}
875		}
876		break;
877#endif /*INET6*/
878	case 4:
879		/* nexthdr & padding are in the last fragment */
880		if (EXTRACT_16BITS(&ip->ip_off) & IP_MF)
881			goto fail;
882		len = EXTRACT_16BITS(&ip->ip_len);
883
884		/* see if we can find the SA, and if so, decode it */
885		for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
886			struct sockaddr_in *sin = (struct sockaddr_in *)&sa->daddr;
887			if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
888			    sin->sin_family == AF_INET &&
889			    sin->sin_addr.s_addr == ip->ip_dst.s_addr) {
890				break;
891			}
892		}
893		break;
894	default:
895		goto fail;
896	}
897
898	/* if we didn't find the specific one, then look for
899	 * an unspecified one.
900	 */
901	if (sa == NULL)
902		sa = ndo->ndo_sa_default;
903
904	/* if not found fail */
905	if (sa == NULL)
906		goto fail;
907
908	/* if we can't get nexthdr, we do not need to decrypt it */
909	if (ep - bp2 < len)
910		goto fail;
911	if (ep - bp2 > len) {
912		/* FCS included at end of frame (NetBSD 1.6 or later) */
913		ep = bp2 + len;
914	}
915
916	ivoff = (u_char *)(esp + 1) + 0;
917	ivlen = sa->ivlen;
918	secret = sa->secret;
919	espsecret_keylen = sa->secretlen;
920	ep = ep - sa->authlen;
921
922#ifdef __APPLE__
923	if (sa->cipherData.algorithm != (CCAlgorithm)-1) {
924		ctx = NULL;
925		p = ivoff;
926		if (kCCSuccess != CCCryptorCreateFromCipherData(&sa->cipherData, kCCDecrypt, secret, p, &ctx))
927			(*ndo->ndo_warning)(ndo, "espkey init failed");
928		len = ep - (p + ivlen);
929		CCCryptorUpdate(ctx, p + ivlen, len, p + ivlen, len, &dataMoved);
930		CCCryptorRelease(ctx);
931		ctx = NULL;
932		advance = ivoff - (u_char *)esp + ivlen;
933	}
934	else
935		advance = sizeof(struct newesp);
936#else /* __APPLE__ */
937	if (sa->evp) {
938		memset(&ctx, 0, sizeof(ctx));
939		if (EVP_CipherInit(&ctx, sa->evp, secret, NULL, 0) < 0)
940			(*ndo->ndo_warning)(ndo, "espkey init failed");
941
942		blocksz = EVP_CIPHER_CTX_block_size(&ctx);
943
944		p = ivoff;
945		EVP_CipherInit(&ctx, NULL, NULL, p, 0);
946		EVP_Cipher(&ctx, p + ivlen, p + ivlen, ep - (p + ivlen));
947		EVP_CIPHER_CTX_cleanup(&ctx);
948		advance = ivoff - (u_char *)esp + ivlen;
949	} else
950		advance = sizeof(struct newesp);
951#endif /* __APPLE__ */
952
953	/* sanity check for pad length */
954	if (ep - bp < *(ep - 2))
955		goto fail;
956
957	if (padlen)
958		*padlen = *(ep - 2) + 2;
959
960	if (nhdr)
961		*nhdr = *(ep - 1);
962
963	(ndo->ndo_printf)(ndo, ": ");
964	return advance;
965#endif
966
967fail:
968	return -1;
969}
970
971/*
972 * Local Variables:
973 * c-style: whitesmith
974 * c-basic-offset: 8
975 * End:
976 */
977