The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet6/ah_core.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 05f231b0f480d03c2cd04e33e1246d0d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.