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

Cache object: 51dbaccf1413a0f6dc92711f173adffd


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