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