kernel - Change machdep.pmap_dynamic_delete default
[dragonfly.git] / sys / netinet6 / ah_core.c
blob174e12a01cbf9ada1ec478402c2cf2fb5a4afd04
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 $ */
4 /*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
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.
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.
34 * RFC1826/2402 authentication header.
37 /* TODO: have shared routines for hmac-* algorithms */
39 #include "opt_inet.h"
40 #include "opt_inet6.h"
41 #include "opt_ipsec.h"
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>
55 #include <net/if.h>
56 #include <net/route.h>
58 #include <netinet/in.h>
59 #include <netinet/in_systm.h>
60 #include <netinet/ip.h>
61 #include <netinet/in_var.h>
63 #ifdef INET6
64 #include <netinet/ip6.h>
65 #include <netinet6/ip6_var.h>
66 #include <netinet/icmp6.h>
67 #endif
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 <netproto/key/keydb.h>
85 #include <sys/md5.h>
86 #include <crypto/sha1.h>
87 #include <crypto/sha2/sha2.h>
89 #include <net/net_osdep.h>
91 #define HMACSIZE 16
93 static int ah_sumsiz_1216 (struct secasvar *);
94 static int ah_sumsiz_zero (struct secasvar *);
95 static int ah_none_mature (struct secasvar *);
96 static int ah_none_init (struct ah_algorithm_state *, struct secasvar *);
97 static void ah_none_loop (struct ah_algorithm_state *, caddr_t, size_t);
98 static void ah_none_result (struct ah_algorithm_state *, caddr_t);
99 static int ah_keyed_md5_mature (struct secasvar *);
100 static int ah_keyed_md5_init (struct ah_algorithm_state *,
101 struct secasvar *);
102 static void ah_keyed_md5_loop (struct ah_algorithm_state *, caddr_t,
103 size_t);
104 static void ah_keyed_md5_result (struct ah_algorithm_state *, caddr_t);
105 static int ah_keyed_sha1_mature (struct secasvar *);
106 static int ah_keyed_sha1_init (struct ah_algorithm_state *,
107 struct secasvar *);
108 static void ah_keyed_sha1_loop (struct ah_algorithm_state *, caddr_t,
109 size_t);
110 static void ah_keyed_sha1_result (struct ah_algorithm_state *, caddr_t);
111 static int ah_hmac_md5_mature (struct secasvar *);
112 static int ah_hmac_md5_init (struct ah_algorithm_state *,
113 struct secasvar *);
114 static void ah_hmac_md5_loop (struct ah_algorithm_state *, caddr_t,
115 size_t);
116 static void ah_hmac_md5_result (struct ah_algorithm_state *, caddr_t);
117 static int ah_hmac_sha1_mature (struct secasvar *);
118 static int ah_hmac_sha1_init (struct ah_algorithm_state *,
119 struct secasvar *);
120 static void ah_hmac_sha1_loop (struct ah_algorithm_state *, caddr_t,
121 size_t);
122 static void ah_hmac_sha1_result (struct ah_algorithm_state *, caddr_t);
123 static int ah_hmac_sha2_256_mature (struct secasvar *);
124 static int ah_hmac_sha2_256_init (struct ah_algorithm_state *,
125 struct secasvar *);
126 static void ah_hmac_sha2_256_loop (struct ah_algorithm_state *, caddr_t,
127 size_t);
128 static void ah_hmac_sha2_256_result (struct ah_algorithm_state *, caddr_t);
129 static int ah_hmac_sha2_384_mature (struct secasvar *);
130 static int ah_hmac_sha2_384_init (struct ah_algorithm_state *,
131 struct secasvar *);
132 static void ah_hmac_sha2_384_loop (struct ah_algorithm_state *, caddr_t,
133 size_t);
134 static void ah_hmac_sha2_384_result (struct ah_algorithm_state *, caddr_t);
135 static int ah_hmac_sha2_512_mature (struct secasvar *);
136 static int ah_hmac_sha2_512_init (struct ah_algorithm_state *,
137 struct secasvar *);
138 static void ah_hmac_sha2_512_loop (struct ah_algorithm_state *, caddr_t,
139 size_t);
140 static void ah_hmac_sha2_512_result (struct ah_algorithm_state *, caddr_t);
142 static void ah_update_mbuf (struct mbuf *, int, int,
143 const struct ah_algorithm *, struct ah_algorithm_state *);
145 const struct ah_algorithm *
146 ah_algorithm_lookup(int idx)
148 /* checksum algorithms */
149 static struct ah_algorithm ah_algorithms[] = {
150 { ah_sumsiz_1216, ah_hmac_md5_mature, 128, 128, "hmac-md5",
151 ah_hmac_md5_init, ah_hmac_md5_loop,
152 ah_hmac_md5_result, },
153 { ah_sumsiz_1216, ah_hmac_sha1_mature, 160, 160, "hmac-sha1",
154 ah_hmac_sha1_init, ah_hmac_sha1_loop,
155 ah_hmac_sha1_result, },
156 { ah_sumsiz_1216, ah_keyed_md5_mature, 128, 128, "keyed-md5",
157 ah_keyed_md5_init, ah_keyed_md5_loop,
158 ah_keyed_md5_result, },
159 { ah_sumsiz_1216, ah_keyed_sha1_mature, 160, 160, "keyed-sha1",
160 ah_keyed_sha1_init, ah_keyed_sha1_loop,
161 ah_keyed_sha1_result, },
162 { ah_sumsiz_zero, ah_none_mature, 0, 2048, "none",
163 ah_none_init, ah_none_loop, ah_none_result, },
164 { ah_sumsiz_1216, ah_hmac_sha2_256_mature, 256, 256,
165 "hmac-sha2-256",
166 ah_hmac_sha2_256_init, ah_hmac_sha2_256_loop,
167 ah_hmac_sha2_256_result, },
168 { ah_sumsiz_1216, ah_hmac_sha2_384_mature, 384, 384,
169 "hmac-sha2-384",
170 ah_hmac_sha2_384_init, ah_hmac_sha2_384_loop,
171 ah_hmac_sha2_384_result, },
172 { ah_sumsiz_1216, ah_hmac_sha2_512_mature, 512, 512,
173 "hmac-sha2-512",
174 ah_hmac_sha2_512_init, ah_hmac_sha2_512_loop,
175 ah_hmac_sha2_512_result, },
178 switch (idx) {
179 case SADB_AALG_MD5HMAC:
180 return &ah_algorithms[0];
181 case SADB_AALG_SHA1HMAC:
182 return &ah_algorithms[1];
183 case SADB_X_AALG_MD5:
184 return &ah_algorithms[2];
185 case SADB_X_AALG_SHA:
186 return &ah_algorithms[3];
187 case SADB_X_AALG_NULL:
188 return &ah_algorithms[4];
189 case SADB_X_AALG_SHA2_256:
190 return &ah_algorithms[5];
191 case SADB_X_AALG_SHA2_384:
192 return &ah_algorithms[6];
193 case SADB_X_AALG_SHA2_512:
194 return &ah_algorithms[7];
195 default:
196 return NULL;
201 static int
202 ah_sumsiz_1216(struct secasvar *sav)
204 if (!sav)
205 return -1;
206 if (sav->flags & SADB_X_EXT_OLD)
207 return 16;
208 else
209 return 12;
212 static int
213 ah_sumsiz_zero(struct secasvar *sav)
215 if (!sav)
216 return -1;
217 return 0;
220 static int
221 ah_none_mature(struct secasvar *sav)
223 if (sav->sah->saidx.proto == IPPROTO_AH) {
224 ipseclog((LOG_ERR,
225 "ah_none_mature: protocol and algorithm mismatch.\n"));
226 return 1;
228 return 0;
231 static int
232 ah_none_init(struct ah_algorithm_state *state, struct secasvar *sav)
234 state->foo = NULL;
235 return 0;
238 static void
239 ah_none_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
243 static void
244 ah_none_result(struct ah_algorithm_state *state, caddr_t addr)
248 static int
249 ah_keyed_md5_mature(struct secasvar *sav)
251 /* anything is okay */
252 return 0;
255 static int
256 ah_keyed_md5_init(struct ah_algorithm_state *state, struct secasvar *sav)
258 size_t padlen;
259 size_t keybitlen;
260 u_int8_t buf[32];
262 if (!state)
263 panic("ah_keyed_md5_init: what?");
265 state->sav = sav;
266 state->foo = (void *)kmalloc(sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
267 if (state->foo == NULL)
268 return ENOBUFS;
270 MD5Init((MD5_CTX *)state->foo);
271 if (state->sav) {
272 MD5Update((MD5_CTX *)state->foo,
273 (u_int8_t *)_KEYBUF(state->sav->key_auth),
274 (u_int)_KEYLEN(state->sav->key_auth));
277 * Pad after the key.
278 * We cannot simply use md5_pad() since the function
279 * won't update the total length.
281 if (_KEYLEN(state->sav->key_auth) < 56)
282 padlen = 64 - 8 - _KEYLEN(state->sav->key_auth);
283 else
284 padlen = 64 + 64 - 8 - _KEYLEN(state->sav->key_auth);
285 keybitlen = _KEYLEN(state->sav->key_auth);
286 keybitlen *= 8;
288 buf[0] = 0x80;
289 MD5Update((MD5_CTX *)state->foo, &buf[0], 1);
290 padlen--;
292 bzero(buf, sizeof(buf));
293 while (sizeof(buf) < padlen) {
294 MD5Update((MD5_CTX *)state->foo, &buf[0], sizeof(buf));
295 padlen -= sizeof(buf);
297 if (padlen) {
298 MD5Update((MD5_CTX *)state->foo, &buf[0], padlen);
301 buf[0] = (keybitlen >> 0) & 0xff;
302 buf[1] = (keybitlen >> 8) & 0xff;
303 buf[2] = (keybitlen >> 16) & 0xff;
304 buf[3] = (keybitlen >> 24) & 0xff;
305 MD5Update((MD5_CTX *)state->foo, buf, 8);
308 return 0;
311 static void
312 ah_keyed_md5_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
314 if (!state)
315 panic("ah_keyed_md5_loop: what?");
317 MD5Update((MD5_CTX *)state->foo, addr, len);
320 static void
321 ah_keyed_md5_result(struct ah_algorithm_state *state, caddr_t addr)
323 u_char digest[16];
325 if (!state)
326 panic("ah_keyed_md5_result: what?");
328 if (state->sav) {
329 MD5Update((MD5_CTX *)state->foo,
330 (u_int8_t *)_KEYBUF(state->sav->key_auth),
331 (u_int)_KEYLEN(state->sav->key_auth));
333 MD5Final(&digest[0], (MD5_CTX *)state->foo);
334 kfree(state->foo, M_TEMP);
335 bcopy(&digest[0], (void *)addr, sizeof(digest));
338 static int
339 ah_keyed_sha1_mature(struct secasvar *sav)
341 const struct ah_algorithm *algo;
343 if (!sav->key_auth) {
344 ipseclog((LOG_ERR, "ah_keyed_sha1_mature: no key is given.\n"));
345 return 1;
348 algo = ah_algorithm_lookup(sav->alg_auth);
349 if (!algo) {
350 ipseclog((LOG_ERR, "ah_keyed_sha1_mature: unsupported algorithm.\n"));
351 return 1;
354 if (sav->key_auth->sadb_key_bits < algo->keymin
355 || algo->keymax < sav->key_auth->sadb_key_bits) {
356 ipseclog((LOG_ERR,
357 "ah_keyed_sha1_mature: invalid key length %d.\n",
358 sav->key_auth->sadb_key_bits));
359 return 1;
362 return 0;
365 static int
366 ah_keyed_sha1_init(struct ah_algorithm_state *state, struct secasvar *sav)
368 SHA1_CTX *ctxt;
369 size_t padlen;
370 size_t keybitlen;
371 u_int8_t buf[32];
373 if (!state)
374 panic("ah_keyed_sha1_init: what?");
376 state->sav = sav;
377 state->foo = (void *)kmalloc(sizeof(SHA1_CTX), M_TEMP, M_NOWAIT);
378 if (!state->foo)
379 return ENOBUFS;
381 ctxt = (SHA1_CTX *)state->foo;
382 SHA1Init(ctxt);
384 if (state->sav) {
385 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth),
386 (u_int)_KEYLEN(state->sav->key_auth));
389 * Pad after the key.
391 if (_KEYLEN(state->sav->key_auth) < 56)
392 padlen = 64 - 8 - _KEYLEN(state->sav->key_auth);
393 else
394 padlen = 64 + 64 - 8 - _KEYLEN(state->sav->key_auth);
395 keybitlen = _KEYLEN(state->sav->key_auth);
396 keybitlen *= 8;
398 buf[0] = 0x80;
399 SHA1Update(ctxt, &buf[0], 1);
400 padlen--;
402 bzero(buf, sizeof(buf));
403 while (sizeof(buf) < padlen) {
404 SHA1Update(ctxt, &buf[0], sizeof(buf));
405 padlen -= sizeof(buf);
407 if (padlen) {
408 SHA1Update(ctxt, &buf[0], padlen);
411 buf[0] = (keybitlen >> 0) & 0xff;
412 buf[1] = (keybitlen >> 8) & 0xff;
413 buf[2] = (keybitlen >> 16) & 0xff;
414 buf[3] = (keybitlen >> 24) & 0xff;
415 SHA1Update(ctxt, buf, 8);
418 return 0;
421 static void
422 ah_keyed_sha1_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
424 SHA1_CTX *ctxt;
426 if (!state || !state->foo)
427 panic("ah_keyed_sha1_loop: what?");
428 ctxt = (SHA1_CTX *)state->foo;
430 SHA1Update(ctxt, addr, len);
433 static void
434 ah_keyed_sha1_result(struct ah_algorithm_state *state, caddr_t addr)
436 u_char digest[SHA1_RESULTLEN]; /* SHA-1 generates 160 bits */
437 SHA1_CTX *ctxt;
439 if (!state || !state->foo)
440 panic("ah_keyed_sha1_result: what?");
441 ctxt = (SHA1_CTX *)state->foo;
443 if (state->sav) {
444 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth),
445 (u_int)_KEYLEN(state->sav->key_auth));
447 SHA1Final((caddr_t)&digest[0], ctxt);
448 bcopy(&digest[0], (void *)addr, HMACSIZE);
450 kfree(state->foo, M_TEMP);
453 static int
454 ah_hmac_md5_mature(struct secasvar *sav)
456 const struct ah_algorithm *algo;
458 if (!sav->key_auth) {
459 ipseclog((LOG_ERR, "ah_hmac_md5_mature: no key is given.\n"));
460 return 1;
463 algo = ah_algorithm_lookup(sav->alg_auth);
464 if (!algo) {
465 ipseclog((LOG_ERR, "ah_hmac_md5_mature: unsupported algorithm.\n"));
466 return 1;
469 if (sav->key_auth->sadb_key_bits < algo->keymin
470 || algo->keymax < sav->key_auth->sadb_key_bits) {
471 ipseclog((LOG_ERR,
472 "ah_hmac_md5_mature: invalid key length %d.\n",
473 sav->key_auth->sadb_key_bits));
474 return 1;
477 return 0;
480 static int
481 ah_hmac_md5_init(struct ah_algorithm_state *state, struct secasvar *sav)
483 u_char *ipad;
484 u_char *opad;
485 u_char tk[16];
486 u_char *key;
487 size_t keylen;
488 size_t i;
489 MD5_CTX *ctxt;
491 if (!state)
492 panic("ah_hmac_md5_init: what?");
494 state->sav = sav;
495 state->foo = (void *)kmalloc(64 + 64 + sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
496 if (!state->foo)
497 return ENOBUFS;
499 ipad = (u_char *)state->foo;
500 opad = (u_char *)(ipad + 64);
501 ctxt = (MD5_CTX *)(opad + 64);
503 /* compress the key if necessery */
504 if (64 < _KEYLEN(state->sav->key_auth)) {
505 MD5Init(ctxt);
506 MD5Update(ctxt, _KEYBUF(state->sav->key_auth),
507 _KEYLEN(state->sav->key_auth));
508 MD5Final(&tk[0], ctxt);
509 key = &tk[0];
510 keylen = 16;
511 } else {
512 key = _KEYBUF(state->sav->key_auth);
513 keylen = _KEYLEN(state->sav->key_auth);
516 bzero(ipad, 64);
517 bzero(opad, 64);
518 bcopy(key, ipad, keylen);
519 bcopy(key, opad, keylen);
520 for (i = 0; i < 64; i++) {
521 ipad[i] ^= 0x36;
522 opad[i] ^= 0x5c;
525 MD5Init(ctxt);
526 MD5Update(ctxt, ipad, 64);
528 return 0;
531 static void
532 ah_hmac_md5_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
534 MD5_CTX *ctxt;
536 if (!state || !state->foo)
537 panic("ah_hmac_md5_loop: what?");
538 ctxt = (MD5_CTX *)(((caddr_t)state->foo) + 128);
539 MD5Update(ctxt, addr, len);
542 static void
543 ah_hmac_md5_result(struct ah_algorithm_state *state, caddr_t addr)
545 u_char digest[16];
546 u_char *ipad;
547 u_char *opad;
548 MD5_CTX *ctxt;
550 if (!state || !state->foo)
551 panic("ah_hmac_md5_result: what?");
553 ipad = (u_char *)state->foo;
554 opad = (u_char *)(ipad + 64);
555 ctxt = (MD5_CTX *)(opad + 64);
557 MD5Final(&digest[0], ctxt);
559 MD5Init(ctxt);
560 MD5Update(ctxt, opad, 64);
561 MD5Update(ctxt, &digest[0], sizeof(digest));
562 MD5Final(&digest[0], ctxt);
564 bcopy(&digest[0], (void *)addr, HMACSIZE);
566 kfree(state->foo, M_TEMP);
569 static int
570 ah_hmac_sha1_mature(struct secasvar *sav)
572 const struct ah_algorithm *algo;
574 if (!sav->key_auth) {
575 ipseclog((LOG_ERR, "ah_hmac_sha1_mature: no key is given.\n"));
576 return 1;
579 algo = ah_algorithm_lookup(sav->alg_auth);
580 if (!algo) {
581 ipseclog((LOG_ERR, "ah_hmac_sha1_mature: unsupported algorithm.\n"));
582 return 1;
585 if (sav->key_auth->sadb_key_bits < algo->keymin
586 || algo->keymax < sav->key_auth->sadb_key_bits) {
587 ipseclog((LOG_ERR,
588 "ah_hmac_sha1_mature: invalid key length %d.\n",
589 sav->key_auth->sadb_key_bits));
590 return 1;
593 return 0;
596 static int
597 ah_hmac_sha1_init(struct ah_algorithm_state *state, struct secasvar *sav)
599 u_char *ipad;
600 u_char *opad;
601 SHA1_CTX *ctxt;
602 u_char tk[SHA1_RESULTLEN]; /* SHA-1 generates 160 bits */
603 u_char *key;
604 size_t keylen;
605 size_t i;
607 if (!state)
608 panic("ah_hmac_sha1_init: what?");
610 state->sav = sav;
611 state->foo = (void *)kmalloc(64 + 64 + sizeof(SHA1_CTX),
612 M_TEMP, M_NOWAIT);
613 if (!state->foo)
614 return ENOBUFS;
616 ipad = (u_char *)state->foo;
617 opad = (u_char *)(ipad + 64);
618 ctxt = (SHA1_CTX *)(opad + 64);
620 /* compress the key if necessery */
621 if (64 < _KEYLEN(state->sav->key_auth)) {
622 SHA1Init(ctxt);
623 SHA1Update(ctxt, _KEYBUF(state->sav->key_auth),
624 _KEYLEN(state->sav->key_auth));
625 SHA1Final(&tk[0], ctxt);
626 key = &tk[0];
627 keylen = SHA1_RESULTLEN;
628 } else {
629 key = _KEYBUF(state->sav->key_auth);
630 keylen = _KEYLEN(state->sav->key_auth);
633 bzero(ipad, 64);
634 bzero(opad, 64);
635 bcopy(key, ipad, keylen);
636 bcopy(key, opad, keylen);
637 for (i = 0; i < 64; i++) {
638 ipad[i] ^= 0x36;
639 opad[i] ^= 0x5c;
642 SHA1Init(ctxt);
643 SHA1Update(ctxt, ipad, 64);
645 return 0;
648 static void
649 ah_hmac_sha1_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
651 SHA1_CTX *ctxt;
653 if (!state || !state->foo)
654 panic("ah_hmac_sha1_loop: what?");
656 ctxt = (SHA1_CTX *)(((u_char *)state->foo) + 128);
657 SHA1Update(ctxt, addr, len);
660 static void
661 ah_hmac_sha1_result(struct ah_algorithm_state *state, caddr_t addr)
663 u_char digest[SHA1_RESULTLEN]; /* SHA-1 generates 160 bits */
664 u_char *ipad;
665 u_char *opad;
666 SHA1_CTX *ctxt;
668 if (!state || !state->foo)
669 panic("ah_hmac_sha1_result: what?");
671 ipad = (u_char *)state->foo;
672 opad = (u_char *)(ipad + 64);
673 ctxt = (SHA1_CTX *)(opad + 64);
675 SHA1Final((caddr_t)&digest[0], ctxt);
677 SHA1Init(ctxt);
678 SHA1Update(ctxt, opad, 64);
679 SHA1Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
680 SHA1Final((caddr_t)&digest[0], ctxt);
682 bcopy(&digest[0], (void *)addr, HMACSIZE);
684 kfree(state->foo, M_TEMP);
687 static int
688 ah_hmac_sha2_256_mature(struct secasvar *sav)
690 const struct ah_algorithm *algo;
692 if (!sav->key_auth) {
693 ipseclog((LOG_ERR,
694 "ah_hmac_sha2_256_mature: no key is given.\n"));
695 return 1;
698 algo = ah_algorithm_lookup(sav->alg_auth);
699 if (!algo) {
700 ipseclog((LOG_ERR,
701 "ah_hmac_sha2_256_mature: unsupported algorithm.\n"));
702 return 1;
705 if (sav->key_auth->sadb_key_bits < algo->keymin ||
706 algo->keymax < sav->key_auth->sadb_key_bits) {
707 ipseclog((LOG_ERR,
708 "ah_hmac_sha2_256_mature: invalid key length %d.\n",
709 sav->key_auth->sadb_key_bits));
710 return 1;
713 return 0;
716 static int
717 ah_hmac_sha2_256_init(struct ah_algorithm_state *state, struct secasvar *sav)
719 u_char *ipad;
720 u_char *opad;
721 SHA256_CTX *ctxt;
722 u_char tk[SHA256_DIGEST_LENGTH];
723 u_char *key;
724 size_t keylen;
725 size_t i;
727 if (!state)
728 panic("ah_hmac_sha2_256_init: what?");
730 state->sav = sav;
731 state->foo = (void *)kmalloc(64 + 64 + sizeof(SHA256_CTX),
732 M_TEMP, M_NOWAIT);
733 if (!state->foo)
734 return ENOBUFS;
736 ipad = (u_char *)state->foo;
737 opad = (u_char *)(ipad + 64);
738 ctxt = (SHA256_CTX *)(opad + 64);
740 /* compress the key if necessery */
741 if (64 < _KEYLEN(state->sav->key_auth)) {
742 bzero(tk, sizeof(tk));
743 bzero(ctxt, sizeof(*ctxt));
744 SHA256_Init(ctxt);
745 SHA256_Update(ctxt, _KEYBUF(state->sav->key_auth),
746 _KEYLEN(state->sav->key_auth));
747 SHA256_Final(&tk[0], ctxt);
748 key = &tk[0];
749 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
750 } else {
751 key = _KEYBUF(state->sav->key_auth);
752 keylen = _KEYLEN(state->sav->key_auth);
755 bzero(ipad, 64);
756 bzero(opad, 64);
757 bcopy(key, ipad, keylen);
758 bcopy(key, opad, keylen);
759 for (i = 0; i < 64; i++) {
760 ipad[i] ^= 0x36;
761 opad[i] ^= 0x5c;
764 bzero(ctxt, sizeof(*ctxt));
765 SHA256_Init(ctxt);
766 SHA256_Update(ctxt, ipad, 64);
768 return 0;
771 static void
772 ah_hmac_sha2_256_loop(struct ah_algorithm_state *state, caddr_t addr, size_t
773 len)
775 SHA256_CTX *ctxt;
777 if (!state || !state->foo)
778 panic("ah_hmac_sha2_256_loop: what?");
780 ctxt = (SHA256_CTX *)(((u_char *)state->foo) + 128);
781 SHA256_Update(ctxt, addr, len);
784 static void
785 ah_hmac_sha2_256_result(struct ah_algorithm_state *state, caddr_t addr)
787 u_char digest[SHA256_DIGEST_LENGTH];
788 u_char *ipad;
789 u_char *opad;
790 SHA256_CTX *ctxt;
792 if (!state || !state->foo)
793 panic("ah_hmac_sha2_256_result: what?");
795 ipad = (u_char *)state->foo;
796 opad = (u_char *)(ipad + 64);
797 ctxt = (SHA256_CTX *)(opad + 64);
799 SHA256_Final((caddr_t)&digest[0], ctxt);
801 bzero(ctxt, sizeof(*ctxt));
802 SHA256_Init(ctxt);
803 SHA256_Update(ctxt, opad, 64);
804 SHA256_Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
805 SHA256_Final((caddr_t)&digest[0], ctxt);
807 bcopy(&digest[0], (void *)addr, HMACSIZE);
809 kfree(state->foo, M_TEMP);
812 static int
813 ah_hmac_sha2_384_mature(struct secasvar *sav)
815 const struct ah_algorithm *algo;
817 if (!sav->key_auth) {
818 ipseclog((LOG_ERR,
819 "ah_hmac_sha2_384_mature: no key is given.\n"));
820 return 1;
823 algo = ah_algorithm_lookup(sav->alg_auth);
824 if (!algo) {
825 ipseclog((LOG_ERR,
826 "ah_hmac_sha2_384_mature: unsupported algorithm.\n"));
827 return 1;
830 if (sav->key_auth->sadb_key_bits < algo->keymin ||
831 algo->keymax < sav->key_auth->sadb_key_bits) {
832 ipseclog((LOG_ERR,
833 "ah_hmac_sha2_384_mature: invalid key length %d.\n",
834 sav->key_auth->sadb_key_bits));
835 return 1;
838 return 0;
841 static int
842 ah_hmac_sha2_384_init(struct ah_algorithm_state *state, struct secasvar *sav)
844 u_char *ipad;
845 u_char *opad;
846 SHA384_CTX *ctxt;
847 u_char tk[SHA384_DIGEST_LENGTH];
848 u_char *key;
849 size_t keylen;
850 size_t i;
852 if (!state)
853 panic("ah_hmac_sha2_384_init: what?");
855 state->sav = sav;
856 state->foo = (void *)kmalloc(64 + 64 + sizeof(SHA384_CTX),
857 M_TEMP, M_NOWAIT | M_ZERO);
858 if (!state->foo)
859 return ENOBUFS;
861 ipad = (u_char *)state->foo;
862 opad = (u_char *)(ipad + 64);
863 ctxt = (SHA384_CTX *)(opad + 64);
865 /* compress the key if necessery */
866 if (64 < _KEYLEN(state->sav->key_auth)) {
867 bzero(tk, sizeof(tk));
868 bzero(ctxt, sizeof(*ctxt));
869 SHA384_Init(ctxt);
870 SHA384_Update(ctxt, _KEYBUF(state->sav->key_auth),
871 _KEYLEN(state->sav->key_auth));
872 SHA384_Final(&tk[0], ctxt);
873 key = &tk[0];
874 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
875 } else {
876 key = _KEYBUF(state->sav->key_auth);
877 keylen = _KEYLEN(state->sav->key_auth);
880 bzero(ipad, 64);
881 bzero(opad, 64);
882 bcopy(key, ipad, keylen);
883 bcopy(key, opad, keylen);
884 for (i = 0; i < 64; i++) {
885 ipad[i] ^= 0x36;
886 opad[i] ^= 0x5c;
889 bzero(ctxt, sizeof(*ctxt));
890 SHA384_Init(ctxt);
891 SHA384_Update(ctxt, ipad, 64);
893 return 0;
896 static void
897 ah_hmac_sha2_384_loop(struct ah_algorithm_state *state, caddr_t addr,
898 size_t len)
900 SHA384_CTX *ctxt;
902 if (!state || !state->foo)
903 panic("ah_hmac_sha2_384_loop: what?");
905 ctxt = (SHA384_CTX *)(((u_char *)state->foo) + 128);
906 SHA384_Update(ctxt, addr, len);
909 static void
910 ah_hmac_sha2_384_result(struct ah_algorithm_state *state, caddr_t addr)
912 u_char digest[SHA384_DIGEST_LENGTH];
913 u_char *ipad;
914 u_char *opad;
915 SHA384_CTX *ctxt;
917 if (!state || !state->foo)
918 panic("ah_hmac_sha2_384_result: what?");
920 ipad = (u_char *)state->foo;
921 opad = (u_char *)(ipad + 64);
922 ctxt = (SHA384_CTX *)(opad + 64);
924 SHA384_Final((caddr_t)&digest[0], ctxt);
926 bzero(ctxt, sizeof(*ctxt));
927 SHA384_Init(ctxt);
928 SHA384_Update(ctxt, opad, 64);
929 SHA384_Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
930 SHA384_Final((caddr_t)&digest[0], ctxt);
932 bcopy(&digest[0], (void *)addr, HMACSIZE);
934 kfree(state->foo, M_TEMP);
937 static int
938 ah_hmac_sha2_512_mature(struct secasvar *sav)
940 const struct ah_algorithm *algo;
942 if (!sav->key_auth) {
943 ipseclog((LOG_ERR,
944 "ah_hmac_sha2_512_mature: no key is given.\n"));
945 return 1;
948 algo = ah_algorithm_lookup(sav->alg_auth);
949 if (!algo) {
950 ipseclog((LOG_ERR,
951 "ah_hmac_sha2_512_mature: unsupported algorithm.\n"));
952 return 1;
955 if (sav->key_auth->sadb_key_bits < algo->keymin ||
956 algo->keymax < sav->key_auth->sadb_key_bits) {
957 ipseclog((LOG_ERR,
958 "ah_hmac_sha2_512_mature: invalid key length %d.\n",
959 sav->key_auth->sadb_key_bits));
960 return 1;
963 return 0;
966 static int
967 ah_hmac_sha2_512_init(struct ah_algorithm_state *state, struct secasvar *sav)
969 u_char *ipad;
970 u_char *opad;
971 SHA512_CTX *ctxt;
972 u_char tk[SHA512_DIGEST_LENGTH];
973 u_char *key;
974 size_t keylen;
975 size_t i;
977 if (!state)
978 panic("ah_hmac_sha2_512_init: what?");
980 state->sav = sav;
981 state->foo = (void *)kmalloc(64 + 64 + sizeof(SHA512_CTX),
982 M_TEMP, M_NOWAIT | M_ZERO);
983 if (!state->foo)
984 return ENOBUFS;
986 ipad = (u_char *)state->foo;
987 opad = (u_char *)(ipad + 64);
988 ctxt = (SHA512_CTX *)(opad + 64);
990 /* compress the key if necessery */
991 if (64 < _KEYLEN(state->sav->key_auth)) {
992 bzero(tk, sizeof(tk));
993 bzero(ctxt, sizeof(*ctxt));
994 SHA512_Init(ctxt);
995 SHA512_Update(ctxt, _KEYBUF(state->sav->key_auth),
996 _KEYLEN(state->sav->key_auth));
997 SHA512_Final(&tk[0], ctxt);
998 key = &tk[0];
999 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
1000 } else {
1001 key = _KEYBUF(state->sav->key_auth);
1002 keylen = _KEYLEN(state->sav->key_auth);
1005 bzero(ipad, 64);
1006 bzero(opad, 64);
1007 bcopy(key, ipad, keylen);
1008 bcopy(key, opad, keylen);
1009 for (i = 0; i < 64; i++) {
1010 ipad[i] ^= 0x36;
1011 opad[i] ^= 0x5c;
1014 bzero(ctxt, sizeof(*ctxt));
1015 SHA512_Init(ctxt);
1016 SHA512_Update(ctxt, ipad, 64);
1018 return 0;
1021 static void
1022 ah_hmac_sha2_512_loop(struct ah_algorithm_state *state, caddr_t addr,
1023 size_t len)
1025 SHA512_CTX *ctxt;
1027 if (!state || !state->foo)
1028 panic("ah_hmac_sha2_512_loop: what?");
1030 ctxt = (SHA512_CTX *)(((u_char *)state->foo) + 128);
1031 SHA512_Update(ctxt, addr, len);
1034 static void
1035 ah_hmac_sha2_512_result(struct ah_algorithm_state *state, caddr_t addr)
1037 u_char digest[SHA512_DIGEST_LENGTH];
1038 u_char *ipad;
1039 u_char *opad;
1040 SHA512_CTX *ctxt;
1042 if (!state || !state->foo)
1043 panic("ah_hmac_sha2_512_result: what?");
1045 ipad = (u_char *)state->foo;
1046 opad = (u_char *)(ipad + 64);
1047 ctxt = (SHA512_CTX *)(opad + 64);
1049 SHA512_Final((caddr_t)&digest[0], ctxt);
1051 bzero(ctxt, sizeof(*ctxt));
1052 SHA512_Init(ctxt);
1053 SHA512_Update(ctxt, opad, 64);
1054 SHA512_Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
1055 SHA512_Final((caddr_t)&digest[0], ctxt);
1057 bcopy(&digest[0], (void *)addr, HMACSIZE);
1059 kfree(state->foo, M_TEMP);
1062 /*------------------------------------------------------------*/
1065 * go generate the checksum.
1067 static void
1068 ah_update_mbuf(struct mbuf *m, int off, int len,
1069 const struct ah_algorithm *algo,
1070 struct ah_algorithm_state *algos)
1072 struct mbuf *n;
1073 int tlen;
1075 /* easy case first */
1076 if (off + len <= m->m_len) {
1077 (algo->update)(algos, mtod(m, caddr_t) + off, len);
1078 return;
1081 for (n = m; n; n = n->m_next) {
1082 if (off < n->m_len)
1083 break;
1085 off -= n->m_len;
1088 if (!n)
1089 panic("ah_update_mbuf: wrong offset specified");
1091 for (/* nothing */; n && len > 0; n = n->m_next) {
1092 if (n->m_len == 0)
1093 continue;
1094 if (n->m_len - off < len)
1095 tlen = n->m_len - off;
1096 else
1097 tlen = len;
1099 (algo->update)(algos, mtod(n, caddr_t) + off, tlen);
1101 len -= tlen;
1102 off = 0;
1106 #ifdef INET
1108 * Go generate the checksum. This function won't modify the mbuf chain
1109 * except AH itself.
1111 * NOTE: the function does not free mbuf on failure.
1112 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1115 ah4_calccksum(struct mbuf *m, caddr_t ahdat, size_t len,
1116 const struct ah_algorithm *algo, struct secasvar *sav)
1118 int off;
1119 int hdrtype;
1120 size_t advancewidth;
1121 struct ah_algorithm_state algos;
1122 u_char sumbuf[AH_MAXSUMSIZE];
1123 int error = 0;
1124 int ahseen;
1125 struct mbuf *n = NULL;
1127 if ((m->m_flags & M_PKTHDR) == 0)
1128 return EINVAL;
1130 ahseen = 0;
1131 hdrtype = -1; /* dummy, it is called IPPROTO_IP */
1133 off = 0;
1135 error = (algo->init)(&algos, sav);
1136 if (error)
1137 return error;
1139 advancewidth = 0; /* safety */
1141 again:
1142 /* gory. */
1143 switch (hdrtype) {
1144 case -1: /* first one only */
1147 * copy ip hdr, modify to fit the AH checksum rule,
1148 * then take a checksum.
1150 struct ip iphdr;
1151 size_t hlen;
1153 m_copydata(m, off, sizeof(iphdr), (caddr_t)&iphdr);
1154 #ifdef _IP_VHL
1155 hlen = IP_VHL_HL(iphdr.ip_vhl) << 2;
1156 #else
1157 hlen = iphdr.ip_hl << 2;
1158 #endif
1159 iphdr.ip_ttl = 0;
1160 iphdr.ip_sum = htons(0);
1161 if (ip4_ah_cleartos)
1162 iphdr.ip_tos = 0;
1163 iphdr.ip_off = htons(ntohs(iphdr.ip_off) & ip4_ah_offsetmask);
1164 (algo->update)(&algos, (caddr_t)&iphdr, sizeof(struct ip));
1166 if (hlen != sizeof(struct ip)) {
1167 u_char *p;
1168 int i, l, skip;
1170 if (hlen > MCLBYTES) {
1171 error = EMSGSIZE;
1172 goto fail;
1174 n = m_getb(hlen, M_NOWAIT, MT_DATA, 0);
1175 if (n == NULL) {
1176 error = ENOBUFS;
1177 goto fail;
1179 m_copydata(m, off, hlen, mtod(n, caddr_t));
1182 * IP options processing.
1183 * See RFC2402 appendix A.
1185 p = mtod(n, u_char *);
1186 i = sizeof(struct ip);
1187 while (i < hlen) {
1188 if (i + IPOPT_OPTVAL >= hlen) {
1189 ipseclog((LOG_ERR, "ah4_calccksum: "
1190 "invalid IP option\n"));
1191 error = EINVAL;
1192 goto fail;
1194 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL ||
1195 p[i + IPOPT_OPTVAL] == IPOPT_NOP ||
1196 i + IPOPT_OLEN < hlen)
1198 else {
1199 ipseclog((LOG_ERR,
1200 "ah4_calccksum: invalid IP option "
1201 "(type=%02x)\n",
1202 p[i + IPOPT_OPTVAL]));
1203 error = EINVAL;
1204 goto fail;
1207 skip = 1;
1208 switch (p[i + IPOPT_OPTVAL]) {
1209 case IPOPT_EOL:
1210 case IPOPT_NOP:
1211 l = 1;
1212 skip = 0;
1213 break;
1214 case IPOPT_SECURITY: /* 0x82 */
1215 case 0x85: /* Extended security */
1216 case 0x86: /* Commercial security */
1217 case 0x94: /* Router alert */
1218 case 0x95: /* RFC1770 */
1219 l = p[i + IPOPT_OLEN];
1220 if (l < 2)
1221 goto invalopt;
1222 skip = 0;
1223 break;
1224 default:
1225 l = p[i + IPOPT_OLEN];
1226 if (l < 2)
1227 goto invalopt;
1228 skip = 1;
1229 break;
1231 if (l < 1 || hlen - i < l) {
1232 invalopt:
1233 ipseclog((LOG_ERR,
1234 "ah4_calccksum: invalid IP option "
1235 "(type=%02x len=%02x)\n",
1236 p[i + IPOPT_OPTVAL],
1237 p[i + IPOPT_OLEN]));
1238 error = EINVAL;
1239 goto fail;
1241 if (skip)
1242 bzero(p + i, l);
1243 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL)
1244 break;
1245 i += l;
1247 p = mtod(n, u_char *) + sizeof(struct ip);
1248 (algo->update)(&algos, p, hlen - sizeof(struct ip));
1250 m_free(n);
1251 n = NULL;
1254 hdrtype = (iphdr.ip_p) & 0xff;
1255 advancewidth = hlen;
1256 break;
1259 case IPPROTO_AH:
1261 struct ah ah;
1262 int siz;
1263 int hdrsiz;
1264 int totlen;
1266 m_copydata(m, off, sizeof(ah), (caddr_t)&ah);
1267 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1268 ? sizeof(struct ah)
1269 : sizeof(struct newah);
1270 siz = (*algo->sumsiz)(sav);
1271 totlen = (ah.ah_len + 2) << 2;
1274 * special treatment is necessary for the first one, not others
1276 if (!ahseen) {
1277 if (totlen > m->m_pkthdr.len - off ||
1278 totlen > MCLBYTES) {
1279 error = EMSGSIZE;
1280 goto fail;
1282 n = m_getb(totlen, M_NOWAIT, MT_DATA, 0);
1283 if (n == NULL) {
1284 error = ENOBUFS;
1285 goto fail;
1287 m_copydata(m, off, totlen, mtod(n, caddr_t));
1288 n->m_len = totlen;
1289 bzero(mtod(n, caddr_t) + hdrsiz, siz);
1290 (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1291 m_free(n);
1292 n = NULL;
1293 } else
1294 ah_update_mbuf(m, off, totlen, algo, &algos);
1295 ahseen++;
1297 hdrtype = ah.ah_nxt;
1298 advancewidth = totlen;
1299 break;
1302 default:
1303 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo, &algos);
1304 advancewidth = m->m_pkthdr.len - off;
1305 break;
1308 off += advancewidth;
1309 if (off < m->m_pkthdr.len)
1310 goto again;
1312 if (len < (*algo->sumsiz)(sav)) {
1313 error = EINVAL;
1314 goto fail;
1317 (algo->result)(&algos, &sumbuf[0]);
1318 bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
1320 if (n)
1321 m_free(n);
1322 return error;
1324 fail:
1325 if (n)
1326 m_free(n);
1327 return error;
1329 #endif
1331 #ifdef INET6
1333 * Go generate the checksum. This function won't modify the mbuf chain
1334 * except AH itself.
1336 * NOTE: the function does not free mbuf on failure.
1337 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1340 ah6_calccksum(struct mbuf *m, caddr_t ahdat, size_t len,
1341 const struct ah_algorithm *algo, struct secasvar *sav)
1343 int newoff, off;
1344 int proto, nxt;
1345 struct mbuf *n = NULL;
1346 int error;
1347 int ahseen;
1348 struct ah_algorithm_state algos;
1349 u_char sumbuf[AH_MAXSUMSIZE];
1351 if ((m->m_flags & M_PKTHDR) == 0)
1352 return EINVAL;
1354 error = (algo->init)(&algos, sav);
1355 if (error)
1356 return error;
1358 off = 0;
1359 proto = IPPROTO_IPV6;
1360 nxt = -1;
1361 ahseen = 0;
1363 again:
1364 newoff = ip6_nexthdr(m, off, proto, &nxt);
1365 if (newoff < 0)
1366 newoff = m->m_pkthdr.len;
1367 else if (newoff <= off) {
1368 error = EINVAL;
1369 goto fail;
1372 switch (proto) {
1373 case IPPROTO_IPV6:
1375 * special treatment is necessary for the first one, not others
1377 if (off == 0) {
1378 struct ip6_hdr ip6copy;
1380 if (newoff - off != sizeof(struct ip6_hdr)) {
1381 error = EINVAL;
1382 goto fail;
1385 m_copydata(m, off, newoff - off, (caddr_t)&ip6copy);
1386 /* RFC2402 */
1387 ip6copy.ip6_flow = 0;
1388 ip6copy.ip6_vfc &= ~IPV6_VERSION_MASK;
1389 ip6copy.ip6_vfc |= IPV6_VERSION;
1390 ip6copy.ip6_hlim = 0;
1391 in6_clearscope(&ip6copy.ip6_src); /* XXX */
1392 in6_clearscope(&ip6copy.ip6_dst); /* XXX */
1393 (algo->update)(&algos, (caddr_t)&ip6copy,
1394 sizeof(struct ip6_hdr));
1395 } else {
1396 newoff = m->m_pkthdr.len;
1397 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo,
1398 &algos);
1400 break;
1402 case IPPROTO_AH:
1404 int siz;
1405 int hdrsiz;
1407 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1408 ? sizeof(struct ah)
1409 : sizeof(struct newah);
1410 siz = (*algo->sumsiz)(sav);
1413 * special treatment is necessary for the first one, not others
1415 if (!ahseen) {
1416 if (newoff - off > MCLBYTES) {
1417 error = EMSGSIZE;
1418 goto fail;
1420 n = m_getb(newoff - off, M_NOWAIT, MT_DATA, 0);
1421 if (n == NULL) {
1422 error = ENOBUFS;
1423 goto fail;
1425 m_copydata(m, off, newoff - off, mtod(n, caddr_t));
1426 n->m_len = newoff - off;
1427 bzero(mtod(n, caddr_t) + hdrsiz, siz);
1428 (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1429 m_free(n);
1430 n = NULL;
1431 } else
1432 ah_update_mbuf(m, off, newoff - off, algo, &algos);
1433 ahseen++;
1434 break;
1437 case IPPROTO_HOPOPTS:
1438 case IPPROTO_DSTOPTS:
1440 struct ip6_ext *ip6e;
1441 int hdrlen, optlen;
1442 u_int8_t *p, *optend, *optp;
1444 if (newoff - off > MCLBYTES) {
1445 error = EMSGSIZE;
1446 goto fail;
1448 n = m_getb(newoff - off, M_NOWAIT, MT_DATA, 0);
1449 if (n == NULL) {
1450 error = ENOBUFS;
1451 goto fail;
1453 m_copydata(m, off, newoff - off, mtod(n, caddr_t));
1454 n->m_len = newoff - off;
1456 ip6e = mtod(n, struct ip6_ext *);
1457 hdrlen = (ip6e->ip6e_len + 1) << 3;
1458 if (newoff - off < hdrlen) {
1459 error = EINVAL;
1460 m_free(n);
1461 n = NULL;
1462 goto fail;
1464 p = mtod(n, u_int8_t *);
1465 optend = p + hdrlen;
1468 * ICV calculation for the options header including all
1469 * options. This part is a little tricky since there are
1470 * two type of options; mutable and immutable. We try to
1471 * null-out mutable ones here.
1473 optp = p + 2;
1474 while (optp < optend) {
1475 if (optp[0] == IP6OPT_PAD1)
1476 optlen = 1;
1477 else {
1478 if (optp + 2 > optend) {
1479 error = EINVAL;
1480 m_free(n);
1481 n = NULL;
1482 goto fail;
1484 optlen = optp[1] + 2;
1486 if (optp[0] & IP6OPT_MUTABLE)
1487 bzero(optp + 2, optlen - 2);
1490 optp += optlen;
1493 (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1494 m_free(n);
1495 n = NULL;
1496 break;
1499 case IPPROTO_ROUTING:
1501 * For an input packet, we can just calculate `as is'.
1502 * For an output packet, we assume ip6_output have already
1503 * made packet how it will be received at the final
1504 * destination.
1506 /* FALLTHROUGH */
1508 default:
1509 ah_update_mbuf(m, off, newoff - off, algo, &algos);
1510 break;
1513 if (newoff < m->m_pkthdr.len) {
1514 proto = nxt;
1515 off = newoff;
1516 goto again;
1519 if (len < (*algo->sumsiz)(sav)) {
1520 error = EINVAL;
1521 goto fail;
1524 (algo->result)(&algos, &sumbuf[0]);
1525 bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
1527 /* just in case */
1528 if (n)
1529 m_free(n);
1530 return 0;
1531 fail:
1532 /* just in case */
1533 if (n)
1534 m_free(n);
1535 return error;
1537 #endif