6976ea718411a8d3c7464f37fe31a6330d15e347
[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.10 2006/10/24 06:18:42 hsu 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 *)kmalloc(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 *)kmalloc(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 *)kmalloc(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 *)kmalloc(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                         n = m_getb(hlen, MB_DONTWAIT, MT_DATA, 0);
1178                         if (n == NULL) {
1179                                 error = ENOBUFS;
1180                                 goto fail;
1181                         }
1182                         m_copydata(m, off, hlen, mtod(n, caddr_t));
1183
1184                         /*
1185                          * IP options processing.
1186                          * See RFC2402 appendix A.
1187                          */
1188                         p = mtod(n, u_char *);
1189                         i = sizeof(struct ip);
1190                         while (i < hlen) {
1191                                 if (i + IPOPT_OPTVAL >= hlen) {
1192                                         ipseclog((LOG_ERR, "ah4_calccksum: "
1193                                             "invalid IP option\n"));
1194                                         error = EINVAL;
1195                                         goto fail;
1196                                 }
1197                                 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL ||
1198                                     p[i + IPOPT_OPTVAL] == IPOPT_NOP ||
1199                                     i + IPOPT_OLEN < hlen)
1200                                         ;
1201                                 else {
1202                                         ipseclog((LOG_ERR,
1203                                             "ah4_calccksum: invalid IP option "
1204                                             "(type=%02x)\n",
1205                                             p[i + IPOPT_OPTVAL]));
1206                                         error = EINVAL;
1207                                         goto fail;
1208                                 }
1209
1210                                 skip = 1;
1211                                 switch (p[i + IPOPT_OPTVAL]) {
1212                                 case IPOPT_EOL:
1213                                 case IPOPT_NOP:
1214                                         l = 1;
1215                                         skip = 0;
1216                                         break;
1217                                 case IPOPT_SECURITY:    /* 0x82 */
1218                                 case 0x85:      /* Extended security */
1219                                 case 0x86:      /* Commercial security */
1220                                 case 0x94:      /* Router alert */
1221                                 case 0x95:      /* RFC1770 */
1222                                         l = p[i + IPOPT_OLEN];
1223                                         if (l < 2)
1224                                                 goto invalopt;
1225                                         skip = 0;
1226                                         break;
1227                                 default:
1228                                         l = p[i + IPOPT_OLEN];
1229                                         if (l < 2)
1230                                                 goto invalopt;
1231                                         skip = 1;
1232                                         break;
1233                                 }
1234                                 if (l < 1 || hlen - i < l) {
1235                         invalopt:
1236                                         ipseclog((LOG_ERR,
1237                                             "ah4_calccksum: invalid IP option "
1238                                             "(type=%02x len=%02x)\n",
1239                                             p[i + IPOPT_OPTVAL],
1240                                             p[i + IPOPT_OLEN]));
1241                                         error = EINVAL;
1242                                         goto fail;
1243                                 }
1244                                 if (skip)
1245                                         bzero(p + i, l);
1246                                 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL)
1247                                         break;
1248                                 i += l;
1249                         }
1250                         p = mtod(n, u_char *) + sizeof(struct ip);
1251                         (algo->update)(&algos, p, hlen - sizeof(struct ip));
1252
1253                         m_free(n);
1254                         n = NULL;
1255                 }
1256
1257                 hdrtype = (iphdr.ip_p) & 0xff;
1258                 advancewidth = hlen;
1259                 break;
1260             }
1261
1262         case IPPROTO_AH:
1263             {
1264                 struct ah ah;
1265                 int siz;
1266                 int hdrsiz;
1267                 int totlen;
1268
1269                 m_copydata(m, off, sizeof(ah), (caddr_t)&ah);
1270                 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1271                                 ? sizeof(struct ah)
1272                                 : sizeof(struct newah);
1273                 siz = (*algo->sumsiz)(sav);
1274                 totlen = (ah.ah_len + 2) << 2;
1275
1276                 /*
1277                  * special treatment is necessary for the first one, not others
1278                  */
1279                 if (!ahseen) {
1280                         if (totlen > m->m_pkthdr.len - off ||
1281                             totlen > MCLBYTES) {
1282                                 error = EMSGSIZE;
1283                                 goto fail;
1284                         }
1285                         n = m_getb(totlen, MB_DONTWAIT, MT_DATA, 0);
1286                         if (n == NULL) {
1287                                 error = ENOBUFS;
1288                                 goto fail;
1289                         }
1290                         m_copydata(m, off, totlen, mtod(n, caddr_t));
1291                         n->m_len = totlen;
1292                         bzero(mtod(n, caddr_t) + hdrsiz, siz);
1293                         (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1294                         m_free(n);
1295                         n = NULL;
1296                 } else
1297                         ah_update_mbuf(m, off, totlen, algo, &algos);
1298                 ahseen++;
1299
1300                 hdrtype = ah.ah_nxt;
1301                 advancewidth = totlen;
1302                 break;
1303             }
1304
1305         default:
1306                 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo, &algos);
1307                 advancewidth = m->m_pkthdr.len - off;
1308                 break;
1309         }
1310
1311         off += advancewidth;
1312         if (off < m->m_pkthdr.len)
1313                 goto again;
1314
1315         if (len < (*algo->sumsiz)(sav)) {
1316                 error = EINVAL;
1317                 goto fail;
1318         }
1319
1320         (algo->result)(&algos, &sumbuf[0]);
1321         bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
1322
1323         if (n)
1324                 m_free(n);
1325         return error;
1326
1327 fail:
1328         if (n)
1329                 m_free(n);
1330         return error;
1331 }
1332 #endif
1333
1334 #ifdef INET6
1335 /*
1336  * Go generate the checksum. This function won't modify the mbuf chain
1337  * except AH itself.
1338  *
1339  * NOTE: the function does not free mbuf on failure.
1340  * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1341  */
1342 int
1343 ah6_calccksum(struct mbuf *m, caddr_t ahdat, size_t len,
1344               const struct ah_algorithm *algo, struct secasvar *sav)
1345 {
1346         int newoff, off;
1347         int proto, nxt;
1348         struct mbuf *n = NULL;
1349         int error;
1350         int ahseen;
1351         struct ah_algorithm_state algos;
1352         u_char sumbuf[AH_MAXSUMSIZE];
1353
1354         if ((m->m_flags & M_PKTHDR) == 0)
1355                 return EINVAL;
1356
1357         error = (algo->init)(&algos, sav);
1358         if (error)
1359                 return error;
1360
1361         off = 0;
1362         proto = IPPROTO_IPV6;
1363         nxt = -1;
1364         ahseen = 0;
1365
1366 again:
1367         newoff = ip6_nexthdr(m, off, proto, &nxt);
1368         if (newoff < 0)
1369                 newoff = m->m_pkthdr.len;
1370         else if (newoff <= off) {
1371                 error = EINVAL;
1372                 goto fail;
1373         }
1374
1375         switch (proto) {
1376         case IPPROTO_IPV6:
1377                 /*
1378                  * special treatment is necessary for the first one, not others
1379                  */
1380                 if (off == 0) {
1381                         struct ip6_hdr ip6copy;
1382
1383                         if (newoff - off != sizeof(struct ip6_hdr)) {
1384                                 error = EINVAL;
1385                                 goto fail;
1386                         }
1387
1388                         m_copydata(m, off, newoff - off, (caddr_t)&ip6copy);
1389                         /* RFC2402 */
1390                         ip6copy.ip6_flow = 0;
1391                         ip6copy.ip6_vfc &= ~IPV6_VERSION_MASK;
1392                         ip6copy.ip6_vfc |= IPV6_VERSION;
1393                         ip6copy.ip6_hlim = 0;
1394                         if (IN6_IS_ADDR_LINKLOCAL(&ip6copy.ip6_src))
1395                                 ip6copy.ip6_src.s6_addr16[1] = 0x0000;
1396                         if (IN6_IS_ADDR_LINKLOCAL(&ip6copy.ip6_dst))
1397                                 ip6copy.ip6_dst.s6_addr16[1] = 0x0000;
1398                         (algo->update)(&algos, (caddr_t)&ip6copy,
1399                                        sizeof(struct ip6_hdr));
1400                 } else {
1401                         newoff = m->m_pkthdr.len;
1402                         ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo,
1403                             &algos);
1404                 }
1405                 break;
1406
1407         case IPPROTO_AH:
1408             {
1409                 int siz;
1410                 int hdrsiz;
1411
1412                 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1413                                 ? sizeof(struct ah)
1414                                 : sizeof(struct newah);
1415                 siz = (*algo->sumsiz)(sav);
1416
1417                 /*
1418                  * special treatment is necessary for the first one, not others
1419                  */
1420                 if (!ahseen) {
1421                         if (newoff - off > MCLBYTES) {
1422                                 error = EMSGSIZE;
1423                                 goto fail;
1424                         }
1425                         n = m_getb(newoff - off, MB_DONTWAIT, MT_DATA, 0);
1426                         if (n == NULL) {
1427                                 error = ENOBUFS;
1428                                 goto fail;
1429                         }
1430                         m_copydata(m, off, newoff - off, mtod(n, caddr_t));
1431                         n->m_len = newoff - off;
1432                         bzero(mtod(n, caddr_t) + hdrsiz, siz);
1433                         (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1434                         m_free(n);
1435                         n = NULL;
1436                 } else
1437                         ah_update_mbuf(m, off, newoff - off, algo, &algos);
1438                 ahseen++;
1439                 break;
1440             }
1441
1442          case IPPROTO_HOPOPTS:
1443          case IPPROTO_DSTOPTS:
1444          {
1445                 struct ip6_ext *ip6e;
1446                 int hdrlen, optlen;
1447                 u_int8_t *p, *optend, *optp;
1448
1449                 if (newoff - off > MCLBYTES) {
1450                         error = EMSGSIZE;
1451                         goto fail;
1452                 }
1453                 n = m_getb(newoff - off, MB_DONTWAIT, MT_DATA, 0);
1454                 if (n == NULL) {
1455                         error = ENOBUFS;
1456                         goto fail;
1457                 }
1458                 m_copydata(m, off, newoff - off, mtod(n, caddr_t));
1459                 n->m_len = newoff - off;
1460
1461                 ip6e = mtod(n, struct ip6_ext *);
1462                 hdrlen = (ip6e->ip6e_len + 1) << 3;
1463                 if (newoff - off < hdrlen) {
1464                          error = EINVAL;
1465                          m_free(n);
1466                          n = NULL;
1467                          goto fail;
1468                 }
1469                 p = mtod(n, u_int8_t *);
1470                 optend = p + hdrlen;
1471
1472                 /*
1473                  * ICV calculation for the options header including all
1474                  * options.  This part is a little tricky since there are
1475                  * two type of options; mutable and immutable.  We try to
1476                  * null-out mutable ones here.
1477                  */
1478                 optp = p + 2;
1479                 while (optp < optend) {
1480                         if (optp[0] == IP6OPT_PAD1)
1481                                 optlen = 1;
1482                         else {
1483                                 if (optp + 2 > optend) {
1484                                         error = EINVAL;
1485                                         m_free(n);
1486                                         n = NULL;
1487                                         goto fail;
1488                                 }
1489                                 optlen = optp[1] + 2;
1490
1491                                 if (optp[0] & IP6OPT_MUTABLE)
1492                                         bzero(optp + 2, optlen - 2);
1493                         }
1494
1495                         optp += optlen;
1496                 }
1497
1498                 (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1499                 m_free(n);
1500                 n = NULL;
1501                 break;
1502          }
1503
1504          case IPPROTO_ROUTING:
1505                 /*
1506                  * For an input packet, we can just calculate `as is'.
1507                  * For an output packet, we assume ip6_output have already
1508                  * made packet how it will be received at the final
1509                  * destination.
1510                  */
1511                 /* FALLTHROUGH */
1512
1513         default:
1514                 ah_update_mbuf(m, off, newoff - off, algo, &algos);
1515                 break;
1516         }
1517
1518         if (newoff < m->m_pkthdr.len) {
1519                 proto = nxt;
1520                 off = newoff;
1521                 goto again;
1522         }
1523
1524         if (len < (*algo->sumsiz)(sav)) {
1525                 error = EINVAL;
1526                 goto fail;
1527         }
1528
1529         (algo->result)(&algos, &sumbuf[0]);
1530         bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
1531
1532         /* just in case */
1533         if (n)
1534                 m_free(n);
1535         return 0;
1536 fail:
1537         /* just in case */
1538         if (n)
1539                 m_free(n);
1540         return error;
1541 }
1542 #endif