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