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