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