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


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

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

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

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

Cache object: d9819aededccf5c09badd6746552723f


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