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