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