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