1b0453382SBill Fenner /* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */ 2b0453382SBill Fenner 3b0453382SBill Fenner /* 4b0453382SBill Fenner * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 5b0453382SBill Fenner * The Regents of the University of California. All rights reserved. 6b0453382SBill Fenner * 7b0453382SBill Fenner * Redistribution and use in source and binary forms, with or without 8b0453382SBill Fenner * modification, are permitted provided that: (1) source code distributions 9b0453382SBill Fenner * retain the above copyright notice and this paragraph in its entirety, (2) 10b0453382SBill Fenner * distributions including binary code include the above copyright notice and 11b0453382SBill Fenner * this paragraph in its entirety in the documentation or other materials 12b0453382SBill Fenner * provided with the distribution, and (3) all advertising materials mentioning 13b0453382SBill Fenner * features or use of this software display the following acknowledgement: 14b0453382SBill Fenner * ``This product includes software developed by the University of California, 15b0453382SBill Fenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16b0453382SBill Fenner * the University nor the names of its contributors may be used to endorse 17b0453382SBill Fenner * or promote products derived from this software without specific prior 18b0453382SBill Fenner * written permission. 19b0453382SBill Fenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20b0453382SBill Fenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21b0453382SBill Fenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22b0453382SBill Fenner */ 23b0453382SBill Fenner 243340d773SGleb Smirnoff /* \summary: IPSEC Encapsulating Security Payload (ESP) printer */ 253340d773SGleb Smirnoff 26b0453382SBill Fenner #ifdef HAVE_CONFIG_H 27*ee67461eSJoseph Mingrone #include <config.h> 28b0453382SBill Fenner #endif 29b0453382SBill Fenner 30*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 315b0fe478SBruce M Simpson 323c602fabSXin LI #include <string.h> 339afd0c29SBill Fenner #include <stdlib.h> 34b0453382SBill Fenner 353c602fabSXin LI /* Any code in this file that depends on HAVE_LIBCRYPTO depends on 363c602fabSXin LI * HAVE_OPENSSL_EVP_H too. Undefining the former when the latter isn't defined 373c602fabSXin LI * is the simplest way of handling the dependency. 383c602fabSXin LI */ 39685295f4SBill Fenner #ifdef HAVE_LIBCRYPTO 405b0fe478SBruce M Simpson #ifdef HAVE_OPENSSL_EVP_H 415b0fe478SBruce M Simpson #include <openssl/evp.h> 423c602fabSXin LI #else 433c602fabSXin LI #undef HAVE_LIBCRYPTO 44b0453382SBill Fenner #endif 45b0453382SBill Fenner #endif 46b0453382SBill Fenner 473340d773SGleb Smirnoff #include "netdissect.h" 485b0fe478SBruce M Simpson #include "extract.h" 49b0453382SBill Fenner 50*ee67461eSJoseph Mingrone #include "diag-control.h" 51*ee67461eSJoseph Mingrone 52*ee67461eSJoseph Mingrone #ifdef HAVE_LIBCRYPTO 53*ee67461eSJoseph Mingrone #include "strtoaddr.h" 543340d773SGleb Smirnoff #include "ascii_strcasecmp.h" 55*ee67461eSJoseph Mingrone #endif 563340d773SGleb Smirnoff 573340d773SGleb Smirnoff #include "ip.h" 583340d773SGleb Smirnoff #include "ip6.h" 593340d773SGleb Smirnoff 603c602fabSXin LI /* 613c602fabSXin LI * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 623c602fabSXin LI * All rights reserved. 633c602fabSXin LI * 643c602fabSXin LI * Redistribution and use in source and binary forms, with or without 653c602fabSXin LI * modification, are permitted provided that the following conditions 663c602fabSXin LI * are met: 673c602fabSXin LI * 1. Redistributions of source code must retain the above copyright 683c602fabSXin LI * notice, this list of conditions and the following disclaimer. 693c602fabSXin LI * 2. Redistributions in binary form must reproduce the above copyright 703c602fabSXin LI * notice, this list of conditions and the following disclaimer in the 713c602fabSXin LI * documentation and/or other materials provided with the distribution. 723c602fabSXin LI * 3. Neither the name of the project nor the names of its contributors 733c602fabSXin LI * may be used to endorse or promote products derived from this software 743c602fabSXin LI * without specific prior written permission. 753c602fabSXin LI * 763c602fabSXin LI * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 773c602fabSXin LI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 783c602fabSXin LI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 793c602fabSXin LI * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 803c602fabSXin LI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 813c602fabSXin LI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 823c602fabSXin LI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 833c602fabSXin LI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 843c602fabSXin LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 853c602fabSXin LI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 863c602fabSXin LI * SUCH DAMAGE. 873c602fabSXin LI */ 883c602fabSXin LI 893c602fabSXin LI /* 903c602fabSXin LI * RFC1827/2406 Encapsulated Security Payload. 913c602fabSXin LI */ 923c602fabSXin LI 933c602fabSXin LI struct newesp { 94*ee67461eSJoseph Mingrone nd_uint32_t esp_spi; /* ESP */ 95*ee67461eSJoseph Mingrone nd_uint32_t esp_seq; /* Sequence number */ 963c602fabSXin LI /*variable size*/ /* (IV and) Payload data */ 973c602fabSXin LI /*variable size*/ /* padding */ 983c602fabSXin LI /*8bit*/ /* pad size */ 993c602fabSXin LI /*8bit*/ /* next header */ 1003c602fabSXin LI /*8bit*/ /* next header */ 1013c602fabSXin LI /*variable size, 32bit bound*/ /* Authentication data */ 1025b0fe478SBruce M Simpson }; 103a90e161bSBill Fenner 1045b0fe478SBruce M Simpson #ifdef HAVE_LIBCRYPTO 1053c602fabSXin LI union inaddr_u { 106*ee67461eSJoseph Mingrone nd_ipv4 in4; 107*ee67461eSJoseph Mingrone nd_ipv6 in6; 1083c602fabSXin LI }; 1095b0fe478SBruce M Simpson struct sa_list { 1105b0fe478SBruce M Simpson struct sa_list *next; 1113c602fabSXin LI u_int daddr_version; 1123c602fabSXin LI union inaddr_u daddr; 1133c602fabSXin LI uint32_t spi; /* if == 0, then IKEv2 */ 11427df3f5dSRui Paulo int initiator; 11527df3f5dSRui Paulo u_char spii[8]; /* for IKEv2 */ 11627df3f5dSRui Paulo u_char spir[8]; 1175b0fe478SBruce M Simpson const EVP_CIPHER *evp; 118*ee67461eSJoseph Mingrone u_int ivlen; 119a90e161bSBill Fenner int authlen; 12027df3f5dSRui Paulo u_char authsecret[256]; 12127df3f5dSRui Paulo int authsecret_len; 122f4d0c64aSSam Leffler u_char secret[256]; /* is that big enough for all secrets? */ 1235b0fe478SBruce M Simpson int secretlen; 124a90e161bSBill Fenner }; 125a90e161bSBill Fenner 1263340d773SGleb Smirnoff #ifndef HAVE_EVP_CIPHER_CTX_NEW 1273340d773SGleb Smirnoff /* 1283340d773SGleb Smirnoff * Allocate an EVP_CIPHER_CTX. 1293340d773SGleb Smirnoff * Used if we have an older version of OpenSSL that doesn't provide 1303340d773SGleb Smirnoff * routines to allocate and free them. 1313340d773SGleb Smirnoff */ 1323340d773SGleb Smirnoff static EVP_CIPHER_CTX * 1333340d773SGleb Smirnoff EVP_CIPHER_CTX_new(void) 1343340d773SGleb Smirnoff { 1353340d773SGleb Smirnoff EVP_CIPHER_CTX *ctx; 1363340d773SGleb Smirnoff 1373340d773SGleb Smirnoff ctx = malloc(sizeof(*ctx)); 1383340d773SGleb Smirnoff if (ctx == NULL) 1393340d773SGleb Smirnoff return (NULL); 1403340d773SGleb Smirnoff memset(ctx, 0, sizeof(*ctx)); 1413340d773SGleb Smirnoff return (ctx); 1423340d773SGleb Smirnoff } 1433340d773SGleb Smirnoff 1443340d773SGleb Smirnoff static void 1453340d773SGleb Smirnoff EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) 1463340d773SGleb Smirnoff { 1473340d773SGleb Smirnoff EVP_CIPHER_CTX_cleanup(ctx); 1483340d773SGleb Smirnoff free(ctx); 1493340d773SGleb Smirnoff } 1503340d773SGleb Smirnoff #endif 1513340d773SGleb Smirnoff 152*ee67461eSJoseph Mingrone #ifdef HAVE_EVP_DECRYPTINIT_EX 1530bff6a5aSEd Maste /* 154*ee67461eSJoseph Mingrone * Initialize the cipher by calling EVP_DecryptInit_ex(), because 155*ee67461eSJoseph Mingrone * calling EVP_DecryptInit() will reset the cipher context, clearing 1560bff6a5aSEd Maste * the cipher, so calling it twice, with the second call having a 157*ee67461eSJoseph Mingrone * null cipher, will clear the already-set cipher. EVP_DecryptInit_ex(), 1580bff6a5aSEd Maste * however, won't reset the cipher context, so you can use it to specify 159*ee67461eSJoseph Mingrone * the IV in a second call after a first call to EVP_DecryptInit_ex() 1600bff6a5aSEd Maste * to set the cipher and the key. 1610bff6a5aSEd Maste * 1620bff6a5aSEd Maste * XXX - is there some reason why we need to make two calls? 1630bff6a5aSEd Maste */ 1640bff6a5aSEd Maste static int 1650bff6a5aSEd Maste set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 1660bff6a5aSEd Maste const unsigned char *key, 167*ee67461eSJoseph Mingrone const unsigned char *iv) 1680bff6a5aSEd Maste { 169*ee67461eSJoseph Mingrone return EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv); 1700bff6a5aSEd Maste } 1710bff6a5aSEd Maste #else 1720bff6a5aSEd Maste /* 173*ee67461eSJoseph Mingrone * Initialize the cipher by calling EVP_DecryptInit(), because we don't 174*ee67461eSJoseph Mingrone * have EVP_DecryptInit_ex(); we rely on it not trashing the context. 1750bff6a5aSEd Maste */ 1760bff6a5aSEd Maste static int 1770bff6a5aSEd Maste set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 1780bff6a5aSEd Maste const unsigned char *key, 179*ee67461eSJoseph Mingrone const unsigned char *iv) 1800bff6a5aSEd Maste { 181*ee67461eSJoseph Mingrone return EVP_DecryptInit(ctx, cipher, key, iv); 1820bff6a5aSEd Maste } 1830bff6a5aSEd Maste #endif 1840bff6a5aSEd Maste 185*ee67461eSJoseph Mingrone static u_char * 186*ee67461eSJoseph Mingrone do_decrypt(netdissect_options *ndo, const char *caller, struct sa_list *sa, 187*ee67461eSJoseph Mingrone const u_char *iv, const u_char *ct, unsigned int ctlen) 188*ee67461eSJoseph Mingrone { 189*ee67461eSJoseph Mingrone EVP_CIPHER_CTX *ctx; 190*ee67461eSJoseph Mingrone unsigned int block_size; 191*ee67461eSJoseph Mingrone unsigned int ptlen; 192*ee67461eSJoseph Mingrone u_char *pt; 193*ee67461eSJoseph Mingrone int len; 194*ee67461eSJoseph Mingrone 195*ee67461eSJoseph Mingrone ctx = EVP_CIPHER_CTX_new(); 196*ee67461eSJoseph Mingrone if (ctx == NULL) { 19727df3f5dSRui Paulo /* 198*ee67461eSJoseph Mingrone * Failed to initialize the cipher context. 199*ee67461eSJoseph Mingrone * From a look at the OpenSSL code, this appears to 200*ee67461eSJoseph Mingrone * mean "couldn't allocate memory for the cipher context"; 201*ee67461eSJoseph Mingrone * note that we're not passing any parameters, so there's 202*ee67461eSJoseph Mingrone * not much else it can mean. 20327df3f5dSRui Paulo */ 204*ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 205*ee67461eSJoseph Mingrone "%s: can't allocate memory for cipher context", caller); 206*ee67461eSJoseph Mingrone return NULL; 207*ee67461eSJoseph Mingrone } 208*ee67461eSJoseph Mingrone 209*ee67461eSJoseph Mingrone if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL) < 0) { 210*ee67461eSJoseph Mingrone EVP_CIPHER_CTX_free(ctx); 211*ee67461eSJoseph Mingrone (*ndo->ndo_warning)(ndo, "%s: espkey init failed", caller); 212*ee67461eSJoseph Mingrone return NULL; 213*ee67461eSJoseph Mingrone } 214*ee67461eSJoseph Mingrone if (set_cipher_parameters(ctx, NULL, NULL, iv) < 0) { 215*ee67461eSJoseph Mingrone EVP_CIPHER_CTX_free(ctx); 216*ee67461eSJoseph Mingrone (*ndo->ndo_warning)(ndo, "%s: IV init failed", caller); 217*ee67461eSJoseph Mingrone return NULL; 218*ee67461eSJoseph Mingrone } 219*ee67461eSJoseph Mingrone 220*ee67461eSJoseph Mingrone /* 221*ee67461eSJoseph Mingrone * At least as I read RFC 5996 section 3.14 and RFC 4303 section 2.4, 222*ee67461eSJoseph Mingrone * if the cipher has a block size of which the ciphertext's size must 223*ee67461eSJoseph Mingrone * be a multiple, the payload must be padded to make that happen, so 224*ee67461eSJoseph Mingrone * the ciphertext length must be a multiple of the block size. Fail 225*ee67461eSJoseph Mingrone * if that's not the case. 226*ee67461eSJoseph Mingrone */ 227*ee67461eSJoseph Mingrone block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx); 228*ee67461eSJoseph Mingrone if ((ctlen % block_size) != 0) { 229*ee67461eSJoseph Mingrone EVP_CIPHER_CTX_free(ctx); 230*ee67461eSJoseph Mingrone (*ndo->ndo_warning)(ndo, 231*ee67461eSJoseph Mingrone "%s: ciphertext size %u is not a multiple of the cipher block size %u", 232*ee67461eSJoseph Mingrone caller, ctlen, block_size); 233*ee67461eSJoseph Mingrone return NULL; 234*ee67461eSJoseph Mingrone } 235*ee67461eSJoseph Mingrone 236*ee67461eSJoseph Mingrone /* 237*ee67461eSJoseph Mingrone * Attempt to allocate a buffer for the decrypted data, because 238*ee67461eSJoseph Mingrone * we can't decrypt on top of the input buffer. 239*ee67461eSJoseph Mingrone */ 240*ee67461eSJoseph Mingrone ptlen = ctlen; 241*ee67461eSJoseph Mingrone pt = (u_char *)calloc(1, ptlen); 242*ee67461eSJoseph Mingrone if (pt == NULL) { 243*ee67461eSJoseph Mingrone EVP_CIPHER_CTX_free(ctx); 244*ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 245*ee67461eSJoseph Mingrone "%s: can't allocate memory for decryption buffer", caller); 246*ee67461eSJoseph Mingrone return NULL; 247*ee67461eSJoseph Mingrone } 248*ee67461eSJoseph Mingrone 249*ee67461eSJoseph Mingrone /* 250*ee67461eSJoseph Mingrone * The size of the ciphertext handed to us is a multiple of the 251*ee67461eSJoseph Mingrone * cipher block size, so we don't need to worry about padding. 252*ee67461eSJoseph Mingrone */ 253*ee67461eSJoseph Mingrone if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) { 254*ee67461eSJoseph Mingrone free(pt); 255*ee67461eSJoseph Mingrone EVP_CIPHER_CTX_free(ctx); 256*ee67461eSJoseph Mingrone (*ndo->ndo_warning)(ndo, 257*ee67461eSJoseph Mingrone "%s: EVP_CIPHER_CTX_set_padding failed", caller); 258*ee67461eSJoseph Mingrone return NULL; 259*ee67461eSJoseph Mingrone } 260*ee67461eSJoseph Mingrone if (!EVP_DecryptUpdate(ctx, pt, &len, ct, ctlen)) { 261*ee67461eSJoseph Mingrone free(pt); 262*ee67461eSJoseph Mingrone EVP_CIPHER_CTX_free(ctx); 263*ee67461eSJoseph Mingrone (*ndo->ndo_warning)(ndo, "%s: EVP_DecryptUpdate failed", 264*ee67461eSJoseph Mingrone caller); 265*ee67461eSJoseph Mingrone return NULL; 266*ee67461eSJoseph Mingrone } 267*ee67461eSJoseph Mingrone EVP_CIPHER_CTX_free(ctx); 268*ee67461eSJoseph Mingrone return pt; 269*ee67461eSJoseph Mingrone } 270*ee67461eSJoseph Mingrone 271*ee67461eSJoseph Mingrone /* 272*ee67461eSJoseph Mingrone * This will allocate a new buffer containing the decrypted data. 273*ee67461eSJoseph Mingrone * It returns 1 on success and 0 on failure. 274*ee67461eSJoseph Mingrone * 275*ee67461eSJoseph Mingrone * It will push the new buffer and the values of ndo->ndo_packetp and 276*ee67461eSJoseph Mingrone * ndo->ndo_snapend onto the buffer stack, and change ndo->ndo_packetp 277*ee67461eSJoseph Mingrone * and ndo->ndo_snapend to refer to the new buffer. 278*ee67461eSJoseph Mingrone * 279*ee67461eSJoseph Mingrone * Our caller must pop the buffer off the stack when it's finished 280*ee67461eSJoseph Mingrone * dissecting anything in it and before it does any dissection of 281*ee67461eSJoseph Mingrone * anything in the old buffer. That will free the new buffer. 282*ee67461eSJoseph Mingrone */ 283*ee67461eSJoseph Mingrone DIAG_OFF_DEPRECATION 284*ee67461eSJoseph Mingrone int esp_decrypt_buffer_by_ikev2_print(netdissect_options *ndo, 28527df3f5dSRui Paulo int initiator, 286*ee67461eSJoseph Mingrone const u_char spii[8], 287*ee67461eSJoseph Mingrone const u_char spir[8], 2883340d773SGleb Smirnoff const u_char *buf, const u_char *end) 28927df3f5dSRui Paulo { 29027df3f5dSRui Paulo struct sa_list *sa; 2913340d773SGleb Smirnoff const u_char *iv; 292*ee67461eSJoseph Mingrone const u_char *ct; 293*ee67461eSJoseph Mingrone unsigned int ctlen; 294*ee67461eSJoseph Mingrone u_char *pt; 29527df3f5dSRui Paulo 29627df3f5dSRui Paulo /* initiator arg is any non-zero value */ 29727df3f5dSRui Paulo if(initiator) initiator=1; 29827df3f5dSRui Paulo 29927df3f5dSRui Paulo /* see if we can find the SA, and if so, decode it */ 30027df3f5dSRui Paulo for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { 30127df3f5dSRui Paulo if (sa->spi == 0 30227df3f5dSRui Paulo && initiator == sa->initiator 30327df3f5dSRui Paulo && memcmp(spii, sa->spii, 8) == 0 30427df3f5dSRui Paulo && memcmp(spir, sa->spir, 8) == 0) 30527df3f5dSRui Paulo break; 30627df3f5dSRui Paulo } 30727df3f5dSRui Paulo 30827df3f5dSRui Paulo if(sa == NULL) return 0; 30927df3f5dSRui Paulo if(sa->evp == NULL) return 0; 31027df3f5dSRui Paulo 31127df3f5dSRui Paulo /* 31227df3f5dSRui Paulo * remove authenticator, and see if we still have something to 31327df3f5dSRui Paulo * work with 31427df3f5dSRui Paulo */ 31527df3f5dSRui Paulo end = end - sa->authlen; 31627df3f5dSRui Paulo iv = buf; 317*ee67461eSJoseph Mingrone ct = iv + sa->ivlen; 318*ee67461eSJoseph Mingrone ctlen = end-ct; 31927df3f5dSRui Paulo 320*ee67461eSJoseph Mingrone if(end <= ct) return 0; 32127df3f5dSRui Paulo 322*ee67461eSJoseph Mingrone pt = do_decrypt(ndo, __func__, sa, iv, 323*ee67461eSJoseph Mingrone ct, ctlen); 324*ee67461eSJoseph Mingrone if (pt == NULL) 3253340d773SGleb Smirnoff return 0; 32639e421e8SCy Schubert 32739e421e8SCy Schubert /* 328*ee67461eSJoseph Mingrone * Switch to the output buffer for dissection, and save it 329*ee67461eSJoseph Mingrone * on the buffer stack so it can be freed; our caller must 330*ee67461eSJoseph Mingrone * pop it when done. 33139e421e8SCy Schubert */ 332*ee67461eSJoseph Mingrone if (!nd_push_buffer(ndo, pt, pt, ctlen)) { 333*ee67461eSJoseph Mingrone free(pt); 334*ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 335*ee67461eSJoseph Mingrone "%s: can't push buffer on buffer stack", __func__); 3360bff6a5aSEd Maste } 33727df3f5dSRui Paulo 33827df3f5dSRui Paulo return 1; 33927df3f5dSRui Paulo } 340*ee67461eSJoseph Mingrone DIAG_ON_DEPRECATION 34127df3f5dSRui Paulo 3421de50e9fSSam Leffler static void esp_print_addsa(netdissect_options *ndo, 343*ee67461eSJoseph Mingrone const struct sa_list *sa, int sa_def) 3445b0fe478SBruce M Simpson { 3455b0fe478SBruce M Simpson /* copy the "sa" */ 3465b0fe478SBruce M Simpson 3475b0fe478SBruce M Simpson struct sa_list *nsa; 3485b0fe478SBruce M Simpson 349*ee67461eSJoseph Mingrone /* malloc() return used in a 'struct sa_list': do not free() */ 3505b0fe478SBruce M Simpson nsa = (struct sa_list *)malloc(sizeof(struct sa_list)); 3515b0fe478SBruce M Simpson if (nsa == NULL) 352*ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 353*ee67461eSJoseph Mingrone "%s: malloc", __func__); 3545b0fe478SBruce M Simpson 3555b0fe478SBruce M Simpson *nsa = *sa; 3565b0fe478SBruce M Simpson 3575b0fe478SBruce M Simpson if (sa_def) 3581de50e9fSSam Leffler ndo->ndo_sa_default = nsa; 3595b0fe478SBruce M Simpson 3601de50e9fSSam Leffler nsa->next = ndo->ndo_sa_list_head; 3611de50e9fSSam Leffler ndo->ndo_sa_list_head = nsa; 3625b0fe478SBruce M Simpson } 3635b0fe478SBruce M Simpson 364a90e161bSBill Fenner 365f4d0c64aSSam Leffler static u_int hexdigit(netdissect_options *ndo, char hex) 366a90e161bSBill Fenner { 3675b0fe478SBruce M Simpson if (hex >= '0' && hex <= '9') 368a90e161bSBill Fenner return (hex - '0'); 3695b0fe478SBruce M Simpson else if (hex >= 'A' && hex <= 'F') 370a90e161bSBill Fenner return (hex - 'A' + 10); 3715b0fe478SBruce M Simpson else if (hex >= 'a' && hex <= 'f') 372a90e161bSBill Fenner return (hex - 'a' + 10); 3735b0fe478SBruce M Simpson else { 374*ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_ESP_SECRET, 375*ee67461eSJoseph Mingrone "invalid hex digit %c in espsecret\n", hex); 376a90e161bSBill Fenner } 377a90e161bSBill Fenner } 378a90e161bSBill Fenner 379f4d0c64aSSam Leffler static u_int hex2byte(netdissect_options *ndo, char *hexstring) 380a90e161bSBill Fenner { 381f4d0c64aSSam Leffler u_int byte; 382a90e161bSBill Fenner 3831de50e9fSSam Leffler byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]); 384a90e161bSBill Fenner return byte; 385a90e161bSBill Fenner } 386a90e161bSBill Fenner 3875b0fe478SBruce M Simpson /* 38827df3f5dSRui Paulo * returns size of binary, 0 on failure. 38927df3f5dSRui Paulo */ 390*ee67461eSJoseph Mingrone static int 391*ee67461eSJoseph Mingrone espprint_decode_hex(netdissect_options *ndo, 392*ee67461eSJoseph Mingrone u_char *binbuf, unsigned int binbuf_len, char *hex) 39327df3f5dSRui Paulo { 39427df3f5dSRui Paulo unsigned int len; 39527df3f5dSRui Paulo int i; 39627df3f5dSRui Paulo 39727df3f5dSRui Paulo len = strlen(hex) / 2; 39827df3f5dSRui Paulo 39927df3f5dSRui Paulo if (len > binbuf_len) { 400*ee67461eSJoseph Mingrone (*ndo->ndo_warning)(ndo, "secret is too big: %u\n", len); 40127df3f5dSRui Paulo return 0; 40227df3f5dSRui Paulo } 40327df3f5dSRui Paulo 40427df3f5dSRui Paulo i = 0; 40527df3f5dSRui Paulo while (hex[0] != '\0' && hex[1]!='\0') { 40627df3f5dSRui Paulo binbuf[i] = hex2byte(ndo, hex); 40727df3f5dSRui Paulo hex += 2; 40827df3f5dSRui Paulo i++; 40927df3f5dSRui Paulo } 41027df3f5dSRui Paulo 41127df3f5dSRui Paulo return i; 41227df3f5dSRui Paulo } 41327df3f5dSRui Paulo 41427df3f5dSRui Paulo /* 4155b0fe478SBruce M Simpson * decode the form: SPINUM@IP <tab> ALGONAME:0xsecret 41627df3f5dSRui Paulo */ 41727df3f5dSRui Paulo 418*ee67461eSJoseph Mingrone DIAG_OFF_DEPRECATION 41927df3f5dSRui Paulo static int 42027df3f5dSRui Paulo espprint_decode_encalgo(netdissect_options *ndo, 42127df3f5dSRui Paulo char *decode, struct sa_list *sa) 42227df3f5dSRui Paulo { 42327df3f5dSRui Paulo size_t i; 42427df3f5dSRui Paulo const EVP_CIPHER *evp; 42527df3f5dSRui Paulo int authlen = 0; 42627df3f5dSRui Paulo char *colon, *p; 42727df3f5dSRui Paulo 42827df3f5dSRui Paulo colon = strchr(decode, ':'); 42927df3f5dSRui Paulo if (colon == NULL) { 43027df3f5dSRui Paulo (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); 43127df3f5dSRui Paulo return 0; 43227df3f5dSRui Paulo } 43327df3f5dSRui Paulo *colon = '\0'; 43427df3f5dSRui Paulo 43527df3f5dSRui Paulo if (strlen(decode) > strlen("-hmac96") && 43627df3f5dSRui Paulo !strcmp(decode + strlen(decode) - strlen("-hmac96"), 43727df3f5dSRui Paulo "-hmac96")) { 43827df3f5dSRui Paulo p = strstr(decode, "-hmac96"); 43927df3f5dSRui Paulo *p = '\0'; 44027df3f5dSRui Paulo authlen = 12; 44127df3f5dSRui Paulo } 44227df3f5dSRui Paulo if (strlen(decode) > strlen("-cbc") && 44327df3f5dSRui Paulo !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) { 44427df3f5dSRui Paulo p = strstr(decode, "-cbc"); 44527df3f5dSRui Paulo *p = '\0'; 44627df3f5dSRui Paulo } 44727df3f5dSRui Paulo evp = EVP_get_cipherbyname(decode); 44827df3f5dSRui Paulo 44927df3f5dSRui Paulo if (!evp) { 45027df3f5dSRui Paulo (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode); 45127df3f5dSRui Paulo sa->evp = NULL; 45227df3f5dSRui Paulo sa->authlen = 0; 45327df3f5dSRui Paulo sa->ivlen = 0; 45427df3f5dSRui Paulo return 0; 45527df3f5dSRui Paulo } 45627df3f5dSRui Paulo 45727df3f5dSRui Paulo sa->evp = evp; 45827df3f5dSRui Paulo sa->authlen = authlen; 459*ee67461eSJoseph Mingrone /* This returns an int, but it should never be negative */ 46027df3f5dSRui Paulo sa->ivlen = EVP_CIPHER_iv_length(evp); 46127df3f5dSRui Paulo 46227df3f5dSRui Paulo colon++; 46327df3f5dSRui Paulo if (colon[0] == '0' && colon[1] == 'x') { 46427df3f5dSRui Paulo /* decode some hex! */ 46527df3f5dSRui Paulo 46627df3f5dSRui Paulo colon += 2; 46727df3f5dSRui Paulo sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon); 46827df3f5dSRui Paulo if(sa->secretlen == 0) return 0; 46927df3f5dSRui Paulo } else { 47027df3f5dSRui Paulo i = strlen(colon); 47127df3f5dSRui Paulo 47227df3f5dSRui Paulo if (i < sizeof(sa->secret)) { 47327df3f5dSRui Paulo memcpy(sa->secret, colon, i); 47427df3f5dSRui Paulo sa->secretlen = i; 47527df3f5dSRui Paulo } else { 47627df3f5dSRui Paulo memcpy(sa->secret, colon, sizeof(sa->secret)); 47727df3f5dSRui Paulo sa->secretlen = sizeof(sa->secret); 47827df3f5dSRui Paulo } 47927df3f5dSRui Paulo } 48027df3f5dSRui Paulo 48127df3f5dSRui Paulo return 1; 48227df3f5dSRui Paulo } 483*ee67461eSJoseph Mingrone DIAG_ON_DEPRECATION 48427df3f5dSRui Paulo 48527df3f5dSRui Paulo /* 48639e421e8SCy Schubert * for the moment, ignore the auth algorithm, just hard code the authenticator 48727df3f5dSRui Paulo * length. Need to research how openssl looks up HMAC stuff. 48827df3f5dSRui Paulo */ 48927df3f5dSRui Paulo static int 49027df3f5dSRui Paulo espprint_decode_authalgo(netdissect_options *ndo, 49127df3f5dSRui Paulo char *decode, struct sa_list *sa) 49227df3f5dSRui Paulo { 49327df3f5dSRui Paulo char *colon; 49427df3f5dSRui Paulo 49527df3f5dSRui Paulo colon = strchr(decode, ':'); 49627df3f5dSRui Paulo if (colon == NULL) { 49727df3f5dSRui Paulo (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); 49827df3f5dSRui Paulo return 0; 49927df3f5dSRui Paulo } 50027df3f5dSRui Paulo *colon = '\0'; 50127df3f5dSRui Paulo 502*ee67461eSJoseph Mingrone if(ascii_strcasecmp(decode,"sha1") == 0 || 503*ee67461eSJoseph Mingrone ascii_strcasecmp(decode,"md5") == 0) { 50427df3f5dSRui Paulo sa->authlen = 12; 50527df3f5dSRui Paulo } 50627df3f5dSRui Paulo return 1; 50727df3f5dSRui Paulo } 50827df3f5dSRui Paulo 50927df3f5dSRui Paulo static void esp_print_decode_ikeline(netdissect_options *ndo, char *line, 51027df3f5dSRui Paulo const char *file, int lineno) 51127df3f5dSRui Paulo { 51227df3f5dSRui Paulo /* it's an IKEv2 secret, store it instead */ 51327df3f5dSRui Paulo struct sa_list sa1; 51427df3f5dSRui Paulo 51527df3f5dSRui Paulo char *init; 51627df3f5dSRui Paulo char *icookie, *rcookie; 51727df3f5dSRui Paulo int ilen, rlen; 51827df3f5dSRui Paulo char *authkey; 51927df3f5dSRui Paulo char *enckey; 52027df3f5dSRui Paulo 52127df3f5dSRui Paulo init = strsep(&line, " \t"); 52227df3f5dSRui Paulo icookie = strsep(&line, " \t"); 52327df3f5dSRui Paulo rcookie = strsep(&line, " \t"); 52427df3f5dSRui Paulo authkey = strsep(&line, " \t"); 52527df3f5dSRui Paulo enckey = strsep(&line, " \t"); 52627df3f5dSRui Paulo 52727df3f5dSRui Paulo /* if any fields are missing */ 52827df3f5dSRui Paulo if(!init || !icookie || !rcookie || !authkey || !enckey) { 52927df3f5dSRui Paulo (*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u", 53027df3f5dSRui Paulo file, lineno); 53127df3f5dSRui Paulo 53227df3f5dSRui Paulo return; 53327df3f5dSRui Paulo } 53427df3f5dSRui Paulo 53527df3f5dSRui Paulo ilen = strlen(icookie); 53627df3f5dSRui Paulo rlen = strlen(rcookie); 53727df3f5dSRui Paulo 53827df3f5dSRui Paulo if((init[0]!='I' && init[0]!='R') 53927df3f5dSRui Paulo || icookie[0]!='0' || icookie[1]!='x' 54027df3f5dSRui Paulo || rcookie[0]!='0' || rcookie[1]!='x' 54127df3f5dSRui Paulo || ilen!=18 54227df3f5dSRui Paulo || rlen!=18) { 54327df3f5dSRui Paulo (*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.", 54427df3f5dSRui Paulo file, lineno); 54527df3f5dSRui Paulo 54627df3f5dSRui Paulo (*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)", 54727df3f5dSRui Paulo init, icookie, ilen, rcookie, rlen); 54827df3f5dSRui Paulo 54927df3f5dSRui Paulo return; 55027df3f5dSRui Paulo } 55127df3f5dSRui Paulo 55227df3f5dSRui Paulo sa1.spi = 0; 55327df3f5dSRui Paulo sa1.initiator = (init[0] == 'I'); 55427df3f5dSRui Paulo if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8) 55527df3f5dSRui Paulo return; 55627df3f5dSRui Paulo 55727df3f5dSRui Paulo if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8) 55827df3f5dSRui Paulo return; 55927df3f5dSRui Paulo 56027df3f5dSRui Paulo if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return; 56127df3f5dSRui Paulo 56227df3f5dSRui Paulo if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return; 56327df3f5dSRui Paulo 56427df3f5dSRui Paulo esp_print_addsa(ndo, &sa1, FALSE); 56527df3f5dSRui Paulo } 56627df3f5dSRui Paulo 56727df3f5dSRui Paulo /* 5685b0fe478SBruce M Simpson * 5695b0fe478SBruce M Simpson * special form: file /name 5705b0fe478SBruce M Simpson * causes us to go read from this file instead. 5715b0fe478SBruce M Simpson * 5725b0fe478SBruce M Simpson */ 57327df3f5dSRui Paulo static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, 57427df3f5dSRui Paulo const char *file, int lineno) 575a90e161bSBill Fenner { 5765b0fe478SBruce M Simpson struct sa_list sa1; 5775b0fe478SBruce M Simpson int sa_def; 578a90e161bSBill Fenner 5795b0fe478SBruce M Simpson char *spikey; 5805b0fe478SBruce M Simpson char *decode; 5815b0fe478SBruce M Simpson 5825b0fe478SBruce M Simpson spikey = strsep(&line, " \t"); 5835b0fe478SBruce M Simpson sa_def = 0; 5845b0fe478SBruce M Simpson memset(&sa1, 0, sizeof(struct sa_list)); 5855b0fe478SBruce M Simpson 5865b0fe478SBruce M Simpson /* if there is only one token, then it is an algo:key token */ 5875b0fe478SBruce M Simpson if (line == NULL) { 5885b0fe478SBruce M Simpson decode = spikey; 5895b0fe478SBruce M Simpson spikey = NULL; 5903c602fabSXin LI /* sa1.daddr.version = 0; */ 5915b0fe478SBruce M Simpson /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */ 5925b0fe478SBruce M Simpson /* sa1.spi = 0; */ 5935b0fe478SBruce M Simpson sa_def = 1; 5945b0fe478SBruce M Simpson } else 5955b0fe478SBruce M Simpson decode = line; 5965b0fe478SBruce M Simpson 5973340d773SGleb Smirnoff if (spikey && ascii_strcasecmp(spikey, "file") == 0) { 5985b0fe478SBruce M Simpson /* open file and read it */ 5995b0fe478SBruce M Simpson FILE *secretfile; 6005b0fe478SBruce M Simpson char fileline[1024]; 6013340d773SGleb Smirnoff int subfile_lineno=0; 6025b0fe478SBruce M Simpson char *nl; 60327df3f5dSRui Paulo char *filename = line; 6045b0fe478SBruce M Simpson 60527df3f5dSRui Paulo secretfile = fopen(filename, FOPEN_READ_TXT); 6065b0fe478SBruce M Simpson if (secretfile == NULL) { 607*ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_OPEN_FILE, 608*ee67461eSJoseph Mingrone "%s: can't open %s: %s\n", 609*ee67461eSJoseph Mingrone __func__, filename, strerror(errno)); 6105b0fe478SBruce M Simpson } 6115b0fe478SBruce M Simpson 6125b0fe478SBruce M Simpson while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) { 6133340d773SGleb Smirnoff subfile_lineno++; 6145b0fe478SBruce M Simpson /* remove newline from the line */ 6155b0fe478SBruce M Simpson nl = strchr(fileline, '\n'); 6165b0fe478SBruce M Simpson if (nl) 6175b0fe478SBruce M Simpson *nl = '\0'; 6185b0fe478SBruce M Simpson if (fileline[0] == '#') continue; 6195b0fe478SBruce M Simpson if (fileline[0] == '\0') continue; 6205b0fe478SBruce M Simpson 6213340d773SGleb Smirnoff esp_print_decode_onesecret(ndo, fileline, filename, subfile_lineno); 6225b0fe478SBruce M Simpson } 6235b0fe478SBruce M Simpson fclose(secretfile); 6245b0fe478SBruce M Simpson 625a90e161bSBill Fenner return; 626a90e161bSBill Fenner } 627a90e161bSBill Fenner 6283340d773SGleb Smirnoff if (spikey && ascii_strcasecmp(spikey, "ikev2") == 0) { 62927df3f5dSRui Paulo esp_print_decode_ikeline(ndo, line, file, lineno); 63027df3f5dSRui Paulo return; 63127df3f5dSRui Paulo } 63227df3f5dSRui Paulo 6335b0fe478SBruce M Simpson if (spikey) { 63427df3f5dSRui Paulo 6355b0fe478SBruce M Simpson char *spistr, *foo; 6363c602fabSXin LI uint32_t spino; 6375b0fe478SBruce M Simpson 6385b0fe478SBruce M Simpson spistr = strsep(&spikey, "@"); 63939e421e8SCy Schubert if (spistr == NULL) { 64039e421e8SCy Schubert (*ndo->ndo_warning)(ndo, "print_esp: failed to find the @ token"); 64139e421e8SCy Schubert return; 64239e421e8SCy Schubert } 6435b0fe478SBruce M Simpson 6445b0fe478SBruce M Simpson spino = strtoul(spistr, &foo, 0); 6455b0fe478SBruce M Simpson if (spistr == foo || !spikey) { 6461de50e9fSSam Leffler (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo); 647a90e161bSBill Fenner return; 648a90e161bSBill Fenner } 649a90e161bSBill Fenner 6505b0fe478SBruce M Simpson sa1.spi = spino; 6515b0fe478SBruce M Simpson 6523340d773SGleb Smirnoff if (strtoaddr6(spikey, &sa1.daddr.in6) == 1) { 6533c602fabSXin LI sa1.daddr_version = 6; 6543340d773SGleb Smirnoff } else if (strtoaddr(spikey, &sa1.daddr.in4) == 1) { 6553c602fabSXin LI sa1.daddr_version = 4; 6565b0fe478SBruce M Simpson } else { 6571de50e9fSSam Leffler (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); 6585b0fe478SBruce M Simpson return; 6595b0fe478SBruce M Simpson } 6605b0fe478SBruce M Simpson } 6615b0fe478SBruce M Simpson 6625b0fe478SBruce M Simpson if (decode) { 6635b0fe478SBruce M Simpson /* skip any blank spaces */ 664*ee67461eSJoseph Mingrone while (*decode == ' ' || *decode == '\t' || *decode == '\r' || *decode == '\n') 6655b0fe478SBruce M Simpson decode++; 6665b0fe478SBruce M Simpson 66727df3f5dSRui Paulo if(!espprint_decode_encalgo(ndo, decode, &sa1)) { 668a90e161bSBill Fenner return; 669a90e161bSBill Fenner } 670a90e161bSBill Fenner } 671a90e161bSBill Fenner 6721de50e9fSSam Leffler esp_print_addsa(ndo, &sa1, sa_def); 6735b0fe478SBruce M Simpson } 6745b0fe478SBruce M Simpson 675*ee67461eSJoseph Mingrone DIAG_OFF_DEPRECATION 6761de50e9fSSam Leffler static void esp_init(netdissect_options *ndo _U_) 6775b0fe478SBruce M Simpson { 6783340d773SGleb Smirnoff /* 6793340d773SGleb Smirnoff * 0.9.6 doesn't appear to define OPENSSL_API_COMPAT, so 6803340d773SGleb Smirnoff * we check whether it's undefined or it's less than the 6813340d773SGleb Smirnoff * value for 1.1.0. 6823340d773SGleb Smirnoff */ 6833340d773SGleb Smirnoff #if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < 0x10100000L 6845b0fe478SBruce M Simpson OpenSSL_add_all_algorithms(); 6853340d773SGleb Smirnoff #endif 6865b0fe478SBruce M Simpson EVP_add_cipher_alias(SN_des_ede3_cbc, "3des"); 6875b0fe478SBruce M Simpson } 688*ee67461eSJoseph Mingrone DIAG_ON_DEPRECATION 68927df3f5dSRui Paulo 690*ee67461eSJoseph Mingrone void esp_decodesecret_print(netdissect_options *ndo) 69127df3f5dSRui Paulo { 69227df3f5dSRui Paulo char *line; 69327df3f5dSRui Paulo char *p; 69427df3f5dSRui Paulo static int initialized = 0; 69527df3f5dSRui Paulo 69627df3f5dSRui Paulo if (!initialized) { 69727df3f5dSRui Paulo esp_init(ndo); 69827df3f5dSRui Paulo initialized = 1; 69927df3f5dSRui Paulo } 70027df3f5dSRui Paulo 70127df3f5dSRui Paulo p = ndo->ndo_espsecret; 70227df3f5dSRui Paulo 70327df3f5dSRui Paulo while (p && p[0] != '\0') { 70427df3f5dSRui Paulo /* pick out the first line or first thing until a comma */ 70527df3f5dSRui Paulo if ((line = strsep(&p, "\n,")) == NULL) { 70627df3f5dSRui Paulo line = p; 70727df3f5dSRui Paulo p = NULL; 70827df3f5dSRui Paulo } 70927df3f5dSRui Paulo 71027df3f5dSRui Paulo esp_print_decode_onesecret(ndo, line, "cmdline", 0); 71127df3f5dSRui Paulo } 71227df3f5dSRui Paulo 71327df3f5dSRui Paulo ndo->ndo_espsecret = NULL; 71427df3f5dSRui Paulo } 71527df3f5dSRui Paulo 7165b0fe478SBruce M Simpson #endif 7175b0fe478SBruce M Simpson 7183c602fabSXin LI #ifdef HAVE_LIBCRYPTO 719*ee67461eSJoseph Mingrone #define USED_IF_LIBCRYPTO 720*ee67461eSJoseph Mingrone #else 721*ee67461eSJoseph Mingrone #define USED_IF_LIBCRYPTO _U_ 7223c602fabSXin LI #endif 723*ee67461eSJoseph Mingrone 724*ee67461eSJoseph Mingrone #ifdef HAVE_LIBCRYPTO 725*ee67461eSJoseph Mingrone DIAG_OFF_DEPRECATION 726*ee67461eSJoseph Mingrone #endif 727*ee67461eSJoseph Mingrone void 7281de50e9fSSam Leffler esp_print(netdissect_options *ndo, 729*ee67461eSJoseph Mingrone const u_char *bp, u_int length, 730*ee67461eSJoseph Mingrone const u_char *bp2 USED_IF_LIBCRYPTO, 731*ee67461eSJoseph Mingrone u_int ver USED_IF_LIBCRYPTO, 732*ee67461eSJoseph Mingrone int fragmented USED_IF_LIBCRYPTO, 733*ee67461eSJoseph Mingrone u_int ttl_hl USED_IF_LIBCRYPTO) 7345b0fe478SBruce M Simpson { 735*ee67461eSJoseph Mingrone const struct newesp *esp; 736*ee67461eSJoseph Mingrone const u_char *ep; 7375b0fe478SBruce M Simpson #ifdef HAVE_LIBCRYPTO 7383340d773SGleb Smirnoff const struct ip *ip; 7395b0fe478SBruce M Simpson struct sa_list *sa = NULL; 7403340d773SGleb Smirnoff const struct ip6_hdr *ip6 = NULL; 741*ee67461eSJoseph Mingrone const u_char *iv; 742*ee67461eSJoseph Mingrone u_int ivlen; 743*ee67461eSJoseph Mingrone u_int payloadlen; 744*ee67461eSJoseph Mingrone const u_char *ct; 745*ee67461eSJoseph Mingrone u_char *pt; 746*ee67461eSJoseph Mingrone u_int padlen; 747*ee67461eSJoseph Mingrone u_int nh; 7485b0fe478SBruce M Simpson #endif 749b0453382SBill Fenner 750*ee67461eSJoseph Mingrone ndo->ndo_protocol = "esp"; 7513340d773SGleb Smirnoff esp = (const struct newesp *)bp; 7525b0fe478SBruce M Simpson 753685295f4SBill Fenner /* 'ep' points to the end of available data. */ 7541de50e9fSSam Leffler ep = ndo->ndo_snapend; 755b0453382SBill Fenner 7563340d773SGleb Smirnoff if ((const u_char *)(esp + 1) >= ep) { 757*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 758*ee67461eSJoseph Mingrone return; 759b0453382SBill Fenner } 760*ee67461eSJoseph Mingrone ND_PRINT("ESP(spi=0x%08x", GET_BE_U_4(esp->esp_spi)); 761*ee67461eSJoseph Mingrone ND_PRINT(",seq=0x%x)", GET_BE_U_4(esp->esp_seq)); 762*ee67461eSJoseph Mingrone ND_PRINT(", length %u", length); 763b0453382SBill Fenner 764*ee67461eSJoseph Mingrone #ifdef HAVE_LIBCRYPTO 765*ee67461eSJoseph Mingrone /* initialize SAs */ 7661de50e9fSSam Leffler if (ndo->ndo_sa_list_head == NULL) { 7671de50e9fSSam Leffler if (!ndo->ndo_espsecret) 768*ee67461eSJoseph Mingrone return; 769b0453382SBill Fenner 770*ee67461eSJoseph Mingrone esp_decodesecret_print(ndo); 771a90e161bSBill Fenner } 7725b0fe478SBruce M Simpson 7731de50e9fSSam Leffler if (ndo->ndo_sa_list_head == NULL) 774*ee67461eSJoseph Mingrone return; 775b0453382SBill Fenner 7763340d773SGleb Smirnoff ip = (const struct ip *)bp2; 777*ee67461eSJoseph Mingrone switch (ver) { 778b0453382SBill Fenner case 6: 7793340d773SGleb Smirnoff ip6 = (const struct ip6_hdr *)bp2; 780b0453382SBill Fenner /* we do not attempt to decrypt jumbograms */ 781*ee67461eSJoseph Mingrone if (!GET_BE_U_2(ip6->ip6_plen)) 782*ee67461eSJoseph Mingrone return; 783*ee67461eSJoseph Mingrone /* XXX - check whether it's fragmented? */ 784b0453382SBill Fenner /* if we can't get nexthdr, we do not need to decrypt it */ 7855b0fe478SBruce M Simpson 7865b0fe478SBruce M Simpson /* see if we can find the SA, and if so, decode it */ 7871de50e9fSSam Leffler for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { 788*ee67461eSJoseph Mingrone if (sa->spi == GET_BE_U_4(esp->esp_spi) && 7893c602fabSXin LI sa->daddr_version == 6 && 7903c602fabSXin LI UNALIGNED_MEMCMP(&sa->daddr.in6, &ip6->ip6_dst, 791*ee67461eSJoseph Mingrone sizeof(nd_ipv6)) == 0) { 7925b0fe478SBruce M Simpson break; 7935b0fe478SBruce M Simpson } 7945b0fe478SBruce M Simpson } 795b0453382SBill Fenner break; 796b0453382SBill Fenner case 4: 797a90e161bSBill Fenner /* nexthdr & padding are in the last fragment */ 798*ee67461eSJoseph Mingrone if (fragmented) 799*ee67461eSJoseph Mingrone return; 8005b0fe478SBruce M Simpson 8015b0fe478SBruce M Simpson /* see if we can find the SA, and if so, decode it */ 8021de50e9fSSam Leffler for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { 803*ee67461eSJoseph Mingrone if (sa->spi == GET_BE_U_4(esp->esp_spi) && 8043c602fabSXin LI sa->daddr_version == 4 && 8053c602fabSXin LI UNALIGNED_MEMCMP(&sa->daddr.in4, &ip->ip_dst, 806*ee67461eSJoseph Mingrone sizeof(nd_ipv4)) == 0) { 8075b0fe478SBruce M Simpson break; 8085b0fe478SBruce M Simpson } 8095b0fe478SBruce M Simpson } 810b0453382SBill Fenner break; 811b0453382SBill Fenner default: 812*ee67461eSJoseph Mingrone return; 813b0453382SBill Fenner } 814b0453382SBill Fenner 8155b0fe478SBruce M Simpson /* if we didn't find the specific one, then look for 8165b0fe478SBruce M Simpson * an unspecified one. 8175b0fe478SBruce M Simpson */ 8185b0fe478SBruce M Simpson if (sa == NULL) 8191de50e9fSSam Leffler sa = ndo->ndo_sa_default; 8205b0fe478SBruce M Simpson 8215b0fe478SBruce M Simpson /* if not found fail */ 8225b0fe478SBruce M Simpson if (sa == NULL) 823*ee67461eSJoseph Mingrone return; 824b0453382SBill Fenner 8250bff6a5aSEd Maste /* pointer to the IV, if there is one */ 826*ee67461eSJoseph Mingrone iv = (const u_char *)(esp + 1) + 0; 8270bff6a5aSEd Maste /* length of the IV, if there is one; 0, if there isn't */ 8285b0fe478SBruce M Simpson ivlen = sa->ivlen; 829*ee67461eSJoseph Mingrone 830*ee67461eSJoseph Mingrone /* 831*ee67461eSJoseph Mingrone * Get a pointer to the ciphertext. 832*ee67461eSJoseph Mingrone * 833*ee67461eSJoseph Mingrone * p points to the beginning of the payload, i.e. to the 834*ee67461eSJoseph Mingrone * initialization vector, so if we skip past the initialization 835*ee67461eSJoseph Mingrone * vector, it points to the beginning of the ciphertext. 836*ee67461eSJoseph Mingrone */ 837*ee67461eSJoseph Mingrone ct = iv + ivlen; 838*ee67461eSJoseph Mingrone 839*ee67461eSJoseph Mingrone /* 840*ee67461eSJoseph Mingrone * Make sure the authentication data/integrity check value length 841*ee67461eSJoseph Mingrone * isn't bigger than the total amount of data available after 842*ee67461eSJoseph Mingrone * the ESP header and initialization vector is removed and, 843*ee67461eSJoseph Mingrone * if not, slice the authentication data/ICV off. 844*ee67461eSJoseph Mingrone */ 845*ee67461eSJoseph Mingrone if (ep - ct < sa->authlen) { 846*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 847*ee67461eSJoseph Mingrone return; 848*ee67461eSJoseph Mingrone } 8491de50e9fSSam Leffler ep = ep - sa->authlen; 850b0453382SBill Fenner 851*ee67461eSJoseph Mingrone /* 852*ee67461eSJoseph Mingrone * Calculate the length of the ciphertext. ep points to 853*ee67461eSJoseph Mingrone * the beginning of the authentication data/integrity check 854*ee67461eSJoseph Mingrone * value, i.e. right past the end of the ciphertext; 855*ee67461eSJoseph Mingrone */ 856*ee67461eSJoseph Mingrone payloadlen = ep - ct; 8575b0fe478SBruce M Simpson 858*ee67461eSJoseph Mingrone if (sa->evp == NULL) 859*ee67461eSJoseph Mingrone return; 8600bff6a5aSEd Maste 8610bff6a5aSEd Maste /* 862*ee67461eSJoseph Mingrone * If the next header value is past the end of the available 863*ee67461eSJoseph Mingrone * data, we won't be able to fetch it once we've decrypted 864*ee67461eSJoseph Mingrone * the ciphertext, so there's no point in decrypting the data. 865*ee67461eSJoseph Mingrone * 866*ee67461eSJoseph Mingrone * Report it as truncation. 8670bff6a5aSEd Maste */ 868*ee67461eSJoseph Mingrone if (!ND_TTEST_1(ep - 1)) { 869*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 870*ee67461eSJoseph Mingrone return; 8710bff6a5aSEd Maste } 8720bff6a5aSEd Maste 873*ee67461eSJoseph Mingrone pt = do_decrypt(ndo, __func__, sa, iv, ct, payloadlen); 874*ee67461eSJoseph Mingrone if (pt == NULL) 875*ee67461eSJoseph Mingrone return; 876*ee67461eSJoseph Mingrone 8770bff6a5aSEd Maste /* 878*ee67461eSJoseph Mingrone * Switch to the output buffer for dissection, and 879*ee67461eSJoseph Mingrone * save it on the buffer stack so it can be freed. 8800bff6a5aSEd Maste */ 881*ee67461eSJoseph Mingrone if (!nd_push_buffer(ndo, pt, pt, payloadlen)) { 882*ee67461eSJoseph Mingrone free(pt); 883*ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 884*ee67461eSJoseph Mingrone "%s: can't push buffer on buffer stack", __func__); 885*ee67461eSJoseph Mingrone } 886b0453382SBill Fenner 887*ee67461eSJoseph Mingrone /* 888*ee67461eSJoseph Mingrone * Sanity check for pad length; if it, plus 2 for the pad 889*ee67461eSJoseph Mingrone * length and next header fields, is bigger than the ciphertext 890*ee67461eSJoseph Mingrone * length (which is also the plaintext length), it's too big. 891*ee67461eSJoseph Mingrone * 892*ee67461eSJoseph Mingrone * XXX - the check can fail if the packet is corrupt *or* if 893*ee67461eSJoseph Mingrone * it was not decrypted with the correct key, so that the 894*ee67461eSJoseph Mingrone * "plaintext" is not what was being sent. 895*ee67461eSJoseph Mingrone */ 896*ee67461eSJoseph Mingrone padlen = GET_U_1(pt + payloadlen - 2); 897*ee67461eSJoseph Mingrone if (padlen + 2 > payloadlen) { 898*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 899*ee67461eSJoseph Mingrone return; 900*ee67461eSJoseph Mingrone } 901b0453382SBill Fenner 902*ee67461eSJoseph Mingrone /* Get the next header */ 903*ee67461eSJoseph Mingrone nh = GET_U_1(pt + payloadlen - 1); 904a90e161bSBill Fenner 905*ee67461eSJoseph Mingrone ND_PRINT(": "); 906b0453382SBill Fenner 907*ee67461eSJoseph Mingrone /* 908*ee67461eSJoseph Mingrone * Don't put padding + padding length(1 byte) + next header(1 byte) 909*ee67461eSJoseph Mingrone * in the buffer because they are not part of the plaintext to decode. 910*ee67461eSJoseph Mingrone */ 911*ee67461eSJoseph Mingrone if (!nd_push_snaplen(ndo, pt, payloadlen - (padlen + 2))) { 912*ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 913*ee67461eSJoseph Mingrone "%s: can't push snaplen on buffer stack", __func__); 914*ee67461eSJoseph Mingrone } 915*ee67461eSJoseph Mingrone 916*ee67461eSJoseph Mingrone /* Now dissect the plaintext. */ 917*ee67461eSJoseph Mingrone ip_demux_print(ndo, pt, payloadlen - (padlen + 2), ver, fragmented, 918*ee67461eSJoseph Mingrone ttl_hl, nh, bp2); 919*ee67461eSJoseph Mingrone 920*ee67461eSJoseph Mingrone /* Pop the buffer, freeing it. */ 921*ee67461eSJoseph Mingrone nd_pop_packet_info(ndo); 922*ee67461eSJoseph Mingrone /* Pop the nd_push_snaplen */ 923*ee67461eSJoseph Mingrone nd_pop_packet_info(ndo); 9245b0fe478SBruce M Simpson #endif 925b0453382SBill Fenner } 9263c602fabSXin LI #ifdef HAVE_LIBCRYPTO 927*ee67461eSJoseph Mingrone DIAG_ON_DEPRECATION 9283c602fabSXin LI #endif 929