]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/ah_core.c
xnu-2782.1.97.tar.gz
[apple/xnu.git] / bsd / netinet6 / ah_core.c
1 /*
2 * Copyright (c) 2008-2011 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 <libkern/crypto/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, size_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, size_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, size_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, size_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, size_t);
139 #if AH_ALL_CRYPTO
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, size_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, size_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, size_t);
158 #endif /* AH_ALL_CRYPTO */
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 AH_ALL_CRYPTO
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 /* AH_ALL_CRYPTO */
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 AH_ALL_CRYPTO
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 /* AH_ALL_CRYPTO */
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 __unused size_t l)
285 {
286 }
287
288 static int
289 ah_keyed_md5_mature(
290 __unused struct secasvar *sav)
291 {
292 /* anything is okay */
293 return 0;
294 }
295
296 static int
297 ah_keyed_md5_init(state, sav)
298 struct ah_algorithm_state *state;
299 struct secasvar *sav;
300 {
301 size_t padlen;
302 size_t keybitlen;
303 u_int8_t buf[32] __attribute__((aligned(4)));
304
305 if (!state)
306 panic("ah_keyed_md5_init: what?");
307
308 state->sav = sav;
309 state->foo = (void *)_MALLOC(sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
310 if (state->foo == NULL)
311 return ENOBUFS;
312
313 MD5Init((MD5_CTX *)state->foo);
314 if (state->sav) {
315 MD5Update((MD5_CTX *)state->foo,
316 (u_int8_t *)_KEYBUF(state->sav->key_auth),
317 (u_int)_KEYLEN(state->sav->key_auth));
318
319 /*
320 * Pad after the key.
321 * We cannot simply use md5_pad() since the function
322 * won't update the total length.
323 */
324 if (_KEYLEN(state->sav->key_auth) < 56)
325 padlen = 64 - 8 - _KEYLEN(state->sav->key_auth);
326 else
327 padlen = 64 + 64 - 8 - _KEYLEN(state->sav->key_auth);
328 keybitlen = _KEYLEN(state->sav->key_auth);
329 keybitlen *= 8;
330
331 buf[0] = 0x80;
332 MD5Update((MD5_CTX *)state->foo, &buf[0], 1);
333 padlen--;
334
335 bzero(buf, sizeof(buf));
336 while (sizeof(buf) < padlen) {
337 MD5Update((MD5_CTX *)state->foo, &buf[0], sizeof(buf));
338 padlen -= sizeof(buf);
339 }
340 if (padlen) {
341 MD5Update((MD5_CTX *)state->foo, &buf[0], padlen);
342 }
343
344 buf[0] = (keybitlen >> 0) & 0xff;
345 buf[1] = (keybitlen >> 8) & 0xff;
346 buf[2] = (keybitlen >> 16) & 0xff;
347 buf[3] = (keybitlen >> 24) & 0xff;
348 MD5Update((MD5_CTX *)state->foo, buf, 8);
349 }
350
351 return 0;
352 }
353
354 static void
355 ah_keyed_md5_loop(state, addr, len)
356 struct ah_algorithm_state *state;
357 caddr_t addr;
358 size_t len;
359 {
360 if (!state)
361 panic("ah_keyed_md5_loop: what?");
362
363 MD5Update((MD5_CTX *)state->foo, addr, len);
364 }
365
366 static void
367 ah_keyed_md5_result(state, addr, l)
368 struct ah_algorithm_state *state;
369 caddr_t addr;
370 size_t l;
371 {
372 u_char digest[16] __attribute__((aligned(4)));
373
374 if (!state)
375 panic("ah_keyed_md5_result: what?");
376
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));
381 }
382 MD5Final(&digest[0], (MD5_CTX *)state->foo);
383 FREE(state->foo, M_TEMP);
384 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
385 }
386
387 static int
388 ah_keyed_sha1_mature(sav)
389 struct secasvar *sav;
390 {
391 const struct ah_algorithm *algo;
392
393 if (!sav->key_auth) {
394 ipseclog((LOG_ERR, "ah_keyed_sha1_mature: no key is given.\n"));
395 return 1;
396 }
397
398 algo = ah_algorithm_lookup(sav->alg_auth);
399 if (!algo) {
400 ipseclog((LOG_ERR, "ah_keyed_sha1_mature: unsupported algorithm.\n"));
401 return 1;
402 }
403
404 if (sav->key_auth->sadb_key_bits < algo->keymin
405 || algo->keymax < sav->key_auth->sadb_key_bits) {
406 ipseclog((LOG_ERR,
407 "ah_keyed_sha1_mature: invalid key length %d.\n",
408 sav->key_auth->sadb_key_bits));
409 return 1;
410 }
411
412 return 0;
413 }
414
415 static int
416 ah_keyed_sha1_init(state, sav)
417 struct ah_algorithm_state *state;
418 struct secasvar *sav;
419 {
420 SHA1_CTX *ctxt;
421 size_t padlen;
422 size_t keybitlen;
423 u_int8_t buf[32] __attribute__((aligned(4)));
424
425 if (!state)
426 panic("ah_keyed_sha1_init: what?");
427
428 state->sav = sav;
429 state->foo = (void *)_MALLOC(sizeof(SHA1_CTX), M_TEMP, M_NOWAIT);
430 if (!state->foo)
431 return ENOBUFS;
432
433 ctxt = (SHA1_CTX *)state->foo;
434 SHA1Init(ctxt);
435
436 if (state->sav) {
437 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth),
438 (u_int)_KEYLEN(state->sav->key_auth));
439
440 /*
441 * Pad after the key.
442 */
443 if (_KEYLEN(state->sav->key_auth) < 56)
444 padlen = 64 - 8 - _KEYLEN(state->sav->key_auth);
445 else
446 padlen = 64 + 64 - 8 - _KEYLEN(state->sav->key_auth);
447 keybitlen = _KEYLEN(state->sav->key_auth);
448 keybitlen *= 8;
449
450 buf[0] = 0x80;
451 SHA1Update(ctxt, &buf[0], 1);
452 padlen--;
453
454 bzero(buf, sizeof(buf));
455 while (sizeof(buf) < padlen) {
456 SHA1Update(ctxt, &buf[0], sizeof(buf));
457 padlen -= sizeof(buf);
458 }
459 if (padlen) {
460 SHA1Update(ctxt, &buf[0], padlen);
461 }
462
463 buf[0] = (keybitlen >> 0) & 0xff;
464 buf[1] = (keybitlen >> 8) & 0xff;
465 buf[2] = (keybitlen >> 16) & 0xff;
466 buf[3] = (keybitlen >> 24) & 0xff;
467 SHA1Update(ctxt, buf, 8);
468 }
469
470 return 0;
471 }
472
473 static void
474 ah_keyed_sha1_loop(state, addr, len)
475 struct ah_algorithm_state *state;
476 caddr_t addr;
477 size_t len;
478 {
479 SHA1_CTX *ctxt;
480
481 if (!state || !state->foo)
482 panic("ah_keyed_sha1_loop: what?");
483 ctxt = (SHA1_CTX *)state->foo;
484
485 SHA1Update(ctxt, (caddr_t)addr, (size_t)len);
486 }
487
488 static void
489 ah_keyed_sha1_result(state, addr, l)
490 struct ah_algorithm_state *state;
491 caddr_t addr;
492 size_t l;
493 {
494 u_char digest[SHA1_RESULTLEN] __attribute__((aligned(4))); /* SHA-1 generates 160 bits */
495 SHA1_CTX *ctxt;
496
497 if (!state || !state->foo)
498 panic("ah_keyed_sha1_result: what?");
499 ctxt = (SHA1_CTX *)state->foo;
500
501 if (state->sav) {
502 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth),
503 (u_int)_KEYLEN(state->sav->key_auth));
504 }
505 SHA1Final((caddr_t)&digest[0], ctxt);
506 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
507
508 FREE(state->foo, M_TEMP);
509 }
510
511 static int
512 ah_hmac_md5_mature(sav)
513 struct secasvar *sav;
514 {
515 const struct ah_algorithm *algo;
516
517 if (!sav->key_auth) {
518 ipseclog((LOG_ERR, "ah_hmac_md5_mature: no key is given.\n"));
519 return 1;
520 }
521
522 algo = ah_algorithm_lookup(sav->alg_auth);
523 if (!algo) {
524 ipseclog((LOG_ERR, "ah_hmac_md5_mature: unsupported algorithm.\n"));
525 return 1;
526 }
527
528 if (sav->key_auth->sadb_key_bits < algo->keymin
529 || algo->keymax < sav->key_auth->sadb_key_bits) {
530 ipseclog((LOG_ERR,
531 "ah_hmac_md5_mature: invalid key length %d.\n",
532 sav->key_auth->sadb_key_bits));
533 return 1;
534 }
535
536 return 0;
537 }
538
539 static int
540 ah_hmac_md5_init(state, sav)
541 struct ah_algorithm_state *state;
542 struct secasvar *sav;
543 {
544 u_char *ipad;
545 u_char *opad;
546 u_char tk[16] __attribute__((aligned(4)));
547 u_char *key;
548 size_t keylen;
549 size_t i;
550 MD5_CTX *ctxt;
551
552 if (!state)
553 panic("ah_hmac_md5_init: what?");
554
555 state->sav = sav;
556 state->foo = (void *)_MALLOC(64 + 64 + sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
557 if (!state->foo)
558 return ENOBUFS;
559
560 ipad = (u_char *)state->foo;
561 opad = (u_char *)(ipad + 64);
562 ctxt = (MD5_CTX *)(void *)(opad + 64);
563
564 /* compress the key if necessery */
565 if (64 < _KEYLEN(state->sav->key_auth)) {
566 MD5Init(ctxt);
567 MD5Update(ctxt, _KEYBUF(state->sav->key_auth),
568 _KEYLEN(state->sav->key_auth));
569 MD5Final(&tk[0], ctxt);
570 key = &tk[0];
571 keylen = 16;
572 } else {
573 key = (u_char *) _KEYBUF(state->sav->key_auth);
574 keylen = _KEYLEN(state->sav->key_auth);
575 }
576
577 bzero(ipad, 64);
578 bzero(opad, 64);
579 bcopy(key, ipad, keylen);
580 bcopy(key, opad, keylen);
581 for (i = 0; i < 64; i++) {
582 ipad[i] ^= 0x36;
583 opad[i] ^= 0x5c;
584 }
585
586 MD5Init(ctxt);
587 MD5Update(ctxt, ipad, 64);
588
589 return 0;
590 }
591
592 static void
593 ah_hmac_md5_loop(state, addr, len)
594 struct ah_algorithm_state *state;
595 caddr_t addr;
596 size_t len;
597 {
598 MD5_CTX *ctxt;
599
600 if (!state || !state->foo)
601 panic("ah_hmac_md5_loop: what?");
602 ctxt = (MD5_CTX *)(void *)(((caddr_t)state->foo) + 128);
603 MD5Update(ctxt, addr, len);
604 }
605
606 static void
607 ah_hmac_md5_result(state, addr, l)
608 struct ah_algorithm_state *state;
609 caddr_t addr;
610 size_t l;
611 {
612 u_char digest[16] __attribute__((aligned(4)));
613 u_char *ipad;
614 u_char *opad;
615 MD5_CTX *ctxt;
616
617 if (!state || !state->foo)
618 panic("ah_hmac_md5_result: what?");
619
620 ipad = (u_char *)state->foo;
621 opad = (u_char *)(ipad + 64);
622 ctxt = (MD5_CTX *)(void *)(opad + 64);
623
624 MD5Final(&digest[0], ctxt);
625
626 MD5Init(ctxt);
627 MD5Update(ctxt, opad, 64);
628 MD5Update(ctxt, &digest[0], sizeof(digest));
629 MD5Final(&digest[0], ctxt);
630
631 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
632
633 FREE(state->foo, M_TEMP);
634 }
635
636 static int
637 ah_hmac_sha1_mature(sav)
638 struct secasvar *sav;
639 {
640 const struct ah_algorithm *algo;
641
642 if (!sav->key_auth) {
643 ipseclog((LOG_ERR, "ah_hmac_sha1_mature: no key is given.\n"));
644 return 1;
645 }
646
647 algo = ah_algorithm_lookup(sav->alg_auth);
648 if (!algo) {
649 ipseclog((LOG_ERR, "ah_hmac_sha1_mature: unsupported algorithm.\n"));
650 return 1;
651 }
652
653 if (sav->key_auth->sadb_key_bits < algo->keymin
654 || algo->keymax < sav->key_auth->sadb_key_bits) {
655 ipseclog((LOG_ERR,
656 "ah_hmac_sha1_mature: invalid key length %d.\n",
657 sav->key_auth->sadb_key_bits));
658 return 1;
659 }
660
661 return 0;
662 }
663
664 static int
665 ah_hmac_sha1_init(state, sav)
666 struct ah_algorithm_state *state;
667 struct secasvar *sav;
668 {
669 u_char *ipad;
670 u_char *opad;
671 SHA1_CTX *ctxt;
672 u_char tk[SHA1_RESULTLEN] __attribute__((aligned(4))); /* SHA-1 generates 160 bits */
673 u_char *key;
674 size_t keylen;
675 size_t i;
676
677 if (!state)
678 panic("ah_hmac_sha1_init: what?");
679
680 state->sav = sav;
681 state->foo = (void *)_MALLOC(64 + 64 + sizeof(SHA1_CTX),
682 M_TEMP, M_NOWAIT);
683 if (!state->foo)
684 return ENOBUFS;
685
686 ipad = (u_char *)state->foo;
687 opad = (u_char *)(ipad + 64);
688 ctxt = (SHA1_CTX *)(void *)(opad + 64);
689
690 /* compress the key if necessery */
691 if (64 < _KEYLEN(state->sav->key_auth)) {
692 SHA1Init(ctxt);
693 SHA1Update(ctxt, _KEYBUF(state->sav->key_auth),
694 _KEYLEN(state->sav->key_auth));
695 SHA1Final(&tk[0], ctxt);
696 key = &tk[0];
697 keylen = SHA1_RESULTLEN;
698 } else {
699 key = (u_char *) _KEYBUF(state->sav->key_auth);
700 keylen = _KEYLEN(state->sav->key_auth);
701 }
702
703 bzero(ipad, 64);
704 bzero(opad, 64);
705 bcopy(key, ipad, keylen);
706 bcopy(key, opad, keylen);
707 for (i = 0; i < 64; i++) {
708 ipad[i] ^= 0x36;
709 opad[i] ^= 0x5c;
710 }
711
712 SHA1Init(ctxt);
713 SHA1Update(ctxt, ipad, 64);
714
715 return 0;
716 }
717
718 static void
719 ah_hmac_sha1_loop(state, addr, len)
720 struct ah_algorithm_state *state;
721 caddr_t addr;
722 size_t len;
723 {
724 SHA1_CTX *ctxt;
725
726 if (!state || !state->foo)
727 panic("ah_hmac_sha1_loop: what?");
728
729 ctxt = (SHA1_CTX *)(void *)(((u_char *)state->foo) + 128);
730 SHA1Update(ctxt, (caddr_t)addr, (size_t)len);
731 }
732
733 static void
734 ah_hmac_sha1_result(state, addr, l)
735 struct ah_algorithm_state *state;
736 caddr_t addr;
737 size_t l;
738 {
739 u_char digest[SHA1_RESULTLEN] __attribute__((aligned(4))); /* SHA-1 generates 160 bits */
740 u_char *ipad;
741 u_char *opad;
742 SHA1_CTX *ctxt;
743
744 if (!state || !state->foo)
745 panic("ah_hmac_sha1_result: what?");
746
747 ipad = (u_char *)state->foo;
748 opad = (u_char *)(ipad + 64);
749 ctxt = (SHA1_CTX *)(void *)(opad + 64);
750
751 SHA1Final((caddr_t)&digest[0], ctxt);
752
753 SHA1Init(ctxt);
754 SHA1Update(ctxt, opad, 64);
755 SHA1Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
756 SHA1Final((caddr_t)&digest[0], ctxt);
757
758 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
759
760 FREE(state->foo, M_TEMP);
761 }
762
763 #if AH_ALL_CRYPTO
764 static int
765 ah_sumsiz_sha2_256(sav)
766 struct secasvar *sav;
767 {
768 if (!sav)
769 return -1;
770 // return half the output size (in bytes), as per rfc 4868
771 return 16; // 256/(8*2)
772 }
773
774 static int
775 ah_hmac_sha2_256_mature(sav)
776 struct secasvar *sav;
777 {
778 const struct ah_algorithm *algo;
779
780 if (!sav->key_auth) {
781 ipseclog((LOG_ERR,
782 "ah_hmac_sha2_256_mature: no key is given.\n"));
783 return 1;
784 }
785
786 algo = ah_algorithm_lookup(sav->alg_auth);
787 if (!algo) {
788 ipseclog((LOG_ERR,
789 "ah_hmac_sha2_256_mature: unsupported algorithm.\n"));
790 return 1;
791 }
792
793 if (sav->key_auth->sadb_key_bits < algo->keymin ||
794 algo->keymax < sav->key_auth->sadb_key_bits) {
795 ipseclog((LOG_ERR,
796 "ah_hmac_sha2_256_mature: invalid key length %d.\n",
797 sav->key_auth->sadb_key_bits));
798 return 1;
799 }
800
801 return 0;
802 }
803
804 static int
805 ah_hmac_sha2_256_init(state, sav)
806 struct ah_algorithm_state *state;
807 struct secasvar *sav;
808 {
809 u_char *ipad;
810 u_char *opad;
811 SHA256_CTX *ctxt;
812 u_char tk[SHA256_DIGEST_LENGTH] __attribute__((aligned(4)));
813 u_char *key;
814 size_t keylen;
815 size_t i;
816
817 if (!state)
818 panic("ah_hmac_sha2_256_init: what?");
819
820 state->sav = sav;
821 state->foo = (void *)_MALLOC(64 + 64 + sizeof(SHA256_CTX),
822 M_TEMP, M_NOWAIT);
823 if (!state->foo)
824 return ENOBUFS;
825
826 ipad = (u_char *)state->foo;
827 opad = (u_char *)(ipad + 64);
828 ctxt = (SHA256_CTX *)(void *)(opad + 64);
829
830 /* compress the key if necessery */
831 if (64 < _KEYLEN(state->sav->key_auth)) {
832 bzero(tk, sizeof(tk));
833 bzero(ctxt, sizeof(*ctxt));
834 SHA256_Init(ctxt);
835 SHA256_Update(ctxt, (const u_int8_t *) _KEYBUF(state->sav->key_auth),
836 _KEYLEN(state->sav->key_auth));
837 SHA256_Final(&tk[0], ctxt);
838 key = &tk[0];
839 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
840 } else {
841 key = (u_char *) _KEYBUF(state->sav->key_auth);
842 keylen = _KEYLEN(state->sav->key_auth);
843 }
844
845 bzero(ipad, 64);
846 bzero(opad, 64);
847 bcopy(key, ipad, keylen);
848 bcopy(key, opad, keylen);
849 for (i = 0; i < 64; i++) {
850 ipad[i] ^= 0x36;
851 opad[i] ^= 0x5c;
852 }
853
854 bzero(ctxt, sizeof(*ctxt));
855 SHA256_Init(ctxt);
856 SHA256_Update(ctxt, ipad, 64);
857
858 return 0;
859 }
860
861 static void
862 ah_hmac_sha2_256_loop(state, addr, len)
863 struct ah_algorithm_state *state;
864 caddr_t addr;
865 size_t len;
866 {
867 SHA256_CTX *ctxt;
868
869 if (!state || !state->foo)
870 panic("ah_hmac_sha2_256_loop: what?");
871
872 ctxt = (SHA256_CTX *)(void *)(((u_char *)state->foo) + 128);
873 SHA256_Update(ctxt, (const u_int8_t *)addr, (size_t)len);
874 }
875
876 static void
877 ah_hmac_sha2_256_result(state, addr, l)
878 struct ah_algorithm_state *state;
879 caddr_t addr;
880 size_t l;
881 {
882 u_char digest[SHA256_DIGEST_LENGTH] __attribute__((aligned(4)));
883 u_char *ipad;
884 u_char *opad;
885 SHA256_CTX *ctxt;
886
887 if (!state || !state->foo)
888 panic("ah_hmac_sha2_256_result: what?");
889
890 ipad = (u_char *)state->foo;
891 opad = (u_char *)(ipad + 64);
892 ctxt = (SHA256_CTX *)(void *)(opad + 64);
893
894 SHA256_Final((u_int8_t *)digest, ctxt);
895
896 SHA256_Init(ctxt);
897 SHA256_Update(ctxt, opad, 64);
898 SHA256_Update(ctxt, (const u_int8_t *)digest, sizeof(digest));
899 SHA256_Final((u_int8_t *)digest, ctxt);
900
901 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
902
903 FREE(state->foo, M_TEMP);
904 }
905
906 static int
907 ah_sumsiz_sha2_384(sav)
908 struct secasvar *sav;
909 {
910 if (!sav)
911 return -1;
912 // return half the output size (in bytes), as per rfc 4868
913 return 24; // 384/(8*2)
914 }
915
916 static int
917 ah_hmac_sha2_384_mature(sav)
918 struct secasvar *sav;
919 {
920 const struct ah_algorithm *algo;
921
922 if (!sav->key_auth) {
923 ipseclog((LOG_ERR,
924 "ah_hmac_sha2_384_mature: no key is given.\n"));
925 return 1;
926 }
927
928 algo = ah_algorithm_lookup(sav->alg_auth);
929 if (!algo) {
930 ipseclog((LOG_ERR,
931 "ah_hmac_sha2_384_mature: unsupported algorithm.\n"));
932 return 1;
933 }
934
935 if (sav->key_auth->sadb_key_bits < algo->keymin ||
936 algo->keymax < sav->key_auth->sadb_key_bits) {
937 ipseclog((LOG_ERR,
938 "ah_hmac_sha2_384_mature: invalid key length %d.\n",
939 sav->key_auth->sadb_key_bits));
940 return 1;
941 }
942
943 return 0;
944 }
945
946 static int
947 ah_hmac_sha2_384_init(state, sav)
948 struct ah_algorithm_state *state;
949 struct secasvar *sav;
950 {
951 u_char *ipad;
952 u_char *opad;
953 SHA384_CTX *ctxt;
954 u_char tk[SHA384_DIGEST_LENGTH] __attribute__((aligned(4)));
955 u_char *key;
956 size_t keylen;
957 size_t i;
958
959 if (!state)
960 panic("ah_hmac_sha2_384_init: what?");
961
962 state->sav = sav;
963 state->foo = (void *)_MALLOC(128 + 128 + sizeof(SHA384_CTX),
964 M_TEMP, M_NOWAIT);
965 if (!state->foo)
966 return ENOBUFS;
967 bzero(state->foo, 128 + 128 + sizeof(SHA384_CTX));
968
969 ipad = (u_char *)state->foo;
970 opad = (u_char *)(ipad + 128);
971 ctxt = (SHA384_CTX *)(void *)(opad + 128);
972
973 /* compress the key if necessery */
974 if (128 < _KEYLEN(state->sav->key_auth)) {
975 bzero(tk, sizeof(tk));
976 bzero(ctxt, sizeof(*ctxt));
977 SHA384_Init(ctxt);
978 SHA384_Update(ctxt, (const u_int8_t *) _KEYBUF(state->sav->key_auth),
979 _KEYLEN(state->sav->key_auth));
980 SHA384_Final(&tk[0], ctxt);
981 key = &tk[0];
982 keylen = sizeof(tk) < 128 ? sizeof(tk) : 128;
983 } else {
984 key = (u_char *) _KEYBUF(state->sav->key_auth);
985 keylen = _KEYLEN(state->sav->key_auth);
986 }
987
988 bzero(ipad, 128);
989 bzero(opad, 128);
990 bcopy(key, ipad, keylen);
991 bcopy(key, opad, keylen);
992 for (i = 0; i < 128; i++) {
993 ipad[i] ^= 0x36;
994 opad[i] ^= 0x5c;
995 }
996
997 bzero(ctxt, sizeof(*ctxt));
998 SHA384_Init(ctxt);
999 SHA384_Update(ctxt, ipad, 128);
1000
1001 return 0;
1002 }
1003
1004 static void
1005 ah_hmac_sha2_384_loop(state, addr, len)
1006 struct ah_algorithm_state *state;
1007 caddr_t addr;
1008 size_t len;
1009 {
1010 SHA384_CTX *ctxt;
1011
1012 if (!state || !state->foo)
1013 panic("ah_hmac_sha2_384_loop: what?");
1014
1015 ctxt = (SHA384_CTX *)(void *)(((u_char *)state->foo) + 256);
1016 SHA384_Update(ctxt, (const u_int8_t *)addr, (size_t)len);
1017 }
1018
1019 static void
1020 ah_hmac_sha2_384_result(state, addr, l)
1021 struct ah_algorithm_state *state;
1022 caddr_t addr;
1023 size_t l;
1024 {
1025 u_char digest[SHA384_DIGEST_LENGTH];
1026 u_char *ipad;
1027 u_char *opad;
1028 SHA384_CTX *ctxt;
1029
1030 if (!state || !state->foo)
1031 panic("ah_hmac_sha2_384_result: what?");
1032
1033 ipad = (u_char *)state->foo;
1034 opad = (u_char *)(ipad + 128);
1035 ctxt = (SHA384_CTX *)(void *)(opad + 128);
1036
1037 SHA384_Final((u_int8_t *)digest, ctxt);
1038
1039 SHA384_Init(ctxt);
1040 SHA384_Update(ctxt, opad, 128);
1041 SHA384_Update(ctxt, (const u_int8_t *)digest, sizeof(digest));
1042 SHA384_Final((u_int8_t *)digest, ctxt);
1043
1044 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
1045
1046 FREE(state->foo, M_TEMP);
1047 }
1048
1049 static int
1050 ah_sumsiz_sha2_512(sav)
1051 struct secasvar *sav;
1052 {
1053 if (!sav)
1054 return -1;
1055 // return half the output size (in bytes), as per rfc 4868
1056 return 32; // 512/(8*2)
1057 }
1058
1059 static int
1060 ah_hmac_sha2_512_mature(sav)
1061 struct secasvar *sav;
1062 {
1063 const struct ah_algorithm *algo;
1064
1065 if (!sav->key_auth) {
1066 ipseclog((LOG_ERR,
1067 "ah_hmac_sha2_512_mature: no key is given.\n"));
1068 return 1;
1069 }
1070
1071 algo = ah_algorithm_lookup(sav->alg_auth);
1072 if (!algo) {
1073 ipseclog((LOG_ERR,
1074 "ah_hmac_sha2_512_mature: unsupported algorithm.\n"));
1075 return 1;
1076 }
1077
1078 if (sav->key_auth->sadb_key_bits < algo->keymin ||
1079 algo->keymax < sav->key_auth->sadb_key_bits) {
1080 ipseclog((LOG_ERR,
1081 "ah_hmac_sha2_512_mature: invalid key length %d.\n",
1082 sav->key_auth->sadb_key_bits));
1083 return 1;
1084 }
1085
1086 return 0;
1087 }
1088
1089 static int
1090 ah_hmac_sha2_512_init(state, sav)
1091 struct ah_algorithm_state *state;
1092 struct secasvar *sav;
1093 {
1094 u_char *ipad;
1095 u_char *opad;
1096 SHA512_CTX *ctxt;
1097 u_char tk[SHA512_DIGEST_LENGTH] __attribute__((aligned(4)));
1098 u_char *key;
1099 size_t keylen;
1100 size_t i;
1101
1102 if (!state)
1103 panic("ah_hmac_sha2_512_init: what?");
1104
1105 state->sav = sav;
1106 state->foo = (void *)_MALLOC(128 + 128 + sizeof(SHA512_CTX),
1107 M_TEMP, M_NOWAIT);
1108 if (!state->foo)
1109 return ENOBUFS;
1110 bzero(state->foo, 128 + 128 + sizeof(SHA512_CTX));
1111
1112 ipad = (u_char *)state->foo;
1113 opad = (u_char *)(ipad + 128);
1114 ctxt = (SHA512_CTX *)(void *)(opad + 128);
1115
1116 /* compress the key if necessery */
1117 if (128 < _KEYLEN(state->sav->key_auth)) {
1118 bzero(tk, sizeof(tk));
1119 bzero(ctxt, sizeof(*ctxt));
1120 SHA512_Init(ctxt);
1121 SHA512_Update(ctxt, (const u_int8_t *) _KEYBUF(state->sav->key_auth),
1122 _KEYLEN(state->sav->key_auth));
1123 SHA512_Final(&tk[0], ctxt);
1124 key = &tk[0];
1125 keylen = sizeof(tk) < 128 ? sizeof(tk) : 128;
1126 } else {
1127 key = (u_char *) _KEYBUF(state->sav->key_auth);
1128 keylen = _KEYLEN(state->sav->key_auth);
1129 }
1130
1131 bzero(ipad, 128);
1132 bzero(opad, 128);
1133 bcopy(key, ipad, keylen);
1134 bcopy(key, opad, keylen);
1135 for (i = 0; i < 128; i++) {
1136 ipad[i] ^= 0x36;
1137 opad[i] ^= 0x5c;
1138 }
1139
1140 bzero(ctxt, sizeof(*ctxt));
1141 SHA512_Init(ctxt);
1142 SHA512_Update(ctxt, ipad, 128);
1143
1144 return 0;
1145 }
1146
1147 static void
1148 ah_hmac_sha2_512_loop(state, addr, len)
1149 struct ah_algorithm_state *state;
1150 caddr_t addr;
1151 size_t len;
1152 {
1153 SHA512_CTX *ctxt;
1154
1155 if (!state || !state->foo)
1156 panic("ah_hmac_sha2_512_loop: what?");
1157
1158 ctxt = (SHA512_CTX *)(void *)(((u_char *)state->foo) + 256);
1159 SHA512_Update(ctxt, (const u_int8_t *) addr, (size_t)len);
1160 }
1161
1162 static void
1163 ah_hmac_sha2_512_result(state, addr, l)
1164 struct ah_algorithm_state *state;
1165 caddr_t addr;
1166 size_t l;
1167 {
1168 u_char digest[SHA512_DIGEST_LENGTH] __attribute__((aligned(4)));
1169 u_char *ipad;
1170 u_char *opad;
1171 SHA512_CTX *ctxt;
1172
1173 if (!state || !state->foo)
1174 panic("ah_hmac_sha2_512_result: what?");
1175
1176 ipad = (u_char *)state->foo;
1177 opad = (u_char *)(ipad + 128);
1178 ctxt = (SHA512_CTX *)(void *)(opad + 128);
1179
1180 SHA512_Final((u_int8_t *)digest, ctxt);
1181
1182 SHA512_Init(ctxt);
1183 SHA512_Update(ctxt, opad, 128);
1184 SHA512_Update(ctxt, (const u_int8_t *)digest, sizeof(digest));
1185 SHA512_Final((u_int8_t *)digest, ctxt);
1186
1187 bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
1188
1189 FREE(state->foo, M_TEMP);
1190 }
1191 #endif /* AH_ALL_CRYPTO */
1192
1193 /*------------------------------------------------------------*/
1194
1195 /*
1196 * go generate the checksum.
1197 */
1198 static void
1199 ah_update_mbuf(m, off, len, algo, algos)
1200 struct mbuf *m;
1201 int off;
1202 int len;
1203 const struct ah_algorithm *algo;
1204 struct ah_algorithm_state *algos;
1205 {
1206 struct mbuf *n;
1207 int tlen;
1208
1209 /* easy case first */
1210 if (off + len <= m->m_len) {
1211 (algo->update)(algos, mtod(m, caddr_t) + off, len);
1212 return;
1213 }
1214
1215 for (n = m; n; n = n->m_next) {
1216 if (off < n->m_len)
1217 break;
1218
1219 off -= n->m_len;
1220 }
1221
1222 if (!n)
1223 panic("ah_update_mbuf: wrong offset specified");
1224
1225 for (/*nothing*/; n && len > 0; n = n->m_next) {
1226 if (n->m_len == 0)
1227 continue;
1228 if (n->m_len - off < len)
1229 tlen = n->m_len - off;
1230 else
1231 tlen = len;
1232
1233 (algo->update)(algos, mtod(n, caddr_t) + off, tlen);
1234
1235 len -= tlen;
1236 off = 0;
1237 }
1238 }
1239
1240 #if INET
1241 /*
1242 * Go generate the checksum. This function won't modify the mbuf chain
1243 * except AH itself.
1244 *
1245 * NOTE: the function does not free mbuf on failure.
1246 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1247 */
1248 int
1249 ah4_calccksum(m, ahdat, len, algo, sav)
1250 struct mbuf *m;
1251 caddr_t ahdat;
1252 size_t len;
1253 const struct ah_algorithm *algo;
1254 struct secasvar *sav;
1255 {
1256 int off;
1257 int hdrtype;
1258 size_t advancewidth;
1259 struct ah_algorithm_state algos;
1260 u_char sumbuf[AH_MAXSUMSIZE] __attribute__((aligned(4)));
1261 int error = 0;
1262 int ahseen;
1263 struct mbuf *n = NULL;
1264
1265 if ((m->m_flags & M_PKTHDR) == 0)
1266 return EINVAL;
1267
1268 ahseen = 0;
1269 hdrtype = -1; /*dummy, it is called IPPROTO_IP*/
1270
1271 off = 0;
1272
1273 error = (algo->init)(&algos, sav);
1274 if (error)
1275 return error;
1276
1277 advancewidth = 0; /*safety*/
1278
1279 again:
1280 /* gory. */
1281 switch (hdrtype) {
1282 case -1: /*first one only*/
1283 {
1284 /*
1285 * copy ip hdr, modify to fit the AH checksum rule,
1286 * then take a checksum.
1287 */
1288 struct ip iphdr;
1289 size_t hlen;
1290
1291 m_copydata(m, off, sizeof(iphdr), (caddr_t)&iphdr);
1292 #if _IP_VHL
1293 hlen = IP_VHL_HL(iphdr.ip_vhl) << 2;
1294 #else
1295 hlen = iphdr.ip_hl << 2;
1296 #endif
1297 iphdr.ip_ttl = 0;
1298 iphdr.ip_sum = htons(0);
1299 if (ip4_ah_cleartos)
1300 iphdr.ip_tos = 0;
1301 iphdr.ip_off = htons(ntohs(iphdr.ip_off) & ip4_ah_offsetmask);
1302 (algo->update)(&algos, (caddr_t)&iphdr, sizeof(struct ip));
1303
1304 if (hlen != sizeof(struct ip)) {
1305 u_char *p;
1306 int i, l, skip;
1307
1308 if (hlen > MCLBYTES) {
1309 error = EMSGSIZE;
1310 goto fail;
1311 }
1312 MGET(n, M_DONTWAIT, MT_DATA);
1313 if (n && hlen > MLEN) {
1314 MCLGET(n, M_DONTWAIT);
1315 if ((n->m_flags & M_EXT) == 0) {
1316 m_free(n);
1317 n = NULL;
1318 }
1319 }
1320 if (n == NULL) {
1321 error = ENOBUFS;
1322 goto fail;
1323 }
1324 m_copydata(m, off, hlen, mtod(n, caddr_t));
1325
1326 /*
1327 * IP options processing.
1328 * See RFC2402 appendix A.
1329 */
1330 p = mtod(n, u_char *);
1331 i = sizeof(struct ip);
1332 while (i < hlen) {
1333 if (i + IPOPT_OPTVAL >= hlen) {
1334 ipseclog((LOG_ERR, "ah4_calccksum: "
1335 "invalid IP option\n"));
1336 error = EINVAL;
1337 goto fail;
1338 }
1339 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL ||
1340 p[i + IPOPT_OPTVAL] == IPOPT_NOP ||
1341 i + IPOPT_OLEN < hlen)
1342 ;
1343 else {
1344 ipseclog((LOG_ERR,
1345 "ah4_calccksum: invalid IP option "
1346 "(type=%02x)\n",
1347 p[i + IPOPT_OPTVAL]));
1348 error = EINVAL;
1349 goto fail;
1350 }
1351
1352 skip = 1;
1353 switch (p[i + IPOPT_OPTVAL]) {
1354 case IPOPT_EOL:
1355 case IPOPT_NOP:
1356 l = 1;
1357 skip = 0;
1358 break;
1359 case IPOPT_SECURITY: /* 0x82 */
1360 case 0x85: /* Extended security */
1361 case 0x86: /* Commercial security */
1362 case 0x94: /* Router alert */
1363 case 0x95: /* RFC1770 */
1364 l = p[i + IPOPT_OLEN];
1365 if (l < 2)
1366 goto invalopt;
1367 skip = 0;
1368 break;
1369 default:
1370 l = p[i + IPOPT_OLEN];
1371 if (l < 2)
1372 goto invalopt;
1373 skip = 1;
1374 break;
1375 }
1376 if (l < 1 || hlen - i < l) {
1377 invalopt:
1378 ipseclog((LOG_ERR,
1379 "ah4_calccksum: invalid IP option "
1380 "(type=%02x len=%02x)\n",
1381 p[i + IPOPT_OPTVAL],
1382 p[i + IPOPT_OLEN]));
1383 error = EINVAL;
1384 goto fail;
1385 }
1386 if (skip)
1387 bzero(p + i, l);
1388 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL)
1389 break;
1390 i += l;
1391 }
1392
1393 p = mtod(n, u_char *) + sizeof(struct ip);
1394 (algo->update)(&algos, (caddr_t)p, hlen - sizeof(struct ip));
1395
1396 m_free(n);
1397 n = NULL;
1398 }
1399
1400 hdrtype = (iphdr.ip_p) & 0xff;
1401 advancewidth = hlen;
1402 break;
1403 }
1404
1405 case IPPROTO_AH:
1406 {
1407 struct ah ah;
1408 int siz;
1409 int hdrsiz;
1410 int totlen;
1411
1412 m_copydata(m, off, sizeof(ah), (caddr_t)&ah);
1413 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1414 ? sizeof(struct ah)
1415 : sizeof(struct newah);
1416 siz = (*algo->sumsiz)(sav);
1417 totlen = (ah.ah_len + 2) << 2;
1418
1419 /*
1420 * special treatment is necessary for the first one, not others
1421 */
1422 if (!ahseen) {
1423 if (totlen > m->m_pkthdr.len - off ||
1424 totlen > MCLBYTES) {
1425 error = EMSGSIZE;
1426 goto fail;
1427 }
1428 MGET(n, M_DONTWAIT, MT_DATA);
1429 if (n && totlen > MLEN) {
1430 MCLGET(n, M_DONTWAIT);
1431 if ((n->m_flags & M_EXT) == 0) {
1432 m_free(n);
1433 n = NULL;
1434 }
1435 }
1436 if (n == NULL) {
1437 error = ENOBUFS;
1438 goto fail;
1439 }
1440 m_copydata(m, off, totlen, mtod(n, caddr_t));
1441 n->m_len = totlen;
1442 bzero(mtod(n, caddr_t) + hdrsiz, siz);
1443 (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1444 m_free(n);
1445 n = NULL;
1446 } else
1447 ah_update_mbuf(m, off, totlen, algo, &algos);
1448 ahseen++;
1449
1450 hdrtype = ah.ah_nxt;
1451 advancewidth = totlen;
1452 break;
1453 }
1454
1455 default:
1456 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo, &algos);
1457 advancewidth = m->m_pkthdr.len - off;
1458 break;
1459 }
1460
1461 off += advancewidth;
1462 if (off < m->m_pkthdr.len)
1463 goto again;
1464
1465 if (len < (*algo->sumsiz)(sav)) {
1466 error = EINVAL;
1467 goto fail;
1468 }
1469
1470 (algo->result)(&algos, (caddr_t) &sumbuf[0], sizeof(sumbuf));
1471 bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
1472
1473 if (n)
1474 m_free(n);
1475 return error;
1476
1477 fail:
1478 if (n)
1479 m_free(n);
1480 return error;
1481 }
1482 #endif
1483
1484 #if INET6
1485 /*
1486 * Go generate the checksum. This function won't modify the mbuf chain
1487 * except AH itself.
1488 *
1489 * NOTE: the function does not free mbuf on failure.
1490 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1491 */
1492 int
1493 ah6_calccksum(m, ahdat, len, algo, sav)
1494 struct mbuf *m;
1495 caddr_t ahdat;
1496 size_t len;
1497 const struct ah_algorithm *algo;
1498 struct secasvar *sav;
1499 {
1500 int newoff, off;
1501 int proto, nxt;
1502 struct mbuf *n = NULL;
1503 int error;
1504 int ahseen;
1505 struct ah_algorithm_state algos;
1506 u_char sumbuf[AH_MAXSUMSIZE] __attribute__((aligned(4)));
1507
1508 if ((m->m_flags & M_PKTHDR) == 0)
1509 return EINVAL;
1510
1511 error = (algo->init)(&algos, sav);
1512 if (error)
1513 return error;
1514
1515 off = 0;
1516 proto = IPPROTO_IPV6;
1517 nxt = -1;
1518 ahseen = 0;
1519
1520 again:
1521 newoff = ip6_nexthdr(m, off, proto, &nxt);
1522 if (newoff < 0)
1523 newoff = m->m_pkthdr.len;
1524 else if (newoff <= off) {
1525 error = EINVAL;
1526 goto fail;
1527 }
1528
1529 switch (proto) {
1530 case IPPROTO_IPV6:
1531 /*
1532 * special treatment is necessary for the first one, not others
1533 */
1534 if (off == 0) {
1535 struct ip6_hdr ip6copy;
1536
1537 if (newoff - off != sizeof(struct ip6_hdr)) {
1538 error = EINVAL;
1539 goto fail;
1540 }
1541
1542 m_copydata(m, off, newoff - off, (caddr_t)&ip6copy);
1543 /* RFC2402 */
1544 ip6copy.ip6_flow = 0;
1545 ip6copy.ip6_vfc &= ~IPV6_VERSION_MASK;
1546 ip6copy.ip6_vfc |= IPV6_VERSION;
1547 ip6copy.ip6_hlim = 0;
1548 if (IN6_IS_ADDR_LINKLOCAL(&ip6copy.ip6_src))
1549 ip6copy.ip6_src.s6_addr16[1] = 0x0000;
1550 if (IN6_IS_ADDR_LINKLOCAL(&ip6copy.ip6_dst))
1551 ip6copy.ip6_dst.s6_addr16[1] = 0x0000;
1552 (algo->update)(&algos, (caddr_t)&ip6copy,
1553 sizeof(struct ip6_hdr));
1554 } else {
1555 newoff = m->m_pkthdr.len;
1556 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo,
1557 &algos);
1558 }
1559 break;
1560
1561 case IPPROTO_AH:
1562 {
1563 int siz;
1564 int hdrsiz;
1565
1566 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1567 ? sizeof(struct ah)
1568 : sizeof(struct newah);
1569 siz = (*algo->sumsiz)(sav);
1570
1571 /*
1572 * special treatment is necessary for the first one, not others
1573 */
1574 if (!ahseen) {
1575 if (newoff - off > MCLBYTES) {
1576 error = EMSGSIZE;
1577 goto fail;
1578 }
1579 MGET(n, M_DONTWAIT, MT_DATA);
1580 if (n && newoff - off > MLEN) {
1581 MCLGET(n, M_DONTWAIT);
1582 if ((n->m_flags & M_EXT) == 0) {
1583 m_free(n);
1584 n = NULL;
1585 }
1586 }
1587 if (n == NULL) {
1588 error = ENOBUFS;
1589 goto fail;
1590 }
1591 m_copydata(m, off, newoff - off, mtod(n, caddr_t));
1592 n->m_len = newoff - off;
1593 bzero(mtod(n, caddr_t) + hdrsiz, siz);
1594 (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1595 m_free(n);
1596 n = NULL;
1597 } else
1598 ah_update_mbuf(m, off, newoff - off, algo, &algos);
1599 ahseen++;
1600 break;
1601 }
1602
1603 case IPPROTO_HOPOPTS:
1604 case IPPROTO_DSTOPTS:
1605 {
1606 struct ip6_ext *ip6e;
1607 int hdrlen, optlen;
1608 u_int8_t *p, *optend, *optp;
1609
1610 if (newoff - off > MCLBYTES) {
1611 error = EMSGSIZE;
1612 goto fail;
1613 }
1614 MGET(n, M_DONTWAIT, MT_DATA);
1615 if (n && newoff - off > MLEN) {
1616 MCLGET(n, M_DONTWAIT);
1617 if ((n->m_flags & M_EXT) == 0) {
1618 m_free(n);
1619 n = NULL;
1620 }
1621 }
1622 if (n == NULL) {
1623 error = ENOBUFS;
1624 goto fail;
1625 }
1626 m_copydata(m, off, newoff - off, mtod(n, caddr_t));
1627 n->m_len = newoff - off;
1628
1629 ip6e = mtod(n, struct ip6_ext *);
1630 hdrlen = (ip6e->ip6e_len + 1) << 3;
1631 if (newoff - off < hdrlen) {
1632 error = EINVAL;
1633 m_free(n);
1634 n = NULL;
1635 goto fail;
1636 }
1637 p = mtod(n, u_int8_t *);
1638 optend = p + hdrlen;
1639
1640 /*
1641 * ICV calculation for the options header including all
1642 * options. This part is a little tricky since there are
1643 * two type of options; mutable and immutable. We try to
1644 * null-out mutable ones here.
1645 */
1646 optp = p + 2;
1647 while (optp < optend) {
1648 if (optp[0] == IP6OPT_PAD1)
1649 optlen = 1;
1650 else {
1651 if (optp + 2 > optend) {
1652 error = EINVAL;
1653 m_free(n);
1654 n = NULL;
1655 goto fail;
1656 }
1657 optlen = optp[1] + 2;
1658
1659 if (optp[0] & IP6OPT_MUTABLE)
1660 bzero(optp + 2, optlen - 2);
1661 }
1662
1663 optp += optlen;
1664 }
1665
1666 (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1667 m_free(n);
1668 n = NULL;
1669 break;
1670 }
1671
1672 case IPPROTO_ROUTING:
1673 /*
1674 * For an input packet, we can just calculate `as is'.
1675 * For an output packet, we assume ip6_output have already
1676 * made packet how it will be received at the final
1677 * destination.
1678 */
1679 /* FALLTHROUGH */
1680
1681 default:
1682 ah_update_mbuf(m, off, newoff - off, algo, &algos);
1683 break;
1684 }
1685
1686 if (newoff < m->m_pkthdr.len) {
1687 proto = nxt;
1688 off = newoff;
1689 goto again;
1690 }
1691
1692 if (len < (*algo->sumsiz)(sav)) {
1693 error = EINVAL;
1694 goto fail;
1695 }
1696
1697 (algo->result)(&algos, (caddr_t) &sumbuf[0], sizeof(sumbuf));
1698 bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
1699
1700 /* just in case */
1701 if (n)
1702 m_free(n);
1703 return 0;
1704 fail:
1705 /* just in case */
1706 if (n)
1707 m_free(n);
1708 return error;
1709 }
1710 #endif