1/* 2 * Copyright (c) 2008-2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29/* $FreeBSD: src/sys/netinet6/ah_core.c,v 1.2.2.4 2001/07/03 11:01:49 ume Exp $ */ 30/* $KAME: ah_core.c,v 1.44 2001/03/12 11:24:39 itojun Exp $ */ 31 32/* 33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the project nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 */ 60 61/* 62 * RFC1826/2402 authentication header. 63 */ 64 65/* TODO: have shared routines for hmac-* algorithms */ 66 67#include <sys/param.h> 68#include <sys/systm.h> 69#include <sys/malloc.h> 70#include <sys/mbuf.h> 71#include <sys/domain.h> 72#include <sys/protosw.h> 73#include <sys/socket.h> 74#include <sys/socketvar.h> 75#include <sys/errno.h> 76#include <sys/time.h> 77#include <sys/syslog.h> 78 79#include <net/if.h> 80#include <net/route.h> 81 82#include <netinet/in.h> 83#include <netinet/in_systm.h> 84#include <netinet/ip.h> 85#include <netinet/in_var.h> 86 87#if INET6 88#include <netinet/ip6.h> 89#include <netinet6/ip6_var.h> 90#include <netinet/icmp6.h> 91#endif 92 93#include <netinet6/ipsec.h> 94#if INET6 95#include <netinet6/ipsec6.h> 96#endif 97#include <netinet6/ah.h> 98#if INET6 99#include <netinet6/ah6.h> 100#endif 101#if IPSEC_ESP 102#include <netinet6/esp.h> 103#if INET6 104#include <netinet6/esp6.h> 105#endif 106#endif 107#include <net/pfkeyv2.h> 108#include <netkey/keydb.h> 109#include <libkern/crypto/md5.h> 110#include <libkern/crypto/sha1.h> 111#include <libkern/crypto/sha2.h> 112 113#include <net/net_osdep.h> 114 115#define HMACSIZE 16 116 117static int ah_sumsiz_1216(struct secasvar *); 118static int ah_sumsiz_zero(struct secasvar *); 119static int ah_none_mature(struct secasvar *); 120static int ah_none_init(struct ah_algorithm_state *, struct secasvar *); 121static void ah_none_loop(struct ah_algorithm_state *, caddr_t, size_t); 122static void ah_none_result(struct ah_algorithm_state *, caddr_t, size_t); 123static int ah_keyed_md5_mature(struct secasvar *); 124static int ah_keyed_md5_init(struct ah_algorithm_state *, struct secasvar *); 125static void ah_keyed_md5_loop(struct ah_algorithm_state *, caddr_t, size_t); 126static void ah_keyed_md5_result(struct ah_algorithm_state *, caddr_t, size_t); 127static int ah_keyed_sha1_mature(struct secasvar *); 128static int ah_keyed_sha1_init(struct ah_algorithm_state *, struct secasvar *); 129static void ah_keyed_sha1_loop(struct ah_algorithm_state *, caddr_t, size_t); 130static void ah_keyed_sha1_result(struct ah_algorithm_state *, caddr_t, size_t); 131static int ah_hmac_md5_mature(struct secasvar *); 132static int ah_hmac_md5_init(struct ah_algorithm_state *, struct secasvar *); 133static void ah_hmac_md5_loop(struct ah_algorithm_state *, caddr_t, size_t); 134static void ah_hmac_md5_result(struct ah_algorithm_state *, caddr_t, size_t); 135static int ah_hmac_sha1_mature(struct secasvar *); 136static int ah_hmac_sha1_init(struct ah_algorithm_state *, struct secasvar *); 137static void ah_hmac_sha1_loop(struct ah_algorithm_state *, caddr_t, size_t); 138static void ah_hmac_sha1_result(struct ah_algorithm_state *, caddr_t, size_t); 139#if ALLCRYPTO 140static int ah_sumsiz_sha2_256(struct secasvar *); 141static int ah_hmac_sha2_256_mature(struct secasvar *); 142static int ah_hmac_sha2_256_init(struct ah_algorithm_state *, 143 struct secasvar *); 144static void ah_hmac_sha2_256_loop(struct ah_algorithm_state *, caddr_t, size_t); 145static void ah_hmac_sha2_256_result(struct ah_algorithm_state *, caddr_t, size_t); 146static int ah_sumsiz_sha2_384(struct secasvar *); 147static int ah_hmac_sha2_384_mature(struct secasvar *); 148static int ah_hmac_sha2_384_init(struct ah_algorithm_state *, 149 struct secasvar *); 150static void ah_hmac_sha2_384_loop(struct ah_algorithm_state *, caddr_t, size_t); 151static void ah_hmac_sha2_384_result(struct ah_algorithm_state *, caddr_t, size_t); 152static int ah_sumsiz_sha2_512(struct secasvar *); 153static int ah_hmac_sha2_512_mature(struct secasvar *); 154static int ah_hmac_sha2_512_init(struct ah_algorithm_state *, 155 struct secasvar *); 156static void ah_hmac_sha2_512_loop(struct ah_algorithm_state *, caddr_t, size_t); 157static void ah_hmac_sha2_512_result(struct ah_algorithm_state *, caddr_t, size_t); 158#endif /* ALLCRYPTO */ 159 160static void ah_update_mbuf(struct mbuf *, int, int, 161 const struct ah_algorithm *, struct ah_algorithm_state *); 162 163const struct ah_algorithm * 164ah_algorithm_lookup(idx) 165 int idx; 166{ 167 /* checksum algorithms */ 168 static struct ah_algorithm hmac_md5 = 169 { ah_sumsiz_1216, ah_hmac_md5_mature, 128, 128, "hmac-md5", 170 ah_hmac_md5_init, ah_hmac_md5_loop, 171 ah_hmac_md5_result, }; 172 static struct ah_algorithm keyed_md5 = 173 { ah_sumsiz_1216, ah_keyed_md5_mature, 128, 128, "keyed-md5", 174 ah_keyed_md5_init, ah_keyed_md5_loop, 175 ah_keyed_md5_result, }; 176 static struct ah_algorithm hmac_sha1 = 177 { ah_sumsiz_1216, ah_hmac_sha1_mature, 160, 160, "hmac-sha1", 178 ah_hmac_sha1_init, ah_hmac_sha1_loop, 179 ah_hmac_sha1_result, }; 180 static struct ah_algorithm keyed_sha1 = 181 { ah_sumsiz_1216, ah_keyed_sha1_mature, 160, 160, "keyed-sha1", 182 ah_keyed_sha1_init, ah_keyed_sha1_loop, 183 ah_keyed_sha1_result, }; 184 static struct ah_algorithm ah_none = 185 { ah_sumsiz_zero, ah_none_mature, 0, 2048, "none", 186 ah_none_init, ah_none_loop, ah_none_result, }; 187#if ALLCRYPTO 188 static struct ah_algorithm hmac_sha2_256 = 189 { ah_sumsiz_sha2_256, ah_hmac_sha2_256_mature, 256, 256, 190 "hmac-sha2-256", 191 ah_hmac_sha2_256_init, ah_hmac_sha2_256_loop, 192 ah_hmac_sha2_256_result, }; 193 static struct ah_algorithm hmac_sha2_384 = 194 { ah_sumsiz_sha2_384, ah_hmac_sha2_384_mature, 384, 384, 195 "hmac-sha2-384", 196 ah_hmac_sha2_384_init, ah_hmac_sha2_384_loop, 197 ah_hmac_sha2_384_result, }; 198 static struct ah_algorithm hmac_sha2_512 = 199 { ah_sumsiz_sha2_512, ah_hmac_sha2_512_mature, 512, 512, 200 "hmac-sha2-512", 201 ah_hmac_sha2_512_init, ah_hmac_sha2_512_loop, 202 ah_hmac_sha2_512_result, }; 203#endif /* ALLCRYPTO */ 204 205 switch (idx) { 206 case SADB_AALG_MD5HMAC: 207 return &hmac_md5; 208 case SADB_AALG_SHA1HMAC: 209 return &hmac_sha1; 210 case SADB_X_AALG_MD5: 211 return &keyed_md5; 212 case SADB_X_AALG_SHA: 213 return &keyed_sha1; 214 case SADB_X_AALG_NULL: 215 return &ah_none; 216#if ALLCRYPTO 217 case SADB_X_AALG_SHA2_256: 218 return &hmac_sha2_256; 219 case SADB_X_AALG_SHA2_384: 220 return &hmac_sha2_384; 221 case SADB_X_AALG_SHA2_512: 222 return &hmac_sha2_512; 223#endif /* ALLCRYPTO */ 224 default: 225 return NULL; 226 } 227} 228 229 230static int 231ah_sumsiz_1216(sav) 232 struct secasvar *sav; 233{ 234 if (!sav) 235 return -1; 236 if (sav->flags & SADB_X_EXT_OLD) 237 return 16; 238 else 239 return 12; 240} 241 242static int 243ah_sumsiz_zero(sav) 244 struct secasvar *sav; 245{ 246 if (!sav) 247 return -1; 248 return 0; 249} 250 251static int 252ah_none_mature(sav) 253 struct secasvar *sav; 254{ 255 if (sav->sah->saidx.proto == IPPROTO_AH) { 256 ipseclog((LOG_ERR, 257 "ah_none_mature: protocol and algorithm mismatch.\n")); 258 return 1; 259 } 260 return 0; 261} 262 263static int 264ah_none_init( 265 struct ah_algorithm_state *state, 266 __unused struct secasvar *sav) 267{ 268 state->foo = NULL; 269 return 0; 270} 271 272static void 273ah_none_loop( 274 __unused struct ah_algorithm_state *state, 275 __unused caddr_t addr, 276 __unused size_t len) 277{ 278} 279 280static void 281ah_none_result( 282 __unused struct ah_algorithm_state *state, 283 __unused caddr_t addr, 284 __unused size_t l) 285{ 286} 287 288static int 289ah_keyed_md5_mature( 290 __unused struct secasvar *sav) 291{ 292 /* anything is okay */ 293 return 0; 294} 295 296static int 297ah_keyed_md5_init(state, sav) 298 struct ah_algorithm_state *state; 299 struct secasvar *sav; 300{ 301 size_t padlen; 302 size_t keybitlen; 303 u_int8_t buf[32] __attribute__((aligned(4))); 304 305 if (!state) 306 panic("ah_keyed_md5_init: what?"); 307 308 state->sav = sav; 309 state->foo = (void *)_MALLOC(sizeof(MD5_CTX), M_TEMP, M_NOWAIT); 310 if (state->foo == NULL) 311 return ENOBUFS; 312 313 MD5Init((MD5_CTX *)state->foo); 314 if (state->sav) { 315 MD5Update((MD5_CTX *)state->foo, 316 (u_int8_t *)_KEYBUF(state->sav->key_auth), 317 (u_int)_KEYLEN(state->sav->key_auth)); 318 319 /* 320 * Pad after the key. 321 * We cannot simply use md5_pad() since the function 322 * won't update the total length. 323 */ 324 if (_KEYLEN(state->sav->key_auth) < 56) 325 padlen = 64 - 8 - _KEYLEN(state->sav->key_auth); 326 else 327 padlen = 64 + 64 - 8 - _KEYLEN(state->sav->key_auth); 328 keybitlen = _KEYLEN(state->sav->key_auth); 329 keybitlen *= 8; 330 331 buf[0] = 0x80; 332 MD5Update((MD5_CTX *)state->foo, &buf[0], 1); 333 padlen--; 334 335 bzero(buf, sizeof(buf)); 336 while (sizeof(buf) < padlen) { 337 MD5Update((MD5_CTX *)state->foo, &buf[0], sizeof(buf)); 338 padlen -= sizeof(buf); 339 } 340 if (padlen) { 341 MD5Update((MD5_CTX *)state->foo, &buf[0], padlen); 342 } 343 344 buf[0] = (keybitlen >> 0) & 0xff; 345 buf[1] = (keybitlen >> 8) & 0xff; 346 buf[2] = (keybitlen >> 16) & 0xff; 347 buf[3] = (keybitlen >> 24) & 0xff; 348 MD5Update((MD5_CTX *)state->foo, buf, 8); 349 } 350 351 return 0; 352} 353 354static void 355ah_keyed_md5_loop(state, addr, len) 356 struct ah_algorithm_state *state; 357 caddr_t addr; 358 size_t len; 359{ 360 if (!state) 361 panic("ah_keyed_md5_loop: what?"); 362 363 MD5Update((MD5_CTX *)state->foo, addr, len); 364} 365 366static void 367ah_keyed_md5_result(state, addr, l) 368 struct ah_algorithm_state *state; 369 caddr_t addr; 370 size_t l; 371{ 372 u_char digest[16] __attribute__((aligned(4))); 373 374 if (!state) 375 panic("ah_keyed_md5_result: what?"); 376 377 if (state->sav) { 378 MD5Update((MD5_CTX *)state->foo, 379 (u_int8_t *)_KEYBUF(state->sav->key_auth), 380 (u_int)_KEYLEN(state->sav->key_auth)); 381 } 382 MD5Final(&digest[0], (MD5_CTX *)state->foo); 383 FREE(state->foo, M_TEMP); 384 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest)); 385} 386 387static int 388ah_keyed_sha1_mature(sav) 389 struct secasvar *sav; 390{ 391 const struct ah_algorithm *algo; 392 393 if (!sav->key_auth) { 394 ipseclog((LOG_ERR, "ah_keyed_sha1_mature: no key is given.\n")); 395 return 1; 396 } 397 398 algo = ah_algorithm_lookup(sav->alg_auth); 399 if (!algo) { 400 ipseclog((LOG_ERR, "ah_keyed_sha1_mature: unsupported algorithm.\n")); 401 return 1; 402 } 403 404 if (sav->key_auth->sadb_key_bits < algo->keymin 405 || algo->keymax < sav->key_auth->sadb_key_bits) { 406 ipseclog((LOG_ERR, 407 "ah_keyed_sha1_mature: invalid key length %d.\n", 408 sav->key_auth->sadb_key_bits)); 409 return 1; 410 } 411 412 return 0; 413} 414 415static int 416ah_keyed_sha1_init(state, sav) 417 struct ah_algorithm_state *state; 418 struct secasvar *sav; 419{ 420 SHA1_CTX *ctxt; 421 size_t padlen; 422 size_t keybitlen; 423 u_int8_t buf[32] __attribute__((aligned(4))); 424 425 if (!state) 426 panic("ah_keyed_sha1_init: what?"); 427 428 state->sav = sav; 429 state->foo = (void *)_MALLOC(sizeof(SHA1_CTX), M_TEMP, M_NOWAIT); 430 if (!state->foo) 431 return ENOBUFS; 432 433 ctxt = (SHA1_CTX *)state->foo; 434 SHA1Init(ctxt); 435 436 if (state->sav) { 437 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth), 438 (u_int)_KEYLEN(state->sav->key_auth)); 439 440 /* 441 * Pad after the key. 442 */ 443 if (_KEYLEN(state->sav->key_auth) < 56) 444 padlen = 64 - 8 - _KEYLEN(state->sav->key_auth); 445 else 446 padlen = 64 + 64 - 8 - _KEYLEN(state->sav->key_auth); 447 keybitlen = _KEYLEN(state->sav->key_auth); 448 keybitlen *= 8; 449 450 buf[0] = 0x80; 451 SHA1Update(ctxt, &buf[0], 1); 452 padlen--; 453 454 bzero(buf, sizeof(buf)); 455 while (sizeof(buf) < padlen) { 456 SHA1Update(ctxt, &buf[0], sizeof(buf)); 457 padlen -= sizeof(buf); 458 } 459 if (padlen) { 460 SHA1Update(ctxt, &buf[0], padlen); 461 } 462 463 buf[0] = (keybitlen >> 0) & 0xff; 464 buf[1] = (keybitlen >> 8) & 0xff; 465 buf[2] = (keybitlen >> 16) & 0xff; 466 buf[3] = (keybitlen >> 24) & 0xff; 467 SHA1Update(ctxt, buf, 8); 468 } 469 470 return 0; 471} 472 473static void 474ah_keyed_sha1_loop(state, addr, len) 475 struct ah_algorithm_state *state; 476 caddr_t addr; 477 size_t len; 478{ 479 SHA1_CTX *ctxt; 480 481 if (!state || !state->foo) 482 panic("ah_keyed_sha1_loop: what?"); 483 ctxt = (SHA1_CTX *)state->foo; 484 485 SHA1Update(ctxt, (caddr_t)addr, (size_t)len); 486} 487 488static void 489ah_keyed_sha1_result(state, addr, l) 490 struct ah_algorithm_state *state; 491 caddr_t addr; 492 size_t l; 493{ 494 u_char digest[SHA1_RESULTLEN] __attribute__((aligned(4))); /* SHA-1 generates 160 bits */ 495 SHA1_CTX *ctxt; 496 497 if (!state || !state->foo) 498 panic("ah_keyed_sha1_result: what?"); 499 ctxt = (SHA1_CTX *)state->foo; 500 501 if (state->sav) { 502 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth), 503 (u_int)_KEYLEN(state->sav->key_auth)); 504 } 505 SHA1Final((caddr_t)&digest[0], ctxt); 506 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest)); 507 508 FREE(state->foo, M_TEMP); 509} 510 511static int 512ah_hmac_md5_mature(sav) 513 struct secasvar *sav; 514{ 515 const struct ah_algorithm *algo; 516 517 if (!sav->key_auth) { 518 ipseclog((LOG_ERR, "ah_hmac_md5_mature: no key is given.\n")); 519 return 1; 520 } 521 522 algo = ah_algorithm_lookup(sav->alg_auth); 523 if (!algo) { 524 ipseclog((LOG_ERR, "ah_hmac_md5_mature: unsupported algorithm.\n")); 525 return 1; 526 } 527 528 if (sav->key_auth->sadb_key_bits < algo->keymin 529 || algo->keymax < sav->key_auth->sadb_key_bits) { 530 ipseclog((LOG_ERR, 531 "ah_hmac_md5_mature: invalid key length %d.\n", 532 sav->key_auth->sadb_key_bits)); 533 return 1; 534 } 535 536 return 0; 537} 538 539static int 540ah_hmac_md5_init(state, sav) 541 struct ah_algorithm_state *state; 542 struct secasvar *sav; 543{ 544 u_char *ipad; 545 u_char *opad; 546 u_char tk[16] __attribute__((aligned(4))); 547 u_char *key; 548 size_t keylen; 549 size_t i; 550 MD5_CTX *ctxt; 551 552 if (!state) 553 panic("ah_hmac_md5_init: what?"); 554 555 state->sav = sav; 556 state->foo = (void *)_MALLOC(64 + 64 + sizeof(MD5_CTX), M_TEMP, M_NOWAIT); 557 if (!state->foo) 558 return ENOBUFS; 559 560 ipad = (u_char *)state->foo; 561 opad = (u_char *)(ipad + 64); 562 ctxt = (MD5_CTX *)(void *)(opad + 64); 563 564 /* compress the key if necessery */ 565 if (64 < _KEYLEN(state->sav->key_auth)) { 566 MD5Init(ctxt); 567 MD5Update(ctxt, _KEYBUF(state->sav->key_auth), 568 _KEYLEN(state->sav->key_auth)); 569 MD5Final(&tk[0], ctxt); 570 key = &tk[0]; 571 keylen = 16; 572 } else { 573 key = (u_char *) _KEYBUF(state->sav->key_auth); 574 keylen = _KEYLEN(state->sav->key_auth); 575 } 576 577 bzero(ipad, 64); 578 bzero(opad, 64); 579 bcopy(key, ipad, keylen); 580 bcopy(key, opad, keylen); 581 for (i = 0; i < 64; i++) { 582 ipad[i] ^= 0x36; 583 opad[i] ^= 0x5c; 584 } 585 586 MD5Init(ctxt); 587 MD5Update(ctxt, ipad, 64); 588 589 return 0; 590} 591 592static void 593ah_hmac_md5_loop(state, addr, len) 594 struct ah_algorithm_state *state; 595 caddr_t addr; 596 size_t len; 597{ 598 MD5_CTX *ctxt; 599 600 if (!state || !state->foo) 601 panic("ah_hmac_md5_loop: what?"); 602 ctxt = (MD5_CTX *)(void *)(((caddr_t)state->foo) + 128); 603 MD5Update(ctxt, addr, len); 604} 605 606static void 607ah_hmac_md5_result(state, addr, l) 608 struct ah_algorithm_state *state; 609 caddr_t addr; 610 size_t l; 611{ 612 u_char digest[16] __attribute__((aligned(4))); 613 u_char *ipad; 614 u_char *opad; 615 MD5_CTX *ctxt; 616 617 if (!state || !state->foo) 618 panic("ah_hmac_md5_result: what?"); 619 620 ipad = (u_char *)state->foo; 621 opad = (u_char *)(ipad + 64); 622 ctxt = (MD5_CTX *)(void *)(opad + 64); 623 624 MD5Final(&digest[0], ctxt); 625 626 MD5Init(ctxt); 627 MD5Update(ctxt, opad, 64); 628 MD5Update(ctxt, &digest[0], sizeof(digest)); 629 MD5Final(&digest[0], ctxt); 630 631 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest)); 632 633 FREE(state->foo, M_TEMP); 634} 635 636static int 637ah_hmac_sha1_mature(sav) 638 struct secasvar *sav; 639{ 640 const struct ah_algorithm *algo; 641 642 if (!sav->key_auth) { 643 ipseclog((LOG_ERR, "ah_hmac_sha1_mature: no key is given.\n")); 644 return 1; 645 } 646 647 algo = ah_algorithm_lookup(sav->alg_auth); 648 if (!algo) { 649 ipseclog((LOG_ERR, "ah_hmac_sha1_mature: unsupported algorithm.\n")); 650 return 1; 651 } 652 653 if (sav->key_auth->sadb_key_bits < algo->keymin 654 || algo->keymax < sav->key_auth->sadb_key_bits) { 655 ipseclog((LOG_ERR, 656 "ah_hmac_sha1_mature: invalid key length %d.\n", 657 sav->key_auth->sadb_key_bits)); 658 return 1; 659 } 660 661 return 0; 662} 663 664static int 665ah_hmac_sha1_init(state, sav) 666 struct ah_algorithm_state *state; 667 struct secasvar *sav; 668{ 669 u_char *ipad; 670 u_char *opad; 671 SHA1_CTX *ctxt; 672 u_char tk[SHA1_RESULTLEN] __attribute__((aligned(4))); /* SHA-1 generates 160 bits */ 673 u_char *key; 674 size_t keylen; 675 size_t i; 676 677 if (!state) 678 panic("ah_hmac_sha1_init: what?"); 679 680 state->sav = sav; 681 state->foo = (void *)_MALLOC(64 + 64 + sizeof(SHA1_CTX), 682 M_TEMP, M_NOWAIT); 683 if (!state->foo) 684 return ENOBUFS; 685 686 ipad = (u_char *)state->foo; 687 opad = (u_char *)(ipad + 64); 688 ctxt = (SHA1_CTX *)(void *)(opad + 64); 689 690 /* compress the key if necessery */ 691 if (64 < _KEYLEN(state->sav->key_auth)) { 692 SHA1Init(ctxt); 693 SHA1Update(ctxt, _KEYBUF(state->sav->key_auth), 694 _KEYLEN(state->sav->key_auth)); 695 SHA1Final(&tk[0], ctxt); 696 key = &tk[0]; 697 keylen = SHA1_RESULTLEN; 698 } else { 699 key = (u_char *) _KEYBUF(state->sav->key_auth); 700 keylen = _KEYLEN(state->sav->key_auth); 701 } 702 703 bzero(ipad, 64); 704 bzero(opad, 64); 705 bcopy(key, ipad, keylen); 706 bcopy(key, opad, keylen); 707 for (i = 0; i < 64; i++) { 708 ipad[i] ^= 0x36; 709 opad[i] ^= 0x5c; 710 } 711 712 SHA1Init(ctxt); 713 SHA1Update(ctxt, ipad, 64); 714 715 return 0; 716} 717 718static void 719ah_hmac_sha1_loop(state, addr, len) 720 struct ah_algorithm_state *state; 721 caddr_t addr; 722 size_t len; 723{ 724 SHA1_CTX *ctxt; 725 726 if (!state || !state->foo) 727 panic("ah_hmac_sha1_loop: what?"); 728 729 ctxt = (SHA1_CTX *)(void *)(((u_char *)state->foo) + 128); 730 SHA1Update(ctxt, (caddr_t)addr, (size_t)len); 731} 732 733static void 734ah_hmac_sha1_result(state, addr, l) 735 struct ah_algorithm_state *state; 736 caddr_t addr; 737 size_t l; 738{ 739 u_char digest[SHA1_RESULTLEN] __attribute__((aligned(4))); /* SHA-1 generates 160 bits */ 740 u_char *ipad; 741 u_char *opad; 742 SHA1_CTX *ctxt; 743 744 if (!state || !state->foo) 745 panic("ah_hmac_sha1_result: what?"); 746 747 ipad = (u_char *)state->foo; 748 opad = (u_char *)(ipad + 64); 749 ctxt = (SHA1_CTX *)(void *)(opad + 64); 750 751 SHA1Final((caddr_t)&digest[0], ctxt); 752 753 SHA1Init(ctxt); 754 SHA1Update(ctxt, opad, 64); 755 SHA1Update(ctxt, (caddr_t)&digest[0], sizeof(digest)); 756 SHA1Final((caddr_t)&digest[0], ctxt); 757 758 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest)); 759 760 FREE(state->foo, M_TEMP); 761} 762 763#if ALLCRYPTO 764static int 765ah_sumsiz_sha2_256(sav) 766 struct secasvar *sav; 767{ 768 if (!sav) 769 return -1; 770 // return half the output size (in bytes), as per rfc 4868 771 return 16; // 256/(8*2) 772} 773 774static int 775ah_hmac_sha2_256_mature(sav) 776 struct secasvar *sav; 777{ 778 const struct ah_algorithm *algo; 779 780 if (!sav->key_auth) { 781 ipseclog((LOG_ERR, 782 "ah_hmac_sha2_256_mature: no key is given.\n")); 783 return 1; 784 } 785 786 algo = ah_algorithm_lookup(sav->alg_auth); 787 if (!algo) { 788 ipseclog((LOG_ERR, 789 "ah_hmac_sha2_256_mature: unsupported algorithm.\n")); 790 return 1; 791 } 792 793 if (sav->key_auth->sadb_key_bits < algo->keymin || 794 algo->keymax < sav->key_auth->sadb_key_bits) { 795 ipseclog((LOG_ERR, 796 "ah_hmac_sha2_256_mature: invalid key length %d.\n", 797 sav->key_auth->sadb_key_bits)); 798 return 1; 799 } 800 801 return 0; 802} 803 804static int 805ah_hmac_sha2_256_init(state, sav) 806 struct ah_algorithm_state *state; 807 struct secasvar *sav; 808{ 809 u_char *ipad; 810 u_char *opad; 811 SHA256_CTX *ctxt; 812 u_char tk[SHA256_DIGEST_LENGTH] __attribute__((aligned(4))); 813 u_char *key; 814 size_t keylen; 815 size_t i; 816 817 if (!state) 818 panic("ah_hmac_sha2_256_init: what?"); 819 820 state->sav = sav; 821 state->foo = (void *)_MALLOC(64 + 64 + sizeof(SHA256_CTX), 822 M_TEMP, M_NOWAIT); 823 if (!state->foo) 824 return ENOBUFS; 825 826 ipad = (u_char *)state->foo; 827 opad = (u_char *)(ipad + 64); 828 ctxt = (SHA256_CTX *)(void *)(opad + 64); 829 830 /* compress the key if necessery */ 831 if (64 < _KEYLEN(state->sav->key_auth)) { 832 bzero(tk, sizeof(tk)); 833 bzero(ctxt, sizeof(*ctxt)); 834 SHA256_Init(ctxt); 835 SHA256_Update(ctxt, (const u_int8_t *) _KEYBUF(state->sav->key_auth), 836 _KEYLEN(state->sav->key_auth)); 837 SHA256_Final(&tk[0], ctxt); 838 key = &tk[0]; 839 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64; 840 } else { 841 key = (u_char *) _KEYBUF(state->sav->key_auth); 842 keylen = _KEYLEN(state->sav->key_auth); 843 } 844 845 bzero(ipad, 64); 846 bzero(opad, 64); 847 bcopy(key, ipad, keylen); 848 bcopy(key, opad, keylen); 849 for (i = 0; i < 64; i++) { 850 ipad[i] ^= 0x36; 851 opad[i] ^= 0x5c; 852 } 853 854 bzero(ctxt, sizeof(*ctxt)); 855 SHA256_Init(ctxt); 856 SHA256_Update(ctxt, ipad, 64); 857 858 return 0; 859} 860 861static void 862ah_hmac_sha2_256_loop(state, addr, len) 863 struct ah_algorithm_state *state; 864 caddr_t addr; 865 size_t len; 866{ 867 SHA256_CTX *ctxt; 868 869 if (!state || !state->foo) 870 panic("ah_hmac_sha2_256_loop: what?"); 871 872 ctxt = (SHA256_CTX *)(void *)(((u_char *)state->foo) + 128); 873 SHA256_Update(ctxt, (const u_int8_t *)addr, (size_t)len); 874} 875 876static void 877ah_hmac_sha2_256_result(state, addr, l) 878 struct ah_algorithm_state *state; 879 caddr_t addr; 880 size_t l; 881{ 882 u_char digest[SHA256_DIGEST_LENGTH] __attribute__((aligned(4))); 883 u_char *ipad; 884 u_char *opad; 885 SHA256_CTX *ctxt; 886 887 if (!state || !state->foo) 888 panic("ah_hmac_sha2_256_result: what?"); 889 890 ipad = (u_char *)state->foo; 891 opad = (u_char *)(ipad + 64); 892 ctxt = (SHA256_CTX *)(void *)(opad + 64); 893 894 SHA256_Final((u_int8_t *)digest, ctxt); 895 896 SHA256_Init(ctxt); 897 SHA256_Update(ctxt, opad, 64); 898 SHA256_Update(ctxt, (const u_int8_t *)digest, sizeof(digest)); 899 SHA256_Final((u_int8_t *)digest, ctxt); 900 901 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest)); 902 903 FREE(state->foo, M_TEMP); 904} 905 906static int 907ah_sumsiz_sha2_384(sav) 908 struct secasvar *sav; 909{ 910 if (!sav) 911 return -1; 912 // return half the output size (in bytes), as per rfc 4868 913 return 24; // 384/(8*2) 914} 915 916static int 917ah_hmac_sha2_384_mature(sav) 918 struct secasvar *sav; 919{ 920 const struct ah_algorithm *algo; 921 922 if (!sav->key_auth) { 923 ipseclog((LOG_ERR, 924 "ah_hmac_sha2_384_mature: no key is given.\n")); 925 return 1; 926 } 927 928 algo = ah_algorithm_lookup(sav->alg_auth); 929 if (!algo) { 930 ipseclog((LOG_ERR, 931 "ah_hmac_sha2_384_mature: unsupported algorithm.\n")); 932 return 1; 933 } 934 935 if (sav->key_auth->sadb_key_bits < algo->keymin || 936 algo->keymax < sav->key_auth->sadb_key_bits) { 937 ipseclog((LOG_ERR, 938 "ah_hmac_sha2_384_mature: invalid key length %d.\n", 939 sav->key_auth->sadb_key_bits)); 940 return 1; 941 } 942 943 return 0; 944} 945 946static int 947ah_hmac_sha2_384_init(state, sav) 948 struct ah_algorithm_state *state; 949 struct secasvar *sav; 950{ 951 u_char *ipad; 952 u_char *opad; 953 SHA384_CTX *ctxt; 954 u_char tk[SHA384_DIGEST_LENGTH] __attribute__((aligned(4))); 955 u_char *key; 956 size_t keylen; 957 size_t i; 958 959 if (!state) 960 panic("ah_hmac_sha2_384_init: what?"); 961 962 state->sav = sav; 963 state->foo = (void *)_MALLOC(128 + 128 + sizeof(SHA384_CTX), 964 M_TEMP, M_NOWAIT); 965 if (!state->foo) 966 return ENOBUFS; 967 bzero(state->foo, 128 + 128 + sizeof(SHA384_CTX)); 968 969 ipad = (u_char *)state->foo; 970 opad = (u_char *)(ipad + 128); 971 ctxt = (SHA384_CTX *)(void *)(opad + 128); 972 973 /* compress the key if necessery */ 974 if (128 < _KEYLEN(state->sav->key_auth)) { 975 bzero(tk, sizeof(tk)); 976 bzero(ctxt, sizeof(*ctxt)); 977 SHA384_Init(ctxt); 978 SHA384_Update(ctxt, (const u_int8_t *) _KEYBUF(state->sav->key_auth), 979 _KEYLEN(state->sav->key_auth)); 980 SHA384_Final(&tk[0], ctxt); 981 key = &tk[0]; 982 keylen = sizeof(tk) < 128 ? sizeof(tk) : 128; 983 } else { 984 key = (u_char *) _KEYBUF(state->sav->key_auth); 985 keylen = _KEYLEN(state->sav->key_auth); 986 } 987 988 bzero(ipad, 128); 989 bzero(opad, 128); 990 bcopy(key, ipad, keylen); 991 bcopy(key, opad, keylen); 992 for (i = 0; i < 128; i++) { 993 ipad[i] ^= 0x36; 994 opad[i] ^= 0x5c; 995 } 996 997 bzero(ctxt, sizeof(*ctxt)); 998 SHA384_Init(ctxt); 999 SHA384_Update(ctxt, ipad, 128); 1000 1001 return 0; 1002} 1003 1004static void 1005ah_hmac_sha2_384_loop(state, addr, len) 1006 struct ah_algorithm_state *state; 1007 caddr_t addr; 1008 size_t len; 1009{ 1010 SHA384_CTX *ctxt; 1011 1012 if (!state || !state->foo) 1013 panic("ah_hmac_sha2_384_loop: what?"); 1014 1015 ctxt = (SHA384_CTX *)(void *)(((u_char *)state->foo) + 256); 1016 SHA384_Update(ctxt, (const u_int8_t *)addr, (size_t)len); 1017} 1018 1019static void 1020ah_hmac_sha2_384_result(state, addr, l) 1021 struct ah_algorithm_state *state; 1022 caddr_t addr; 1023 size_t l; 1024{ 1025 u_char digest[SHA384_DIGEST_LENGTH]; 1026 u_char *ipad; 1027 u_char *opad; 1028 SHA384_CTX *ctxt; 1029 1030 if (!state || !state->foo) 1031 panic("ah_hmac_sha2_384_result: what?"); 1032 1033 ipad = (u_char *)state->foo; 1034 opad = (u_char *)(ipad + 128); 1035 ctxt = (SHA384_CTX *)(void *)(opad + 128); 1036 1037 SHA384_Final((u_int8_t *)digest, ctxt); 1038 1039 SHA384_Init(ctxt); 1040 SHA384_Update(ctxt, opad, 128); 1041 SHA384_Update(ctxt, (const u_int8_t *)digest, sizeof(digest)); 1042 SHA384_Final((u_int8_t *)digest, ctxt); 1043 1044 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest)); 1045 1046 FREE(state->foo, M_TEMP); 1047} 1048 1049static int 1050ah_sumsiz_sha2_512(sav) 1051 struct secasvar *sav; 1052{ 1053 if (!sav) 1054 return -1; 1055 // return half the output size (in bytes), as per rfc 4868 1056 return 32; // 512/(8*2) 1057} 1058 1059static int 1060ah_hmac_sha2_512_mature(sav) 1061 struct secasvar *sav; 1062{ 1063 const struct ah_algorithm *algo; 1064 1065 if (!sav->key_auth) { 1066 ipseclog((LOG_ERR, 1067 "ah_hmac_sha2_512_mature: no key is given.\n")); 1068 return 1; 1069 } 1070 1071 algo = ah_algorithm_lookup(sav->alg_auth); 1072 if (!algo) { 1073 ipseclog((LOG_ERR, 1074 "ah_hmac_sha2_512_mature: unsupported algorithm.\n")); 1075 return 1; 1076 } 1077 1078 if (sav->key_auth->sadb_key_bits < algo->keymin || 1079 algo->keymax < sav->key_auth->sadb_key_bits) { 1080 ipseclog((LOG_ERR, 1081 "ah_hmac_sha2_512_mature: invalid key length %d.\n", 1082 sav->key_auth->sadb_key_bits)); 1083 return 1; 1084 } 1085 1086 return 0; 1087} 1088 1089static int 1090ah_hmac_sha2_512_init(state, sav) 1091 struct ah_algorithm_state *state; 1092 struct secasvar *sav; 1093{ 1094 u_char *ipad; 1095 u_char *opad; 1096 SHA512_CTX *ctxt; 1097 u_char tk[SHA512_DIGEST_LENGTH] __attribute__((aligned(4))); 1098 u_char *key; 1099 size_t keylen; 1100 size_t i; 1101 1102 if (!state) 1103 panic("ah_hmac_sha2_512_init: what?"); 1104 1105 state->sav = sav; 1106 state->foo = (void *)_MALLOC(128 + 128 + sizeof(SHA512_CTX), 1107 M_TEMP, M_NOWAIT); 1108 if (!state->foo) 1109 return ENOBUFS; 1110 bzero(state->foo, 128 + 128 + sizeof(SHA512_CTX)); 1111 1112 ipad = (u_char *)state->foo; 1113 opad = (u_char *)(ipad + 128); 1114 ctxt = (SHA512_CTX *)(void *)(opad + 128); 1115 1116 /* compress the key if necessery */ 1117 if (128 < _KEYLEN(state->sav->key_auth)) { 1118 bzero(tk, sizeof(tk)); 1119 bzero(ctxt, sizeof(*ctxt)); 1120 SHA512_Init(ctxt); 1121 SHA512_Update(ctxt, (const u_int8_t *) _KEYBUF(state->sav->key_auth), 1122 _KEYLEN(state->sav->key_auth)); 1123 SHA512_Final(&tk[0], ctxt); 1124 key = &tk[0]; 1125 keylen = sizeof(tk) < 128 ? sizeof(tk) : 128; 1126 } else { 1127 key = (u_char *) _KEYBUF(state->sav->key_auth); 1128 keylen = _KEYLEN(state->sav->key_auth); 1129 } 1130 1131 bzero(ipad, 128); 1132 bzero(opad, 128); 1133 bcopy(key, ipad, keylen); 1134 bcopy(key, opad, keylen); 1135 for (i = 0; i < 128; i++) { 1136 ipad[i] ^= 0x36; 1137 opad[i] ^= 0x5c; 1138 } 1139 1140 bzero(ctxt, sizeof(*ctxt)); 1141 SHA512_Init(ctxt); 1142 SHA512_Update(ctxt, ipad, 128); 1143 1144 return 0; 1145} 1146 1147static void 1148ah_hmac_sha2_512_loop(state, addr, len) 1149 struct ah_algorithm_state *state; 1150 caddr_t addr; 1151 size_t len; 1152{ 1153 SHA512_CTX *ctxt; 1154 1155 if (!state || !state->foo) 1156 panic("ah_hmac_sha2_512_loop: what?"); 1157 1158 ctxt = (SHA512_CTX *)(void *)(((u_char *)state->foo) + 256); 1159 SHA512_Update(ctxt, (const u_int8_t *) addr, (size_t)len); 1160} 1161 1162static void 1163ah_hmac_sha2_512_result(state, addr, l) 1164 struct ah_algorithm_state *state; 1165 caddr_t addr; 1166 size_t l; 1167{ 1168 u_char digest[SHA512_DIGEST_LENGTH] __attribute__((aligned(4))); 1169 u_char *ipad; 1170 u_char *opad; 1171 SHA512_CTX *ctxt; 1172 1173 if (!state || !state->foo) 1174 panic("ah_hmac_sha2_512_result: what?"); 1175 1176 ipad = (u_char *)state->foo; 1177 opad = (u_char *)(ipad + 128); 1178 ctxt = (SHA512_CTX *)(void *)(opad + 128); 1179 1180 SHA512_Final((u_int8_t *)digest, ctxt); 1181 1182 SHA512_Init(ctxt); 1183 SHA512_Update(ctxt, opad, 128); 1184 SHA512_Update(ctxt, (const u_int8_t *)digest, sizeof(digest)); 1185 SHA512_Final((u_int8_t *)digest, ctxt); 1186 1187 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest)); 1188 1189 FREE(state->foo, M_TEMP); 1190} 1191#endif /* ALLCRYPTO */ 1192 1193/*------------------------------------------------------------*/ 1194 1195/* 1196 * go generate the checksum. 1197 */ 1198static void 1199ah_update_mbuf(m, off, len, algo, algos) 1200 struct mbuf *m; 1201 int off; 1202 int len; 1203 const struct ah_algorithm *algo; 1204 struct ah_algorithm_state *algos; 1205{ 1206 struct mbuf *n; 1207 int tlen; 1208 1209 /* easy case first */ 1210 if (off + len <= m->m_len) { 1211 (algo->update)(algos, mtod(m, caddr_t) + off, len); 1212 return; 1213 } 1214 1215 for (n = m; n; n = n->m_next) { 1216 if (off < n->m_len) 1217 break; 1218 1219 off -= n->m_len; 1220 } 1221 1222 if (!n) 1223 panic("ah_update_mbuf: wrong offset specified"); 1224 1225 for (/*nothing*/; n && len > 0; n = n->m_next) { 1226 if (n->m_len == 0) 1227 continue; 1228 if (n->m_len - off < len) 1229 tlen = n->m_len - off; 1230 else 1231 tlen = len; 1232 1233 (algo->update)(algos, mtod(n, caddr_t) + off, tlen); 1234 1235 len -= tlen; 1236 off = 0; 1237 } 1238} 1239 1240#if INET 1241/* 1242 * Go generate the checksum. This function won't modify the mbuf chain 1243 * except AH itself. 1244 * 1245 * NOTE: the function does not free mbuf on failure. 1246 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt. 1247 */ 1248int 1249ah4_calccksum(m, ahdat, len, algo, sav) 1250 struct mbuf *m; 1251 caddr_t ahdat; 1252 size_t len; 1253 const struct ah_algorithm *algo; 1254 struct secasvar *sav; 1255{ 1256 int off; 1257 int hdrtype; 1258 size_t advancewidth; 1259 struct ah_algorithm_state algos; 1260 u_char sumbuf[AH_MAXSUMSIZE] __attribute__((aligned(4))); 1261 int error = 0; 1262 int ahseen; 1263 struct mbuf *n = NULL; 1264 1265 if ((m->m_flags & M_PKTHDR) == 0) 1266 return EINVAL; 1267 1268 ahseen = 0; 1269 hdrtype = -1; /*dummy, it is called IPPROTO_IP*/ 1270 1271 off = 0; 1272 1273 error = (algo->init)(&algos, sav); 1274 if (error) 1275 return error; 1276 1277 advancewidth = 0; /*safety*/ 1278 1279again: 1280 /* gory. */ 1281 switch (hdrtype) { 1282 case -1: /*first one only*/ 1283 { 1284 /* 1285 * copy ip hdr, modify to fit the AH checksum rule, 1286 * then take a checksum. 1287 */ 1288 struct ip iphdr; 1289 size_t hlen; 1290 1291 m_copydata(m, off, sizeof(iphdr), (caddr_t)&iphdr); 1292#if _IP_VHL 1293 hlen = IP_VHL_HL(iphdr.ip_vhl) << 2; 1294#else 1295 hlen = iphdr.ip_hl << 2; 1296#endif 1297 iphdr.ip_ttl = 0; 1298 iphdr.ip_sum = htons(0); 1299 if (ip4_ah_cleartos) 1300 iphdr.ip_tos = 0; 1301 iphdr.ip_off = htons(ntohs(iphdr.ip_off) & ip4_ah_offsetmask); 1302 (algo->update)(&algos, (caddr_t)&iphdr, sizeof(struct ip)); 1303 1304 if (hlen != sizeof(struct ip)) { 1305 u_char *p; 1306 int i, l, skip; 1307 1308 if (hlen > MCLBYTES) { 1309 error = EMSGSIZE; 1310 goto fail; 1311 } 1312 MGET(n, M_DONTWAIT, MT_DATA); 1313 if (n && hlen > MLEN) { 1314 MCLGET(n, M_DONTWAIT); 1315 if ((n->m_flags & M_EXT) == 0) { 1316 m_free(n); 1317 n = NULL; 1318 } 1319 } 1320 if (n == NULL) { 1321 error = ENOBUFS; 1322 goto fail; 1323 } 1324 m_copydata(m, off, hlen, mtod(n, caddr_t)); 1325 1326 /* 1327 * IP options processing. 1328 * See RFC2402 appendix A. 1329 */ 1330 p = mtod(n, u_char *); 1331 i = sizeof(struct ip); 1332 while (i < hlen) { 1333 if (i + IPOPT_OPTVAL >= hlen) { 1334 ipseclog((LOG_ERR, "ah4_calccksum: " 1335 "invalid IP option\n")); 1336 error = EINVAL; 1337 goto fail; 1338 } 1339 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL || 1340 p[i + IPOPT_OPTVAL] == IPOPT_NOP || 1341 i + IPOPT_OLEN < hlen) 1342 ; 1343 else { 1344 ipseclog((LOG_ERR, 1345 "ah4_calccksum: invalid IP option " 1346 "(type=%02x)\n", 1347 p[i + IPOPT_OPTVAL])); 1348 error = EINVAL; 1349 goto fail; 1350 } 1351 1352 skip = 1; 1353 switch (p[i + IPOPT_OPTVAL]) { 1354 case IPOPT_EOL: 1355 case IPOPT_NOP: 1356 l = 1; 1357 skip = 0; 1358 break; 1359 case IPOPT_SECURITY: /* 0x82 */ 1360 case 0x85: /* Extended security */ 1361 case 0x86: /* Commercial security */ 1362 case 0x94: /* Router alert */ 1363 case 0x95: /* RFC1770 */ 1364 l = p[i + IPOPT_OLEN]; 1365 if (l < 2) 1366 goto invalopt; 1367 skip = 0; 1368 break; 1369 default: 1370 l = p[i + IPOPT_OLEN]; 1371 if (l < 2) 1372 goto invalopt; 1373 skip = 1; 1374 break; 1375 } 1376 if (l < 1 || hlen - i < l) { 1377 invalopt: 1378 ipseclog((LOG_ERR, 1379 "ah4_calccksum: invalid IP option " 1380 "(type=%02x len=%02x)\n", 1381 p[i + IPOPT_OPTVAL], 1382 p[i + IPOPT_OLEN])); 1383 error = EINVAL; 1384 goto fail; 1385 } 1386 if (skip) 1387 bzero(p + i, l); 1388 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL) 1389 break; 1390 i += l; 1391 } 1392 1393 p = mtod(n, u_char *) + sizeof(struct ip); 1394 (algo->update)(&algos, (caddr_t)p, hlen - sizeof(struct ip)); 1395 1396 m_free(n); 1397 n = NULL; 1398 } 1399 1400 hdrtype = (iphdr.ip_p) & 0xff; 1401 advancewidth = hlen; 1402 break; 1403 } 1404 1405 case IPPROTO_AH: 1406 { 1407 struct ah ah; 1408 int siz; 1409 int hdrsiz; 1410 int totlen; 1411 1412 m_copydata(m, off, sizeof(ah), (caddr_t)&ah); 1413 hdrsiz = (sav->flags & SADB_X_EXT_OLD) 1414 ? sizeof(struct ah) 1415 : sizeof(struct newah); 1416 siz = (*algo->sumsiz)(sav); 1417 totlen = (ah.ah_len + 2) << 2; 1418 1419 /* 1420 * special treatment is necessary for the first one, not others 1421 */ 1422 if (!ahseen) { 1423 if (totlen > m->m_pkthdr.len - off || 1424 totlen > MCLBYTES) { 1425 error = EMSGSIZE; 1426 goto fail; 1427 } 1428 MGET(n, M_DONTWAIT, MT_DATA); 1429 if (n && totlen > MLEN) { 1430 MCLGET(n, M_DONTWAIT); 1431 if ((n->m_flags & M_EXT) == 0) { 1432 m_free(n); 1433 n = NULL; 1434 } 1435 } 1436 if (n == NULL) { 1437 error = ENOBUFS; 1438 goto fail; 1439 } 1440 m_copydata(m, off, totlen, mtod(n, caddr_t)); 1441 n->m_len = totlen; 1442 bzero(mtod(n, caddr_t) + hdrsiz, siz); 1443 (algo->update)(&algos, mtod(n, caddr_t), n->m_len); 1444 m_free(n); 1445 n = NULL; 1446 } else 1447 ah_update_mbuf(m, off, totlen, algo, &algos); 1448 ahseen++; 1449 1450 hdrtype = ah.ah_nxt; 1451 advancewidth = totlen; 1452 break; 1453 } 1454 1455 default: 1456 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo, &algos); 1457 advancewidth = m->m_pkthdr.len - off; 1458 break; 1459 } 1460 1461 off += advancewidth; 1462 if (off < m->m_pkthdr.len) 1463 goto again; 1464 1465 if (len < (*algo->sumsiz)(sav)) { 1466 error = EINVAL; 1467 goto fail; 1468 } 1469 1470 (algo->result)(&algos, (caddr_t) &sumbuf[0], sizeof(sumbuf)); 1471 bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav)); 1472 1473 if (n) 1474 m_free(n); 1475 return error; 1476 1477fail: 1478 if (n) 1479 m_free(n); 1480 return error; 1481} 1482#endif 1483 1484#if INET6 1485/* 1486 * Go generate the checksum. This function won't modify the mbuf chain 1487 * except AH itself. 1488 * 1489 * NOTE: the function does not free mbuf on failure. 1490 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt. 1491 */ 1492int 1493ah6_calccksum(m, ahdat, len, algo, sav) 1494 struct mbuf *m; 1495 caddr_t ahdat; 1496 size_t len; 1497 const struct ah_algorithm *algo; 1498 struct secasvar *sav; 1499{ 1500 int newoff, off; 1501 int proto, nxt; 1502 struct mbuf *n = NULL; 1503 int error; 1504 int ahseen; 1505 struct ah_algorithm_state algos; 1506 u_char sumbuf[AH_MAXSUMSIZE] __attribute__((aligned(4))); 1507 1508 if ((m->m_flags & M_PKTHDR) == 0) 1509 return EINVAL; 1510 1511 error = (algo->init)(&algos, sav); 1512 if (error) 1513 return error; 1514 1515 off = 0; 1516 proto = IPPROTO_IPV6; 1517 nxt = -1; 1518 ahseen = 0; 1519 1520 again: 1521 newoff = ip6_nexthdr(m, off, proto, &nxt); 1522 if (newoff < 0) 1523 newoff = m->m_pkthdr.len; 1524 else if (newoff <= off) { 1525 error = EINVAL; 1526 goto fail; 1527 } 1528 1529 switch (proto) { 1530 case IPPROTO_IPV6: 1531 /* 1532 * special treatment is necessary for the first one, not others 1533 */ 1534 if (off == 0) { 1535 struct ip6_hdr ip6copy; 1536 1537 if (newoff - off != sizeof(struct ip6_hdr)) { 1538 error = EINVAL; 1539 goto fail; 1540 } 1541 1542 m_copydata(m, off, newoff - off, (caddr_t)&ip6copy); 1543 /* RFC2402 */ 1544 ip6copy.ip6_flow = 0; 1545 ip6copy.ip6_vfc &= ~IPV6_VERSION_MASK; 1546 ip6copy.ip6_vfc |= IPV6_VERSION; 1547 ip6copy.ip6_hlim = 0; 1548 if (IN6_IS_ADDR_LINKLOCAL(&ip6copy.ip6_src)) 1549 ip6copy.ip6_src.s6_addr16[1] = 0x0000; 1550 if (IN6_IS_ADDR_LINKLOCAL(&ip6copy.ip6_dst)) 1551 ip6copy.ip6_dst.s6_addr16[1] = 0x0000; 1552 (algo->update)(&algos, (caddr_t)&ip6copy, 1553 sizeof(struct ip6_hdr)); 1554 } else { 1555 newoff = m->m_pkthdr.len; 1556 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo, 1557 &algos); 1558 } 1559 break; 1560 1561 case IPPROTO_AH: 1562 { 1563 int siz; 1564 int hdrsiz; 1565 1566 hdrsiz = (sav->flags & SADB_X_EXT_OLD) 1567 ? sizeof(struct ah) 1568 : sizeof(struct newah); 1569 siz = (*algo->sumsiz)(sav); 1570 1571 /* 1572 * special treatment is necessary for the first one, not others 1573 */ 1574 if (!ahseen) { 1575 if (newoff - off > MCLBYTES) { 1576 error = EMSGSIZE; 1577 goto fail; 1578 } 1579 MGET(n, M_DONTWAIT, MT_DATA); 1580 if (n && newoff - off > MLEN) { 1581 MCLGET(n, M_DONTWAIT); 1582 if ((n->m_flags & M_EXT) == 0) { 1583 m_free(n); 1584 n = NULL; 1585 } 1586 } 1587 if (n == NULL) { 1588 error = ENOBUFS; 1589 goto fail; 1590 } 1591 m_copydata(m, off, newoff - off, mtod(n, caddr_t)); 1592 n->m_len = newoff - off; 1593 bzero(mtod(n, caddr_t) + hdrsiz, siz); 1594 (algo->update)(&algos, mtod(n, caddr_t), n->m_len); 1595 m_free(n); 1596 n = NULL; 1597 } else 1598 ah_update_mbuf(m, off, newoff - off, algo, &algos); 1599 ahseen++; 1600 break; 1601 } 1602 1603 case IPPROTO_HOPOPTS: 1604 case IPPROTO_DSTOPTS: 1605 { 1606 struct ip6_ext *ip6e; 1607 int hdrlen, optlen; 1608 u_int8_t *p, *optend, *optp; 1609 1610 if (newoff - off > MCLBYTES) { 1611 error = EMSGSIZE; 1612 goto fail; 1613 } 1614 MGET(n, M_DONTWAIT, MT_DATA); 1615 if (n && newoff - off > MLEN) { 1616 MCLGET(n, M_DONTWAIT); 1617 if ((n->m_flags & M_EXT) == 0) { 1618 m_free(n); 1619 n = NULL; 1620 } 1621 } 1622 if (n == NULL) { 1623 error = ENOBUFS; 1624 goto fail; 1625 } 1626 m_copydata(m, off, newoff - off, mtod(n, caddr_t)); 1627 n->m_len = newoff - off; 1628 1629 ip6e = mtod(n, struct ip6_ext *); 1630 hdrlen = (ip6e->ip6e_len + 1) << 3; 1631 if (newoff - off < hdrlen) { 1632 error = EINVAL; 1633 m_free(n); 1634 n = NULL; 1635 goto fail; 1636 } 1637 p = mtod(n, u_int8_t *); 1638 optend = p + hdrlen; 1639 1640 /* 1641 * ICV calculation for the options header including all 1642 * options. This part is a little tricky since there are 1643 * two type of options; mutable and immutable. We try to 1644 * null-out mutable ones here. 1645 */ 1646 optp = p + 2; 1647 while (optp < optend) { 1648 if (optp[0] == IP6OPT_PAD1) 1649 optlen = 1; 1650 else { 1651 if (optp + 2 > optend) { 1652 error = EINVAL; 1653 m_free(n); 1654 n = NULL; 1655 goto fail; 1656 } 1657 optlen = optp[1] + 2; 1658 1659 if (optp[0] & IP6OPT_MUTABLE) 1660 bzero(optp + 2, optlen - 2); 1661 } 1662 1663 optp += optlen; 1664 } 1665 1666 (algo->update)(&algos, mtod(n, caddr_t), n->m_len); 1667 m_free(n); 1668 n = NULL; 1669 break; 1670 } 1671 1672 case IPPROTO_ROUTING: 1673 /* 1674 * For an input packet, we can just calculate `as is'. 1675 * For an output packet, we assume ip6_output have already 1676 * made packet how it will be received at the final 1677 * destination. 1678 */ 1679 /* FALLTHROUGH */ 1680 1681 default: 1682 ah_update_mbuf(m, off, newoff - off, algo, &algos); 1683 break; 1684 } 1685 1686 if (newoff < m->m_pkthdr.len) { 1687 proto = nxt; 1688 off = newoff; 1689 goto again; 1690 } 1691 1692 if (len < (*algo->sumsiz)(sav)) { 1693 error = EINVAL; 1694 goto fail; 1695 } 1696 1697 (algo->result)(&algos, (caddr_t) &sumbuf[0], sizeof(sumbuf)); 1698 bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav)); 1699 1700 /* just in case */ 1701 if (n) 1702 m_free(n); 1703 return 0; 1704fail: 1705 /* just in case */ 1706 if (n) 1707 m_free(n); 1708 return error; 1709} 1710#endif 1711