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