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