Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / netinet6 / ah_core.c
blob9abf01146050b2faa3a37929a8347f79285456c6
1 /* $NetBSD: ah_core.c,v 1.47 2009/03/18 17:06:52 cegger Exp $ */
2 /* $KAME: ah_core.c,v 1.57 2003/07/25 09:33:36 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 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: ah_core.c,v 1.47 2009/03/18 17:06:52 cegger Exp $");
40 #include "opt_inet.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/kernel.h>
54 #include <sys/syslog.h>
56 #include <net/if.h>
57 #include <net/route.h>
59 #include <netinet/in.h>
60 #include <netinet/in_systm.h>
61 #include <netinet/ip.h>
62 #include <netinet/in_var.h>
64 #ifdef INET6
65 #include <netinet/ip6.h>
66 #include <netinet6/ip6_var.h>
67 #include <netinet/icmp6.h>
68 #include <netinet6/scope6_var.h>
69 #endif
71 #include <netinet6/ipsec.h>
72 #include <netinet6/ah.h>
73 #include <netinet6/ah_aesxcbcmac.h>
74 #ifdef IPSEC_ESP
75 #include <netinet6/esp.h>
76 #endif
77 #include <net/pfkeyv2.h>
78 #include <netkey/keydb.h>
79 #include <sys/md5.h>
80 #define MD5_RESULTLEN 16
81 #include <sys/sha1.h>
82 #define SHA1_RESULTLEN 20
83 #include <sys/sha2.h>
84 #include <sys/rmd160.h>
85 #define RIPEMD160_RESULTLEN 20
87 #include <net/net_osdep.h>
89 static int ah_sumsiz_1216(struct secasvar *);
90 static int ah_sumsiz_zero(struct secasvar *);
91 static int ah_common_mature(struct secasvar *);
92 static int ah_none_mature(struct secasvar *);
93 static int ah_none_init(struct ah_algorithm_state *, struct secasvar *);
94 static void ah_none_loop(struct ah_algorithm_state *, u_int8_t *, size_t);
95 static void ah_none_result(struct ah_algorithm_state *,
96 u_int8_t *, size_t);
97 static int ah_keyed_md5_mature(struct secasvar *);
98 static int ah_keyed_md5_init(struct ah_algorithm_state *,
99 struct secasvar *);
100 static void ah_keyed_md5_loop(struct ah_algorithm_state *, u_int8_t *,
101 size_t);
102 static void ah_keyed_md5_result(struct ah_algorithm_state *,
103 u_int8_t *, size_t);
104 static int ah_keyed_sha1_init(struct ah_algorithm_state *,
105 struct secasvar *);
106 static void ah_keyed_sha1_loop(struct ah_algorithm_state *, u_int8_t *,
107 size_t);
108 static void ah_keyed_sha1_result(struct ah_algorithm_state *, u_int8_t *,
109 size_t);
110 static int ah_hmac_md5_init(struct ah_algorithm_state *,
111 struct secasvar *);
112 static void ah_hmac_md5_loop(struct ah_algorithm_state *, u_int8_t *,
113 size_t);
114 static void ah_hmac_md5_result(struct ah_algorithm_state *,
115 u_int8_t *, size_t);
116 static int ah_hmac_sha1_init(struct ah_algorithm_state *,
117 struct secasvar *);
118 static void ah_hmac_sha1_loop(struct ah_algorithm_state *, u_int8_t *,
119 size_t);
120 static void ah_hmac_sha1_result(struct ah_algorithm_state *,
121 u_int8_t *, size_t);
122 static int ah_hmac_sha2_256_init(struct ah_algorithm_state *,
123 struct secasvar *);
124 static void ah_hmac_sha2_256_loop(struct ah_algorithm_state *, u_int8_t *,
125 size_t);
126 static void ah_hmac_sha2_256_result(struct ah_algorithm_state *,
127 u_int8_t *, size_t);
128 static int ah_hmac_sha2_384_init(struct ah_algorithm_state *,
129 struct secasvar *);
130 static void ah_hmac_sha2_384_loop(struct ah_algorithm_state *, u_int8_t *,
131 size_t);
132 static void ah_hmac_sha2_384_result(struct ah_algorithm_state *,
133 u_int8_t *, size_t);
134 static int ah_hmac_sha2_512_init(struct ah_algorithm_state *,
135 struct secasvar *);
136 static void ah_hmac_sha2_512_loop(struct ah_algorithm_state *, u_int8_t *,
137 size_t);
138 static void ah_hmac_sha2_512_result(struct ah_algorithm_state *,
139 u_int8_t *, size_t);
140 static int ah_hmac_ripemd160_init(struct ah_algorithm_state *,
141 struct secasvar *);
142 static void ah_hmac_ripemd160_loop(struct ah_algorithm_state *, u_int8_t *,
143 size_t);
144 static void ah_hmac_ripemd160_result(struct ah_algorithm_state *,
145 u_int8_t *, size_t);
147 static void ah_update_mbuf(struct mbuf *, int, int,
148 const struct ah_algorithm *, struct ah_algorithm_state *);
150 /* checksum algorithms */
151 static const struct ah_algorithm ah_algorithms[] = {
152 { ah_sumsiz_1216, ah_common_mature, 128, 128, "hmac-md5",
153 ah_hmac_md5_init, ah_hmac_md5_loop,
154 ah_hmac_md5_result, },
155 { ah_sumsiz_1216, ah_common_mature, 160, 160, "hmac-sha1",
156 ah_hmac_sha1_init, ah_hmac_sha1_loop,
157 ah_hmac_sha1_result, },
158 { ah_sumsiz_1216, ah_keyed_md5_mature, 128, 128, "keyed-md5",
159 ah_keyed_md5_init, ah_keyed_md5_loop,
160 ah_keyed_md5_result, },
161 { ah_sumsiz_1216, ah_common_mature, 160, 160, "keyed-sha1",
162 ah_keyed_sha1_init, ah_keyed_sha1_loop,
163 ah_keyed_sha1_result, },
164 { ah_sumsiz_zero, ah_none_mature, 0, 2048, "none",
165 ah_none_init, ah_none_loop, ah_none_result, },
166 { ah_sumsiz_1216, ah_common_mature, 256, 256,
167 "hmac-sha2-256",
168 ah_hmac_sha2_256_init, ah_hmac_sha2_256_loop,
169 ah_hmac_sha2_256_result, },
170 { ah_sumsiz_1216, ah_common_mature, 384, 384,
171 "hmac-sha2-384",
172 ah_hmac_sha2_384_init, ah_hmac_sha2_384_loop,
173 ah_hmac_sha2_384_result, },
174 { ah_sumsiz_1216, ah_common_mature, 512, 512,
175 "hmac-sha2-512",
176 ah_hmac_sha2_512_init, ah_hmac_sha2_512_loop,
177 ah_hmac_sha2_512_result, },
178 { ah_sumsiz_1216, ah_common_mature, 160, 160,
179 "hmac-ripemd160",
180 ah_hmac_ripemd160_init, ah_hmac_ripemd160_loop,
181 ah_hmac_ripemd160_result, },
182 { ah_sumsiz_1216, ah_common_mature, 128, 128,
183 "aes-xcbc-mac",
184 ah_aes_xcbc_mac_init, ah_aes_xcbc_mac_loop,
185 ah_aes_xcbc_mac_result, },
188 const struct ah_algorithm *
189 ah_algorithm_lookup(int idx)
192 switch (idx) {
193 case SADB_AALG_MD5HMAC:
194 return &ah_algorithms[0];
195 case SADB_AALG_SHA1HMAC:
196 return &ah_algorithms[1];
197 case SADB_X_AALG_MD5:
198 return &ah_algorithms[2];
199 case SADB_X_AALG_SHA:
200 return &ah_algorithms[3];
201 case SADB_X_AALG_NULL:
202 return &ah_algorithms[4];
203 case SADB_X_AALG_SHA2_256:
204 return &ah_algorithms[5];
205 case SADB_X_AALG_SHA2_384:
206 return &ah_algorithms[6];
207 case SADB_X_AALG_SHA2_512:
208 return &ah_algorithms[7];
209 case SADB_X_AALG_RIPEMD160HMAC:
210 return &ah_algorithms[8];
211 case SADB_X_AALG_AES_XCBC_MAC:
212 return &ah_algorithms[9];
213 default:
214 return NULL;
219 static int
220 ah_sumsiz_1216(struct secasvar *sav)
222 if (!sav)
223 panic("ah_sumsiz_1216: null pointer is passed");
224 if (sav->flags & SADB_X_EXT_OLD)
225 return 16;
226 else
227 return 12;
230 static int
231 ah_sumsiz_zero(struct secasvar *sav)
233 if (!sav)
234 panic("ah_sumsiz_zero: null pointer is passed");
235 return 0;
238 static int
239 ah_common_mature(struct secasvar *sav)
241 const struct ah_algorithm *algo;
243 if (!sav->key_auth) {
244 ipseclog((LOG_ERR, "ah_common_mature: no key is given.\n"));
245 return 1;
248 algo = ah_algorithm_lookup(sav->alg_auth);
249 if (!algo) {
250 ipseclog((LOG_ERR, "ah_common_mature: unsupported algorithm.\n"));
251 return 1;
254 if (sav->key_auth->sadb_key_bits < algo->keymin ||
255 algo->keymax < sav->key_auth->sadb_key_bits) {
256 ipseclog((LOG_ERR,
257 "ah_common_mature: invalid key length %d for %s.\n",
258 sav->key_auth->sadb_key_bits, algo->name));
259 return 1;
262 return 0;
265 static int
266 ah_none_mature(struct secasvar *sav)
268 if (sav->sah->saidx.proto == IPPROTO_AH) {
269 ipseclog((LOG_ERR,
270 "ah_none_mature: protocol and algorithm mismatch.\n"));
271 return 1;
273 return 0;
276 static int
277 ah_none_init(struct ah_algorithm_state *state, struct secasvar *sav)
279 state->foo = NULL;
280 return 0;
283 static void
284 ah_none_loop(struct ah_algorithm_state *state,
285 u_int8_t *addr, size_t len)
289 static void
290 ah_none_result(struct ah_algorithm_state *state,
291 u_int8_t *addr, size_t l)
295 static int
296 ah_keyed_md5_mature(struct secasvar *sav)
298 /* anything is okay */
299 return 0;
302 static int
303 ah_keyed_md5_init(struct ah_algorithm_state *state, struct secasvar *sav)
305 size_t padlen;
306 size_t keybitlen;
307 u_int8_t buf[32];
309 if (!state)
310 panic("ah_keyed_md5_init: what?");
312 state->sav = sav;
313 state->foo = (void *)malloc(sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
314 if (state->foo == NULL)
315 return ENOBUFS;
317 MD5Init((MD5_CTX *)state->foo);
318 if (state->sav) {
319 MD5Update((MD5_CTX *)state->foo,
320 (u_int8_t *)_KEYBUF(state->sav->key_auth),
321 (u_int)_KEYLEN(state->sav->key_auth));
324 * Pad after the key.
325 * We cannot simply use md5_pad() since the function
326 * won't update the total length.
328 if (_KEYLEN(state->sav->key_auth) < 56)
329 padlen = 64 - 8 - _KEYLEN(state->sav->key_auth);
330 else
331 padlen = 64 + 64 - 8 - _KEYLEN(state->sav->key_auth);
332 keybitlen = _KEYLEN(state->sav->key_auth);
333 keybitlen *= 8;
335 buf[0] = 0x80;
336 MD5Update((MD5_CTX *)state->foo, &buf[0], 1);
337 padlen--;
339 memset(buf, 0, sizeof(buf));
340 while (sizeof(buf) < padlen) {
341 MD5Update((MD5_CTX *)state->foo, &buf[0], sizeof(buf));
342 padlen -= sizeof(buf);
344 if (padlen) {
345 MD5Update((MD5_CTX *)state->foo, &buf[0], padlen);
348 buf[0] = (keybitlen >> 0) & 0xff;
349 buf[1] = (keybitlen >> 8) & 0xff;
350 buf[2] = (keybitlen >> 16) & 0xff;
351 buf[3] = (keybitlen >> 24) & 0xff;
352 MD5Update((MD5_CTX *)state->foo, buf, 8);
355 return 0;
358 static void
359 ah_keyed_md5_loop(struct ah_algorithm_state *state, u_int8_t *addr,
360 size_t len)
362 if (!state)
363 panic("ah_keyed_md5_loop: what?");
365 MD5Update((MD5_CTX *)state->foo, addr, len);
368 static void
369 ah_keyed_md5_result(struct ah_algorithm_state *state, u_int8_t *addr,
370 size_t l)
372 u_char digest[MD5_RESULTLEN];
374 if (!state)
375 panic("ah_keyed_md5_result: what?");
377 if (state->sav) {
378 MD5Update((MD5_CTX *)state->foo,
379 (u_int8_t *)_KEYBUF(state->sav->key_auth),
380 (u_int)_KEYLEN(state->sav->key_auth));
382 MD5Final(digest, (MD5_CTX *)state->foo);
383 free(state->foo, M_TEMP);
384 memcpy(addr, digest, sizeof(digest) > l ? l : sizeof(digest));
387 static int
388 ah_keyed_sha1_init(struct ah_algorithm_state *state, struct secasvar *sav)
390 SHA1_CTX *ctxt;
391 size_t padlen;
392 size_t keybitlen;
393 u_int8_t buf[32];
395 if (!state)
396 panic("ah_keyed_sha1_init: what?");
398 state->sav = sav;
399 state->foo = (void *)malloc(sizeof(SHA1_CTX), M_TEMP, M_NOWAIT);
400 if (!state->foo)
401 return ENOBUFS;
403 ctxt = (SHA1_CTX *)state->foo;
404 SHA1Init(ctxt);
406 if (state->sav) {
407 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth),
408 (u_int)_KEYLEN(state->sav->key_auth));
411 * Pad after the key.
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;
420 buf[0] = 0x80;
421 SHA1Update(ctxt, &buf[0], 1);
422 padlen--;
424 memset(buf, 0, sizeof(buf));
425 while (sizeof(buf) < padlen) {
426 SHA1Update(ctxt, &buf[0], sizeof(buf));
427 padlen -= sizeof(buf);
429 if (padlen) {
430 SHA1Update(ctxt, &buf[0], padlen);
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);
440 return 0;
443 static void
444 ah_keyed_sha1_loop(struct ah_algorithm_state *state, u_int8_t *addr,
445 size_t len)
447 SHA1_CTX *ctxt;
449 if (!state || !state->foo)
450 panic("ah_keyed_sha1_loop: what?");
451 ctxt = (SHA1_CTX *)state->foo;
453 SHA1Update(ctxt, (u_int8_t *)addr, (size_t)len);
456 static void
457 ah_keyed_sha1_result(struct ah_algorithm_state *state, u_int8_t *addr,
458 size_t l)
460 u_char digest[SHA1_RESULTLEN]; /* SHA-1 generates 160 bits */
461 SHA1_CTX *ctxt;
463 if (!state || !state->foo)
464 panic("ah_keyed_sha1_result: what?");
465 ctxt = (SHA1_CTX *)state->foo;
467 if (state->sav) {
468 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth),
469 (u_int)_KEYLEN(state->sav->key_auth));
471 SHA1Final((u_int8_t *)digest, ctxt);
472 memcpy(addr, digest, sizeof(digest) > l ? l : sizeof(digest));
474 free(state->foo, M_TEMP);
477 static int
478 ah_hmac_md5_init(struct ah_algorithm_state *state, struct secasvar *sav)
480 u_char *ipad;
481 u_char *opad;
482 u_char tk[MD5_RESULTLEN];
483 u_char *key;
484 size_t keylen;
485 size_t i;
486 MD5_CTX *ctxt;
488 if (!state)
489 panic("ah_hmac_md5_init: what?");
491 state->sav = sav;
492 state->foo = (void *)malloc(64 + 64 + sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
493 if (!state->foo)
494 return ENOBUFS;
496 ipad = (u_char *)state->foo;
497 opad = (u_char *)(ipad + 64);
498 ctxt = (MD5_CTX *)(opad + 64);
500 /* compress the key if necessery */
501 if (64 < _KEYLEN(state->sav->key_auth)) {
502 MD5Init(ctxt);
503 MD5Update(ctxt, _KEYBUF(state->sav->key_auth),
504 _KEYLEN(state->sav->key_auth));
505 MD5Final(&tk[0], ctxt);
506 key = &tk[0];
507 keylen = 16;
508 } else {
509 key = _KEYBUF(state->sav->key_auth);
510 keylen = _KEYLEN(state->sav->key_auth);
513 memset(ipad, 0, 64);
514 memset(opad, 0, 64);
515 memcpy(ipad, key, keylen);
516 memcpy(opad, key, keylen);
517 for (i = 0; i < 64; i++) {
518 ipad[i] ^= 0x36;
519 opad[i] ^= 0x5c;
522 MD5Init(ctxt);
523 MD5Update(ctxt, ipad, 64);
525 return 0;
528 static void
529 ah_hmac_md5_loop(struct ah_algorithm_state *state, u_int8_t *addr,
530 size_t len)
532 MD5_CTX *ctxt;
534 if (!state || !state->foo)
535 panic("ah_hmac_md5_loop: what?");
536 ctxt = (MD5_CTX *)(((u_int8_t *)state->foo) + 128);
537 MD5Update(ctxt, addr, len);
540 static void
541 ah_hmac_md5_result(struct ah_algorithm_state *state, u_int8_t *addr,
542 size_t l)
544 u_char digest[MD5_RESULTLEN];
545 u_char *ipad;
546 u_char *opad;
547 MD5_CTX *ctxt;
549 if (!state || !state->foo)
550 panic("ah_hmac_md5_result: what?");
552 ipad = (u_char *)state->foo;
553 opad = (u_char *)(ipad + 64);
554 ctxt = (MD5_CTX *)(opad + 64);
556 MD5Final(digest, ctxt);
558 MD5Init(ctxt);
559 MD5Update(ctxt, opad, 64);
560 MD5Update(ctxt, digest, sizeof(digest));
561 MD5Final(digest, ctxt);
563 memcpy(addr, digest, sizeof(digest) > l ? l : sizeof(digest));
565 free(state->foo, M_TEMP);
568 static int
569 ah_hmac_sha1_init(struct ah_algorithm_state *state, struct secasvar *sav)
571 u_char *ipad;
572 u_char *opad;
573 SHA1_CTX *ctxt;
574 u_char tk[SHA1_RESULTLEN]; /* SHA-1 generates 160 bits */
575 u_char *key;
576 size_t keylen;
577 size_t i;
579 if (!state)
580 panic("ah_hmac_sha1_init: what?");
582 state->sav = sav;
583 state->foo = (void *)malloc(64 + 64 + sizeof(SHA1_CTX),
584 M_TEMP, M_NOWAIT);
585 if (!state->foo)
586 return ENOBUFS;
588 ipad = (u_char *)state->foo;
589 opad = (u_char *)(ipad + 64);
590 ctxt = (SHA1_CTX *)(opad + 64);
592 /* compress the key if necessery */
593 if (64 < _KEYLEN(state->sav->key_auth)) {
594 SHA1Init(ctxt);
595 SHA1Update(ctxt, _KEYBUF(state->sav->key_auth),
596 _KEYLEN(state->sav->key_auth));
597 SHA1Final(&tk[0], ctxt);
598 key = &tk[0];
599 keylen = SHA1_RESULTLEN;
600 } else {
601 key = _KEYBUF(state->sav->key_auth);
602 keylen = _KEYLEN(state->sav->key_auth);
605 memset(ipad, 0, 64);
606 memset(opad, 0, 64);
607 memcpy(ipad, key, keylen);
608 memcpy(opad, key, keylen);
609 for (i = 0; i < 64; i++) {
610 ipad[i] ^= 0x36;
611 opad[i] ^= 0x5c;
614 SHA1Init(ctxt);
615 SHA1Update(ctxt, ipad, 64);
617 return 0;
620 static void
621 ah_hmac_sha1_loop(struct ah_algorithm_state *state, u_int8_t *addr,
622 size_t len)
624 SHA1_CTX *ctxt;
626 if (!state || !state->foo)
627 panic("ah_hmac_sha1_loop: what?");
629 ctxt = (SHA1_CTX *)(((u_char *)state->foo) + 128);
630 SHA1Update(ctxt, (u_int8_t *)addr, (size_t)len);
633 static void
634 ah_hmac_sha1_result(struct ah_algorithm_state *state, u_int8_t *addr,
635 size_t l)
637 u_char digest[SHA1_RESULTLEN]; /* SHA-1 generates 160 bits */
638 u_char *ipad;
639 u_char *opad;
640 SHA1_CTX *ctxt;
642 if (!state || !state->foo)
643 panic("ah_hmac_sha1_result: what?");
645 ipad = (u_char *)state->foo;
646 opad = (u_char *)(ipad + 64);
647 ctxt = (SHA1_CTX *)(opad + 64);
649 SHA1Final((u_int8_t *)digest, ctxt);
651 SHA1Init(ctxt);
652 SHA1Update(ctxt, opad, 64);
653 SHA1Update(ctxt, (u_int8_t *)digest, sizeof(digest));
654 SHA1Final((u_int8_t *)digest, ctxt);
656 memcpy(addr, digest, sizeof(digest) > l ? l : sizeof(digest));
658 free(state->foo, M_TEMP);
661 static int
662 ah_hmac_sha2_256_init(struct ah_algorithm_state *state, struct secasvar *sav)
664 u_char *ipad;
665 u_char *opad;
666 SHA256_CTX *ctxt;
667 u_char tk[SHA256_DIGEST_LENGTH];
668 u_char *key;
669 size_t keylen;
670 size_t i;
672 if (!state)
673 panic("ah_hmac_sha2_256_init: what?");
675 state->sav = sav;
676 state->foo = (void *)malloc(64 + 64 + sizeof(SHA256_CTX),
677 M_TEMP, M_NOWAIT);
678 if (!state->foo)
679 return ENOBUFS;
681 ipad = (u_char *)state->foo;
682 opad = (u_char *)(ipad + 64);
683 ctxt = (SHA256_CTX *)(opad + 64);
685 /* compress the key if necessery */
686 if (64 < _KEYLEN(state->sav->key_auth)) {
687 memset(tk, 0, sizeof(tk));
688 SHA256_Init(ctxt);
689 SHA256_Update(ctxt, _KEYBUF(state->sav->key_auth),
690 _KEYLEN(state->sav->key_auth));
691 SHA256_Final(&tk[0], ctxt);
692 key = &tk[0];
693 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
694 } else {
695 key = _KEYBUF(state->sav->key_auth);
696 keylen = _KEYLEN(state->sav->key_auth);
699 memset(ipad, 0, 64);
700 memset(opad, 0, 64);
701 memcpy(ipad, key, keylen);
702 memcpy(opad, key, keylen);
703 for (i = 0; i < 64; i++) {
704 ipad[i] ^= 0x36;
705 opad[i] ^= 0x5c;
708 SHA256_Init(ctxt);
709 SHA256_Update(ctxt, ipad, 64);
711 return 0;
714 static void
715 ah_hmac_sha2_256_loop(struct ah_algorithm_state *state, u_int8_t *addr,
716 size_t len)
718 SHA256_CTX *ctxt;
720 if (!state || !state->foo)
721 panic("ah_hmac_sha2_256_loop: what?");
723 ctxt = (SHA256_CTX *)(((u_char *)state->foo) + 128);
724 SHA256_Update(ctxt, (void *)addr, (size_t)len);
727 static void
728 ah_hmac_sha2_256_result(struct ah_algorithm_state *state, u_int8_t *addr,
729 size_t l)
731 u_char digest[SHA256_DIGEST_LENGTH];
732 u_char *ipad;
733 u_char *opad;
734 SHA256_CTX *ctxt;
736 if (!state || !state->foo)
737 panic("ah_hmac_sha2_256_result: what?");
739 ipad = (u_char *)state->foo;
740 opad = (u_char *)(ipad + 64);
741 ctxt = (SHA256_CTX *)(opad + 64);
743 SHA256_Final((void *)digest, ctxt);
745 SHA256_Init(ctxt);
746 SHA256_Update(ctxt, opad, 64);
747 SHA256_Update(ctxt, (void *)digest, sizeof(digest));
748 SHA256_Final((void *)digest, ctxt);
750 memcpy(addr, digest, sizeof(digest) > l ? l : sizeof(digest));
752 free(state->foo, M_TEMP);
755 static int
756 ah_hmac_sha2_384_init(struct ah_algorithm_state *state, struct secasvar *sav)
758 u_char *ipad;
759 u_char *opad;
760 SHA384_CTX *ctxt;
761 u_char tk[SHA384_DIGEST_LENGTH];
762 u_char *key;
763 size_t keylen;
764 size_t i;
766 if (!state)
767 panic("ah_hmac_sha2_384_init: what?");
769 state->sav = sav;
770 state->foo = (void *)malloc(64 + 64 + sizeof(SHA384_CTX),
771 M_TEMP, M_NOWAIT);
772 if (!state->foo)
773 return ENOBUFS;
774 memset(state->foo, 0, 64 + 64 + sizeof(SHA384_CTX));
776 ipad = (u_char *)state->foo;
777 opad = (u_char *)(ipad + 64);
778 ctxt = (SHA384_CTX *)(opad + 64);
780 /* compress the key if necessery */
781 if (64 < _KEYLEN(state->sav->key_auth)) {
782 memset(tk, 0, sizeof(tk));
783 SHA384_Init(ctxt);
784 SHA384_Update(ctxt, _KEYBUF(state->sav->key_auth),
785 _KEYLEN(state->sav->key_auth));
786 SHA384_Final(&tk[0], ctxt);
787 key = &tk[0];
788 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
789 } else {
790 key = _KEYBUF(state->sav->key_auth);
791 keylen = _KEYLEN(state->sav->key_auth);
794 memset(ipad, 0, 64);
795 memset(opad, 0, 64);
796 memcpy(ipad, key, keylen);
797 memcpy(opad, key, keylen);
798 for (i = 0; i < 64; i++) {
799 ipad[i] ^= 0x36;
800 opad[i] ^= 0x5c;
803 SHA384_Init(ctxt);
804 SHA384_Update(ctxt, ipad, 64);
806 return 0;
809 static void
810 ah_hmac_sha2_384_loop(struct ah_algorithm_state *state, u_int8_t *addr,
811 size_t len)
813 SHA384_CTX *ctxt;
815 if (!state || !state->foo)
816 panic("ah_hmac_sha2_384_loop: what?");
818 ctxt = (SHA384_CTX *)(((u_char *)state->foo) + 128);
819 SHA384_Update(ctxt, (void *)addr, (size_t)len);
822 static void
823 ah_hmac_sha2_384_result(struct ah_algorithm_state *state, u_int8_t *addr,
824 size_t l)
826 u_char digest[SHA384_DIGEST_LENGTH];
827 u_char *ipad;
828 u_char *opad;
829 SHA384_CTX *ctxt;
831 if (!state || !state->foo)
832 panic("ah_hmac_sha2_384_result: what?");
834 ipad = (u_char *)state->foo;
835 opad = (u_char *)(ipad + 64);
836 ctxt = (SHA384_CTX *)(opad + 64);
838 SHA384_Final((void *)digest, ctxt);
840 SHA384_Init(ctxt);
841 SHA384_Update(ctxt, opad, 64);
842 SHA384_Update(ctxt, (void *)digest, sizeof(digest));
843 SHA384_Final((void *)digest, ctxt);
845 memcpy(addr, digest, sizeof(digest) > l ? l : sizeof(digest));
847 free(state->foo, M_TEMP);
850 static int
851 ah_hmac_sha2_512_init(struct ah_algorithm_state *state, struct secasvar *sav)
853 u_char *ipad;
854 u_char *opad;
855 SHA512_CTX *ctxt;
856 u_char tk[SHA512_DIGEST_LENGTH];
857 u_char *key;
858 size_t keylen;
859 size_t i;
861 if (!state)
862 panic("ah_hmac_sha2_512_init: what?");
864 state->sav = sav;
865 state->foo = (void *)malloc(64 + 64 + sizeof(SHA512_CTX),
866 M_TEMP, M_NOWAIT);
867 if (!state->foo)
868 return ENOBUFS;
869 memset(state->foo, 0, 64 + 64 + sizeof(SHA512_CTX));
871 ipad = (u_char *)state->foo;
872 opad = (u_char *)(ipad + 64);
873 ctxt = (SHA512_CTX *)(opad + 64);
875 /* compress the key if necessery */
876 if (64 < _KEYLEN(state->sav->key_auth)) {
877 memset(tk, 0, sizeof(tk));
878 SHA512_Init(ctxt);
879 SHA512_Update(ctxt, _KEYBUF(state->sav->key_auth),
880 _KEYLEN(state->sav->key_auth));
881 SHA512_Final(&tk[0], ctxt);
882 key = &tk[0];
883 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
884 } else {
885 key = _KEYBUF(state->sav->key_auth);
886 keylen = _KEYLEN(state->sav->key_auth);
889 memset(ipad, 0, 64);
890 memset(opad, 0, 64);
891 memcpy(ipad, key, keylen);
892 memcpy(opad, key, keylen);
893 for (i = 0; i < 64; i++) {
894 ipad[i] ^= 0x36;
895 opad[i] ^= 0x5c;
898 SHA512_Init(ctxt);
899 SHA512_Update(ctxt, ipad, 64);
901 return 0;
904 static void
905 ah_hmac_sha2_512_loop(struct ah_algorithm_state *state, u_int8_t *addr,
906 size_t len)
908 SHA512_CTX *ctxt;
910 if (!state || !state->foo)
911 panic("ah_hmac_sha2_512_loop: what?");
913 ctxt = (SHA512_CTX *)(((u_char *)state->foo) + 128);
914 SHA512_Update(ctxt, (void *)addr, (size_t)len);
917 static void
918 ah_hmac_sha2_512_result(struct ah_algorithm_state *state, u_int8_t *addr,
919 size_t l)
921 u_char digest[SHA512_DIGEST_LENGTH];
922 u_char *ipad;
923 u_char *opad;
924 SHA512_CTX *ctxt;
926 if (!state || !state->foo)
927 panic("ah_hmac_sha2_512_result: what?");
929 ipad = (u_char *)state->foo;
930 opad = (u_char *)(ipad + 64);
931 ctxt = (SHA512_CTX *)(opad + 64);
933 SHA512_Final((void *)digest, ctxt);
935 SHA512_Init(ctxt);
936 SHA512_Update(ctxt, opad, 64);
937 SHA512_Update(ctxt, (void *)digest, sizeof(digest));
938 SHA512_Final((void *)digest, ctxt);
940 memcpy(addr, digest, sizeof(digest) > l ? l : sizeof(digest));
942 free(state->foo, M_TEMP);
945 static int
946 ah_hmac_ripemd160_init(struct ah_algorithm_state *state, struct secasvar *sav)
948 u_char *ipad;
949 u_char *opad;
950 RMD160_CTX *ctxt;
951 u_char tk[RIPEMD160_RESULTLEN];
952 u_char *key;
953 size_t keylen;
954 size_t i;
956 if (!state)
957 panic("ah_hmac_ripemd160_init: what?");
959 state->sav = sav;
960 state->foo = (void *)malloc(64 + 64 + sizeof(RMD160_CTX),
961 M_TEMP, M_NOWAIT);
962 if (!state->foo)
963 return ENOBUFS;
964 memset(state->foo, 0, 64 + 64 + sizeof(RMD160_CTX));
966 ipad = (u_char *)state->foo;
967 opad = (u_char *)(ipad + 64);
968 ctxt = (RMD160_CTX *)(opad + 64);
970 /* compress the key if necessery */
971 if (64 < _KEYLEN(state->sav->key_auth)) {
972 memset(tk, 0, sizeof(tk));
973 RMD160Init(ctxt);
974 RMD160Update(ctxt, _KEYBUF(state->sav->key_auth),
975 _KEYLEN(state->sav->key_auth));
976 RMD160Final(&tk[0], ctxt);
977 key = &tk[0];
978 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
979 } else {
980 key = _KEYBUF(state->sav->key_auth);
981 keylen = _KEYLEN(state->sav->key_auth);
984 memset(ipad, 0, 64);
985 memset(opad, 0, 64);
986 memcpy(ipad, key, keylen);
987 memcpy(opad, key, keylen);
988 for (i = 0; i < 64; i++) {
989 ipad[i] ^= 0x36;
990 opad[i] ^= 0x5c;
993 RMD160Init(ctxt);
994 RMD160Update(ctxt, ipad, 64);
996 return 0;
999 static void
1000 ah_hmac_ripemd160_loop(struct ah_algorithm_state *state, u_int8_t *addr,
1001 size_t len)
1003 RMD160_CTX *ctxt;
1005 if (!state || !state->foo)
1006 panic("ah_hmac_ripemd160_loop: what?");
1008 ctxt = (RMD160_CTX *)(((u_char *)state->foo) + 128);
1009 RMD160Update(ctxt, (void *)addr, (size_t)len);
1012 static void
1013 ah_hmac_ripemd160_result(struct ah_algorithm_state *state, u_int8_t *addr,
1014 size_t l)
1016 u_char digest[RIPEMD160_RESULTLEN];
1017 u_char *ipad;
1018 u_char *opad;
1019 RMD160_CTX *ctxt;
1021 if (!state || !state->foo)
1022 panic("ah_hmac_ripemd160_result: what?");
1024 ipad = (u_char *)state->foo;
1025 opad = (u_char *)(ipad + 64);
1026 ctxt = (RMD160_CTX *)(opad + 64);
1028 RMD160Final((void *)digest, ctxt);
1030 RMD160Init(ctxt);
1031 RMD160Update(ctxt, opad, 64);
1032 RMD160Update(ctxt, (void *)digest, sizeof(digest));
1033 RMD160Final((void *)digest, ctxt);
1035 memcpy(addr, digest, sizeof(digest) > l ? l : sizeof(digest));
1037 free(state->foo, M_TEMP);
1040 /*------------------------------------------------------------*/
1043 * go generate the checksum.
1045 static void
1046 ah_update_mbuf(struct mbuf *m, int off, int len,
1047 const struct ah_algorithm *algo, struct ah_algorithm_state *algos)
1049 struct mbuf *n;
1050 int tlen;
1052 /* easy case first */
1053 if (off + len <= m->m_len) {
1054 (algo->update)(algos, mtod(m, u_int8_t *) + off, len);
1055 return;
1058 for (n = m; n; n = n->m_next) {
1059 if (off < n->m_len)
1060 break;
1062 off -= n->m_len;
1065 if (!n)
1066 panic("ah_update_mbuf: wrong offset specified");
1068 for (/* nothing */; n && len > 0; n = n->m_next) {
1069 if (n->m_len == 0)
1070 continue;
1071 if (n->m_len - off < len)
1072 tlen = n->m_len - off;
1073 else
1074 tlen = len;
1076 (algo->update)(algos, mtod(n, u_int8_t *) + off, tlen);
1078 len -= tlen;
1079 off = 0;
1083 #ifdef INET
1085 * Go generate the checksum. This function won't modify the mbuf chain
1086 * except AH itself.
1088 * NOTE: the function does not free mbuf on failure.
1089 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1092 ah4_calccksum(struct mbuf *m, u_int8_t *ahdat, size_t len,
1093 const struct ah_algorithm *algo, struct secasvar *sav)
1095 int off;
1096 int hdrtype;
1097 size_t advancewidth;
1098 struct ah_algorithm_state algos;
1099 u_char sumbuf[AH_MAXSUMSIZE];
1100 int error = 0;
1101 int ahseen;
1102 struct mbuf *n = NULL;
1104 if ((m->m_flags & M_PKTHDR) == 0)
1105 return EINVAL;
1107 ahseen = 0;
1108 hdrtype = -1; /* dummy, it is called IPPROTO_IP */
1110 off = 0;
1112 error = (algo->init)(&algos, sav);
1113 if (error)
1114 return error;
1116 advancewidth = 0; /* safety */
1118 again:
1119 /* gory. */
1120 switch (hdrtype) {
1121 case -1: /* first one only */
1124 * copy ip hdr, modify to fit the AH checksum rule,
1125 * then take a checksum.
1127 struct ip iphdr;
1128 size_t hlen;
1130 m_copydata(m, off, sizeof(iphdr), (void *)&iphdr);
1131 hlen = iphdr.ip_hl << 2;
1132 iphdr.ip_ttl = 0;
1133 iphdr.ip_sum = htons(0);
1134 if (ip4_ah_cleartos)
1135 iphdr.ip_tos = 0;
1136 iphdr.ip_off = htons(ntohs(iphdr.ip_off) & ip4_ah_offsetmask);
1137 (algo->update)(&algos, (u_int8_t *)&iphdr, sizeof(struct ip));
1139 if (hlen != sizeof(struct ip)) {
1140 u_char *p;
1141 int i, l, skip;
1143 if (hlen > MCLBYTES) {
1144 error = EMSGSIZE;
1145 goto fail;
1147 MGET(n, M_DONTWAIT, MT_DATA);
1148 if (n && hlen > MLEN) {
1149 MCLGET(n, M_DONTWAIT);
1150 if ((n->m_flags & M_EXT) == 0) {
1151 m_free(n);
1152 n = NULL;
1155 if (n == NULL) {
1156 error = ENOBUFS;
1157 goto fail;
1159 m_copydata(m, off, hlen, mtod(n, void *));
1162 * IP options processing.
1163 * See RFC2402 appendix A.
1165 p = mtod(n, u_char *);
1166 i = sizeof(struct ip);
1167 while (i < hlen) {
1168 if (i + IPOPT_OPTVAL >= hlen) {
1169 ipseclog((LOG_ERR, "ah4_calccksum: "
1170 "invalid IP option\n"));
1171 error = EINVAL;
1172 goto fail;
1174 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL ||
1175 p[i + IPOPT_OPTVAL] == IPOPT_NOP ||
1176 i + IPOPT_OLEN < hlen)
1178 else {
1179 ipseclog((LOG_ERR,
1180 "ah4_calccksum: invalid IP option "
1181 "(type=%02x)\n",
1182 p[i + IPOPT_OPTVAL]));
1183 error = EINVAL;
1184 goto fail;
1187 skip = 1;
1188 switch (p[i + IPOPT_OPTVAL]) {
1189 case IPOPT_EOL:
1190 case IPOPT_NOP:
1191 l = 1;
1192 skip = 0;
1193 break;
1194 case IPOPT_SECURITY: /* 0x82 */
1195 case 0x85: /* Extended security */
1196 case 0x86: /* Commercial security */
1197 case 0x94: /* Router alert */
1198 case 0x95: /* RFC1770 */
1199 l = p[i + IPOPT_OLEN];
1200 if (l < 2)
1201 goto invalopt;
1202 skip = 0;
1203 break;
1204 default:
1205 l = p[i + IPOPT_OLEN];
1206 if (l < 2)
1207 goto invalopt;
1208 skip = 1;
1209 break;
1211 if (l < 1 || hlen - i < l) {
1212 invalopt:
1213 ipseclog((LOG_ERR,
1214 "ah4_calccksum: invalid IP option "
1215 "(type=%02x len=%02x)\n",
1216 p[i + IPOPT_OPTVAL],
1217 p[i + IPOPT_OLEN]));
1218 error = EINVAL;
1219 goto fail;
1221 if (skip)
1222 memset(p + i, 0, l);
1223 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL)
1224 break;
1225 i += l;
1227 p = mtod(n, u_char *) + sizeof(struct ip);
1228 (algo->update)(&algos, p, hlen - sizeof(struct ip));
1230 m_free(n);
1231 n = NULL;
1234 hdrtype = (iphdr.ip_p) & 0xff;
1235 advancewidth = hlen;
1236 break;
1239 case IPPROTO_AH:
1241 struct ah ah;
1242 int siz;
1243 int hdrsiz;
1244 int totlen;
1246 m_copydata(m, off, sizeof(ah), (void *)&ah);
1247 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1248 ? sizeof(struct ah)
1249 : sizeof(struct newah);
1250 siz = (*algo->sumsiz)(sav);
1251 totlen = (ah.ah_len + 2) << 2;
1254 * special treatment is necessary for the first one, not others
1256 if (!ahseen) {
1257 if (totlen > m->m_pkthdr.len - off ||
1258 totlen > MCLBYTES) {
1259 error = EMSGSIZE;
1260 goto fail;
1262 MGET(n, M_DONTWAIT, MT_DATA);
1263 if (n && totlen > MLEN) {
1264 MCLGET(n, M_DONTWAIT);
1265 if ((n->m_flags & M_EXT) == 0) {
1266 m_free(n);
1267 n = NULL;
1270 if (n == NULL) {
1271 error = ENOBUFS;
1272 goto fail;
1274 m_copydata(m, off, totlen, mtod(n, void *));
1275 n->m_len = totlen;
1276 memset(mtod(n, u_int8_t *) + hdrsiz, 0, siz);
1277 (algo->update)(&algos, mtod(n, u_int8_t *), n->m_len);
1278 m_free(n);
1279 n = NULL;
1280 } else
1281 ah_update_mbuf(m, off, totlen, algo, &algos);
1282 ahseen++;
1284 hdrtype = ah.ah_nxt;
1285 advancewidth = totlen;
1286 break;
1289 default:
1290 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo, &algos);
1291 advancewidth = m->m_pkthdr.len - off;
1292 break;
1295 off += advancewidth;
1296 if (off < m->m_pkthdr.len)
1297 goto again;
1299 if (len < (*algo->sumsiz)(sav)) {
1300 error = EINVAL;
1301 goto fail;
1304 (algo->result)(&algos, sumbuf, sizeof(sumbuf));
1305 memcpy(ahdat, &sumbuf[0], (*algo->sumsiz)(sav));
1307 if (n)
1308 m_free(n);
1309 return error;
1311 fail:
1312 if (n)
1313 m_free(n);
1314 return error;
1316 #endif
1318 #ifdef INET6
1320 * Go generate the checksum. This function won't modify the mbuf chain
1321 * except AH itself.
1323 * NOTE: the function does not free mbuf on failure.
1324 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1327 ah6_calccksum(struct mbuf *m, u_int8_t *ahdat, size_t len,
1328 const struct ah_algorithm *algo, struct secasvar *sav)
1330 int newoff, off;
1331 int proto, nxt;
1332 struct mbuf *n = NULL;
1333 int error;
1334 int ahseen;
1335 struct ah_algorithm_state algos;
1336 u_char sumbuf[AH_MAXSUMSIZE];
1338 if ((m->m_flags & M_PKTHDR) == 0)
1339 return EINVAL;
1341 error = (algo->init)(&algos, sav);
1342 if (error)
1343 return error;
1345 off = 0;
1346 proto = IPPROTO_IPV6;
1347 nxt = -1;
1348 ahseen = 0;
1350 again:
1351 newoff = ip6_nexthdr(m, off, proto, &nxt);
1352 if (newoff < 0)
1353 newoff = m->m_pkthdr.len;
1354 else if (newoff <= off) {
1355 error = EINVAL;
1356 goto fail;
1359 switch (proto) {
1360 case IPPROTO_IPV6:
1362 * special treatment is necessary for the first one, not others
1364 if (off == 0) {
1365 struct ip6_hdr ip6copy;
1367 if (newoff - off != sizeof(struct ip6_hdr)) {
1368 error = EINVAL;
1369 goto fail;
1372 m_copydata(m, off, newoff - off, (void *)&ip6copy);
1373 /* RFC2402 */
1374 ip6copy.ip6_flow = 0;
1375 ip6copy.ip6_vfc &= ~IPV6_VERSION_MASK;
1376 ip6copy.ip6_vfc |= IPV6_VERSION;
1377 ip6copy.ip6_hlim = 0;
1378 in6_clearscope(&ip6copy.ip6_src); /* XXX */
1379 in6_clearscope(&ip6copy.ip6_dst); /* XXX */
1380 (algo->update)(&algos, (u_int8_t *)&ip6copy,
1381 sizeof(struct ip6_hdr));
1382 } else {
1383 newoff = m->m_pkthdr.len;
1384 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo,
1385 &algos);
1387 break;
1389 case IPPROTO_AH:
1391 int siz;
1392 int hdrsiz;
1394 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1395 ? sizeof(struct ah)
1396 : sizeof(struct newah);
1397 siz = (*algo->sumsiz)(sav);
1400 * special treatment is necessary for the first one, not others
1402 if (!ahseen) {
1403 if (newoff - off > MCLBYTES) {
1404 error = EMSGSIZE;
1405 goto fail;
1407 MGET(n, M_DONTWAIT, MT_DATA);
1408 if (n && newoff - off > MLEN) {
1409 MCLGET(n, M_DONTWAIT);
1410 if ((n->m_flags & M_EXT) == 0) {
1411 m_free(n);
1412 n = NULL;
1415 if (n == NULL) {
1416 error = ENOBUFS;
1417 goto fail;
1419 m_copydata(m, off, newoff - off, mtod(n, void *));
1420 n->m_len = newoff - off;
1421 memset(mtod(n, u_int8_t *) + hdrsiz, 0, siz);
1422 (algo->update)(&algos, mtod(n, u_int8_t *), n->m_len);
1423 m_free(n);
1424 n = NULL;
1425 } else
1426 ah_update_mbuf(m, off, newoff - off, algo, &algos);
1427 ahseen++;
1428 break;
1431 case IPPROTO_HOPOPTS:
1432 case IPPROTO_DSTOPTS:
1434 struct ip6_ext *ip6e;
1435 int hdrlen, optlen;
1436 u_int8_t *p, *optend, *optp;
1438 if (newoff - off > MCLBYTES) {
1439 error = EMSGSIZE;
1440 goto fail;
1442 MGET(n, M_DONTWAIT, MT_DATA);
1443 if (n && newoff - off > MLEN) {
1444 MCLGET(n, M_DONTWAIT);
1445 if ((n->m_flags & M_EXT) == 0) {
1446 m_free(n);
1447 n = NULL;
1450 if (n == NULL) {
1451 error = ENOBUFS;
1452 goto fail;
1454 m_copydata(m, off, newoff - off, mtod(n, void *));
1455 n->m_len = newoff - off;
1457 ip6e = mtod(n, struct ip6_ext *);
1458 hdrlen = (ip6e->ip6e_len + 1) << 3;
1459 if (newoff - off < hdrlen) {
1460 error = EINVAL;
1461 m_free(n);
1462 n = NULL;
1463 goto fail;
1465 p = mtod(n, u_int8_t *);
1466 optend = p + hdrlen;
1469 * ICV calculation for the options header including all
1470 * options. This part is a little tricky since there are
1471 * two type of options; mutable and immutable. We try to
1472 * null-out mutable ones here.
1474 optp = p + 2;
1475 while (optp < optend) {
1476 if (optp[0] == IP6OPT_PAD1)
1477 optlen = 1;
1478 else {
1479 if (optp + 2 > optend) {
1480 error = EINVAL;
1481 m_free(n);
1482 n = NULL;
1483 goto fail;
1485 optlen = optp[1] + 2;
1488 if (optp + optlen > optend) {
1489 error = EINVAL;
1490 m_free(n);
1491 n = NULL;
1492 goto fail;
1495 if (optp[0] & IP6OPT_MUTABLE)
1496 memset(optp + 2, 0, optlen - 2);
1498 optp += optlen;
1501 (algo->update)(&algos, mtod(n, u_int8_t *), n->m_len);
1502 m_free(n);
1503 n = NULL;
1504 break;
1507 case IPPROTO_ROUTING:
1509 * For an input packet, we can just calculate `as is'.
1510 * For an output packet, we assume ip6_output have already
1511 * made packet how it will be received at the final
1512 * destination.
1514 /* FALLTHROUGH */
1516 default:
1517 ah_update_mbuf(m, off, newoff - off, algo, &algos);
1518 break;
1521 if (newoff < m->m_pkthdr.len) {
1522 proto = nxt;
1523 off = newoff;
1524 goto again;
1527 if (len < (*algo->sumsiz)(sav)) {
1528 error = EINVAL;
1529 goto fail;
1532 (algo->result)(&algos, sumbuf, sizeof(sumbuf));
1533 memcpy(ahdat, &sumbuf[0], (*algo->sumsiz)(sav));
1535 /* just in case */
1536 if (n)
1537 m_free(n);
1538 return 0;
1539 fail:
1540 /* just in case */
1541 if (n)
1542 m_free(n);
1543 return error;
1545 #endif