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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: 08a03ab776df702dea44bc763a9e8c48


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