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

Cache object: 5df797c82ded9e3f0af768ff24e1449b


[ 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.