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

Cache object: dc6c099f80168ad4f2535c7872779482


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