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