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

Cache object: f58bbf50f3c2a6b58e729ac1b53a8f12


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