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