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

Cache object: fef7b2b275586a09e7a050e5ba9fc060


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