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


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

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

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

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

Cache object: 55ab45f5838479e7b52253df69de3b09


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