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

Cache object: 34979fb4dec0c665d095044a92b938d2


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