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