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